Revert:
[official-gcc.git] / gcc / config / i386 / i386.md
blob5265d838ecfc8a7c4796ed566defc57bdb26322d
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
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 2, 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 COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
51 ;; UNSPEC usage:
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
88    (UNSPEC_TRUNC_NOOP           29)
90    ; For SSE/MMX support:
91    (UNSPEC_FIX_NOTRUNC          30)
92    (UNSPEC_MASKMOV              31)
93    (UNSPEC_MOVMSK               32)
94    (UNSPEC_MOVNT                33)
95    (UNSPEC_MOVU                 34)
96    (UNSPEC_RCP                  35)
97    (UNSPEC_RSQRT                36)
98    (UNSPEC_SFENCE               37)
99    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
100    (UNSPEC_PFRCP                39)
101    (UNSPEC_PFRCPIT1             40)
102    (UNSPEC_PFRCPIT2             41)
103    (UNSPEC_PFRSQRT              42)
104    (UNSPEC_PFRSQIT1             43)
105    (UNSPEC_MFENCE               44)
106    (UNSPEC_LFENCE               45)
107    (UNSPEC_PSADBW               46)
108    (UNSPEC_LDDQU                47)
110    ; Generic math support
111    (UNSPEC_COPYSIGN             50)
112    (UNSPEC_IEEE_MIN             51)     ; not commutative
113    (UNSPEC_IEEE_MAX             52)     ; not commutative
115    ; x87 Floating point
116    (UNSPEC_SIN                  60)
117    (UNSPEC_COS                  61)
118    (UNSPEC_FPATAN               62)
119    (UNSPEC_FYL2X                63)
120    (UNSPEC_FYL2XP1              64)
121    (UNSPEC_FRNDINT              65)
122    (UNSPEC_FIST                 66)
123    (UNSPEC_F2XM1                67)
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_TAN_ONE              82)
137    (UNSPEC_TAN_TAN              83)
138    (UNSPEC_XTRACT_FRACT         84)
139    (UNSPEC_XTRACT_EXP           85)
140    (UNSPEC_FSCALE_FRACT         86)
141    (UNSPEC_FSCALE_EXP           87)
142    (UNSPEC_FPREM_F              88)
143    (UNSPEC_FPREM_U              89)
144    (UNSPEC_FPREM1_F             90)
145    (UNSPEC_FPREM1_U             91)
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)
157   ])
159 (define_constants
160   [(UNSPECV_BLOCKAGE            0)
161    (UNSPECV_STACK_PROBE         1)
162    (UNSPECV_EMMS                2)
163    (UNSPECV_LDMXCSR             3)
164    (UNSPECV_STMXCSR             4)
165    (UNSPECV_FEMMS               5)
166    (UNSPECV_CLFLUSH             6)
167    (UNSPECV_ALIGN               7)
168    (UNSPECV_MONITOR             8)
169    (UNSPECV_MWAIT               9)
170    (UNSPECV_CMPXCHG_1           10)
171    (UNSPECV_CMPXCHG_2           11)
172    (UNSPECV_XCHG                12)
173    (UNSPECV_LOCK                13)
174   ])
176 ;; Registers by name.
177 (define_constants
178   [(BP_REG                       6)
179    (SP_REG                       7)
180    (FLAGS_REG                   17)
181    (FPSR_REG                    18)
182    (FPCR_REG                    19)
183    (DIRFLAG_REG                 20)
184    (R11_REG                     41)
185   ])
187 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
188 ;; from i386.c.
190 ;; In C guard expressions, put expressions which may be compile-time
191 ;; constants first.  This allows for better optimization.  For
192 ;; example, write "TARGET_64BIT && reload_completed", not
193 ;; "reload_completed && TARGET_64BIT".
196 ;; Processor type.  This attribute must exactly match the processor_type
197 ;; enumeration in i386.h.
198 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
199   (const (symbol_ref "ix86_tune")))
201 ;; A basic instruction type.  Refinements due to arguments to be
202 ;; provided in other attributes.
203 (define_attr "type"
204   "other,multi,
205    alu,alu1,negnot,imov,imovx,lea,
206    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
207    icmp,test,ibr,setcc,icmov,
208    push,pop,call,callv,leave,
209    str,cld,
210    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
211    sselog,sselog1,sseiadd,sseishft,sseimul,
212    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
213    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
214   (const_string "other"))
216 ;; Main data type used by the insn
217 (define_attr "mode"
218   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
219   (const_string "unknown"))
221 ;; The CPU unit operations uses.
222 (define_attr "unit" "integer,i387,sse,mmx,unknown"
223   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
224            (const_string "i387")
225          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
226                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
227            (const_string "sse")
228          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
229            (const_string "mmx")
230          (eq_attr "type" "other")
231            (const_string "unknown")]
232          (const_string "integer")))
234 ;; The (bounding maximum) length of an instruction immediate.
235 (define_attr "length_immediate" ""
236   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
237            (const_int 0)
238          (eq_attr "unit" "i387,sse,mmx")
239            (const_int 0)
240          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
241                           imul,icmp,push,pop")
242            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
243          (eq_attr "type" "imov,test")
244            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
245          (eq_attr "type" "call")
246            (if_then_else (match_operand 0 "constant_call_address_operand" "")
247              (const_int 4)
248              (const_int 0))
249          (eq_attr "type" "callv")
250            (if_then_else (match_operand 1 "constant_call_address_operand" "")
251              (const_int 4)
252              (const_int 0))
253          ;; We don't know the size before shorten_branches.  Expect
254          ;; the instruction to fit for better scheduling.
255          (eq_attr "type" "ibr")
256            (const_int 1)
257          ]
258          (symbol_ref "/* Update immediate_length and other attributes! */
259                       gcc_unreachable (),1")))
261 ;; The (bounding maximum) length of an instruction address.
262 (define_attr "length_address" ""
263   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
264            (const_int 0)
265          (and (eq_attr "type" "call")
266               (match_operand 0 "constant_call_address_operand" ""))
267              (const_int 0)
268          (and (eq_attr "type" "callv")
269               (match_operand 1 "constant_call_address_operand" ""))
270              (const_int 0)
271          ]
272          (symbol_ref "ix86_attr_length_address_default (insn)")))
274 ;; Set when length prefix is used.
275 (define_attr "prefix_data16" ""
276   (if_then_else (ior (eq_attr "mode" "HI")
277                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
278     (const_int 1)
279     (const_int 0)))
281 ;; Set when string REP prefix is used.
282 (define_attr "prefix_rep" ""
283   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
284     (const_int 1)
285     (const_int 0)))
287 ;; Set when 0f opcode prefix is used.
288 (define_attr "prefix_0f" ""
289   (if_then_else
290     (ior (eq_attr "type" "imovx,setcc,icmov")
291          (eq_attr "unit" "sse,mmx"))
292     (const_int 1)
293     (const_int 0)))
295 ;; Set when REX opcode prefix is used.
296 (define_attr "prefix_rex" ""
297   (cond [(and (eq_attr "mode" "DI")
298               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
299            (const_int 1)
300          (and (eq_attr "mode" "QI")
301               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
302                   (const_int 0)))
303            (const_int 1)
304          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
305              (const_int 0))
306            (const_int 1)
307         ]
308         (const_int 0)))
310 ;; Set when modrm byte is used.
311 (define_attr "modrm" ""
312   (cond [(eq_attr "type" "str,cld,leave")
313            (const_int 0)
314          (eq_attr "unit" "i387")
315            (const_int 0)
316          (and (eq_attr "type" "incdec")
317               (ior (match_operand:SI 1 "register_operand" "")
318                    (match_operand:HI 1 "register_operand" "")))
319            (const_int 0)
320          (and (eq_attr "type" "push")
321               (not (match_operand 1 "memory_operand" "")))
322            (const_int 0)
323          (and (eq_attr "type" "pop")
324               (not (match_operand 0 "memory_operand" "")))
325            (const_int 0)
326          (and (eq_attr "type" "imov")
327               (ior (and (match_operand 0 "register_operand" "")
328                         (match_operand 1 "immediate_operand" ""))
329                    (ior (and (match_operand 0 "ax_reg_operand" "")
330                              (match_operand 1 "memory_displacement_only_operand" ""))
331                         (and (match_operand 0 "memory_displacement_only_operand" "")
332                              (match_operand 1 "ax_reg_operand" "")))))
333            (const_int 0)
334          (and (eq_attr "type" "call")
335               (match_operand 0 "constant_call_address_operand" ""))
336              (const_int 0)
337          (and (eq_attr "type" "callv")
338               (match_operand 1 "constant_call_address_operand" ""))
339              (const_int 0)
340          ]
341          (const_int 1)))
343 ;; The (bounding maximum) length of an instruction in bytes.
344 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
345 ;; Later we may want to split them and compute proper length as for
346 ;; other insns.
347 (define_attr "length" ""
348   (cond [(eq_attr "type" "other,multi,fistp,frndint")
349            (const_int 16)
350          (eq_attr "type" "fcmp")
351            (const_int 4)
352          (eq_attr "unit" "i387")
353            (plus (const_int 2)
354                  (plus (attr "prefix_data16")
355                        (attr "length_address")))]
356          (plus (plus (attr "modrm")
357                      (plus (attr "prefix_0f")
358                            (plus (attr "prefix_rex")
359                                  (const_int 1))))
360                (plus (attr "prefix_rep")
361                      (plus (attr "prefix_data16")
362                            (plus (attr "length_immediate")
363                                  (attr "length_address")))))))
365 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
366 ;; `store' if there is a simple memory reference therein, or `unknown'
367 ;; if the instruction is complex.
369 (define_attr "memory" "none,load,store,both,unknown"
370   (cond [(eq_attr "type" "other,multi,str")
371            (const_string "unknown")
372          (eq_attr "type" "lea,fcmov,fpspc,cld")
373            (const_string "none")
374          (eq_attr "type" "fistp,leave")
375            (const_string "both")
376          (eq_attr "type" "frndint")
377            (const_string "load")
378          (eq_attr "type" "push")
379            (if_then_else (match_operand 1 "memory_operand" "")
380              (const_string "both")
381              (const_string "store"))
382          (eq_attr "type" "pop")
383            (if_then_else (match_operand 0 "memory_operand" "")
384              (const_string "both")
385              (const_string "load"))
386          (eq_attr "type" "setcc")
387            (if_then_else (match_operand 0 "memory_operand" "")
388              (const_string "store")
389              (const_string "none"))
390          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
391            (if_then_else (ior (match_operand 0 "memory_operand" "")
392                               (match_operand 1 "memory_operand" ""))
393              (const_string "load")
394              (const_string "none"))
395          (eq_attr "type" "ibr")
396            (if_then_else (match_operand 0 "memory_operand" "")
397              (const_string "load")
398              (const_string "none"))
399          (eq_attr "type" "call")
400            (if_then_else (match_operand 0 "constant_call_address_operand" "")
401              (const_string "none")
402              (const_string "load"))
403          (eq_attr "type" "callv")
404            (if_then_else (match_operand 1 "constant_call_address_operand" "")
405              (const_string "none")
406              (const_string "load"))
407          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
408               (match_operand 1 "memory_operand" ""))
409            (const_string "both")
410          (and (match_operand 0 "memory_operand" "")
411               (match_operand 1 "memory_operand" ""))
412            (const_string "both")
413          (match_operand 0 "memory_operand" "")
414            (const_string "store")
415          (match_operand 1 "memory_operand" "")
416            (const_string "load")
417          (and (eq_attr "type"
418                  "!alu1,negnot,ishift1,
419                    imov,imovx,icmp,test,
420                    fmov,fcmp,fsgn,
421                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
422                    mmx,mmxmov,mmxcmp,mmxcvt")
423               (match_operand 2 "memory_operand" ""))
424            (const_string "load")
425          (and (eq_attr "type" "icmov")
426               (match_operand 3 "memory_operand" ""))
427            (const_string "load")
428         ]
429         (const_string "none")))
431 ;; Indicates if an instruction has both an immediate and a displacement.
433 (define_attr "imm_disp" "false,true,unknown"
434   (cond [(eq_attr "type" "other,multi")
435            (const_string "unknown")
436          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
437               (and (match_operand 0 "memory_displacement_operand" "")
438                    (match_operand 1 "immediate_operand" "")))
439            (const_string "true")
440          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
441               (and (match_operand 0 "memory_displacement_operand" "")
442                    (match_operand 2 "immediate_operand" "")))
443            (const_string "true")
444         ]
445         (const_string "false")))
447 ;; Indicates if an FP operation has an integer source.
449 (define_attr "fp_int_src" "false,true"
450   (const_string "false"))
452 ;; Defines rounding mode of an FP operation.
454 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
455   (const_string "any"))
457 ;; Describe a user's asm statement.
458 (define_asm_attributes
459   [(set_attr "length" "128")
460    (set_attr "type" "multi")])
462 ;; All x87 floating point modes
463 (define_mode_macro X87MODEF [SF DF XF])
465 ;; x87 SFmode and DFMode floating point modes
466 (define_mode_macro X87MODEF12 [SF DF])
468 ;; All integer modes handled by x87 fisttp operator.
469 (define_mode_macro X87MODEI [HI SI DI])
471 ;; All integer modes handled by integer x87 operators.
472 (define_mode_macro X87MODEI12 [HI SI])
474 ;; All SSE floating point modes
475 (define_mode_macro SSEMODEF [SF DF])
477 ;; All integer modes handled by SSE cvtts?2si* operators.
478 (define_mode_macro SSEMODEI24 [SI DI])
480 ;; SSE asm suffix for floating point modes
481 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
484 ;; Scheduling descriptions
486 (include "pentium.md")
487 (include "ppro.md")
488 (include "k6.md")
489 (include "athlon.md")
490 (include "geode.md")
493 ;; Operand and operator predicates and constraints
495 (include "predicates.md")
496 (include "constraints.md")
499 ;; Compare instructions.
501 ;; All compare insns have expanders that save the operands away without
502 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
503 ;; after the cmp) will actually emit the cmpM.
505 (define_expand "cmpti"
506   [(set (reg:CC FLAGS_REG)
507         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
508                     (match_operand:TI 1 "x86_64_general_operand" "")))]
509   "TARGET_64BIT"
511   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
512     operands[0] = force_reg (TImode, operands[0]);
513   ix86_compare_op0 = operands[0];
514   ix86_compare_op1 = operands[1];
515   DONE;
518 (define_expand "cmpdi"
519   [(set (reg:CC FLAGS_REG)
520         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
521                     (match_operand:DI 1 "x86_64_general_operand" "")))]
522   ""
524   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
525     operands[0] = force_reg (DImode, operands[0]);
526   ix86_compare_op0 = operands[0];
527   ix86_compare_op1 = operands[1];
528   DONE;
531 (define_expand "cmpsi"
532   [(set (reg:CC FLAGS_REG)
533         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
534                     (match_operand:SI 1 "general_operand" "")))]
535   ""
537   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
538     operands[0] = force_reg (SImode, operands[0]);
539   ix86_compare_op0 = operands[0];
540   ix86_compare_op1 = operands[1];
541   DONE;
544 (define_expand "cmphi"
545   [(set (reg:CC FLAGS_REG)
546         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
547                     (match_operand:HI 1 "general_operand" "")))]
548   ""
550   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
551     operands[0] = force_reg (HImode, operands[0]);
552   ix86_compare_op0 = operands[0];
553   ix86_compare_op1 = operands[1];
554   DONE;
557 (define_expand "cmpqi"
558   [(set (reg:CC FLAGS_REG)
559         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
560                     (match_operand:QI 1 "general_operand" "")))]
561   "TARGET_QIMODE_MATH"
563   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
564     operands[0] = force_reg (QImode, operands[0]);
565   ix86_compare_op0 = operands[0];
566   ix86_compare_op1 = operands[1];
567   DONE;
570 (define_insn "cmpdi_ccno_1_rex64"
571   [(set (reg FLAGS_REG)
572         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
573                  (match_operand:DI 1 "const0_operand" "n,n")))]
574   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
575   "@
576    test{q}\t{%0, %0|%0, %0}
577    cmp{q}\t{%1, %0|%0, %1}"
578   [(set_attr "type" "test,icmp")
579    (set_attr "length_immediate" "0,1")
580    (set_attr "mode" "DI")])
582 (define_insn "*cmpdi_minus_1_rex64"
583   [(set (reg FLAGS_REG)
584         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
585                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
586                  (const_int 0)))]
587   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
588   "cmp{q}\t{%1, %0|%0, %1}"
589   [(set_attr "type" "icmp")
590    (set_attr "mode" "DI")])
592 (define_expand "cmpdi_1_rex64"
593   [(set (reg:CC FLAGS_REG)
594         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
595                     (match_operand:DI 1 "general_operand" "")))]
596   "TARGET_64BIT"
597   "")
599 (define_insn "cmpdi_1_insn_rex64"
600   [(set (reg FLAGS_REG)
601         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
602                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
603   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
604   "cmp{q}\t{%1, %0|%0, %1}"
605   [(set_attr "type" "icmp")
606    (set_attr "mode" "DI")])
609 (define_insn "*cmpsi_ccno_1"
610   [(set (reg FLAGS_REG)
611         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
612                  (match_operand:SI 1 "const0_operand" "n,n")))]
613   "ix86_match_ccmode (insn, CCNOmode)"
614   "@
615    test{l}\t{%0, %0|%0, %0}
616    cmp{l}\t{%1, %0|%0, %1}"
617   [(set_attr "type" "test,icmp")
618    (set_attr "length_immediate" "0,1")
619    (set_attr "mode" "SI")])
621 (define_insn "*cmpsi_minus_1"
622   [(set (reg FLAGS_REG)
623         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
624                            (match_operand:SI 1 "general_operand" "ri,mr"))
625                  (const_int 0)))]
626   "ix86_match_ccmode (insn, CCGOCmode)"
627   "cmp{l}\t{%1, %0|%0, %1}"
628   [(set_attr "type" "icmp")
629    (set_attr "mode" "SI")])
631 (define_expand "cmpsi_1"
632   [(set (reg:CC FLAGS_REG)
633         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
634                     (match_operand:SI 1 "general_operand" "ri,mr")))]
635   ""
636   "")
638 (define_insn "*cmpsi_1_insn"
639   [(set (reg FLAGS_REG)
640         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
641                  (match_operand:SI 1 "general_operand" "ri,mr")))]
642   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
643     && ix86_match_ccmode (insn, CCmode)"
644   "cmp{l}\t{%1, %0|%0, %1}"
645   [(set_attr "type" "icmp")
646    (set_attr "mode" "SI")])
648 (define_insn "*cmphi_ccno_1"
649   [(set (reg FLAGS_REG)
650         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
651                  (match_operand:HI 1 "const0_operand" "n,n")))]
652   "ix86_match_ccmode (insn, CCNOmode)"
653   "@
654    test{w}\t{%0, %0|%0, %0}
655    cmp{w}\t{%1, %0|%0, %1}"
656   [(set_attr "type" "test,icmp")
657    (set_attr "length_immediate" "0,1")
658    (set_attr "mode" "HI")])
660 (define_insn "*cmphi_minus_1"
661   [(set (reg FLAGS_REG)
662         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
663                            (match_operand:HI 1 "general_operand" "ri,mr"))
664                  (const_int 0)))]
665   "ix86_match_ccmode (insn, CCGOCmode)"
666   "cmp{w}\t{%1, %0|%0, %1}"
667   [(set_attr "type" "icmp")
668    (set_attr "mode" "HI")])
670 (define_insn "*cmphi_1"
671   [(set (reg FLAGS_REG)
672         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
673                  (match_operand:HI 1 "general_operand" "ri,mr")))]
674   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
675    && ix86_match_ccmode (insn, CCmode)"
676   "cmp{w}\t{%1, %0|%0, %1}"
677   [(set_attr "type" "icmp")
678    (set_attr "mode" "HI")])
680 (define_insn "*cmpqi_ccno_1"
681   [(set (reg FLAGS_REG)
682         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
683                  (match_operand:QI 1 "const0_operand" "n,n")))]
684   "ix86_match_ccmode (insn, CCNOmode)"
685   "@
686    test{b}\t{%0, %0|%0, %0}
687    cmp{b}\t{$0, %0|%0, 0}"
688   [(set_attr "type" "test,icmp")
689    (set_attr "length_immediate" "0,1")
690    (set_attr "mode" "QI")])
692 (define_insn "*cmpqi_1"
693   [(set (reg FLAGS_REG)
694         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
695                  (match_operand:QI 1 "general_operand" "qi,mq")))]
696   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
697     && ix86_match_ccmode (insn, CCmode)"
698   "cmp{b}\t{%1, %0|%0, %1}"
699   [(set_attr "type" "icmp")
700    (set_attr "mode" "QI")])
702 (define_insn "*cmpqi_minus_1"
703   [(set (reg FLAGS_REG)
704         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
705                            (match_operand:QI 1 "general_operand" "qi,mq"))
706                  (const_int 0)))]
707   "ix86_match_ccmode (insn, CCGOCmode)"
708   "cmp{b}\t{%1, %0|%0, %1}"
709   [(set_attr "type" "icmp")
710    (set_attr "mode" "QI")])
712 (define_insn "*cmpqi_ext_1"
713   [(set (reg FLAGS_REG)
714         (compare
715           (match_operand:QI 0 "general_operand" "Qm")
716           (subreg:QI
717             (zero_extract:SI
718               (match_operand 1 "ext_register_operand" "Q")
719               (const_int 8)
720               (const_int 8)) 0)))]
721   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
722   "cmp{b}\t{%h1, %0|%0, %h1}"
723   [(set_attr "type" "icmp")
724    (set_attr "mode" "QI")])
726 (define_insn "*cmpqi_ext_1_rex64"
727   [(set (reg FLAGS_REG)
728         (compare
729           (match_operand:QI 0 "register_operand" "Q")
730           (subreg:QI
731             (zero_extract:SI
732               (match_operand 1 "ext_register_operand" "Q")
733               (const_int 8)
734               (const_int 8)) 0)))]
735   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
736   "cmp{b}\t{%h1, %0|%0, %h1}"
737   [(set_attr "type" "icmp")
738    (set_attr "mode" "QI")])
740 (define_insn "*cmpqi_ext_2"
741   [(set (reg FLAGS_REG)
742         (compare
743           (subreg:QI
744             (zero_extract:SI
745               (match_operand 0 "ext_register_operand" "Q")
746               (const_int 8)
747               (const_int 8)) 0)
748           (match_operand:QI 1 "const0_operand" "n")))]
749   "ix86_match_ccmode (insn, CCNOmode)"
750   "test{b}\t%h0, %h0"
751   [(set_attr "type" "test")
752    (set_attr "length_immediate" "0")
753    (set_attr "mode" "QI")])
755 (define_expand "cmpqi_ext_3"
756   [(set (reg:CC FLAGS_REG)
757         (compare:CC
758           (subreg:QI
759             (zero_extract:SI
760               (match_operand 0 "ext_register_operand" "")
761               (const_int 8)
762               (const_int 8)) 0)
763           (match_operand:QI 1 "general_operand" "")))]
764   ""
765   "")
767 (define_insn "cmpqi_ext_3_insn"
768   [(set (reg FLAGS_REG)
769         (compare
770           (subreg:QI
771             (zero_extract:SI
772               (match_operand 0 "ext_register_operand" "Q")
773               (const_int 8)
774               (const_int 8)) 0)
775           (match_operand:QI 1 "general_operand" "Qmn")))]
776   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
777   "cmp{b}\t{%1, %h0|%h0, %1}"
778   [(set_attr "type" "icmp")
779    (set_attr "mode" "QI")])
781 (define_insn "cmpqi_ext_3_insn_rex64"
782   [(set (reg FLAGS_REG)
783         (compare
784           (subreg:QI
785             (zero_extract:SI
786               (match_operand 0 "ext_register_operand" "Q")
787               (const_int 8)
788               (const_int 8)) 0)
789           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
790   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
791   "cmp{b}\t{%1, %h0|%h0, %1}"
792   [(set_attr "type" "icmp")
793    (set_attr "mode" "QI")])
795 (define_insn "*cmpqi_ext_4"
796   [(set (reg FLAGS_REG)
797         (compare
798           (subreg:QI
799             (zero_extract:SI
800               (match_operand 0 "ext_register_operand" "Q")
801               (const_int 8)
802               (const_int 8)) 0)
803           (subreg:QI
804             (zero_extract:SI
805               (match_operand 1 "ext_register_operand" "Q")
806               (const_int 8)
807               (const_int 8)) 0)))]
808   "ix86_match_ccmode (insn, CCmode)"
809   "cmp{b}\t{%h1, %h0|%h0, %h1}"
810   [(set_attr "type" "icmp")
811    (set_attr "mode" "QI")])
813 ;; These implement float point compares.
814 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
815 ;; which would allow mix and match FP modes on the compares.  Which is what
816 ;; the old patterns did, but with many more of them.
818 (define_expand "cmpxf"
819   [(set (reg:CC FLAGS_REG)
820         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
821                     (match_operand:XF 1 "nonmemory_operand" "")))]
822   "TARGET_80387"
824   ix86_compare_op0 = operands[0];
825   ix86_compare_op1 = operands[1];
826   DONE;
829 (define_expand "cmpdf"
830   [(set (reg:CC FLAGS_REG)
831         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
832                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
833   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
835   ix86_compare_op0 = operands[0];
836   ix86_compare_op1 = operands[1];
837   DONE;
840 (define_expand "cmpsf"
841   [(set (reg:CC FLAGS_REG)
842         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
843                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
844   "TARGET_80387 || TARGET_SSE_MATH"
846   ix86_compare_op0 = operands[0];
847   ix86_compare_op1 = operands[1];
848   DONE;
851 ;; FP compares, step 1:
852 ;; Set the FP condition codes.
854 ;; CCFPmode     compare with exceptions
855 ;; CCFPUmode    compare with no exceptions
857 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
858 ;; used to manage the reg stack popping would not be preserved.
860 (define_insn "*cmpfp_0"
861   [(set (match_operand:HI 0 "register_operand" "=a")
862         (unspec:HI
863           [(compare:CCFP
864              (match_operand 1 "register_operand" "f")
865              (match_operand 2 "const0_operand" "X"))]
866         UNSPEC_FNSTSW))]
867   "TARGET_80387
868    && FLOAT_MODE_P (GET_MODE (operands[1]))
869    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
870   "* return output_fp_compare (insn, operands, 0, 0);"
871   [(set_attr "type" "multi")
872    (set_attr "unit" "i387")
873    (set (attr "mode")
874      (cond [(match_operand:SF 1 "" "")
875               (const_string "SF")
876             (match_operand:DF 1 "" "")
877               (const_string "DF")
878            ]
879            (const_string "XF")))])
881 (define_insn "*cmpfp_sf"
882   [(set (match_operand:HI 0 "register_operand" "=a")
883         (unspec:HI
884           [(compare:CCFP
885              (match_operand:SF 1 "register_operand" "f")
886              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
887           UNSPEC_FNSTSW))]
888   "TARGET_80387"
889   "* return output_fp_compare (insn, operands, 0, 0);"
890   [(set_attr "type" "multi")
891    (set_attr "unit" "i387")
892    (set_attr "mode" "SF")])
894 (define_insn "*cmpfp_df"
895   [(set (match_operand:HI 0 "register_operand" "=a")
896         (unspec:HI
897           [(compare:CCFP
898              (match_operand:DF 1 "register_operand" "f")
899              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
900           UNSPEC_FNSTSW))]
901   "TARGET_80387"
902   "* return output_fp_compare (insn, operands, 0, 0);"
903   [(set_attr "type" "multi")
904    (set_attr "unit" "i387")
905    (set_attr "mode" "DF")])
907 (define_insn "*cmpfp_xf"
908   [(set (match_operand:HI 0 "register_operand" "=a")
909         (unspec:HI
910           [(compare:CCFP
911              (match_operand:XF 1 "register_operand" "f")
912              (match_operand:XF 2 "register_operand" "f"))]
913           UNSPEC_FNSTSW))]
914   "TARGET_80387"
915   "* return output_fp_compare (insn, operands, 0, 0);"
916   [(set_attr "type" "multi")
917    (set_attr "unit" "i387")
918    (set_attr "mode" "XF")])
920 (define_insn "*cmpfp_u"
921   [(set (match_operand:HI 0 "register_operand" "=a")
922         (unspec:HI
923           [(compare:CCFPU
924              (match_operand 1 "register_operand" "f")
925              (match_operand 2 "register_operand" "f"))]
926           UNSPEC_FNSTSW))]
927   "TARGET_80387
928    && FLOAT_MODE_P (GET_MODE (operands[1]))
929    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
930   "* return output_fp_compare (insn, operands, 0, 1);"
931   [(set_attr "type" "multi")
932    (set_attr "unit" "i387")
933    (set (attr "mode")
934      (cond [(match_operand:SF 1 "" "")
935               (const_string "SF")
936             (match_operand:DF 1 "" "")
937               (const_string "DF")
938            ]
939            (const_string "XF")))])
941 (define_insn "*cmpfp_<mode>"
942   [(set (match_operand:HI 0 "register_operand" "=a")
943         (unspec:HI
944           [(compare:CCFP
945              (match_operand 1 "register_operand" "f")
946              (match_operator 3 "float_operator"
947                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
948           UNSPEC_FNSTSW))]
949   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
950    && FLOAT_MODE_P (GET_MODE (operands[1]))
951    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
952   "* return output_fp_compare (insn, operands, 0, 0);"
953   [(set_attr "type" "multi")
954    (set_attr "unit" "i387")
955    (set_attr "fp_int_src" "true")
956    (set_attr "mode" "<MODE>")])
958 ;; FP compares, step 2
959 ;; Move the fpsw to ax.
961 (define_insn "x86_fnstsw_1"
962   [(set (match_operand:HI 0 "register_operand" "=a")
963         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
964   "TARGET_80387"
965   "fnstsw\t%0"
966   [(set_attr "length" "2")
967    (set_attr "mode" "SI")
968    (set_attr "unit" "i387")])
970 ;; FP compares, step 3
971 ;; Get ax into flags, general case.
973 (define_insn "x86_sahf_1"
974   [(set (reg:CC FLAGS_REG)
975         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
976   "!TARGET_64BIT"
977   "sahf"
978   [(set_attr "length" "1")
979    (set_attr "athlon_decode" "vector")
980    (set_attr "mode" "SI")])
982 ;; Pentium Pro can do steps 1 through 3 in one go.
984 (define_insn "*cmpfp_i_mixed"
985   [(set (reg:CCFP FLAGS_REG)
986         (compare:CCFP (match_operand 0 "register_operand" "f,x")
987                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
988   "TARGET_MIX_SSE_I387
989    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991   "* return output_fp_compare (insn, operands, 1, 0);"
992   [(set_attr "type" "fcmp,ssecomi")
993    (set (attr "mode")
994      (if_then_else (match_operand:SF 1 "" "")
995         (const_string "SF")
996         (const_string "DF")))
997    (set_attr "athlon_decode" "vector")])
999 (define_insn "*cmpfp_i_sse"
1000   [(set (reg:CCFP FLAGS_REG)
1001         (compare:CCFP (match_operand 0 "register_operand" "x")
1002                       (match_operand 1 "nonimmediate_operand" "xm")))]
1003   "TARGET_SSE_MATH
1004    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1005    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006   "* return output_fp_compare (insn, operands, 1, 0);"
1007   [(set_attr "type" "ssecomi")
1008    (set (attr "mode")
1009      (if_then_else (match_operand:SF 1 "" "")
1010         (const_string "SF")
1011         (const_string "DF")))
1012    (set_attr "athlon_decode" "vector")])
1014 (define_insn "*cmpfp_i_i387"
1015   [(set (reg:CCFP FLAGS_REG)
1016         (compare:CCFP (match_operand 0 "register_operand" "f")
1017                       (match_operand 1 "register_operand" "f")))]
1018   "TARGET_80387 && TARGET_CMOVE
1019    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1020    && FLOAT_MODE_P (GET_MODE (operands[0]))
1021    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022   "* return output_fp_compare (insn, operands, 1, 0);"
1023   [(set_attr "type" "fcmp")
1024    (set (attr "mode")
1025      (cond [(match_operand:SF 1 "" "")
1026               (const_string "SF")
1027             (match_operand:DF 1 "" "")
1028               (const_string "DF")
1029            ]
1030            (const_string "XF")))
1031    (set_attr "athlon_decode" "vector")])
1033 (define_insn "*cmpfp_iu_mixed"
1034   [(set (reg:CCFPU FLAGS_REG)
1035         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1036                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1037   "TARGET_MIX_SSE_I387
1038    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040   "* return output_fp_compare (insn, operands, 1, 1);"
1041   [(set_attr "type" "fcmp,ssecomi")
1042    (set (attr "mode")
1043      (if_then_else (match_operand:SF 1 "" "")
1044         (const_string "SF")
1045         (const_string "DF")))
1046    (set_attr "athlon_decode" "vector")])
1048 (define_insn "*cmpfp_iu_sse"
1049   [(set (reg:CCFPU FLAGS_REG)
1050         (compare:CCFPU (match_operand 0 "register_operand" "x")
1051                        (match_operand 1 "nonimmediate_operand" "xm")))]
1052   "TARGET_SSE_MATH
1053    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1054    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055   "* return output_fp_compare (insn, operands, 1, 1);"
1056   [(set_attr "type" "ssecomi")
1057    (set (attr "mode")
1058      (if_then_else (match_operand:SF 1 "" "")
1059         (const_string "SF")
1060         (const_string "DF")))
1061    (set_attr "athlon_decode" "vector")])
1063 (define_insn "*cmpfp_iu_387"
1064   [(set (reg:CCFPU FLAGS_REG)
1065         (compare:CCFPU (match_operand 0 "register_operand" "f")
1066                        (match_operand 1 "register_operand" "f")))]
1067   "TARGET_80387 && TARGET_CMOVE
1068    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1069    && FLOAT_MODE_P (GET_MODE (operands[0]))
1070    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1071   "* return output_fp_compare (insn, operands, 1, 1);"
1072   [(set_attr "type" "fcmp")
1073    (set (attr "mode")
1074      (cond [(match_operand:SF 1 "" "")
1075               (const_string "SF")
1076             (match_operand:DF 1 "" "")
1077               (const_string "DF")
1078            ]
1079            (const_string "XF")))
1080    (set_attr "athlon_decode" "vector")])
1082 ;; Move instructions.
1084 ;; General case of fullword move.
1086 (define_expand "movsi"
1087   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1088         (match_operand:SI 1 "general_operand" ""))]
1089   ""
1090   "ix86_expand_move (SImode, operands); DONE;")
1092 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1093 ;; general_operand.
1095 ;; %%% We don't use a post-inc memory reference because x86 is not a
1096 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1097 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1098 ;; targets without our curiosities, and it is just as easy to represent
1099 ;; this differently.
1101 (define_insn "*pushsi2"
1102   [(set (match_operand:SI 0 "push_operand" "=<")
1103         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1104   "!TARGET_64BIT"
1105   "push{l}\t%1"
1106   [(set_attr "type" "push")
1107    (set_attr "mode" "SI")])
1109 ;; For 64BIT abi we always round up to 8 bytes.
1110 (define_insn "*pushsi2_rex64"
1111   [(set (match_operand:SI 0 "push_operand" "=X")
1112         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1113   "TARGET_64BIT"
1114   "push{q}\t%q1"
1115   [(set_attr "type" "push")
1116    (set_attr "mode" "SI")])
1118 (define_insn "*pushsi2_prologue"
1119   [(set (match_operand:SI 0 "push_operand" "=<")
1120         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1121    (clobber (mem:BLK (scratch)))]
1122   "!TARGET_64BIT"
1123   "push{l}\t%1"
1124   [(set_attr "type" "push")
1125    (set_attr "mode" "SI")])
1127 (define_insn "*popsi1_epilogue"
1128   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1129         (mem:SI (reg:SI SP_REG)))
1130    (set (reg:SI SP_REG)
1131         (plus:SI (reg:SI SP_REG) (const_int 4)))
1132    (clobber (mem:BLK (scratch)))]
1133   "!TARGET_64BIT"
1134   "pop{l}\t%0"
1135   [(set_attr "type" "pop")
1136    (set_attr "mode" "SI")])
1138 (define_insn "popsi1"
1139   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1140         (mem:SI (reg:SI SP_REG)))
1141    (set (reg:SI SP_REG)
1142         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1143   "!TARGET_64BIT"
1144   "pop{l}\t%0"
1145   [(set_attr "type" "pop")
1146    (set_attr "mode" "SI")])
1148 (define_insn "*movsi_xor"
1149   [(set (match_operand:SI 0 "register_operand" "=r")
1150         (match_operand:SI 1 "const0_operand" "i"))
1151    (clobber (reg:CC FLAGS_REG))]
1152   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1153   "xor{l}\t{%0, %0|%0, %0}"
1154   [(set_attr "type" "alu1")
1155    (set_attr "mode" "SI")
1156    (set_attr "length_immediate" "0")])
1158 (define_insn "*movsi_or"
1159   [(set (match_operand:SI 0 "register_operand" "=r")
1160         (match_operand:SI 1 "immediate_operand" "i"))
1161    (clobber (reg:CC FLAGS_REG))]
1162   "reload_completed
1163    && operands[1] == constm1_rtx
1164    && (TARGET_PENTIUM || optimize_size)"
1166   operands[1] = constm1_rtx;
1167   return "or{l}\t{%1, %0|%0, %1}";
1169   [(set_attr "type" "alu1")
1170    (set_attr "mode" "SI")
1171    (set_attr "length_immediate" "1")])
1173 (define_insn "*movsi_1"
1174   [(set (match_operand:SI 0 "nonimmediate_operand"
1175                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1176         (match_operand:SI 1 "general_operand"
1177                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1178   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1180   switch (get_attr_type (insn))
1181     {
1182     case TYPE_SSELOG1:
1183       if (get_attr_mode (insn) == MODE_TI)
1184         return "pxor\t%0, %0";
1185       return "xorps\t%0, %0";
1187     case TYPE_SSEMOV:
1188       switch (get_attr_mode (insn))
1189         {
1190         case MODE_TI:
1191           return "movdqa\t{%1, %0|%0, %1}";
1192         case MODE_V4SF:
1193           return "movaps\t{%1, %0|%0, %1}";
1194         case MODE_SI:
1195           return "movd\t{%1, %0|%0, %1}";
1196         case MODE_SF:
1197           return "movss\t{%1, %0|%0, %1}";
1198         default:
1199           gcc_unreachable ();
1200         }
1202     case TYPE_MMXADD:
1203       return "pxor\t%0, %0";
1205     case TYPE_MMXMOV:
1206       if (get_attr_mode (insn) == MODE_DI)
1207         return "movq\t{%1, %0|%0, %1}";
1208       return "movd\t{%1, %0|%0, %1}";
1210     case TYPE_LEA:
1211       return "lea{l}\t{%1, %0|%0, %1}";
1213     default:
1214       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1215       return "mov{l}\t{%1, %0|%0, %1}";
1216     }
1218   [(set (attr "type")
1219      (cond [(eq_attr "alternative" "2")
1220               (const_string "mmxadd")
1221             (eq_attr "alternative" "3,4,5")
1222               (const_string "mmxmov")
1223             (eq_attr "alternative" "6")
1224               (const_string "sselog1")
1225             (eq_attr "alternative" "7,8,9,10,11")
1226               (const_string "ssemov")
1227             (match_operand:DI 1 "pic_32bit_operand" "")
1228               (const_string "lea")
1229            ]
1230            (const_string "imov")))
1231    (set (attr "mode")
1232      (cond [(eq_attr "alternative" "2,3")
1233               (const_string "DI")
1234             (eq_attr "alternative" "6,7")
1235               (if_then_else
1236                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1237                 (const_string "V4SF")
1238                 (const_string "TI"))
1239             (and (eq_attr "alternative" "8,9,10,11")
1240                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1241               (const_string "SF")
1242            ]
1243            (const_string "SI")))])
1245 ;; Stores and loads of ax to arbitrary constant address.
1246 ;; We fake an second form of instruction to force reload to load address
1247 ;; into register when rax is not available
1248 (define_insn "*movabssi_1_rex64"
1249   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1250         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1251   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1252   "@
1253    movabs{l}\t{%1, %P0|%P0, %1}
1254    mov{l}\t{%1, %a0|%a0, %1}"
1255   [(set_attr "type" "imov")
1256    (set_attr "modrm" "0,*")
1257    (set_attr "length_address" "8,0")
1258    (set_attr "length_immediate" "0,*")
1259    (set_attr "memory" "store")
1260    (set_attr "mode" "SI")])
1262 (define_insn "*movabssi_2_rex64"
1263   [(set (match_operand:SI 0 "register_operand" "=a,r")
1264         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1265   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1266   "@
1267    movabs{l}\t{%P1, %0|%0, %P1}
1268    mov{l}\t{%a1, %0|%0, %a1}"
1269   [(set_attr "type" "imov")
1270    (set_attr "modrm" "0,*")
1271    (set_attr "length_address" "8,0")
1272    (set_attr "length_immediate" "0")
1273    (set_attr "memory" "load")
1274    (set_attr "mode" "SI")])
1276 (define_insn "*swapsi"
1277   [(set (match_operand:SI 0 "register_operand" "+r")
1278         (match_operand:SI 1 "register_operand" "+r"))
1279    (set (match_dup 1)
1280         (match_dup 0))]
1281   ""
1282   "xchg{l}\t%1, %0"
1283   [(set_attr "type" "imov")
1284    (set_attr "mode" "SI")
1285    (set_attr "pent_pair" "np")
1286    (set_attr "athlon_decode" "vector")])
1288 (define_expand "movhi"
1289   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1290         (match_operand:HI 1 "general_operand" ""))]
1291   ""
1292   "ix86_expand_move (HImode, operands); DONE;")
1294 (define_insn "*pushhi2"
1295   [(set (match_operand:HI 0 "push_operand" "=X")
1296         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1297   "!TARGET_64BIT"
1298   "push{l}\t%k1"
1299   [(set_attr "type" "push")
1300    (set_attr "mode" "SI")])
1302 ;; For 64BIT abi we always round up to 8 bytes.
1303 (define_insn "*pushhi2_rex64"
1304   [(set (match_operand:HI 0 "push_operand" "=X")
1305         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1306   "TARGET_64BIT"
1307   "push{q}\t%q1"
1308   [(set_attr "type" "push")
1309    (set_attr "mode" "DI")])
1311 (define_insn "*movhi_1"
1312   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1313         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1314   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1316   switch (get_attr_type (insn))
1317     {
1318     case TYPE_IMOVX:
1319       /* movzwl is faster than movw on p2 due to partial word stalls,
1320          though not as fast as an aligned movl.  */
1321       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1322     default:
1323       if (get_attr_mode (insn) == MODE_SI)
1324         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1325       else
1326         return "mov{w}\t{%1, %0|%0, %1}";
1327     }
1329   [(set (attr "type")
1330      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1331               (const_string "imov")
1332             (and (eq_attr "alternative" "0")
1333                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1334                           (const_int 0))
1335                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1336                           (const_int 0))))
1337               (const_string "imov")
1338             (and (eq_attr "alternative" "1,2")
1339                  (match_operand:HI 1 "aligned_operand" ""))
1340               (const_string "imov")
1341             (and (ne (symbol_ref "TARGET_MOVX")
1342                      (const_int 0))
1343                  (eq_attr "alternative" "0,2"))
1344               (const_string "imovx")
1345            ]
1346            (const_string "imov")))
1347     (set (attr "mode")
1348       (cond [(eq_attr "type" "imovx")
1349                (const_string "SI")
1350              (and (eq_attr "alternative" "1,2")
1351                   (match_operand:HI 1 "aligned_operand" ""))
1352                (const_string "SI")
1353              (and (eq_attr "alternative" "0")
1354                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1355                            (const_int 0))
1356                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1357                            (const_int 0))))
1358                (const_string "SI")
1359             ]
1360             (const_string "HI")))])
1362 ;; Stores and loads of ax to arbitrary constant address.
1363 ;; We fake an second form of instruction to force reload to load address
1364 ;; into register when rax is not available
1365 (define_insn "*movabshi_1_rex64"
1366   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1367         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1368   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1369   "@
1370    movabs{w}\t{%1, %P0|%P0, %1}
1371    mov{w}\t{%1, %a0|%a0, %1}"
1372   [(set_attr "type" "imov")
1373    (set_attr "modrm" "0,*")
1374    (set_attr "length_address" "8,0")
1375    (set_attr "length_immediate" "0,*")
1376    (set_attr "memory" "store")
1377    (set_attr "mode" "HI")])
1379 (define_insn "*movabshi_2_rex64"
1380   [(set (match_operand:HI 0 "register_operand" "=a,r")
1381         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1382   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1383   "@
1384    movabs{w}\t{%P1, %0|%0, %P1}
1385    mov{w}\t{%a1, %0|%0, %a1}"
1386   [(set_attr "type" "imov")
1387    (set_attr "modrm" "0,*")
1388    (set_attr "length_address" "8,0")
1389    (set_attr "length_immediate" "0")
1390    (set_attr "memory" "load")
1391    (set_attr "mode" "HI")])
1393 (define_insn "*swaphi_1"
1394   [(set (match_operand:HI 0 "register_operand" "+r")
1395         (match_operand:HI 1 "register_operand" "+r"))
1396    (set (match_dup 1)
1397         (match_dup 0))]
1398   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1399   "xchg{l}\t%k1, %k0"
1400   [(set_attr "type" "imov")
1401    (set_attr "mode" "SI")
1402    (set_attr "pent_pair" "np")
1403    (set_attr "athlon_decode" "vector")])
1405 (define_insn "*swaphi_2"
1406   [(set (match_operand:HI 0 "register_operand" "+r")
1407         (match_operand:HI 1 "register_operand" "+r"))
1408    (set (match_dup 1)
1409         (match_dup 0))]
1410   "TARGET_PARTIAL_REG_STALL"
1411   "xchg{w}\t%1, %0"
1412   [(set_attr "type" "imov")
1413    (set_attr "mode" "HI")
1414    (set_attr "pent_pair" "np")
1415    (set_attr "athlon_decode" "vector")])
1417 (define_expand "movstricthi"
1418   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1419         (match_operand:HI 1 "general_operand" ""))]
1420   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1422   /* Don't generate memory->memory moves, go through a register */
1423   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1424     operands[1] = force_reg (HImode, operands[1]);
1427 (define_insn "*movstricthi_1"
1428   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1429         (match_operand:HI 1 "general_operand" "rn,m"))]
1430   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1431    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1432   "mov{w}\t{%1, %0|%0, %1}"
1433   [(set_attr "type" "imov")
1434    (set_attr "mode" "HI")])
1436 (define_insn "*movstricthi_xor"
1437   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1438         (match_operand:HI 1 "const0_operand" "i"))
1439    (clobber (reg:CC FLAGS_REG))]
1440   "reload_completed
1441    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1442   "xor{w}\t{%0, %0|%0, %0}"
1443   [(set_attr "type" "alu1")
1444    (set_attr "mode" "HI")
1445    (set_attr "length_immediate" "0")])
1447 (define_expand "movqi"
1448   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1449         (match_operand:QI 1 "general_operand" ""))]
1450   ""
1451   "ix86_expand_move (QImode, operands); DONE;")
1453 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1454 ;; "push a byte".  But actually we use pushl, which has the effect
1455 ;; of rounding the amount pushed up to a word.
1457 (define_insn "*pushqi2"
1458   [(set (match_operand:QI 0 "push_operand" "=X")
1459         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1460   "!TARGET_64BIT"
1461   "push{l}\t%k1"
1462   [(set_attr "type" "push")
1463    (set_attr "mode" "SI")])
1465 ;; For 64BIT abi we always round up to 8 bytes.
1466 (define_insn "*pushqi2_rex64"
1467   [(set (match_operand:QI 0 "push_operand" "=X")
1468         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1469   "TARGET_64BIT"
1470   "push{q}\t%q1"
1471   [(set_attr "type" "push")
1472    (set_attr "mode" "DI")])
1474 ;; Situation is quite tricky about when to choose full sized (SImode) move
1475 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1476 ;; partial register dependency machines (such as AMD Athlon), where QImode
1477 ;; moves issue extra dependency and for partial register stalls machines
1478 ;; that don't use QImode patterns (and QImode move cause stall on the next
1479 ;; instruction).
1481 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1482 ;; register stall machines with, where we use QImode instructions, since
1483 ;; partial register stall can be caused there.  Then we use movzx.
1484 (define_insn "*movqi_1"
1485   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1486         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1487   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1489   switch (get_attr_type (insn))
1490     {
1491     case TYPE_IMOVX:
1492       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1493       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1494     default:
1495       if (get_attr_mode (insn) == MODE_SI)
1496         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1497       else
1498         return "mov{b}\t{%1, %0|%0, %1}";
1499     }
1501   [(set (attr "type")
1502      (cond [(and (eq_attr "alternative" "5")
1503                  (not (match_operand:QI 1 "aligned_operand" "")))
1504               (const_string "imovx")
1505             (ne (symbol_ref "optimize_size") (const_int 0))
1506               (const_string "imov")
1507             (and (eq_attr "alternative" "3")
1508                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1509                           (const_int 0))
1510                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1511                           (const_int 0))))
1512               (const_string "imov")
1513             (eq_attr "alternative" "3,5")
1514               (const_string "imovx")
1515             (and (ne (symbol_ref "TARGET_MOVX")
1516                      (const_int 0))
1517                  (eq_attr "alternative" "2"))
1518               (const_string "imovx")
1519            ]
1520            (const_string "imov")))
1521    (set (attr "mode")
1522       (cond [(eq_attr "alternative" "3,4,5")
1523                (const_string "SI")
1524              (eq_attr "alternative" "6")
1525                (const_string "QI")
1526              (eq_attr "type" "imovx")
1527                (const_string "SI")
1528              (and (eq_attr "type" "imov")
1529                   (and (eq_attr "alternative" "0,1")
1530                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1531                                 (const_int 0))
1532                             (and (eq (symbol_ref "optimize_size")
1533                                      (const_int 0))
1534                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1535                                      (const_int 0))))))
1536                (const_string "SI")
1537              ;; Avoid partial register stalls when not using QImode arithmetic
1538              (and (eq_attr "type" "imov")
1539                   (and (eq_attr "alternative" "0,1")
1540                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1541                                 (const_int 0))
1542                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1543                                 (const_int 0)))))
1544                (const_string "SI")
1545            ]
1546            (const_string "QI")))])
1548 (define_expand "reload_outqi"
1549   [(parallel [(match_operand:QI 0 "" "=m")
1550               (match_operand:QI 1 "register_operand" "r")
1551               (match_operand:QI 2 "register_operand" "=&q")])]
1552   ""
1554   rtx op0, op1, op2;
1555   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1557   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1558   if (! q_regs_operand (op1, QImode))
1559     {
1560       emit_insn (gen_movqi (op2, op1));
1561       op1 = op2;
1562     }
1563   emit_insn (gen_movqi (op0, op1));
1564   DONE;
1567 (define_insn "*swapqi_1"
1568   [(set (match_operand:QI 0 "register_operand" "+r")
1569         (match_operand:QI 1 "register_operand" "+r"))
1570    (set (match_dup 1)
1571         (match_dup 0))]
1572   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1573   "xchg{l}\t%k1, %k0"
1574   [(set_attr "type" "imov")
1575    (set_attr "mode" "SI")
1576    (set_attr "pent_pair" "np")
1577    (set_attr "athlon_decode" "vector")])
1579 (define_insn "*swapqi_2"
1580   [(set (match_operand:QI 0 "register_operand" "+q")
1581         (match_operand:QI 1 "register_operand" "+q"))
1582    (set (match_dup 1)
1583         (match_dup 0))]
1584   "TARGET_PARTIAL_REG_STALL"
1585   "xchg{b}\t%1, %0"
1586   [(set_attr "type" "imov")
1587    (set_attr "mode" "QI")
1588    (set_attr "pent_pair" "np")
1589    (set_attr "athlon_decode" "vector")])
1591 (define_expand "movstrictqi"
1592   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1593         (match_operand:QI 1 "general_operand" ""))]
1594   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1596   /* Don't generate memory->memory moves, go through a register.  */
1597   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1598     operands[1] = force_reg (QImode, operands[1]);
1601 (define_insn "*movstrictqi_1"
1602   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1603         (match_operand:QI 1 "general_operand" "*qn,m"))]
1604   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1605    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1606   "mov{b}\t{%1, %0|%0, %1}"
1607   [(set_attr "type" "imov")
1608    (set_attr "mode" "QI")])
1610 (define_insn "*movstrictqi_xor"
1611   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1612         (match_operand:QI 1 "const0_operand" "i"))
1613    (clobber (reg:CC FLAGS_REG))]
1614   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1615   "xor{b}\t{%0, %0|%0, %0}"
1616   [(set_attr "type" "alu1")
1617    (set_attr "mode" "QI")
1618    (set_attr "length_immediate" "0")])
1620 (define_insn "*movsi_extv_1"
1621   [(set (match_operand:SI 0 "register_operand" "=R")
1622         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1623                          (const_int 8)
1624                          (const_int 8)))]
1625   ""
1626   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1627   [(set_attr "type" "imovx")
1628    (set_attr "mode" "SI")])
1630 (define_insn "*movhi_extv_1"
1631   [(set (match_operand:HI 0 "register_operand" "=R")
1632         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1633                          (const_int 8)
1634                          (const_int 8)))]
1635   ""
1636   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1637   [(set_attr "type" "imovx")
1638    (set_attr "mode" "SI")])
1640 (define_insn "*movqi_extv_1"
1641   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1642         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1643                          (const_int 8)
1644                          (const_int 8)))]
1645   "!TARGET_64BIT"
1647   switch (get_attr_type (insn))
1648     {
1649     case TYPE_IMOVX:
1650       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1651     default:
1652       return "mov{b}\t{%h1, %0|%0, %h1}";
1653     }
1655   [(set (attr "type")
1656      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1657                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1658                              (ne (symbol_ref "TARGET_MOVX")
1659                                  (const_int 0))))
1660         (const_string "imovx")
1661         (const_string "imov")))
1662    (set (attr "mode")
1663      (if_then_else (eq_attr "type" "imovx")
1664         (const_string "SI")
1665         (const_string "QI")))])
1667 (define_insn "*movqi_extv_1_rex64"
1668   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1669         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1670                          (const_int 8)
1671                          (const_int 8)))]
1672   "TARGET_64BIT"
1674   switch (get_attr_type (insn))
1675     {
1676     case TYPE_IMOVX:
1677       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1678     default:
1679       return "mov{b}\t{%h1, %0|%0, %h1}";
1680     }
1682   [(set (attr "type")
1683      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1684                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1685                              (ne (symbol_ref "TARGET_MOVX")
1686                                  (const_int 0))))
1687         (const_string "imovx")
1688         (const_string "imov")))
1689    (set (attr "mode")
1690      (if_then_else (eq_attr "type" "imovx")
1691         (const_string "SI")
1692         (const_string "QI")))])
1694 ;; Stores and loads of ax to arbitrary constant address.
1695 ;; We fake an second form of instruction to force reload to load address
1696 ;; into register when rax is not available
1697 (define_insn "*movabsqi_1_rex64"
1698   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1699         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1700   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1701   "@
1702    movabs{b}\t{%1, %P0|%P0, %1}
1703    mov{b}\t{%1, %a0|%a0, %1}"
1704   [(set_attr "type" "imov")
1705    (set_attr "modrm" "0,*")
1706    (set_attr "length_address" "8,0")
1707    (set_attr "length_immediate" "0,*")
1708    (set_attr "memory" "store")
1709    (set_attr "mode" "QI")])
1711 (define_insn "*movabsqi_2_rex64"
1712   [(set (match_operand:QI 0 "register_operand" "=a,r")
1713         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1714   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1715   "@
1716    movabs{b}\t{%P1, %0|%0, %P1}
1717    mov{b}\t{%a1, %0|%0, %a1}"
1718   [(set_attr "type" "imov")
1719    (set_attr "modrm" "0,*")
1720    (set_attr "length_address" "8,0")
1721    (set_attr "length_immediate" "0")
1722    (set_attr "memory" "load")
1723    (set_attr "mode" "QI")])
1725 (define_insn "*movdi_extzv_1"
1726   [(set (match_operand:DI 0 "register_operand" "=R")
1727         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1728                          (const_int 8)
1729                          (const_int 8)))]
1730   "TARGET_64BIT"
1731   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1732   [(set_attr "type" "imovx")
1733    (set_attr "mode" "DI")])
1735 (define_insn "*movsi_extzv_1"
1736   [(set (match_operand:SI 0 "register_operand" "=R")
1737         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1738                          (const_int 8)
1739                          (const_int 8)))]
1740   ""
1741   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1742   [(set_attr "type" "imovx")
1743    (set_attr "mode" "SI")])
1745 (define_insn "*movqi_extzv_2"
1746   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1747         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1748                                     (const_int 8)
1749                                     (const_int 8)) 0))]
1750   "!TARGET_64BIT"
1752   switch (get_attr_type (insn))
1753     {
1754     case TYPE_IMOVX:
1755       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1756     default:
1757       return "mov{b}\t{%h1, %0|%0, %h1}";
1758     }
1760   [(set (attr "type")
1761      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1762                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1763                              (ne (symbol_ref "TARGET_MOVX")
1764                                  (const_int 0))))
1765         (const_string "imovx")
1766         (const_string "imov")))
1767    (set (attr "mode")
1768      (if_then_else (eq_attr "type" "imovx")
1769         (const_string "SI")
1770         (const_string "QI")))])
1772 (define_insn "*movqi_extzv_2_rex64"
1773   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1774         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1775                                     (const_int 8)
1776                                     (const_int 8)) 0))]
1777   "TARGET_64BIT"
1779   switch (get_attr_type (insn))
1780     {
1781     case TYPE_IMOVX:
1782       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1783     default:
1784       return "mov{b}\t{%h1, %0|%0, %h1}";
1785     }
1787   [(set (attr "type")
1788      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789                         (ne (symbol_ref "TARGET_MOVX")
1790                             (const_int 0)))
1791         (const_string "imovx")
1792         (const_string "imov")))
1793    (set (attr "mode")
1794      (if_then_else (eq_attr "type" "imovx")
1795         (const_string "SI")
1796         (const_string "QI")))])
1798 (define_insn "movsi_insv_1"
1799   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1800                          (const_int 8)
1801                          (const_int 8))
1802         (match_operand:SI 1 "general_operand" "Qmn"))]
1803   "!TARGET_64BIT"
1804   "mov{b}\t{%b1, %h0|%h0, %b1}"
1805   [(set_attr "type" "imov")
1806    (set_attr "mode" "QI")])
1808 (define_insn "movdi_insv_1_rex64"
1809   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1810                          (const_int 8)
1811                          (const_int 8))
1812         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1813   "TARGET_64BIT"
1814   "mov{b}\t{%b1, %h0|%h0, %b1}"
1815   [(set_attr "type" "imov")
1816    (set_attr "mode" "QI")])
1818 (define_insn "*movqi_insv_2"
1819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1820                          (const_int 8)
1821                          (const_int 8))
1822         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1823                      (const_int 8)))]
1824   ""
1825   "mov{b}\t{%h1, %h0|%h0, %h1}"
1826   [(set_attr "type" "imov")
1827    (set_attr "mode" "QI")])
1829 (define_expand "movdi"
1830   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1831         (match_operand:DI 1 "general_operand" ""))]
1832   ""
1833   "ix86_expand_move (DImode, operands); DONE;")
1835 (define_insn "*pushdi"
1836   [(set (match_operand:DI 0 "push_operand" "=<")
1837         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1838   "!TARGET_64BIT"
1839   "#")
1841 (define_insn "*pushdi2_rex64"
1842   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1843         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1844   "TARGET_64BIT"
1845   "@
1846    push{q}\t%1
1847    #"
1848   [(set_attr "type" "push,multi")
1849    (set_attr "mode" "DI")])
1851 ;; Convert impossible pushes of immediate to existing instructions.
1852 ;; First try to get scratch register and go through it.  In case this
1853 ;; fails, push sign extended lower part first and then overwrite
1854 ;; upper part by 32bit move.
1855 (define_peephole2
1856   [(match_scratch:DI 2 "r")
1857    (set (match_operand:DI 0 "push_operand" "")
1858         (match_operand:DI 1 "immediate_operand" ""))]
1859   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1860    && !x86_64_immediate_operand (operands[1], DImode)"
1861   [(set (match_dup 2) (match_dup 1))
1862    (set (match_dup 0) (match_dup 2))]
1863   "")
1865 ;; We need to define this as both peepholer and splitter for case
1866 ;; peephole2 pass is not run.
1867 ;; "&& 1" is needed to keep it from matching the previous pattern.
1868 (define_peephole2
1869   [(set (match_operand:DI 0 "push_operand" "")
1870         (match_operand:DI 1 "immediate_operand" ""))]
1871   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1872    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1873   [(set (match_dup 0) (match_dup 1))
1874    (set (match_dup 2) (match_dup 3))]
1875   "split_di (operands + 1, 1, operands + 2, operands + 3);
1876    operands[1] = gen_lowpart (DImode, operands[2]);
1877    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1878                                                     GEN_INT (4)));
1879   ")
1881 (define_split
1882   [(set (match_operand:DI 0 "push_operand" "")
1883         (match_operand:DI 1 "immediate_operand" ""))]
1884   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1885                     ? flow2_completed : reload_completed)
1886    && !symbolic_operand (operands[1], DImode)
1887    && !x86_64_immediate_operand (operands[1], DImode)"
1888   [(set (match_dup 0) (match_dup 1))
1889    (set (match_dup 2) (match_dup 3))]
1890   "split_di (operands + 1, 1, operands + 2, operands + 3);
1891    operands[1] = gen_lowpart (DImode, operands[2]);
1892    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1893                                                     GEN_INT (4)));
1894   ")
1896 (define_insn "*pushdi2_prologue_rex64"
1897   [(set (match_operand:DI 0 "push_operand" "=<")
1898         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1899    (clobber (mem:BLK (scratch)))]
1900   "TARGET_64BIT"
1901   "push{q}\t%1"
1902   [(set_attr "type" "push")
1903    (set_attr "mode" "DI")])
1905 (define_insn "*popdi1_epilogue_rex64"
1906   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1907         (mem:DI (reg:DI SP_REG)))
1908    (set (reg:DI SP_REG)
1909         (plus:DI (reg:DI SP_REG) (const_int 8)))
1910    (clobber (mem:BLK (scratch)))]
1911   "TARGET_64BIT"
1912   "pop{q}\t%0"
1913   [(set_attr "type" "pop")
1914    (set_attr "mode" "DI")])
1916 (define_insn "popdi1"
1917   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1918         (mem:DI (reg:DI SP_REG)))
1919    (set (reg:DI SP_REG)
1920         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1921   "TARGET_64BIT"
1922   "pop{q}\t%0"
1923   [(set_attr "type" "pop")
1924    (set_attr "mode" "DI")])
1926 (define_insn "*movdi_xor_rex64"
1927   [(set (match_operand:DI 0 "register_operand" "=r")
1928         (match_operand:DI 1 "const0_operand" "i"))
1929    (clobber (reg:CC FLAGS_REG))]
1930   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1931    && reload_completed"
1932   "xor{l}\t{%k0, %k0|%k0, %k0}"
1933   [(set_attr "type" "alu1")
1934    (set_attr "mode" "SI")
1935    (set_attr "length_immediate" "0")])
1937 (define_insn "*movdi_or_rex64"
1938   [(set (match_operand:DI 0 "register_operand" "=r")
1939         (match_operand:DI 1 "const_int_operand" "i"))
1940    (clobber (reg:CC FLAGS_REG))]
1941   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1942    && reload_completed
1943    && operands[1] == constm1_rtx"
1945   operands[1] = constm1_rtx;
1946   return "or{q}\t{%1, %0|%0, %1}";
1948   [(set_attr "type" "alu1")
1949    (set_attr "mode" "DI")
1950    (set_attr "length_immediate" "1")])
1952 (define_insn "*movdi_2"
1953   [(set (match_operand:DI 0 "nonimmediate_operand"
1954                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1955         (match_operand:DI 1 "general_operand"
1956                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1957   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1958   "@
1959    #
1960    #
1961    pxor\t%0, %0
1962    movq\t{%1, %0|%0, %1}
1963    movq\t{%1, %0|%0, %1}
1964    pxor\t%0, %0
1965    movq\t{%1, %0|%0, %1}
1966    movdqa\t{%1, %0|%0, %1}
1967    movq\t{%1, %0|%0, %1}
1968    xorps\t%0, %0
1969    movlps\t{%1, %0|%0, %1}
1970    movaps\t{%1, %0|%0, %1}
1971    movlps\t{%1, %0|%0, %1}"
1972   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1973    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1975 (define_split
1976   [(set (match_operand:DI 0 "push_operand" "")
1977         (match_operand:DI 1 "general_operand" ""))]
1978   "!TARGET_64BIT && reload_completed
1979    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1980   [(const_int 0)]
1981   "ix86_split_long_move (operands); DONE;")
1983 ;; %%% This multiword shite has got to go.
1984 (define_split
1985   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1986         (match_operand:DI 1 "general_operand" ""))]
1987   "!TARGET_64BIT && reload_completed
1988    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1989    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1990   [(const_int 0)]
1991   "ix86_split_long_move (operands); DONE;")
1993 (define_insn "*movdi_1_rex64"
1994   [(set (match_operand:DI 0 "nonimmediate_operand"
1995                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1996         (match_operand:DI 1 "general_operand"
1997                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1998   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2000   switch (get_attr_type (insn))
2001     {
2002     case TYPE_SSECVT:
2003       if (which_alternative == 13)
2004         return "movq2dq\t{%1, %0|%0, %1}";
2005       else
2006         return "movdq2q\t{%1, %0|%0, %1}";
2007     case TYPE_SSEMOV:
2008       if (get_attr_mode (insn) == MODE_TI)
2009           return "movdqa\t{%1, %0|%0, %1}";
2010       /* FALLTHRU */
2011     case TYPE_MMXMOV:
2012       /* Moves from and into integer register is done using movd opcode with
2013          REX prefix.  */
2014       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2015           return "movd\t{%1, %0|%0, %1}";
2016       return "movq\t{%1, %0|%0, %1}";
2017     case TYPE_SSELOG1:
2018     case TYPE_MMXADD:
2019       return "pxor\t%0, %0";
2020     case TYPE_MULTI:
2021       return "#";
2022     case TYPE_LEA:
2023       return "lea{q}\t{%a1, %0|%0, %a1}";
2024     default:
2025       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2026       if (get_attr_mode (insn) == MODE_SI)
2027         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028       else if (which_alternative == 2)
2029         return "movabs{q}\t{%1, %0|%0, %1}";
2030       else
2031         return "mov{q}\t{%1, %0|%0, %1}";
2032     }
2034   [(set (attr "type")
2035      (cond [(eq_attr "alternative" "5")
2036               (const_string "mmxadd")
2037             (eq_attr "alternative" "6,7,8")
2038               (const_string "mmxmov")
2039             (eq_attr "alternative" "9")
2040               (const_string "sselog1")
2041             (eq_attr "alternative" "10,11,12")
2042               (const_string "ssemov")
2043             (eq_attr "alternative" "13,14")
2044               (const_string "ssecvt")
2045             (eq_attr "alternative" "4")
2046               (const_string "multi")
2047             (match_operand:DI 1 "pic_32bit_operand" "")
2048               (const_string "lea")
2049            ]
2050            (const_string "imov")))
2051    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2052    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2053    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2055 ;; Stores and loads of ax to arbitrary constant address.
2056 ;; We fake an second form of instruction to force reload to load address
2057 ;; into register when rax is not available
2058 (define_insn "*movabsdi_1_rex64"
2059   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2060         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2061   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2062   "@
2063    movabs{q}\t{%1, %P0|%P0, %1}
2064    mov{q}\t{%1, %a0|%a0, %1}"
2065   [(set_attr "type" "imov")
2066    (set_attr "modrm" "0,*")
2067    (set_attr "length_address" "8,0")
2068    (set_attr "length_immediate" "0,*")
2069    (set_attr "memory" "store")
2070    (set_attr "mode" "DI")])
2072 (define_insn "*movabsdi_2_rex64"
2073   [(set (match_operand:DI 0 "register_operand" "=a,r")
2074         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2075   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2076   "@
2077    movabs{q}\t{%P1, %0|%0, %P1}
2078    mov{q}\t{%a1, %0|%0, %a1}"
2079   [(set_attr "type" "imov")
2080    (set_attr "modrm" "0,*")
2081    (set_attr "length_address" "8,0")
2082    (set_attr "length_immediate" "0")
2083    (set_attr "memory" "load")
2084    (set_attr "mode" "DI")])
2086 ;; Convert impossible stores of immediate to existing instructions.
2087 ;; First try to get scratch register and go through it.  In case this
2088 ;; fails, move by 32bit parts.
2089 (define_peephole2
2090   [(match_scratch:DI 2 "r")
2091    (set (match_operand:DI 0 "memory_operand" "")
2092         (match_operand:DI 1 "immediate_operand" ""))]
2093   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2094    && !x86_64_immediate_operand (operands[1], DImode)"
2095   [(set (match_dup 2) (match_dup 1))
2096    (set (match_dup 0) (match_dup 2))]
2097   "")
2099 ;; We need to define this as both peepholer and splitter for case
2100 ;; peephole2 pass is not run.
2101 ;; "&& 1" is needed to keep it from matching the previous pattern.
2102 (define_peephole2
2103   [(set (match_operand:DI 0 "memory_operand" "")
2104         (match_operand:DI 1 "immediate_operand" ""))]
2105   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2106    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2107   [(set (match_dup 2) (match_dup 3))
2108    (set (match_dup 4) (match_dup 5))]
2109   "split_di (operands, 2, operands + 2, operands + 4);")
2111 (define_split
2112   [(set (match_operand:DI 0 "memory_operand" "")
2113         (match_operand:DI 1 "immediate_operand" ""))]
2114   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2115                     ? flow2_completed : reload_completed)
2116    && !symbolic_operand (operands[1], DImode)
2117    && !x86_64_immediate_operand (operands[1], DImode)"
2118   [(set (match_dup 2) (match_dup 3))
2119    (set (match_dup 4) (match_dup 5))]
2120   "split_di (operands, 2, operands + 2, operands + 4);")
2122 (define_insn "*swapdi_rex64"
2123   [(set (match_operand:DI 0 "register_operand" "+r")
2124         (match_operand:DI 1 "register_operand" "+r"))
2125    (set (match_dup 1)
2126         (match_dup 0))]
2127   "TARGET_64BIT"
2128   "xchg{q}\t%1, %0"
2129   [(set_attr "type" "imov")
2130    (set_attr "mode" "DI")
2131    (set_attr "pent_pair" "np")
2132    (set_attr "athlon_decode" "vector")])
2134 (define_expand "movti"
2135   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2136         (match_operand:TI 1 "nonimmediate_operand" ""))]
2137   "TARGET_SSE || TARGET_64BIT"
2139   if (TARGET_64BIT)
2140     ix86_expand_move (TImode, operands);
2141   else
2142     ix86_expand_vector_move (TImode, operands);
2143   DONE;
2146 (define_insn "*movti_internal"
2147   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2148         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2149   "TARGET_SSE && !TARGET_64BIT
2150    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2152   switch (which_alternative)
2153     {
2154     case 0:
2155       if (get_attr_mode (insn) == MODE_V4SF)
2156         return "xorps\t%0, %0";
2157       else
2158         return "pxor\t%0, %0";
2159     case 1:
2160     case 2:
2161       if (get_attr_mode (insn) == MODE_V4SF)
2162         return "movaps\t{%1, %0|%0, %1}";
2163       else
2164         return "movdqa\t{%1, %0|%0, %1}";
2165     default:
2166       gcc_unreachable ();
2167     }
2169   [(set_attr "type" "sselog1,ssemov,ssemov")
2170    (set (attr "mode")
2171         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2172                     (ne (symbol_ref "optimize_size") (const_int 0)))
2173                  (const_string "V4SF")
2174                (and (eq_attr "alternative" "2")
2175                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2176                         (const_int 0)))
2177                  (const_string "V4SF")]
2178               (const_string "TI")))])
2180 (define_insn "*movti_rex64"
2181   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2182         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2183   "TARGET_64BIT
2184    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2186   switch (which_alternative)
2187     {
2188     case 0:
2189     case 1:
2190       return "#";
2191     case 2:
2192       if (get_attr_mode (insn) == MODE_V4SF)
2193         return "xorps\t%0, %0";
2194       else
2195         return "pxor\t%0, %0";
2196     case 3:
2197     case 4:
2198       if (get_attr_mode (insn) == MODE_V4SF)
2199         return "movaps\t{%1, %0|%0, %1}";
2200       else
2201         return "movdqa\t{%1, %0|%0, %1}";
2202     default:
2203       gcc_unreachable ();
2204     }
2206   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2207    (set (attr "mode")
2208         (cond [(eq_attr "alternative" "2,3")
2209                  (if_then_else
2210                    (ne (symbol_ref "optimize_size")
2211                        (const_int 0))
2212                    (const_string "V4SF")
2213                    (const_string "TI"))
2214                (eq_attr "alternative" "4")
2215                  (if_then_else
2216                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2217                             (const_int 0))
2218                         (ne (symbol_ref "optimize_size")
2219                             (const_int 0)))
2220                    (const_string "V4SF")
2221                    (const_string "TI"))]
2222                (const_string "DI")))])
2224 (define_split
2225   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2226         (match_operand:TI 1 "general_operand" ""))]
2227   "reload_completed && !SSE_REG_P (operands[0])
2228    && !SSE_REG_P (operands[1])"
2229   [(const_int 0)]
2230   "ix86_split_long_move (operands); DONE;")
2232 (define_expand "movsf"
2233   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2234         (match_operand:SF 1 "general_operand" ""))]
2235   ""
2236   "ix86_expand_move (SFmode, operands); DONE;")
2238 (define_insn "*pushsf"
2239   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2240         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2241   "!TARGET_64BIT"
2243   /* Anything else should be already split before reg-stack.  */
2244   gcc_assert (which_alternative == 1);
2245   return "push{l}\t%1";
2247   [(set_attr "type" "multi,push,multi")
2248    (set_attr "unit" "i387,*,*")
2249    (set_attr "mode" "SF,SI,SF")])
2251 (define_insn "*pushsf_rex64"
2252   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2253         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2254   "TARGET_64BIT"
2256   /* Anything else should be already split before reg-stack.  */
2257   gcc_assert (which_alternative == 1);
2258   return "push{q}\t%q1";
2260   [(set_attr "type" "multi,push,multi")
2261    (set_attr "unit" "i387,*,*")
2262    (set_attr "mode" "SF,DI,SF")])
2264 (define_split
2265   [(set (match_operand:SF 0 "push_operand" "")
2266         (match_operand:SF 1 "memory_operand" ""))]
2267   "reload_completed
2268    && GET_CODE (operands[1]) == MEM
2269    && constant_pool_reference_p (operands[1])"
2270   [(set (match_dup 0)
2271         (match_dup 1))]
2272   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2275 ;; %%% Kill this when call knows how to work this out.
2276 (define_split
2277   [(set (match_operand:SF 0 "push_operand" "")
2278         (match_operand:SF 1 "any_fp_register_operand" ""))]
2279   "!TARGET_64BIT"
2280   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2281    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2283 (define_split
2284   [(set (match_operand:SF 0 "push_operand" "")
2285         (match_operand:SF 1 "any_fp_register_operand" ""))]
2286   "TARGET_64BIT"
2287   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2288    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2290 (define_insn "*movsf_1"
2291   [(set (match_operand:SF 0 "nonimmediate_operand"
2292           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2293         (match_operand:SF 1 "general_operand"
2294           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2295   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2296    && (reload_in_progress || reload_completed
2297        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2298        || GET_CODE (operands[1]) != CONST_DOUBLE
2299        || memory_operand (operands[0], SFmode))"
2301   switch (which_alternative)
2302     {
2303     case 0:
2304       return output_387_reg_move (insn, operands);
2306     case 1:
2307       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2308         return "fstp%z0\t%y0";
2309       else
2310         return "fst%z0\t%y0";
2312     case 2:
2313       return standard_80387_constant_opcode (operands[1]);
2315     case 3:
2316     case 4:
2317       return "mov{l}\t{%1, %0|%0, %1}";
2318     case 5:
2319       if (get_attr_mode (insn) == MODE_TI)
2320         return "pxor\t%0, %0";
2321       else
2322         return "xorps\t%0, %0";
2323     case 6:
2324       if (get_attr_mode (insn) == MODE_V4SF)
2325         return "movaps\t{%1, %0|%0, %1}";
2326       else
2327         return "movss\t{%1, %0|%0, %1}";
2328     case 7:
2329     case 8:
2330       return "movss\t{%1, %0|%0, %1}";
2332     case 9:
2333     case 10:
2334       return "movd\t{%1, %0|%0, %1}";
2336     case 11:
2337       return "movq\t{%1, %0|%0, %1}";
2339     default:
2340       gcc_unreachable ();
2341     }
2343   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2344    (set (attr "mode")
2345         (cond [(eq_attr "alternative" "3,4,9,10")
2346                  (const_string "SI")
2347                (eq_attr "alternative" "5")
2348                  (if_then_else
2349                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2350                                  (const_int 0))
2351                              (ne (symbol_ref "TARGET_SSE2")
2352                                  (const_int 0)))
2353                         (eq (symbol_ref "optimize_size")
2354                             (const_int 0)))
2355                    (const_string "TI")
2356                    (const_string "V4SF"))
2357                /* For architectures resolving dependencies on
2358                   whole SSE registers use APS move to break dependency
2359                   chains, otherwise use short move to avoid extra work.
2361                   Do the same for architectures resolving dependencies on
2362                   the parts.  While in DF mode it is better to always handle
2363                   just register parts, the SF mode is different due to lack
2364                   of instructions to load just part of the register.  It is
2365                   better to maintain the whole registers in single format
2366                   to avoid problems on using packed logical operations.  */
2367                (eq_attr "alternative" "6")
2368                  (if_then_else
2369                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2370                             (const_int 0))
2371                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2372                             (const_int 0)))
2373                    (const_string "V4SF")
2374                    (const_string "SF"))
2375                (eq_attr "alternative" "11")
2376                  (const_string "DI")]
2377                (const_string "SF")))])
2379 (define_insn "*swapsf"
2380   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2381         (match_operand:SF 1 "fp_register_operand" "+f"))
2382    (set (match_dup 1)
2383         (match_dup 0))]
2384   "reload_completed || TARGET_80387"
2386   if (STACK_TOP_P (operands[0]))
2387     return "fxch\t%1";
2388   else
2389     return "fxch\t%0";
2391   [(set_attr "type" "fxch")
2392    (set_attr "mode" "SF")])
2394 (define_expand "movdf"
2395   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2396         (match_operand:DF 1 "general_operand" ""))]
2397   ""
2398   "ix86_expand_move (DFmode, operands); DONE;")
2400 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2401 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2402 ;; On the average, pushdf using integers can be still shorter.  Allow this
2403 ;; pattern for optimize_size too.
2405 (define_insn "*pushdf_nointeger"
2406   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2407         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2408   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2410   /* This insn should be already split before reg-stack.  */
2411   gcc_unreachable ();
2413   [(set_attr "type" "multi")
2414    (set_attr "unit" "i387,*,*,*")
2415    (set_attr "mode" "DF,SI,SI,DF")])
2417 (define_insn "*pushdf_integer"
2418   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2419         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2420   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2422   /* This insn should be already split before reg-stack.  */
2423   gcc_unreachable ();
2425   [(set_attr "type" "multi")
2426    (set_attr "unit" "i387,*,*")
2427    (set_attr "mode" "DF,SI,DF")])
2429 ;; %%% Kill this when call knows how to work this out.
2430 (define_split
2431   [(set (match_operand:DF 0 "push_operand" "")
2432         (match_operand:DF 1 "any_fp_register_operand" ""))]
2433   "!TARGET_64BIT && reload_completed"
2434   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2435    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2436   "")
2438 (define_split
2439   [(set (match_operand:DF 0 "push_operand" "")
2440         (match_operand:DF 1 "any_fp_register_operand" ""))]
2441   "TARGET_64BIT && reload_completed"
2442   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2443    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2444   "")
2446 (define_split
2447   [(set (match_operand:DF 0 "push_operand" "")
2448         (match_operand:DF 1 "general_operand" ""))]
2449   "reload_completed"
2450   [(const_int 0)]
2451   "ix86_split_long_move (operands); DONE;")
2453 ;; Moving is usually shorter when only FP registers are used. This separate
2454 ;; movdf pattern avoids the use of integer registers for FP operations
2455 ;; when optimizing for size.
2457 (define_insn "*movdf_nointeger"
2458   [(set (match_operand:DF 0 "nonimmediate_operand"
2459                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2460         (match_operand:DF 1 "general_operand"
2461                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2462   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2463    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2464    && (reload_in_progress || reload_completed
2465        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2466        || GET_CODE (operands[1]) != CONST_DOUBLE
2467        || memory_operand (operands[0], DFmode))"
2469   switch (which_alternative)
2470     {
2471     case 0:
2472       return output_387_reg_move (insn, operands);
2474     case 1:
2475       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2476         return "fstp%z0\t%y0";
2477       else
2478         return "fst%z0\t%y0";
2480     case 2:
2481       return standard_80387_constant_opcode (operands[1]);
2483     case 3:
2484     case 4:
2485       return "#";
2486     case 5:
2487       switch (get_attr_mode (insn))
2488         {
2489         case MODE_V4SF:
2490           return "xorps\t%0, %0";
2491         case MODE_V2DF:
2492           return "xorpd\t%0, %0";
2493         case MODE_TI:
2494           return "pxor\t%0, %0";
2495         default:
2496           gcc_unreachable ();
2497         }
2498     case 6:
2499     case 7:
2500     case 8:
2501       switch (get_attr_mode (insn))
2502         {
2503         case MODE_V4SF:
2504           return "movaps\t{%1, %0|%0, %1}";
2505         case MODE_V2DF:
2506           return "movapd\t{%1, %0|%0, %1}";
2507         case MODE_TI:
2508           return "movdqa\t{%1, %0|%0, %1}";
2509         case MODE_DI:
2510           return "movq\t{%1, %0|%0, %1}";
2511         case MODE_DF:
2512           return "movsd\t{%1, %0|%0, %1}";
2513         case MODE_V1DF:
2514           return "movlpd\t{%1, %0|%0, %1}";
2515         case MODE_V2SF:
2516           return "movlps\t{%1, %0|%0, %1}";
2517         default:
2518           gcc_unreachable ();
2519         }
2521     default:
2522       gcc_unreachable ();
2523     }
2525   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2526    (set (attr "mode")
2527         (cond [(eq_attr "alternative" "0,1,2")
2528                  (const_string "DF")
2529                (eq_attr "alternative" "3,4")
2530                  (const_string "SI")
2532                /* For SSE1, we have many fewer alternatives.  */
2533                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2534                  (cond [(eq_attr "alternative" "5,6")
2535                           (const_string "V4SF")
2536                        ]
2537                    (const_string "V2SF"))
2539                /* xorps is one byte shorter.  */
2540                (eq_attr "alternative" "5")
2541                  (cond [(ne (symbol_ref "optimize_size")
2542                             (const_int 0))
2543                           (const_string "V4SF")
2544                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2545                             (const_int 0))
2546                           (const_string "TI")
2547                        ]
2548                        (const_string "V2DF"))
2550                /* For architectures resolving dependencies on
2551                   whole SSE registers use APD move to break dependency
2552                   chains, otherwise use short move to avoid extra work.
2554                   movaps encodes one byte shorter.  */
2555                (eq_attr "alternative" "6")
2556                  (cond
2557                    [(ne (symbol_ref "optimize_size")
2558                         (const_int 0))
2559                       (const_string "V4SF")
2560                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2561                         (const_int 0))
2562                       (const_string "V2DF")
2563                    ]
2564                    (const_string "DF"))
2565                /* For architectures resolving dependencies on register
2566                   parts we may avoid extra work to zero out upper part
2567                   of register.  */
2568                (eq_attr "alternative" "7")
2569                  (if_then_else
2570                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2571                        (const_int 0))
2572                    (const_string "V1DF")
2573                    (const_string "DF"))
2574               ]
2575               (const_string "DF")))])
2577 (define_insn "*movdf_integer"
2578   [(set (match_operand:DF 0 "nonimmediate_operand"
2579                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2580         (match_operand:DF 1 "general_operand"
2581                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2582   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2583    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2584    && (reload_in_progress || reload_completed
2585        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2586        || GET_CODE (operands[1]) != CONST_DOUBLE
2587        || memory_operand (operands[0], DFmode))"
2589   switch (which_alternative)
2590     {
2591     case 0:
2592       return output_387_reg_move (insn, operands);
2594     case 1:
2595       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2596         return "fstp%z0\t%y0";
2597       else
2598         return "fst%z0\t%y0";
2600     case 2:
2601       return standard_80387_constant_opcode (operands[1]);
2603     case 3:
2604     case 4:
2605       return "#";
2607     case 5:
2608       switch (get_attr_mode (insn))
2609         {
2610         case MODE_V4SF:
2611           return "xorps\t%0, %0";
2612         case MODE_V2DF:
2613           return "xorpd\t%0, %0";
2614         case MODE_TI:
2615           return "pxor\t%0, %0";
2616         default:
2617           gcc_unreachable ();
2618         }
2619     case 6:
2620     case 7:
2621     case 8:
2622       switch (get_attr_mode (insn))
2623         {
2624         case MODE_V4SF:
2625           return "movaps\t{%1, %0|%0, %1}";
2626         case MODE_V2DF:
2627           return "movapd\t{%1, %0|%0, %1}";
2628         case MODE_TI:
2629           return "movdqa\t{%1, %0|%0, %1}";
2630         case MODE_DI:
2631           return "movq\t{%1, %0|%0, %1}";
2632         case MODE_DF:
2633           return "movsd\t{%1, %0|%0, %1}";
2634         case MODE_V1DF:
2635           return "movlpd\t{%1, %0|%0, %1}";
2636         case MODE_V2SF:
2637           return "movlps\t{%1, %0|%0, %1}";
2638         default:
2639           gcc_unreachable ();
2640         }
2642     default:
2643       gcc_unreachable();
2644     }
2646   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2647    (set (attr "mode")
2648         (cond [(eq_attr "alternative" "0,1,2")
2649                  (const_string "DF")
2650                (eq_attr "alternative" "3,4")
2651                  (const_string "SI")
2653                /* For SSE1, we have many fewer alternatives.  */
2654                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2655                  (cond [(eq_attr "alternative" "5,6")
2656                           (const_string "V4SF")
2657                        ]
2658                    (const_string "V2SF"))
2660                /* xorps is one byte shorter.  */
2661                (eq_attr "alternative" "5")
2662                  (cond [(ne (symbol_ref "optimize_size")
2663                             (const_int 0))
2664                           (const_string "V4SF")
2665                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2666                             (const_int 0))
2667                           (const_string "TI")
2668                        ]
2669                        (const_string "V2DF"))
2671                /* For architectures resolving dependencies on
2672                   whole SSE registers use APD move to break dependency
2673                   chains, otherwise use short move to avoid extra work.
2675                   movaps encodes one byte shorter.  */
2676                (eq_attr "alternative" "6")
2677                  (cond
2678                    [(ne (symbol_ref "optimize_size")
2679                         (const_int 0))
2680                       (const_string "V4SF")
2681                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2682                         (const_int 0))
2683                       (const_string "V2DF")
2684                    ]
2685                    (const_string "DF"))
2686                /* For architectures resolving dependencies on register
2687                   parts we may avoid extra work to zero out upper part
2688                   of register.  */
2689                (eq_attr "alternative" "7")
2690                  (if_then_else
2691                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2692                        (const_int 0))
2693                    (const_string "V1DF")
2694                    (const_string "DF"))
2695               ]
2696               (const_string "DF")))])
2698 (define_split
2699   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2700         (match_operand:DF 1 "general_operand" ""))]
2701   "reload_completed
2702    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2703    && ! (ANY_FP_REG_P (operands[0]) ||
2704          (GET_CODE (operands[0]) == SUBREG
2705           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2706    && ! (ANY_FP_REG_P (operands[1]) ||
2707          (GET_CODE (operands[1]) == SUBREG
2708           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2709   [(const_int 0)]
2710   "ix86_split_long_move (operands); DONE;")
2712 (define_insn "*swapdf"
2713   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2714         (match_operand:DF 1 "fp_register_operand" "+f"))
2715    (set (match_dup 1)
2716         (match_dup 0))]
2717   "reload_completed || TARGET_80387"
2719   if (STACK_TOP_P (operands[0]))
2720     return "fxch\t%1";
2721   else
2722     return "fxch\t%0";
2724   [(set_attr "type" "fxch")
2725    (set_attr "mode" "DF")])
2727 (define_expand "movxf"
2728   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2729         (match_operand:XF 1 "general_operand" ""))]
2730   ""
2731   "ix86_expand_move (XFmode, operands); DONE;")
2733 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2734 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2735 ;; Pushing using integer instructions is longer except for constants
2736 ;; and direct memory references.
2737 ;; (assuming that any given constant is pushed only once, but this ought to be
2738 ;;  handled elsewhere).
2740 (define_insn "*pushxf_nointeger"
2741   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2742         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2743   "optimize_size"
2745   /* This insn should be already split before reg-stack.  */
2746   gcc_unreachable ();
2748   [(set_attr "type" "multi")
2749    (set_attr "unit" "i387,*,*")
2750    (set_attr "mode" "XF,SI,SI")])
2752 (define_insn "*pushxf_integer"
2753   [(set (match_operand:XF 0 "push_operand" "=<,<")
2754         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2755   "!optimize_size"
2757   /* This insn should be already split before reg-stack.  */
2758   gcc_unreachable ();
2760   [(set_attr "type" "multi")
2761    (set_attr "unit" "i387,*")
2762    (set_attr "mode" "XF,SI")])
2764 (define_split
2765   [(set (match_operand 0 "push_operand" "")
2766         (match_operand 1 "general_operand" ""))]
2767   "reload_completed
2768    && (GET_MODE (operands[0]) == XFmode
2769        || GET_MODE (operands[0]) == DFmode)
2770    && !ANY_FP_REG_P (operands[1])"
2771   [(const_int 0)]
2772   "ix86_split_long_move (operands); DONE;")
2774 (define_split
2775   [(set (match_operand:XF 0 "push_operand" "")
2776         (match_operand:XF 1 "any_fp_register_operand" ""))]
2777   "!TARGET_64BIT"
2778   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2779    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2780   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2782 (define_split
2783   [(set (match_operand:XF 0 "push_operand" "")
2784         (match_operand:XF 1 "any_fp_register_operand" ""))]
2785   "TARGET_64BIT"
2786   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2787    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2788   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2790 ;; Do not use integer registers when optimizing for size
2791 (define_insn "*movxf_nointeger"
2792   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2793         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2794   "optimize_size
2795    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2796    && (reload_in_progress || reload_completed
2797        || standard_80387_constant_p (operands[1])
2798        || GET_CODE (operands[1]) != CONST_DOUBLE
2799        || memory_operand (operands[0], XFmode))"
2801   switch (which_alternative)
2802     {
2803     case 0:
2804       return output_387_reg_move (insn, operands);
2806     case 1:
2807       /* There is no non-popping store to memory for XFmode.  So if
2808          we need one, follow the store with a load.  */
2809       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2810         return "fstp%z0\t%y0\;fld%z0\t%y0";
2811       else
2812         return "fstp%z0\t%y0";
2814     case 2:
2815       return standard_80387_constant_opcode (operands[1]);
2817     case 3: case 4:
2818       return "#";
2819     default:
2820       gcc_unreachable ();
2821     }
2823   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2824    (set_attr "mode" "XF,XF,XF,SI,SI")])
2826 (define_insn "*movxf_integer"
2827   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2828         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2829   "!optimize_size
2830    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2831    && (reload_in_progress || reload_completed
2832        || standard_80387_constant_p (operands[1])
2833        || GET_CODE (operands[1]) != CONST_DOUBLE
2834        || memory_operand (operands[0], XFmode))"
2836   switch (which_alternative)
2837     {
2838     case 0:
2839       return output_387_reg_move (insn, operands);
2841     case 1:
2842       /* There is no non-popping store to memory for XFmode.  So if
2843          we need one, follow the store with a load.  */
2844       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2845         return "fstp%z0\t%y0\;fld%z0\t%y0";
2846       else
2847         return "fstp%z0\t%y0";
2849     case 2:
2850       return standard_80387_constant_opcode (operands[1]);
2852     case 3: case 4:
2853       return "#";
2855     default:
2856       gcc_unreachable ();
2857     }
2859   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2860    (set_attr "mode" "XF,XF,XF,SI,SI")])
2862 (define_split
2863   [(set (match_operand 0 "nonimmediate_operand" "")
2864         (match_operand 1 "general_operand" ""))]
2865   "reload_completed
2866    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2867    && GET_MODE (operands[0]) == XFmode
2868    && ! (ANY_FP_REG_P (operands[0]) ||
2869          (GET_CODE (operands[0]) == SUBREG
2870           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2871    && ! (ANY_FP_REG_P (operands[1]) ||
2872          (GET_CODE (operands[1]) == SUBREG
2873           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2874   [(const_int 0)]
2875   "ix86_split_long_move (operands); DONE;")
2877 (define_split
2878   [(set (match_operand 0 "register_operand" "")
2879         (match_operand 1 "memory_operand" ""))]
2880   "reload_completed
2881    && GET_CODE (operands[1]) == MEM
2882    && (GET_MODE (operands[0]) == XFmode
2883        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2884    && constant_pool_reference_p (operands[1])"
2885   [(set (match_dup 0) (match_dup 1))]
2887   rtx c = avoid_constant_pool_reference (operands[1]);
2888   rtx r = operands[0];
2890   if (GET_CODE (r) == SUBREG)
2891     r = SUBREG_REG (r);
2893   if (SSE_REG_P (r))
2894     {
2895       if (!standard_sse_constant_p (c))
2896         FAIL;
2897     }
2898   else if (FP_REG_P (r))
2899     {
2900       if (!standard_80387_constant_p (c))
2901         FAIL;
2902     }
2903   else if (MMX_REG_P (r))
2904     FAIL;
2906   operands[1] = c;
2909 (define_split
2910   [(set (match_operand 0 "register_operand" "")
2911         (float_extend (match_operand 1 "memory_operand" "")))]
2912   "reload_completed
2913    && GET_CODE (operands[1]) == MEM
2914    && (GET_MODE (operands[0]) == XFmode
2915        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2916    && constant_pool_reference_p (operands[1])"
2917   [(set (match_dup 0) (match_dup 1))]
2919   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2920   rtx r = operands[0];
2922   if (GET_CODE (r) == SUBREG)
2923     r = SUBREG_REG (r);
2925   if (SSE_REG_P (r))
2926     {
2927       if (!standard_sse_constant_p (c))
2928         FAIL;
2929     }
2930   else if (FP_REG_P (r))
2931     {
2932       if (!standard_80387_constant_p (c))
2933         FAIL;
2934     }
2935   else if (MMX_REG_P (r))
2936     FAIL;
2938   operands[1] = c;
2941 (define_insn "swapxf"
2942   [(set (match_operand:XF 0 "register_operand" "+f")
2943         (match_operand:XF 1 "register_operand" "+f"))
2944    (set (match_dup 1)
2945         (match_dup 0))]
2946   "TARGET_80387"
2948   if (STACK_TOP_P (operands[0]))
2949     return "fxch\t%1";
2950   else
2951     return "fxch\t%0";
2953   [(set_attr "type" "fxch")
2954    (set_attr "mode" "XF")])
2956 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2957 (define_split
2958   [(set (match_operand:X87MODEF 0 "register_operand" "")
2959         (match_operand:X87MODEF 1 "immediate_operand" ""))]
2960   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2961    && (standard_80387_constant_p (operands[1]) == 8
2962        || standard_80387_constant_p (operands[1]) == 9)"
2963   [(set (match_dup 0)(match_dup 1))
2964    (set (match_dup 0)
2965         (neg:X87MODEF (match_dup 0)))]
2967   REAL_VALUE_TYPE r;
2969   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2970   if (real_isnegzero (&r))
2971     operands[1] = CONST0_RTX (<MODE>mode);
2972   else
2973     operands[1] = CONST1_RTX (<MODE>mode);
2976 (define_expand "movtf"
2977   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2978         (match_operand:TF 1 "nonimmediate_operand" ""))]
2979   "TARGET_64BIT"
2981   ix86_expand_move (TFmode, operands);
2982   DONE;
2985 (define_insn "*movtf_internal"
2986   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2987         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2988   "TARGET_64BIT
2989    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2991   switch (which_alternative)
2992     {
2993     case 0:
2994     case 1:
2995       return "#";
2996     case 2:
2997       if (get_attr_mode (insn) == MODE_V4SF)
2998         return "xorps\t%0, %0";
2999       else
3000         return "pxor\t%0, %0";
3001     case 3:
3002     case 4:
3003       if (get_attr_mode (insn) == MODE_V4SF)
3004         return "movaps\t{%1, %0|%0, %1}";
3005       else
3006         return "movdqa\t{%1, %0|%0, %1}";
3007     default:
3008       gcc_unreachable ();
3009     }
3011   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3012    (set (attr "mode")
3013         (cond [(eq_attr "alternative" "2,3")
3014                  (if_then_else
3015                    (ne (symbol_ref "optimize_size")
3016                        (const_int 0))
3017                    (const_string "V4SF")
3018                    (const_string "TI"))
3019                (eq_attr "alternative" "4")
3020                  (if_then_else
3021                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3022                             (const_int 0))
3023                         (ne (symbol_ref "optimize_size")
3024                             (const_int 0)))
3025                    (const_string "V4SF")
3026                    (const_string "TI"))]
3027                (const_string "DI")))])
3029 (define_split
3030   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3031         (match_operand:TF 1 "general_operand" ""))]
3032   "reload_completed && !SSE_REG_P (operands[0])
3033    && !SSE_REG_P (operands[1])"
3034   [(const_int 0)]
3035   "ix86_split_long_move (operands); DONE;")
3037 ;; Zero extension instructions
3039 (define_expand "zero_extendhisi2"
3040   [(set (match_operand:SI 0 "register_operand" "")
3041      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3042   ""
3044   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3045     {
3046       operands[1] = force_reg (HImode, operands[1]);
3047       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3048       DONE;
3049     }
3052 (define_insn "zero_extendhisi2_and"
3053   [(set (match_operand:SI 0 "register_operand" "=r")
3054      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3055    (clobber (reg:CC FLAGS_REG))]
3056   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3057   "#"
3058   [(set_attr "type" "alu1")
3059    (set_attr "mode" "SI")])
3061 (define_split
3062   [(set (match_operand:SI 0 "register_operand" "")
3063         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3064    (clobber (reg:CC FLAGS_REG))]
3065   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3066   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3067               (clobber (reg:CC FLAGS_REG))])]
3068   "")
3070 (define_insn "*zero_extendhisi2_movzwl"
3071   [(set (match_operand:SI 0 "register_operand" "=r")
3072      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3073   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3074   "movz{wl|x}\t{%1, %0|%0, %1}"
3075   [(set_attr "type" "imovx")
3076    (set_attr "mode" "SI")])
3078 (define_expand "zero_extendqihi2"
3079   [(parallel
3080     [(set (match_operand:HI 0 "register_operand" "")
3081        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3082      (clobber (reg:CC FLAGS_REG))])]
3083   ""
3084   "")
3086 (define_insn "*zero_extendqihi2_and"
3087   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3088      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3089    (clobber (reg:CC FLAGS_REG))]
3090   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3091   "#"
3092   [(set_attr "type" "alu1")
3093    (set_attr "mode" "HI")])
3095 (define_insn "*zero_extendqihi2_movzbw_and"
3096   [(set (match_operand:HI 0 "register_operand" "=r,r")
3097      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3098    (clobber (reg:CC FLAGS_REG))]
3099   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3100   "#"
3101   [(set_attr "type" "imovx,alu1")
3102    (set_attr "mode" "HI")])
3104 ; zero extend to SImode here to avoid partial register stalls
3105 (define_insn "*zero_extendqihi2_movzbl"
3106   [(set (match_operand:HI 0 "register_operand" "=r")
3107      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3110   [(set_attr "type" "imovx")
3111    (set_attr "mode" "SI")])
3113 ;; For the movzbw case strip only the clobber
3114 (define_split
3115   [(set (match_operand:HI 0 "register_operand" "")
3116         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3117    (clobber (reg:CC FLAGS_REG))]
3118   "reload_completed
3119    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3120    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3121   [(set (match_operand:HI 0 "register_operand" "")
3122         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3124 ;; When source and destination does not overlap, clear destination
3125 ;; first and then do the movb
3126 (define_split
3127   [(set (match_operand:HI 0 "register_operand" "")
3128         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3129    (clobber (reg:CC FLAGS_REG))]
3130   "reload_completed
3131    && ANY_QI_REG_P (operands[0])
3132    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3133    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3134   [(set (match_dup 0) (const_int 0))
3135    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3136   "operands[2] = gen_lowpart (QImode, operands[0]);")
3138 ;; Rest is handled by single and.
3139 (define_split
3140   [(set (match_operand:HI 0 "register_operand" "")
3141         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3142    (clobber (reg:CC FLAGS_REG))]
3143   "reload_completed
3144    && true_regnum (operands[0]) == true_regnum (operands[1])"
3145   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3146               (clobber (reg:CC FLAGS_REG))])]
3147   "")
3149 (define_expand "zero_extendqisi2"
3150   [(parallel
3151     [(set (match_operand:SI 0 "register_operand" "")
3152        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3153      (clobber (reg:CC FLAGS_REG))])]
3154   ""
3155   "")
3157 (define_insn "*zero_extendqisi2_and"
3158   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3159      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3160    (clobber (reg:CC FLAGS_REG))]
3161   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3162   "#"
3163   [(set_attr "type" "alu1")
3164    (set_attr "mode" "SI")])
3166 (define_insn "*zero_extendqisi2_movzbw_and"
3167   [(set (match_operand:SI 0 "register_operand" "=r,r")
3168      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3169    (clobber (reg:CC FLAGS_REG))]
3170   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3171   "#"
3172   [(set_attr "type" "imovx,alu1")
3173    (set_attr "mode" "SI")])
3175 (define_insn "*zero_extendqisi2_movzbw"
3176   [(set (match_operand:SI 0 "register_operand" "=r")
3177      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3178   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3179   "movz{bl|x}\t{%1, %0|%0, %1}"
3180   [(set_attr "type" "imovx")
3181    (set_attr "mode" "SI")])
3183 ;; For the movzbl case strip only the clobber
3184 (define_split
3185   [(set (match_operand:SI 0 "register_operand" "")
3186         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3187    (clobber (reg:CC FLAGS_REG))]
3188   "reload_completed
3189    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3190    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3191   [(set (match_dup 0)
3192         (zero_extend:SI (match_dup 1)))])
3194 ;; When source and destination does not overlap, clear destination
3195 ;; first and then do the movb
3196 (define_split
3197   [(set (match_operand:SI 0 "register_operand" "")
3198         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3199    (clobber (reg:CC FLAGS_REG))]
3200   "reload_completed
3201    && ANY_QI_REG_P (operands[0])
3202    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3203    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3204    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3205   [(set (match_dup 0) (const_int 0))
3206    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3207   "operands[2] = gen_lowpart (QImode, operands[0]);")
3209 ;; Rest is handled by single and.
3210 (define_split
3211   [(set (match_operand:SI 0 "register_operand" "")
3212         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3213    (clobber (reg:CC FLAGS_REG))]
3214   "reload_completed
3215    && true_regnum (operands[0]) == true_regnum (operands[1])"
3216   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3217               (clobber (reg:CC FLAGS_REG))])]
3218   "")
3220 ;; %%% Kill me once multi-word ops are sane.
3221 (define_expand "zero_extendsidi2"
3222   [(set (match_operand:DI 0 "register_operand" "=r")
3223      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3224   ""
3225   "if (!TARGET_64BIT)
3226      {
3227        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3228        DONE;
3229      }
3230   ")
3232 (define_insn "zero_extendsidi2_32"
3233   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3234         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3235    (clobber (reg:CC FLAGS_REG))]
3236   "!TARGET_64BIT"
3237   "@
3238    #
3239    #
3240    #
3241    movd\t{%1, %0|%0, %1}
3242    movd\t{%1, %0|%0, %1}"
3243   [(set_attr "mode" "SI,SI,SI,DI,TI")
3244    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3246 (define_insn "zero_extendsidi2_rex64"
3247   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3248      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3249   "TARGET_64BIT"
3250   "@
3251    mov\t{%k1, %k0|%k0, %k1}
3252    #
3253    movd\t{%1, %0|%0, %1}
3254    movd\t{%1, %0|%0, %1}"
3255   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3256    (set_attr "mode" "SI,DI,SI,SI")])
3258 (define_split
3259   [(set (match_operand:DI 0 "memory_operand" "")
3260      (zero_extend:DI (match_dup 0)))]
3261   "TARGET_64BIT"
3262   [(set (match_dup 4) (const_int 0))]
3263   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3265 (define_split
3266   [(set (match_operand:DI 0 "register_operand" "")
3267         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3268    (clobber (reg:CC FLAGS_REG))]
3269   "!TARGET_64BIT && reload_completed
3270    && true_regnum (operands[0]) == true_regnum (operands[1])"
3271   [(set (match_dup 4) (const_int 0))]
3272   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3274 (define_split
3275   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3276         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3277    (clobber (reg:CC FLAGS_REG))]
3278   "!TARGET_64BIT && reload_completed
3279    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3280   [(set (match_dup 3) (match_dup 1))
3281    (set (match_dup 4) (const_int 0))]
3282   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3284 (define_insn "zero_extendhidi2"
3285   [(set (match_operand:DI 0 "register_operand" "=r")
3286      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3287   "TARGET_64BIT"
3288   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3289   [(set_attr "type" "imovx")
3290    (set_attr "mode" "DI")])
3292 (define_insn "zero_extendqidi2"
3293   [(set (match_operand:DI 0 "register_operand" "=r")
3294      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3295   "TARGET_64BIT"
3296   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3297   [(set_attr "type" "imovx")
3298    (set_attr "mode" "DI")])
3300 ;; Sign extension instructions
3302 (define_expand "extendsidi2"
3303   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3304                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3305               (clobber (reg:CC FLAGS_REG))
3306               (clobber (match_scratch:SI 2 ""))])]
3307   ""
3309   if (TARGET_64BIT)
3310     {
3311       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3312       DONE;
3313     }
3316 (define_insn "*extendsidi2_1"
3317   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3318         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3319    (clobber (reg:CC FLAGS_REG))
3320    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3321   "!TARGET_64BIT"
3322   "#")
3324 (define_insn "extendsidi2_rex64"
3325   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3326         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3327   "TARGET_64BIT"
3328   "@
3329    {cltq|cdqe}
3330    movs{lq|x}\t{%1,%0|%0, %1}"
3331   [(set_attr "type" "imovx")
3332    (set_attr "mode" "DI")
3333    (set_attr "prefix_0f" "0")
3334    (set_attr "modrm" "0,1")])
3336 (define_insn "extendhidi2"
3337   [(set (match_operand:DI 0 "register_operand" "=r")
3338         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3339   "TARGET_64BIT"
3340   "movs{wq|x}\t{%1,%0|%0, %1}"
3341   [(set_attr "type" "imovx")
3342    (set_attr "mode" "DI")])
3344 (define_insn "extendqidi2"
3345   [(set (match_operand:DI 0 "register_operand" "=r")
3346         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3347   "TARGET_64BIT"
3348   "movs{bq|x}\t{%1,%0|%0, %1}"
3349    [(set_attr "type" "imovx")
3350     (set_attr "mode" "DI")])
3352 ;; Extend to memory case when source register does die.
3353 (define_split
3354   [(set (match_operand:DI 0 "memory_operand" "")
3355         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3356    (clobber (reg:CC FLAGS_REG))
3357    (clobber (match_operand:SI 2 "register_operand" ""))]
3358   "(reload_completed
3359     && dead_or_set_p (insn, operands[1])
3360     && !reg_mentioned_p (operands[1], operands[0]))"
3361   [(set (match_dup 3) (match_dup 1))
3362    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3363               (clobber (reg:CC FLAGS_REG))])
3364    (set (match_dup 4) (match_dup 1))]
3365   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3367 ;; Extend to memory case when source register does not die.
3368 (define_split
3369   [(set (match_operand:DI 0 "memory_operand" "")
3370         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3371    (clobber (reg:CC FLAGS_REG))
3372    (clobber (match_operand:SI 2 "register_operand" ""))]
3373   "reload_completed"
3374   [(const_int 0)]
3376   split_di (&operands[0], 1, &operands[3], &operands[4]);
3378   emit_move_insn (operands[3], operands[1]);
3380   /* Generate a cltd if possible and doing so it profitable.  */
3381   if (true_regnum (operands[1]) == 0
3382       && true_regnum (operands[2]) == 1
3383       && (optimize_size || TARGET_USE_CLTD))
3384     {
3385       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3386     }
3387   else
3388     {
3389       emit_move_insn (operands[2], operands[1]);
3390       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3391     }
3392   emit_move_insn (operands[4], operands[2]);
3393   DONE;
3396 ;; Extend to register case.  Optimize case where source and destination
3397 ;; registers match and cases where we can use cltd.
3398 (define_split
3399   [(set (match_operand:DI 0 "register_operand" "")
3400         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3401    (clobber (reg:CC FLAGS_REG))
3402    (clobber (match_scratch:SI 2 ""))]
3403   "reload_completed"
3404   [(const_int 0)]
3406   split_di (&operands[0], 1, &operands[3], &operands[4]);
3408   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3409     emit_move_insn (operands[3], operands[1]);
3411   /* Generate a cltd if possible and doing so it profitable.  */
3412   if (true_regnum (operands[3]) == 0
3413       && (optimize_size || TARGET_USE_CLTD))
3414     {
3415       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3416       DONE;
3417     }
3419   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3420     emit_move_insn (operands[4], operands[1]);
3422   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3423   DONE;
3426 (define_insn "extendhisi2"
3427   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3428         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3429   ""
3431   switch (get_attr_prefix_0f (insn))
3432     {
3433     case 0:
3434       return "{cwtl|cwde}";
3435     default:
3436       return "movs{wl|x}\t{%1,%0|%0, %1}";
3437     }
3439   [(set_attr "type" "imovx")
3440    (set_attr "mode" "SI")
3441    (set (attr "prefix_0f")
3442      ;; movsx is short decodable while cwtl is vector decoded.
3443      (if_then_else (and (eq_attr "cpu" "!k6")
3444                         (eq_attr "alternative" "0"))
3445         (const_string "0")
3446         (const_string "1")))
3447    (set (attr "modrm")
3448      (if_then_else (eq_attr "prefix_0f" "0")
3449         (const_string "0")
3450         (const_string "1")))])
3452 (define_insn "*extendhisi2_zext"
3453   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3454         (zero_extend:DI
3455           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3456   "TARGET_64BIT"
3458   switch (get_attr_prefix_0f (insn))
3459     {
3460     case 0:
3461       return "{cwtl|cwde}";
3462     default:
3463       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3464     }
3466   [(set_attr "type" "imovx")
3467    (set_attr "mode" "SI")
3468    (set (attr "prefix_0f")
3469      ;; movsx is short decodable while cwtl is vector decoded.
3470      (if_then_else (and (eq_attr "cpu" "!k6")
3471                         (eq_attr "alternative" "0"))
3472         (const_string "0")
3473         (const_string "1")))
3474    (set (attr "modrm")
3475      (if_then_else (eq_attr "prefix_0f" "0")
3476         (const_string "0")
3477         (const_string "1")))])
3479 (define_insn "extendqihi2"
3480   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3481         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3482   ""
3484   switch (get_attr_prefix_0f (insn))
3485     {
3486     case 0:
3487       return "{cbtw|cbw}";
3488     default:
3489       return "movs{bw|x}\t{%1,%0|%0, %1}";
3490     }
3492   [(set_attr "type" "imovx")
3493    (set_attr "mode" "HI")
3494    (set (attr "prefix_0f")
3495      ;; movsx is short decodable while cwtl is vector decoded.
3496      (if_then_else (and (eq_attr "cpu" "!k6")
3497                         (eq_attr "alternative" "0"))
3498         (const_string "0")
3499         (const_string "1")))
3500    (set (attr "modrm")
3501      (if_then_else (eq_attr "prefix_0f" "0")
3502         (const_string "0")
3503         (const_string "1")))])
3505 (define_insn "extendqisi2"
3506   [(set (match_operand:SI 0 "register_operand" "=r")
3507         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3508   ""
3509   "movs{bl|x}\t{%1,%0|%0, %1}"
3510    [(set_attr "type" "imovx")
3511     (set_attr "mode" "SI")])
3513 (define_insn "*extendqisi2_zext"
3514   [(set (match_operand:DI 0 "register_operand" "=r")
3515         (zero_extend:DI
3516           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3517   "TARGET_64BIT"
3518   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3519    [(set_attr "type" "imovx")
3520     (set_attr "mode" "SI")])
3522 ;; Conversions between float and double.
3524 ;; These are all no-ops in the model used for the 80387.  So just
3525 ;; emit moves.
3527 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3528 (define_insn "*dummy_extendsfdf2"
3529   [(set (match_operand:DF 0 "push_operand" "=<")
3530         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3531   "0"
3532   "#")
3534 (define_split
3535   [(set (match_operand:DF 0 "push_operand" "")
3536         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3537   "!TARGET_64BIT"
3538   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3539    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3541 (define_split
3542   [(set (match_operand:DF 0 "push_operand" "")
3543         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3544   "TARGET_64BIT"
3545   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3546    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3548 (define_insn "*dummy_extendsfxf2"
3549   [(set (match_operand:XF 0 "push_operand" "=<")
3550         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3551   "0"
3552   "#")
3554 (define_split
3555   [(set (match_operand:XF 0 "push_operand" "")
3556         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3557   ""
3558   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3559    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3560   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3562 (define_split
3563   [(set (match_operand:XF 0 "push_operand" "")
3564         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3565   "TARGET_64BIT"
3566   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3567    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3568   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3570 (define_split
3571   [(set (match_operand:XF 0 "push_operand" "")
3572         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3573   ""
3574   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3575    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3576   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3578 (define_split
3579   [(set (match_operand:XF 0 "push_operand" "")
3580         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3581   "TARGET_64BIT"
3582   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3583    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3584   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3586 (define_expand "extendsfdf2"
3587   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3588         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3589   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3591   /* ??? Needed for compress_float_constant since all fp constants
3592      are LEGITIMATE_CONSTANT_P.  */
3593   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3594     {
3595       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3596           && standard_80387_constant_p (operands[1]) > 0)
3597         {
3598           operands[1] = simplify_const_unary_operation
3599             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3600           emit_move_insn_1 (operands[0], operands[1]);
3601           DONE;
3602         }
3603       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3604     }
3607 (define_insn "*extendsfdf2_mixed"
3608   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3609         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3610   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3612   switch (which_alternative)
3613     {
3614     case 0:
3615       return output_387_reg_move (insn, operands);
3617     case 1:
3618       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3619         return "fstp%z0\t%y0";
3620       else
3621         return "fst%z0\t%y0";
3623     case 2:
3624       return "cvtss2sd\t{%1, %0|%0, %1}";
3626     default:
3627       gcc_unreachable ();
3628     }
3630   [(set_attr "type" "fmov,fmov,ssecvt")
3631    (set_attr "mode" "SF,XF,DF")])
3633 (define_insn "*extendsfdf2_sse"
3634   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3635         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3636   "TARGET_SSE2 && TARGET_SSE_MATH"
3637   "cvtss2sd\t{%1, %0|%0, %1}"
3638   [(set_attr "type" "ssecvt")
3639    (set_attr "mode" "DF")])
3641 (define_insn "*extendsfdf2_i387"
3642   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3643         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3644   "TARGET_80387"
3646   switch (which_alternative)
3647     {
3648     case 0:
3649       return output_387_reg_move (insn, operands);
3651     case 1:
3652       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3653         return "fstp%z0\t%y0";
3654       else
3655         return "fst%z0\t%y0";
3657     default:
3658       gcc_unreachable ();
3659     }
3661   [(set_attr "type" "fmov")
3662    (set_attr "mode" "SF,XF")])
3664 (define_expand "extendsfxf2"
3665   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3666         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3667   "TARGET_80387"
3669   /* ??? Needed for compress_float_constant since all fp constants
3670      are LEGITIMATE_CONSTANT_P.  */
3671   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3672     {
3673       if (standard_80387_constant_p (operands[1]) > 0)
3674         {
3675           operands[1] = simplify_const_unary_operation
3676             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3677           emit_move_insn_1 (operands[0], operands[1]);
3678           DONE;
3679         }
3680       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3681     }
3684 (define_insn "*extendsfxf2_i387"
3685   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3686         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3687   "TARGET_80387"
3689   switch (which_alternative)
3690     {
3691     case 0:
3692       return output_387_reg_move (insn, operands);
3694     case 1:
3695       /* There is no non-popping store to memory for XFmode.  So if
3696          we need one, follow the store with a load.  */
3697       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3698         return "fstp%z0\t%y0";
3699       else
3700         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3702     default:
3703       gcc_unreachable ();
3704     }
3706   [(set_attr "type" "fmov")
3707    (set_attr "mode" "SF,XF")])
3709 (define_expand "extenddfxf2"
3710   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3711         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3712   "TARGET_80387"
3714   /* ??? Needed for compress_float_constant since all fp constants
3715      are LEGITIMATE_CONSTANT_P.  */
3716   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3717     {
3718       if (standard_80387_constant_p (operands[1]) > 0)
3719         {
3720           operands[1] = simplify_const_unary_operation
3721             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3722           emit_move_insn_1 (operands[0], operands[1]);
3723           DONE;
3724         }
3725       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3726     }
3729 (define_insn "*extenddfxf2_i387"
3730   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3731         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3732   "TARGET_80387"
3734   switch (which_alternative)
3735     {
3736     case 0:
3737       return output_387_reg_move (insn, operands);
3739     case 1:
3740       /* There is no non-popping store to memory for XFmode.  So if
3741          we need one, follow the store with a load.  */
3742       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3743         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3744       else
3745         return "fstp%z0\t%y0";
3747     default:
3748       gcc_unreachable ();
3749     }
3751   [(set_attr "type" "fmov")
3752    (set_attr "mode" "DF,XF")])
3754 ;; %%% This seems bad bad news.
3755 ;; This cannot output into an f-reg because there is no way to be sure
3756 ;; of truncating in that case.  Otherwise this is just like a simple move
3757 ;; insn.  So we pretend we can output to a reg in order to get better
3758 ;; register preferencing, but we really use a stack slot.
3760 ;; Conversion from DFmode to SFmode.
3762 (define_expand "truncdfsf2"
3763   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3764         (float_truncate:SF
3765           (match_operand:DF 1 "nonimmediate_operand" "")))]
3766   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3768   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3769     ;
3770   else if (flag_unsafe_math_optimizations)
3771     ;
3772   else
3773     {
3774       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3775       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3776       DONE;
3777     }
3780 (define_expand "truncdfsf2_with_temp"
3781   [(parallel [(set (match_operand:SF 0 "" "")
3782                    (float_truncate:SF (match_operand:DF 1 "" "")))
3783               (clobber (match_operand:SF 2 "" ""))])]
3784   "")
3786 (define_insn "*truncdfsf_fast_mixed"
3787   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3788         (float_truncate:SF
3789           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3790   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3792   switch (which_alternative)
3793     {
3794     case 0:
3795       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3796         return "fstp%z0\t%y0";
3797       else
3798         return "fst%z0\t%y0";
3799     case 1:
3800       return output_387_reg_move (insn, operands);
3801     case 2:
3802       return "cvtsd2ss\t{%1, %0|%0, %1}";
3803     default:
3804       gcc_unreachable ();
3805     }
3807   [(set_attr "type" "fmov,fmov,ssecvt")
3808    (set_attr "mode" "SF")])
3810 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3811 ;; because nothing we do here is unsafe.
3812 (define_insn "*truncdfsf_fast_sse"
3813   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3814         (float_truncate:SF
3815           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3816   "TARGET_SSE2 && TARGET_SSE_MATH"
3817   "cvtsd2ss\t{%1, %0|%0, %1}"
3818   [(set_attr "type" "ssecvt")
3819    (set_attr "mode" "SF")])
3821 (define_insn "*truncdfsf_fast_i387"
3822   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3823         (float_truncate:SF
3824           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3825   "TARGET_80387 && flag_unsafe_math_optimizations"
3826   "* return output_387_reg_move (insn, operands);"
3827   [(set_attr "type" "fmov")
3828    (set_attr "mode" "SF")])
3830 (define_insn "*truncdfsf_mixed"
3831   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3832         (float_truncate:SF
3833           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3834    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3835   "TARGET_MIX_SSE_I387"
3837   switch (which_alternative)
3838     {
3839     case 0:
3840       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3841         return "fstp%z0\t%y0";
3842       else
3843         return "fst%z0\t%y0";
3844     case 1:
3845       return "#";
3846     case 2:
3847       return "cvtsd2ss\t{%1, %0|%0, %1}";
3848     default:
3849       gcc_unreachable ();
3850     }
3852   [(set_attr "type" "fmov,multi,ssecvt")
3853    (set_attr "unit" "*,i387,*")
3854    (set_attr "mode" "SF")])
3856 (define_insn "*truncdfsf_i387"
3857   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3858         (float_truncate:SF
3859           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3860    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3861   "TARGET_80387"
3863   switch (which_alternative)
3864     {
3865     case 0:
3866       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3867         return "fstp%z0\t%y0";
3868       else
3869         return "fst%z0\t%y0";
3870     case 1:
3871       return "#";
3872     default:
3873       gcc_unreachable ();
3874     }
3876   [(set_attr "type" "fmov,multi")
3877    (set_attr "unit" "*,i387")
3878    (set_attr "mode" "SF")])
3880 (define_insn "*truncdfsf2_i387_1"
3881   [(set (match_operand:SF 0 "memory_operand" "=m")
3882         (float_truncate:SF
3883           (match_operand:DF 1 "register_operand" "f")))]
3884   "TARGET_80387
3885    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3886    && !TARGET_MIX_SSE_I387"
3888   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3889     return "fstp%z0\t%y0";
3890   else
3891     return "fst%z0\t%y0";
3893   [(set_attr "type" "fmov")
3894    (set_attr "mode" "SF")])
3896 (define_split
3897   [(set (match_operand:SF 0 "register_operand" "")
3898         (float_truncate:SF
3899          (match_operand:DF 1 "fp_register_operand" "")))
3900    (clobber (match_operand 2 "" ""))]
3901   "reload_completed"
3902   [(set (match_dup 2) (match_dup 1))
3903    (set (match_dup 0) (match_dup 2))]
3905   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3908 ;; Conversion from XFmode to SFmode.
3910 (define_expand "truncxfsf2"
3911   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3912                    (float_truncate:SF
3913                     (match_operand:XF 1 "register_operand" "")))
3914               (clobber (match_dup 2))])]
3915   "TARGET_80387"
3917   if (flag_unsafe_math_optimizations)
3918     {
3919       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3920       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3921       if (reg != operands[0])
3922         emit_move_insn (operands[0], reg);
3923       DONE;
3924     }
3925   else
3926     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3929 (define_insn "*truncxfsf2_mixed"
3930   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3931         (float_truncate:SF
3932          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3933    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3934   "TARGET_MIX_SSE_I387"
3936   gcc_assert (!which_alternative);
3937   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3938     return "fstp%z0\t%y0";
3939   else
3940     return "fst%z0\t%y0";
3942   [(set_attr "type" "fmov,multi,multi,multi")
3943    (set_attr "unit" "*,i387,i387,i387")
3944    (set_attr "mode" "SF")])
3946 (define_insn "truncxfsf2_i387_noop"
3947   [(set (match_operand:SF 0 "register_operand" "=f")
3948         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3949   "TARGET_80387 && flag_unsafe_math_optimizations"
3950   "* return output_387_reg_move (insn, operands);"
3951   [(set_attr "type" "fmov")
3952    (set_attr "mode" "SF")])
3954 (define_insn "*truncxfsf2_i387"
3955   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3956         (float_truncate:SF
3957          (match_operand:XF 1 "register_operand" "f,f,f")))
3958    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3959   "TARGET_80387"
3961   gcc_assert (!which_alternative);
3962   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3963     return "fstp%z0\t%y0";
3964    else
3965      return "fst%z0\t%y0";
3967   [(set_attr "type" "fmov,multi,multi")
3968    (set_attr "unit" "*,i387,i387")
3969    (set_attr "mode" "SF")])
3971 (define_insn "*truncxfsf2_i387_1"
3972   [(set (match_operand:SF 0 "memory_operand" "=m")
3973         (float_truncate:SF
3974          (match_operand:XF 1 "register_operand" "f")))]
3975   "TARGET_80387"
3977   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3978     return "fstp%z0\t%y0";
3979   else
3980     return "fst%z0\t%y0";
3982   [(set_attr "type" "fmov")
3983    (set_attr "mode" "SF")])
3985 (define_split
3986   [(set (match_operand:SF 0 "register_operand" "")
3987         (float_truncate:SF
3988          (match_operand:XF 1 "register_operand" "")))
3989    (clobber (match_operand:SF 2 "memory_operand" ""))]
3990   "TARGET_80387 && reload_completed"
3991   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3992    (set (match_dup 0) (match_dup 2))]
3993   "")
3995 (define_split
3996   [(set (match_operand:SF 0 "memory_operand" "")
3997         (float_truncate:SF
3998          (match_operand:XF 1 "register_operand" "")))
3999    (clobber (match_operand:SF 2 "memory_operand" ""))]
4000   "TARGET_80387"
4001   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4002   "")
4004 ;; Conversion from XFmode to DFmode.
4006 (define_expand "truncxfdf2"
4007   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4008                    (float_truncate:DF
4009                     (match_operand:XF 1 "register_operand" "")))
4010               (clobber (match_dup 2))])]
4011   "TARGET_80387"
4013   if (flag_unsafe_math_optimizations)
4014     {
4015       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4016       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4017       if (reg != operands[0])
4018         emit_move_insn (operands[0], reg);
4019       DONE;
4020     }
4021   else
4022     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4025 (define_insn "*truncxfdf2_mixed"
4026   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4027         (float_truncate:DF
4028          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4029    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4030   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4032   gcc_assert (!which_alternative);
4033   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4034     return "fstp%z0\t%y0";
4035   else
4036     return "fst%z0\t%y0";
4038   [(set_attr "type" "fmov,multi,multi,multi")
4039    (set_attr "unit" "*,i387,i387,i387")
4040    (set_attr "mode" "DF")])
4042 (define_insn "truncxfdf2_i387_noop"
4043   [(set (match_operand:DF 0 "register_operand" "=f")
4044         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4045   "TARGET_80387 && flag_unsafe_math_optimizations"
4046   "* return output_387_reg_move (insn, operands);"
4047   [(set_attr "type" "fmov")
4048    (set_attr "mode" "DF")])
4050 (define_insn "*truncxfdf2_i387"
4051   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4052         (float_truncate:DF
4053          (match_operand:XF 1 "register_operand" "f,f,f")))
4054    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4055   "TARGET_80387"
4057   gcc_assert (!which_alternative);
4058   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4059     return "fstp%z0\t%y0";
4060   else
4061     return "fst%z0\t%y0";
4063   [(set_attr "type" "fmov,multi,multi")
4064    (set_attr "unit" "*,i387,i387")
4065    (set_attr "mode" "DF")])
4067 (define_insn "*truncxfdf2_i387_1"
4068   [(set (match_operand:DF 0 "memory_operand" "=m")
4069         (float_truncate:DF
4070           (match_operand:XF 1 "register_operand" "f")))]
4071   "TARGET_80387"
4073   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4074     return "fstp%z0\t%y0";
4075   else
4076     return "fst%z0\t%y0";
4078   [(set_attr "type" "fmov")
4079    (set_attr "mode" "DF")])
4081 (define_split
4082   [(set (match_operand:DF 0 "register_operand" "")
4083         (float_truncate:DF
4084          (match_operand:XF 1 "register_operand" "")))
4085    (clobber (match_operand:DF 2 "memory_operand" ""))]
4086   "TARGET_80387 && reload_completed"
4087   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4088    (set (match_dup 0) (match_dup 2))]
4089   "")
4091 (define_split
4092   [(set (match_operand:DF 0 "memory_operand" "")
4093         (float_truncate:DF
4094          (match_operand:XF 1 "register_operand" "")))
4095    (clobber (match_operand:DF 2 "memory_operand" ""))]
4096   "TARGET_80387"
4097   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4098   "")
4100 ;; Signed conversion to DImode.
4102 (define_expand "fix_truncxfdi2"
4103   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4104                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4105               (clobber (reg:CC FLAGS_REG))])]
4106   "TARGET_80387"
4108   if (TARGET_FISTTP)
4109    {
4110      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4111      DONE;
4112    }
4115 (define_expand "fix_trunc<mode>di2"
4116   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4117                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4118               (clobber (reg:CC FLAGS_REG))])]
4119   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4121   if (TARGET_FISTTP
4122       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4123    {
4124      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4125      DONE;
4126    }
4127   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4128    {
4129      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4130      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4131      if (out != operands[0])
4132         emit_move_insn (operands[0], out);
4133      DONE;
4134    }
4137 ;; Signed conversion to SImode.
4139 (define_expand "fix_truncxfsi2"
4140   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4141                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4142               (clobber (reg:CC FLAGS_REG))])]
4143   "TARGET_80387"
4145   if (TARGET_FISTTP)
4146    {
4147      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4148      DONE;
4149    }
4152 (define_expand "fix_trunc<mode>si2"
4153   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4154                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4155               (clobber (reg:CC FLAGS_REG))])]
4156   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4158   if (TARGET_FISTTP
4159       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4160    {
4161      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4162      DONE;
4163    }
4164   if (SSE_FLOAT_MODE_P (<MODE>mode))
4165    {
4166      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4167      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4168      if (out != operands[0])
4169         emit_move_insn (operands[0], out);
4170      DONE;
4171    }
4174 ;; Signed conversion to HImode.
4176 (define_expand "fix_trunc<mode>hi2"
4177   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4178                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4179               (clobber (reg:CC FLAGS_REG))])]
4180   "TARGET_80387
4181    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4183   if (TARGET_FISTTP)
4184    {
4185      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4186      DONE;
4187    }
4190 ;; When SSE is available, it is always faster to use it!
4191 (define_insn "fix_truncsfdi_sse"
4192   [(set (match_operand:DI 0 "register_operand" "=r,r")
4193         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4194   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4195   "cvttss2si{q}\t{%1, %0|%0, %1}"
4196   [(set_attr "type" "sseicvt")
4197    (set_attr "mode" "SF")
4198    (set_attr "athlon_decode" "double,vector")])
4200 (define_insn "fix_truncdfdi_sse"
4201   [(set (match_operand:DI 0 "register_operand" "=r,r")
4202         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4203   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4204   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4205   [(set_attr "type" "sseicvt")
4206    (set_attr "mode" "DF")
4207    (set_attr "athlon_decode" "double,vector")])
4209 (define_insn "fix_truncsfsi_sse"
4210   [(set (match_operand:SI 0 "register_operand" "=r,r")
4211         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4212   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4213   "cvttss2si\t{%1, %0|%0, %1}"
4214   [(set_attr "type" "sseicvt")
4215    (set_attr "mode" "DF")
4216    (set_attr "athlon_decode" "double,vector")])
4218 (define_insn "fix_truncdfsi_sse"
4219   [(set (match_operand:SI 0 "register_operand" "=r,r")
4220         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4221   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4222   "cvttsd2si\t{%1, %0|%0, %1}"
4223   [(set_attr "type" "sseicvt")
4224    (set_attr "mode" "DF")
4225    (set_attr "athlon_decode" "double,vector")])
4227 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4228 (define_peephole2
4229   [(set (match_operand:DF 0 "register_operand" "")
4230         (match_operand:DF 1 "memory_operand" ""))
4231    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4232         (fix:SSEMODEI24 (match_dup 0)))]
4233   "!TARGET_K8
4234    && peep2_reg_dead_p (2, operands[0])"
4235   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4236   "")
4238 (define_peephole2
4239   [(set (match_operand:SF 0 "register_operand" "")
4240         (match_operand:SF 1 "memory_operand" ""))
4241    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4242         (fix:SSEMODEI24 (match_dup 0)))]
4243   "!TARGET_K8
4244    && peep2_reg_dead_p (2, operands[0])"
4245   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4246   "")
4248 ;; Avoid vector decoded forms of the instruction.
4249 (define_peephole2
4250   [(match_scratch:DF 2 "Y")
4251    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4252         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4253   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4254   [(set (match_dup 2) (match_dup 1))
4255    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4256   "")
4258 (define_peephole2
4259   [(match_scratch:SF 2 "x")
4260    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4261         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4262   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4263   [(set (match_dup 2) (match_dup 1))
4264    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4265   "")
4267 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4268   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4269         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4270   "TARGET_FISTTP
4271    && FLOAT_MODE_P (GET_MODE (operands[1]))
4272    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4273          && (TARGET_64BIT || <MODE>mode != DImode))
4274         && TARGET_SSE_MATH)
4275    && !(reload_completed || reload_in_progress)"
4276   "#"
4277   "&& 1"
4278   [(const_int 0)]
4280   if (memory_operand (operands[0], VOIDmode))
4281     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4282   else
4283     {
4284       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4285       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4286                                                             operands[1],
4287                                                             operands[2]));
4288     }
4289   DONE;
4291   [(set_attr "type" "fisttp")
4292    (set_attr "mode" "<MODE>")])
4294 (define_insn "fix_trunc<mode>_i387_fisttp"
4295   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4296         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4297    (clobber (match_scratch:XF 2 "=&1f"))]
4298   "TARGET_FISTTP
4299    && FLOAT_MODE_P (GET_MODE (operands[1]))
4300    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4301          && (TARGET_64BIT || <MODE>mode != DImode))
4302         && TARGET_SSE_MATH)"
4303   "* return output_fix_trunc (insn, operands, 1);"
4304   [(set_attr "type" "fisttp")
4305    (set_attr "mode" "<MODE>")])
4307 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4308   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4309         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4310    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4311    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4312   "TARGET_FISTTP
4313    && FLOAT_MODE_P (GET_MODE (operands[1]))
4314    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4315         && (TARGET_64BIT || <MODE>mode != DImode))
4316         && TARGET_SSE_MATH)"
4317   "#"
4318   [(set_attr "type" "fisttp")
4319    (set_attr "mode" "<MODE>")])
4321 (define_split
4322   [(set (match_operand:X87MODEI 0 "register_operand" "")
4323         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4324    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4325    (clobber (match_scratch 3 ""))]
4326   "reload_completed"
4327   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4328               (clobber (match_dup 3))])
4329    (set (match_dup 0) (match_dup 2))]
4330   "")
4332 (define_split
4333   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4334         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4335    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4336    (clobber (match_scratch 3 ""))]
4337   "reload_completed"
4338   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4339               (clobber (match_dup 3))])]
4340   "")
4342 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4343 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4344 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4345 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4346 ;; function in i386.c.
4347 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4348   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4349         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4350    (clobber (reg:CC FLAGS_REG))]
4351   "TARGET_80387 && !TARGET_FISTTP
4352    && FLOAT_MODE_P (GET_MODE (operands[1]))
4353    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4354          && (TARGET_64BIT || <MODE>mode != DImode))
4355    && !(reload_completed || reload_in_progress)"
4356   "#"
4357   "&& 1"
4358   [(const_int 0)]
4360   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4362   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4363   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4364   if (memory_operand (operands[0], VOIDmode))
4365     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4366                                          operands[2], operands[3]));
4367   else
4368     {
4369       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4370       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4371                                                      operands[2], operands[3],
4372                                                      operands[4]));
4373     }
4374   DONE;
4376   [(set_attr "type" "fistp")
4377    (set_attr "i387_cw" "trunc")
4378    (set_attr "mode" "<MODE>")])
4380 (define_insn "fix_truncdi_i387"
4381   [(set (match_operand:DI 0 "memory_operand" "=m")
4382         (fix:DI (match_operand 1 "register_operand" "f")))
4383    (use (match_operand:HI 2 "memory_operand" "m"))
4384    (use (match_operand:HI 3 "memory_operand" "m"))
4385    (clobber (match_scratch:XF 4 "=&1f"))]
4386   "TARGET_80387 && !TARGET_FISTTP
4387    && FLOAT_MODE_P (GET_MODE (operands[1]))
4388    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4389   "* return output_fix_trunc (insn, operands, 0);"
4390   [(set_attr "type" "fistp")
4391    (set_attr "i387_cw" "trunc")
4392    (set_attr "mode" "DI")])
4394 (define_insn "fix_truncdi_i387_with_temp"
4395   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4396         (fix:DI (match_operand 1 "register_operand" "f,f")))
4397    (use (match_operand:HI 2 "memory_operand" "m,m"))
4398    (use (match_operand:HI 3 "memory_operand" "m,m"))
4399    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4400    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4401   "TARGET_80387 && !TARGET_FISTTP
4402    && FLOAT_MODE_P (GET_MODE (operands[1]))
4403    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4404   "#"
4405   [(set_attr "type" "fistp")
4406    (set_attr "i387_cw" "trunc")
4407    (set_attr "mode" "DI")])
4409 (define_split
4410   [(set (match_operand:DI 0 "register_operand" "")
4411         (fix:DI (match_operand 1 "register_operand" "")))
4412    (use (match_operand:HI 2 "memory_operand" ""))
4413    (use (match_operand:HI 3 "memory_operand" ""))
4414    (clobber (match_operand:DI 4 "memory_operand" ""))
4415    (clobber (match_scratch 5 ""))]
4416   "reload_completed"
4417   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4418               (use (match_dup 2))
4419               (use (match_dup 3))
4420               (clobber (match_dup 5))])
4421    (set (match_dup 0) (match_dup 4))]
4422   "")
4424 (define_split
4425   [(set (match_operand:DI 0 "memory_operand" "")
4426         (fix:DI (match_operand 1 "register_operand" "")))
4427    (use (match_operand:HI 2 "memory_operand" ""))
4428    (use (match_operand:HI 3 "memory_operand" ""))
4429    (clobber (match_operand:DI 4 "memory_operand" ""))
4430    (clobber (match_scratch 5 ""))]
4431   "reload_completed"
4432   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4433               (use (match_dup 2))
4434               (use (match_dup 3))
4435               (clobber (match_dup 5))])]
4436   "")
4438 (define_insn "fix_trunc<mode>_i387"
4439   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4440         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4441    (use (match_operand:HI 2 "memory_operand" "m"))
4442    (use (match_operand:HI 3 "memory_operand" "m"))]
4443   "TARGET_80387 && !TARGET_FISTTP
4444    && FLOAT_MODE_P (GET_MODE (operands[1]))
4445    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4446   "* return output_fix_trunc (insn, operands, 0);"
4447   [(set_attr "type" "fistp")
4448    (set_attr "i387_cw" "trunc")
4449    (set_attr "mode" "<MODE>")])
4451 (define_insn "fix_trunc<mode>_i387_with_temp"
4452   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4453         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4454    (use (match_operand:HI 2 "memory_operand" "m,m"))
4455    (use (match_operand:HI 3 "memory_operand" "m,m"))
4456    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4457   "TARGET_80387 && !TARGET_FISTTP
4458    && FLOAT_MODE_P (GET_MODE (operands[1]))
4459    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4460   "#"
4461   [(set_attr "type" "fistp")
4462    (set_attr "i387_cw" "trunc")
4463    (set_attr "mode" "<MODE>")])
4465 (define_split
4466   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4467         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4468    (use (match_operand:HI 2 "memory_operand" ""))
4469    (use (match_operand:HI 3 "memory_operand" ""))
4470    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4471   "reload_completed"
4472   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4473               (use (match_dup 2))
4474               (use (match_dup 3))])
4475    (set (match_dup 0) (match_dup 4))]
4476   "")
4478 (define_split
4479   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4480         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4481    (use (match_operand:HI 2 "memory_operand" ""))
4482    (use (match_operand:HI 3 "memory_operand" ""))
4483    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4484   "reload_completed"
4485   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4486               (use (match_dup 2))
4487               (use (match_dup 3))])]
4488   "")
4490 (define_insn "x86_fnstcw_1"
4491   [(set (match_operand:HI 0 "memory_operand" "=m")
4492         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4493   "TARGET_80387"
4494   "fnstcw\t%0"
4495   [(set_attr "length" "2")
4496    (set_attr "mode" "HI")
4497    (set_attr "unit" "i387")])
4499 (define_insn "x86_fldcw_1"
4500   [(set (reg:HI FPCR_REG)
4501         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4502   "TARGET_80387"
4503   "fldcw\t%0"
4504   [(set_attr "length" "2")
4505    (set_attr "mode" "HI")
4506    (set_attr "unit" "i387")
4507    (set_attr "athlon_decode" "vector")])
4509 ;; Conversion between fixed point and floating point.
4511 ;; Even though we only accept memory inputs, the backend _really_
4512 ;; wants to be able to do this between registers.
4514 (define_expand "floathisf2"
4515   [(set (match_operand:SF 0 "register_operand" "")
4516         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4517   "TARGET_80387 || TARGET_SSE_MATH"
4519   if (TARGET_SSE_MATH)
4520     {
4521       emit_insn (gen_floatsisf2 (operands[0],
4522                                  convert_to_mode (SImode, operands[1], 0)));
4523       DONE;
4524     }
4527 (define_insn "*floathisf2_i387"
4528   [(set (match_operand:SF 0 "register_operand" "=f,f")
4529         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4530   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4531   "@
4532    fild%z1\t%1
4533    #"
4534   [(set_attr "type" "fmov,multi")
4535    (set_attr "mode" "SF")
4536    (set_attr "unit" "*,i387")
4537    (set_attr "fp_int_src" "true")])
4539 (define_expand "floatsisf2"
4540   [(set (match_operand:SF 0 "register_operand" "")
4541         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4542   "TARGET_80387 || TARGET_SSE_MATH"
4543   "")
4545 (define_insn "*floatsisf2_mixed"
4546   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4547         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4548   "TARGET_MIX_SSE_I387"
4549   "@
4550    fild%z1\t%1
4551    #
4552    cvtsi2ss\t{%1, %0|%0, %1}
4553    cvtsi2ss\t{%1, %0|%0, %1}"
4554   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4555    (set_attr "mode" "SF")
4556    (set_attr "unit" "*,i387,*,*")
4557    (set_attr "athlon_decode" "*,*,vector,double")
4558    (set_attr "fp_int_src" "true")])
4560 (define_insn "*floatsisf2_sse"
4561   [(set (match_operand:SF 0 "register_operand" "=x,x")
4562         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4563   "TARGET_SSE_MATH"
4564   "cvtsi2ss\t{%1, %0|%0, %1}"
4565   [(set_attr "type" "sseicvt")
4566    (set_attr "mode" "SF")
4567    (set_attr "athlon_decode" "vector,double")
4568    (set_attr "fp_int_src" "true")])
4570 (define_insn "*floatsisf2_i387"
4571   [(set (match_operand:SF 0 "register_operand" "=f,f")
4572         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4573   "TARGET_80387"
4574   "@
4575    fild%z1\t%1
4576    #"
4577   [(set_attr "type" "fmov,multi")
4578    (set_attr "mode" "SF")
4579    (set_attr "unit" "*,i387")
4580    (set_attr "fp_int_src" "true")])
4582 (define_expand "floatdisf2"
4583   [(set (match_operand:SF 0 "register_operand" "")
4584         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4585   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4586   "")
4588 (define_insn "*floatdisf2_mixed"
4589   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4590         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4591   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4592   "@
4593    fild%z1\t%1
4594    #
4595    cvtsi2ss{q}\t{%1, %0|%0, %1}
4596    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4597   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4598    (set_attr "mode" "SF")
4599    (set_attr "unit" "*,i387,*,*")
4600    (set_attr "athlon_decode" "*,*,vector,double")
4601    (set_attr "fp_int_src" "true")])
4603 (define_insn "*floatdisf2_sse"
4604   [(set (match_operand:SF 0 "register_operand" "=x,x")
4605         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4606   "TARGET_64BIT && TARGET_SSE_MATH"
4607   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4608   [(set_attr "type" "sseicvt")
4609    (set_attr "mode" "SF")
4610    (set_attr "athlon_decode" "vector,double")
4611    (set_attr "fp_int_src" "true")])
4613 (define_insn "*floatdisf2_i387"
4614   [(set (match_operand:SF 0 "register_operand" "=f,f")
4615         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4616   "TARGET_80387"
4617   "@
4618    fild%z1\t%1
4619    #"
4620   [(set_attr "type" "fmov,multi")
4621    (set_attr "mode" "SF")
4622    (set_attr "unit" "*,i387")
4623    (set_attr "fp_int_src" "true")])
4625 (define_expand "floathidf2"
4626   [(set (match_operand:DF 0 "register_operand" "")
4627         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4628   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4630   if (TARGET_SSE2 && TARGET_SSE_MATH)
4631     {
4632       emit_insn (gen_floatsidf2 (operands[0],
4633                                  convert_to_mode (SImode, operands[1], 0)));
4634       DONE;
4635     }
4638 (define_insn "*floathidf2_i387"
4639   [(set (match_operand:DF 0 "register_operand" "=f,f")
4640         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4641   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4642   "@
4643    fild%z1\t%1
4644    #"
4645   [(set_attr "type" "fmov,multi")
4646    (set_attr "mode" "DF")
4647    (set_attr "unit" "*,i387")
4648    (set_attr "fp_int_src" "true")])
4650 (define_expand "floatsidf2"
4651   [(set (match_operand:DF 0 "register_operand" "")
4652         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4653   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4654   "")
4656 (define_insn "*floatsidf2_mixed"
4657   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4658         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4659   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4660   "@
4661    fild%z1\t%1
4662    #
4663    cvtsi2sd\t{%1, %0|%0, %1}
4664    cvtsi2sd\t{%1, %0|%0, %1}"
4665   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4666    (set_attr "mode" "DF")
4667    (set_attr "unit" "*,i387,*,*")
4668    (set_attr "athlon_decode" "*,*,double,direct")
4669    (set_attr "fp_int_src" "true")])
4671 (define_insn "*floatsidf2_sse"
4672   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4673         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4674   "TARGET_SSE2 && TARGET_SSE_MATH"
4675   "cvtsi2sd\t{%1, %0|%0, %1}"
4676   [(set_attr "type" "sseicvt")
4677    (set_attr "mode" "DF")
4678    (set_attr "athlon_decode" "double,direct")
4679    (set_attr "fp_int_src" "true")])
4681 (define_insn "*floatsidf2_i387"
4682   [(set (match_operand:DF 0 "register_operand" "=f,f")
4683         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4684   "TARGET_80387"
4685   "@
4686    fild%z1\t%1
4687    #"
4688   [(set_attr "type" "fmov,multi")
4689    (set_attr "mode" "DF")
4690    (set_attr "unit" "*,i387")
4691    (set_attr "fp_int_src" "true")])
4693 (define_expand "floatdidf2"
4694   [(set (match_operand:DF 0 "register_operand" "")
4695         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4696   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4697   "")
4699 (define_insn "*floatdidf2_mixed"
4700   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4701         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4702   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4703   "@
4704    fild%z1\t%1
4705    #
4706    cvtsi2sd{q}\t{%1, %0|%0, %1}
4707    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4708   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4709    (set_attr "mode" "DF")
4710    (set_attr "unit" "*,i387,*,*")
4711    (set_attr "athlon_decode" "*,*,double,direct")
4712    (set_attr "fp_int_src" "true")])
4714 (define_insn "*floatdidf2_sse"
4715   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4716         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4717   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4718   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4719   [(set_attr "type" "sseicvt")
4720    (set_attr "mode" "DF")
4721    (set_attr "athlon_decode" "double,direct")
4722    (set_attr "fp_int_src" "true")])
4724 (define_insn "*floatdidf2_i387"
4725   [(set (match_operand:DF 0 "register_operand" "=f,f")
4726         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4727   "TARGET_80387"
4728   "@
4729    fild%z1\t%1
4730    #"
4731   [(set_attr "type" "fmov,multi")
4732    (set_attr "mode" "DF")
4733    (set_attr "unit" "*,i387")
4734    (set_attr "fp_int_src" "true")])
4736 (define_insn "floathixf2"
4737   [(set (match_operand:XF 0 "register_operand" "=f,f")
4738         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4739   "TARGET_80387"
4740   "@
4741    fild%z1\t%1
4742    #"
4743   [(set_attr "type" "fmov,multi")
4744    (set_attr "mode" "XF")
4745    (set_attr "unit" "*,i387")
4746    (set_attr "fp_int_src" "true")])
4748 (define_insn "floatsixf2"
4749   [(set (match_operand:XF 0 "register_operand" "=f,f")
4750         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4751   "TARGET_80387"
4752   "@
4753    fild%z1\t%1
4754    #"
4755   [(set_attr "type" "fmov,multi")
4756    (set_attr "mode" "XF")
4757    (set_attr "unit" "*,i387")
4758    (set_attr "fp_int_src" "true")])
4760 (define_insn "floatdixf2"
4761   [(set (match_operand:XF 0 "register_operand" "=f,f")
4762         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4763   "TARGET_80387"
4764   "@
4765    fild%z1\t%1
4766    #"
4767   [(set_attr "type" "fmov,multi")
4768    (set_attr "mode" "XF")
4769    (set_attr "unit" "*,i387")
4770    (set_attr "fp_int_src" "true")])
4772 ;; %%% Kill these when reload knows how to do it.
4773 (define_split
4774   [(set (match_operand 0 "fp_register_operand" "")
4775         (float (match_operand 1 "register_operand" "")))]
4776   "reload_completed
4777    && TARGET_80387
4778    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4779   [(const_int 0)]
4781   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4782   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4783   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4784   ix86_free_from_memory (GET_MODE (operands[1]));
4785   DONE;
4788 (define_expand "floatunssisf2"
4789   [(use (match_operand:SF 0 "register_operand" ""))
4790    (use (match_operand:SI 1 "register_operand" ""))]
4791   "!TARGET_64BIT && TARGET_SSE_MATH"
4792   "x86_emit_floatuns (operands); DONE;")
4794 (define_expand "floatunsdisf2"
4795   [(use (match_operand:SF 0 "register_operand" ""))
4796    (use (match_operand:DI 1 "register_operand" ""))]
4797   "TARGET_64BIT && TARGET_SSE_MATH"
4798   "x86_emit_floatuns (operands); DONE;")
4800 (define_expand "floatunsdidf2"
4801   [(use (match_operand:DF 0 "register_operand" ""))
4802    (use (match_operand:DI 1 "register_operand" ""))]
4803   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4804   "x86_emit_floatuns (operands); DONE;")
4806 ;; SSE extract/set expanders
4809 ;; Add instructions
4811 ;; %%% splits for addditi3
4813 (define_expand "addti3"
4814   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4815         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4816                  (match_operand:TI 2 "x86_64_general_operand" "")))
4817    (clobber (reg:CC FLAGS_REG))]
4818   "TARGET_64BIT"
4819   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4821 (define_insn "*addti3_1"
4822   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4823         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4824                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4825    (clobber (reg:CC FLAGS_REG))]
4826   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4827   "#")
4829 (define_split
4830   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4831         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4832                  (match_operand:TI 2 "general_operand" "")))
4833    (clobber (reg:CC FLAGS_REG))]
4834   "TARGET_64BIT && reload_completed"
4835   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4836                                           UNSPEC_ADD_CARRY))
4837               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4838    (parallel [(set (match_dup 3)
4839                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4840                                      (match_dup 4))
4841                             (match_dup 5)))
4842               (clobber (reg:CC FLAGS_REG))])]
4843   "split_ti (operands+0, 1, operands+0, operands+3);
4844    split_ti (operands+1, 1, operands+1, operands+4);
4845    split_ti (operands+2, 1, operands+2, operands+5);")
4847 ;; %%% splits for addsidi3
4848 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4849 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4850 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4852 (define_expand "adddi3"
4853   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4854         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4855                  (match_operand:DI 2 "x86_64_general_operand" "")))
4856    (clobber (reg:CC FLAGS_REG))]
4857   ""
4858   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4860 (define_insn "*adddi3_1"
4861   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4862         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4863                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4864    (clobber (reg:CC FLAGS_REG))]
4865   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4866   "#")
4868 (define_split
4869   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4870         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4871                  (match_operand:DI 2 "general_operand" "")))
4872    (clobber (reg:CC FLAGS_REG))]
4873   "!TARGET_64BIT && reload_completed"
4874   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4875                                           UNSPEC_ADD_CARRY))
4876               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4877    (parallel [(set (match_dup 3)
4878                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4879                                      (match_dup 4))
4880                             (match_dup 5)))
4881               (clobber (reg:CC FLAGS_REG))])]
4882   "split_di (operands+0, 1, operands+0, operands+3);
4883    split_di (operands+1, 1, operands+1, operands+4);
4884    split_di (operands+2, 1, operands+2, operands+5);")
4886 (define_insn "adddi3_carry_rex64"
4887   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4888           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4889                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4890                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4891    (clobber (reg:CC FLAGS_REG))]
4892   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4893   "adc{q}\t{%2, %0|%0, %2}"
4894   [(set_attr "type" "alu")
4895    (set_attr "pent_pair" "pu")
4896    (set_attr "mode" "DI")])
4898 (define_insn "*adddi3_cc_rex64"
4899   [(set (reg:CC FLAGS_REG)
4900         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4901                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4902                    UNSPEC_ADD_CARRY))
4903    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4904         (plus:DI (match_dup 1) (match_dup 2)))]
4905   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4906   "add{q}\t{%2, %0|%0, %2}"
4907   [(set_attr "type" "alu")
4908    (set_attr "mode" "DI")])
4910 (define_insn "addqi3_carry"
4911   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4912           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4913                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4914                    (match_operand:QI 2 "general_operand" "qi,qm")))
4915    (clobber (reg:CC FLAGS_REG))]
4916   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4917   "adc{b}\t{%2, %0|%0, %2}"
4918   [(set_attr "type" "alu")
4919    (set_attr "pent_pair" "pu")
4920    (set_attr "mode" "QI")])
4922 (define_insn "addhi3_carry"
4923   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4924           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4925                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4926                    (match_operand:HI 2 "general_operand" "ri,rm")))
4927    (clobber (reg:CC FLAGS_REG))]
4928   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4929   "adc{w}\t{%2, %0|%0, %2}"
4930   [(set_attr "type" "alu")
4931    (set_attr "pent_pair" "pu")
4932    (set_attr "mode" "HI")])
4934 (define_insn "addsi3_carry"
4935   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4936           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4937                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4938                    (match_operand:SI 2 "general_operand" "ri,rm")))
4939    (clobber (reg:CC FLAGS_REG))]
4940   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4941   "adc{l}\t{%2, %0|%0, %2}"
4942   [(set_attr "type" "alu")
4943    (set_attr "pent_pair" "pu")
4944    (set_attr "mode" "SI")])
4946 (define_insn "*addsi3_carry_zext"
4947   [(set (match_operand:DI 0 "register_operand" "=r")
4948           (zero_extend:DI
4949             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4950                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4951                      (match_operand:SI 2 "general_operand" "rim"))))
4952    (clobber (reg:CC FLAGS_REG))]
4953   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4954   "adc{l}\t{%2, %k0|%k0, %2}"
4955   [(set_attr "type" "alu")
4956    (set_attr "pent_pair" "pu")
4957    (set_attr "mode" "SI")])
4959 (define_insn "*addsi3_cc"
4960   [(set (reg:CC FLAGS_REG)
4961         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4962                     (match_operand:SI 2 "general_operand" "ri,rm")]
4963                    UNSPEC_ADD_CARRY))
4964    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4965         (plus:SI (match_dup 1) (match_dup 2)))]
4966   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4967   "add{l}\t{%2, %0|%0, %2}"
4968   [(set_attr "type" "alu")
4969    (set_attr "mode" "SI")])
4971 (define_insn "addqi3_cc"
4972   [(set (reg:CC FLAGS_REG)
4973         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4974                     (match_operand:QI 2 "general_operand" "qi,qm")]
4975                    UNSPEC_ADD_CARRY))
4976    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4977         (plus:QI (match_dup 1) (match_dup 2)))]
4978   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4979   "add{b}\t{%2, %0|%0, %2}"
4980   [(set_attr "type" "alu")
4981    (set_attr "mode" "QI")])
4983 (define_expand "addsi3"
4984   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4985                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4986                             (match_operand:SI 2 "general_operand" "")))
4987               (clobber (reg:CC FLAGS_REG))])]
4988   ""
4989   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4991 (define_insn "*lea_1"
4992   [(set (match_operand:SI 0 "register_operand" "=r")
4993         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4994   "!TARGET_64BIT"
4995   "lea{l}\t{%a1, %0|%0, %a1}"
4996   [(set_attr "type" "lea")
4997    (set_attr "mode" "SI")])
4999 (define_insn "*lea_1_rex64"
5000   [(set (match_operand:SI 0 "register_operand" "=r")
5001         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5002   "TARGET_64BIT"
5003   "lea{l}\t{%a1, %0|%0, %a1}"
5004   [(set_attr "type" "lea")
5005    (set_attr "mode" "SI")])
5007 (define_insn "*lea_1_zext"
5008   [(set (match_operand:DI 0 "register_operand" "=r")
5009         (zero_extend:DI
5010          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5011   "TARGET_64BIT"
5012   "lea{l}\t{%a1, %k0|%k0, %a1}"
5013   [(set_attr "type" "lea")
5014    (set_attr "mode" "SI")])
5016 (define_insn "*lea_2_rex64"
5017   [(set (match_operand:DI 0 "register_operand" "=r")
5018         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5019   "TARGET_64BIT"
5020   "lea{q}\t{%a1, %0|%0, %a1}"
5021   [(set_attr "type" "lea")
5022    (set_attr "mode" "DI")])
5024 ;; The lea patterns for non-Pmodes needs to be matched by several
5025 ;; insns converted to real lea by splitters.
5027 (define_insn_and_split "*lea_general_1"
5028   [(set (match_operand 0 "register_operand" "=r")
5029         (plus (plus (match_operand 1 "index_register_operand" "l")
5030                     (match_operand 2 "register_operand" "r"))
5031               (match_operand 3 "immediate_operand" "i")))]
5032   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5033     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5034    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5035    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5036    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5037    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5038        || GET_MODE (operands[3]) == VOIDmode)"
5039   "#"
5040   "&& reload_completed"
5041   [(const_int 0)]
5043   rtx pat;
5044   operands[0] = gen_lowpart (SImode, operands[0]);
5045   operands[1] = gen_lowpart (Pmode, operands[1]);
5046   operands[2] = gen_lowpart (Pmode, operands[2]);
5047   operands[3] = gen_lowpart (Pmode, operands[3]);
5048   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5049                       operands[3]);
5050   if (Pmode != SImode)
5051     pat = gen_rtx_SUBREG (SImode, pat, 0);
5052   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5053   DONE;
5055   [(set_attr "type" "lea")
5056    (set_attr "mode" "SI")])
5058 (define_insn_and_split "*lea_general_1_zext"
5059   [(set (match_operand:DI 0 "register_operand" "=r")
5060         (zero_extend:DI
5061           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5062                             (match_operand:SI 2 "register_operand" "r"))
5063                    (match_operand:SI 3 "immediate_operand" "i"))))]
5064   "TARGET_64BIT"
5065   "#"
5066   "&& reload_completed"
5067   [(set (match_dup 0)
5068         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5069                                                      (match_dup 2))
5070                                             (match_dup 3)) 0)))]
5072   operands[1] = gen_lowpart (Pmode, operands[1]);
5073   operands[2] = gen_lowpart (Pmode, operands[2]);
5074   operands[3] = gen_lowpart (Pmode, operands[3]);
5076   [(set_attr "type" "lea")
5077    (set_attr "mode" "SI")])
5079 (define_insn_and_split "*lea_general_2"
5080   [(set (match_operand 0 "register_operand" "=r")
5081         (plus (mult (match_operand 1 "index_register_operand" "l")
5082                     (match_operand 2 "const248_operand" "i"))
5083               (match_operand 3 "nonmemory_operand" "ri")))]
5084   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5085     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5086    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5087    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5088    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5089        || GET_MODE (operands[3]) == VOIDmode)"
5090   "#"
5091   "&& reload_completed"
5092   [(const_int 0)]
5094   rtx pat;
5095   operands[0] = gen_lowpart (SImode, operands[0]);
5096   operands[1] = gen_lowpart (Pmode, operands[1]);
5097   operands[3] = gen_lowpart (Pmode, operands[3]);
5098   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5099                       operands[3]);
5100   if (Pmode != SImode)
5101     pat = gen_rtx_SUBREG (SImode, pat, 0);
5102   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5103   DONE;
5105   [(set_attr "type" "lea")
5106    (set_attr "mode" "SI")])
5108 (define_insn_and_split "*lea_general_2_zext"
5109   [(set (match_operand:DI 0 "register_operand" "=r")
5110         (zero_extend:DI
5111           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5112                             (match_operand:SI 2 "const248_operand" "n"))
5113                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5114   "TARGET_64BIT"
5115   "#"
5116   "&& reload_completed"
5117   [(set (match_dup 0)
5118         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5119                                                      (match_dup 2))
5120                                             (match_dup 3)) 0)))]
5122   operands[1] = gen_lowpart (Pmode, operands[1]);
5123   operands[3] = gen_lowpart (Pmode, operands[3]);
5125   [(set_attr "type" "lea")
5126    (set_attr "mode" "SI")])
5128 (define_insn_and_split "*lea_general_3"
5129   [(set (match_operand 0 "register_operand" "=r")
5130         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5131                           (match_operand 2 "const248_operand" "i"))
5132                     (match_operand 3 "register_operand" "r"))
5133               (match_operand 4 "immediate_operand" "i")))]
5134   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5135     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5136    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5137    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5138    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5139   "#"
5140   "&& reload_completed"
5141   [(const_int 0)]
5143   rtx pat;
5144   operands[0] = gen_lowpart (SImode, operands[0]);
5145   operands[1] = gen_lowpart (Pmode, operands[1]);
5146   operands[3] = gen_lowpart (Pmode, operands[3]);
5147   operands[4] = gen_lowpart (Pmode, operands[4]);
5148   pat = gen_rtx_PLUS (Pmode,
5149                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5150                                                          operands[2]),
5151                                     operands[3]),
5152                       operands[4]);
5153   if (Pmode != SImode)
5154     pat = gen_rtx_SUBREG (SImode, pat, 0);
5155   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5156   DONE;
5158   [(set_attr "type" "lea")
5159    (set_attr "mode" "SI")])
5161 (define_insn_and_split "*lea_general_3_zext"
5162   [(set (match_operand:DI 0 "register_operand" "=r")
5163         (zero_extend:DI
5164           (plus:SI (plus:SI (mult:SI
5165                               (match_operand:SI 1 "index_register_operand" "l")
5166                               (match_operand:SI 2 "const248_operand" "n"))
5167                             (match_operand:SI 3 "register_operand" "r"))
5168                    (match_operand:SI 4 "immediate_operand" "i"))))]
5169   "TARGET_64BIT"
5170   "#"
5171   "&& reload_completed"
5172   [(set (match_dup 0)
5173         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5174                                                               (match_dup 2))
5175                                                      (match_dup 3))
5176                                             (match_dup 4)) 0)))]
5178   operands[1] = gen_lowpart (Pmode, operands[1]);
5179   operands[3] = gen_lowpart (Pmode, operands[3]);
5180   operands[4] = gen_lowpart (Pmode, operands[4]);
5182   [(set_attr "type" "lea")
5183    (set_attr "mode" "SI")])
5185 (define_insn "*adddi_1_rex64"
5186   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5187         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5188                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5189    (clobber (reg:CC FLAGS_REG))]
5190   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5192   switch (get_attr_type (insn))
5193     {
5194     case TYPE_LEA:
5195       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5196       return "lea{q}\t{%a2, %0|%0, %a2}";
5198     case TYPE_INCDEC:
5199       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5200       if (operands[2] == const1_rtx)
5201         return "inc{q}\t%0";
5202       else
5203         {
5204           gcc_assert (operands[2] == constm1_rtx);
5205           return "dec{q}\t%0";
5206         }
5208     default:
5209       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5211       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5212          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5213       if (GET_CODE (operands[2]) == CONST_INT
5214           /* Avoid overflows.  */
5215           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5216           && (INTVAL (operands[2]) == 128
5217               || (INTVAL (operands[2]) < 0
5218                   && INTVAL (operands[2]) != -128)))
5219         {
5220           operands[2] = GEN_INT (-INTVAL (operands[2]));
5221           return "sub{q}\t{%2, %0|%0, %2}";
5222         }
5223       return "add{q}\t{%2, %0|%0, %2}";
5224     }
5226   [(set (attr "type")
5227      (cond [(eq_attr "alternative" "2")
5228               (const_string "lea")
5229             ; Current assemblers are broken and do not allow @GOTOFF in
5230             ; ought but a memory context.
5231             (match_operand:DI 2 "pic_symbolic_operand" "")
5232               (const_string "lea")
5233             (match_operand:DI 2 "incdec_operand" "")
5234               (const_string "incdec")
5235            ]
5236            (const_string "alu")))
5237    (set_attr "mode" "DI")])
5239 ;; Convert lea to the lea pattern to avoid flags dependency.
5240 (define_split
5241   [(set (match_operand:DI 0 "register_operand" "")
5242         (plus:DI (match_operand:DI 1 "register_operand" "")
5243                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5244    (clobber (reg:CC FLAGS_REG))]
5245   "TARGET_64BIT && reload_completed
5246    && true_regnum (operands[0]) != true_regnum (operands[1])"
5247   [(set (match_dup 0)
5248         (plus:DI (match_dup 1)
5249                  (match_dup 2)))]
5250   "")
5252 (define_insn "*adddi_2_rex64"
5253   [(set (reg FLAGS_REG)
5254         (compare
5255           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5256                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5257           (const_int 0)))
5258    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5259         (plus:DI (match_dup 1) (match_dup 2)))]
5260   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5261    && ix86_binary_operator_ok (PLUS, DImode, operands)
5262    /* Current assemblers are broken and do not allow @GOTOFF in
5263       ought but a memory context.  */
5264    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5266   switch (get_attr_type (insn))
5267     {
5268     case TYPE_INCDEC:
5269       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5270       if (operands[2] == const1_rtx)
5271         return "inc{q}\t%0";
5272       else
5273         {
5274           gcc_assert (operands[2] == constm1_rtx);
5275           return "dec{q}\t%0";
5276         }
5278     default:
5279       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5280       /* ???? We ought to handle there the 32bit case too
5281          - do we need new constraint?  */
5282       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5283          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5284       if (GET_CODE (operands[2]) == CONST_INT
5285           /* Avoid overflows.  */
5286           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5287           && (INTVAL (operands[2]) == 128
5288               || (INTVAL (operands[2]) < 0
5289                   && INTVAL (operands[2]) != -128)))
5290         {
5291           operands[2] = GEN_INT (-INTVAL (operands[2]));
5292           return "sub{q}\t{%2, %0|%0, %2}";
5293         }
5294       return "add{q}\t{%2, %0|%0, %2}";
5295     }
5297   [(set (attr "type")
5298      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5299         (const_string "incdec")
5300         (const_string "alu")))
5301    (set_attr "mode" "DI")])
5303 (define_insn "*adddi_3_rex64"
5304   [(set (reg FLAGS_REG)
5305         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5306                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5307    (clobber (match_scratch:DI 0 "=r"))]
5308   "TARGET_64BIT
5309    && ix86_match_ccmode (insn, CCZmode)
5310    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5311    /* Current assemblers are broken and do not allow @GOTOFF in
5312       ought but a memory context.  */
5313    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5315   switch (get_attr_type (insn))
5316     {
5317     case TYPE_INCDEC:
5318       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5319       if (operands[2] == const1_rtx)
5320         return "inc{q}\t%0";
5321       else
5322         {
5323           gcc_assert (operands[2] == constm1_rtx);
5324           return "dec{q}\t%0";
5325         }
5327     default:
5328       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5329       /* ???? We ought to handle there the 32bit case too
5330          - do we need new constraint?  */
5331       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5332          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5333       if (GET_CODE (operands[2]) == CONST_INT
5334           /* Avoid overflows.  */
5335           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5336           && (INTVAL (operands[2]) == 128
5337               || (INTVAL (operands[2]) < 0
5338                   && INTVAL (operands[2]) != -128)))
5339         {
5340           operands[2] = GEN_INT (-INTVAL (operands[2]));
5341           return "sub{q}\t{%2, %0|%0, %2}";
5342         }
5343       return "add{q}\t{%2, %0|%0, %2}";
5344     }
5346   [(set (attr "type")
5347      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5348         (const_string "incdec")
5349         (const_string "alu")))
5350    (set_attr "mode" "DI")])
5352 ; For comparisons against 1, -1 and 128, we may generate better code
5353 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5354 ; is matched then.  We can't accept general immediate, because for
5355 ; case of overflows,  the result is messed up.
5356 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5357 ; when negated.
5358 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5359 ; only for comparisons not depending on it.
5360 (define_insn "*adddi_4_rex64"
5361   [(set (reg FLAGS_REG)
5362         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5363                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5364    (clobber (match_scratch:DI 0 "=rm"))]
5365   "TARGET_64BIT
5366    &&  ix86_match_ccmode (insn, CCGCmode)"
5368   switch (get_attr_type (insn))
5369     {
5370     case TYPE_INCDEC:
5371       if (operands[2] == constm1_rtx)
5372         return "inc{q}\t%0";
5373       else
5374         {
5375           gcc_assert (operands[2] == const1_rtx);
5376           return "dec{q}\t%0";
5377         }
5379     default:
5380       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5381       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5382          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5383       if ((INTVAL (operands[2]) == -128
5384            || (INTVAL (operands[2]) > 0
5385                && INTVAL (operands[2]) != 128))
5386           /* Avoid overflows.  */
5387           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5388         return "sub{q}\t{%2, %0|%0, %2}";
5389       operands[2] = GEN_INT (-INTVAL (operands[2]));
5390       return "add{q}\t{%2, %0|%0, %2}";
5391     }
5393   [(set (attr "type")
5394      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5395         (const_string "incdec")
5396         (const_string "alu")))
5397    (set_attr "mode" "DI")])
5399 (define_insn "*adddi_5_rex64"
5400   [(set (reg FLAGS_REG)
5401         (compare
5402           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5403                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5404           (const_int 0)))
5405    (clobber (match_scratch:DI 0 "=r"))]
5406   "TARGET_64BIT
5407    && ix86_match_ccmode (insn, CCGOCmode)
5408    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5409    /* Current assemblers are broken and do not allow @GOTOFF in
5410       ought but a memory context.  */
5411    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5413   switch (get_attr_type (insn))
5414     {
5415     case TYPE_INCDEC:
5416       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5417       if (operands[2] == const1_rtx)
5418         return "inc{q}\t%0";
5419       else
5420         {
5421           gcc_assert (operands[2] == constm1_rtx);
5422           return "dec{q}\t%0";
5423         }
5425     default:
5426       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5427       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5428          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5429       if (GET_CODE (operands[2]) == CONST_INT
5430           /* Avoid overflows.  */
5431           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5432           && (INTVAL (operands[2]) == 128
5433               || (INTVAL (operands[2]) < 0
5434                   && INTVAL (operands[2]) != -128)))
5435         {
5436           operands[2] = GEN_INT (-INTVAL (operands[2]));
5437           return "sub{q}\t{%2, %0|%0, %2}";
5438         }
5439       return "add{q}\t{%2, %0|%0, %2}";
5440     }
5442   [(set (attr "type")
5443      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5444         (const_string "incdec")
5445         (const_string "alu")))
5446    (set_attr "mode" "DI")])
5449 (define_insn "*addsi_1"
5450   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5451         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5452                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5453    (clobber (reg:CC FLAGS_REG))]
5454   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5456   switch (get_attr_type (insn))
5457     {
5458     case TYPE_LEA:
5459       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5460       return "lea{l}\t{%a2, %0|%0, %a2}";
5462     case TYPE_INCDEC:
5463       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5464       if (operands[2] == const1_rtx)
5465         return "inc{l}\t%0";
5466       else
5467         {
5468           gcc_assert (operands[2] == constm1_rtx);
5469           return "dec{l}\t%0";
5470         }
5472     default:
5473       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5475       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5476          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5477       if (GET_CODE (operands[2]) == CONST_INT
5478           && (INTVAL (operands[2]) == 128
5479               || (INTVAL (operands[2]) < 0
5480                   && INTVAL (operands[2]) != -128)))
5481         {
5482           operands[2] = GEN_INT (-INTVAL (operands[2]));
5483           return "sub{l}\t{%2, %0|%0, %2}";
5484         }
5485       return "add{l}\t{%2, %0|%0, %2}";
5486     }
5488   [(set (attr "type")
5489      (cond [(eq_attr "alternative" "2")
5490               (const_string "lea")
5491             ; Current assemblers are broken and do not allow @GOTOFF in
5492             ; ought but a memory context.
5493             (match_operand:SI 2 "pic_symbolic_operand" "")
5494               (const_string "lea")
5495             (match_operand:SI 2 "incdec_operand" "")
5496               (const_string "incdec")
5497            ]
5498            (const_string "alu")))
5499    (set_attr "mode" "SI")])
5501 ;; Convert lea to the lea pattern to avoid flags dependency.
5502 (define_split
5503   [(set (match_operand 0 "register_operand" "")
5504         (plus (match_operand 1 "register_operand" "")
5505               (match_operand 2 "nonmemory_operand" "")))
5506    (clobber (reg:CC FLAGS_REG))]
5507   "reload_completed
5508    && true_regnum (operands[0]) != true_regnum (operands[1])"
5509   [(const_int 0)]
5511   rtx pat;
5512   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5513      may confuse gen_lowpart.  */
5514   if (GET_MODE (operands[0]) != Pmode)
5515     {
5516       operands[1] = gen_lowpart (Pmode, operands[1]);
5517       operands[2] = gen_lowpart (Pmode, operands[2]);
5518     }
5519   operands[0] = gen_lowpart (SImode, operands[0]);
5520   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5521   if (Pmode != SImode)
5522     pat = gen_rtx_SUBREG (SImode, pat, 0);
5523   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5524   DONE;
5527 ;; It may seem that nonimmediate operand is proper one for operand 1.
5528 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5529 ;; we take care in ix86_binary_operator_ok to not allow two memory
5530 ;; operands so proper swapping will be done in reload.  This allow
5531 ;; patterns constructed from addsi_1 to match.
5532 (define_insn "addsi_1_zext"
5533   [(set (match_operand:DI 0 "register_operand" "=r,r")
5534         (zero_extend:DI
5535           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5536                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5537    (clobber (reg:CC FLAGS_REG))]
5538   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5540   switch (get_attr_type (insn))
5541     {
5542     case TYPE_LEA:
5543       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5544       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5546     case TYPE_INCDEC:
5547       if (operands[2] == const1_rtx)
5548         return "inc{l}\t%k0";
5549       else
5550         {
5551           gcc_assert (operands[2] == constm1_rtx);
5552           return "dec{l}\t%k0";
5553         }
5555     default:
5556       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5557          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5558       if (GET_CODE (operands[2]) == CONST_INT
5559           && (INTVAL (operands[2]) == 128
5560               || (INTVAL (operands[2]) < 0
5561                   && INTVAL (operands[2]) != -128)))
5562         {
5563           operands[2] = GEN_INT (-INTVAL (operands[2]));
5564           return "sub{l}\t{%2, %k0|%k0, %2}";
5565         }
5566       return "add{l}\t{%2, %k0|%k0, %2}";
5567     }
5569   [(set (attr "type")
5570      (cond [(eq_attr "alternative" "1")
5571               (const_string "lea")
5572             ; Current assemblers are broken and do not allow @GOTOFF in
5573             ; ought but a memory context.
5574             (match_operand:SI 2 "pic_symbolic_operand" "")
5575               (const_string "lea")
5576             (match_operand:SI 2 "incdec_operand" "")
5577               (const_string "incdec")
5578            ]
5579            (const_string "alu")))
5580    (set_attr "mode" "SI")])
5582 ;; Convert lea to the lea pattern to avoid flags dependency.
5583 (define_split
5584   [(set (match_operand:DI 0 "register_operand" "")
5585         (zero_extend:DI
5586           (plus:SI (match_operand:SI 1 "register_operand" "")
5587                    (match_operand:SI 2 "nonmemory_operand" ""))))
5588    (clobber (reg:CC FLAGS_REG))]
5589   "TARGET_64BIT && reload_completed
5590    && true_regnum (operands[0]) != true_regnum (operands[1])"
5591   [(set (match_dup 0)
5592         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5594   operands[1] = gen_lowpart (Pmode, operands[1]);
5595   operands[2] = gen_lowpart (Pmode, operands[2]);
5598 (define_insn "*addsi_2"
5599   [(set (reg FLAGS_REG)
5600         (compare
5601           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5602                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5603           (const_int 0)))
5604    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5605         (plus:SI (match_dup 1) (match_dup 2)))]
5606   "ix86_match_ccmode (insn, CCGOCmode)
5607    && ix86_binary_operator_ok (PLUS, SImode, operands)
5608    /* Current assemblers are broken and do not allow @GOTOFF in
5609       ought but a memory context.  */
5610    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5612   switch (get_attr_type (insn))
5613     {
5614     case TYPE_INCDEC:
5615       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5616       if (operands[2] == const1_rtx)
5617         return "inc{l}\t%0";
5618       else
5619         {
5620           gcc_assert (operands[2] == constm1_rtx);
5621           return "dec{l}\t%0";
5622         }
5624     default:
5625       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5626       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5627          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5628       if (GET_CODE (operands[2]) == CONST_INT
5629           && (INTVAL (operands[2]) == 128
5630               || (INTVAL (operands[2]) < 0
5631                   && INTVAL (operands[2]) != -128)))
5632         {
5633           operands[2] = GEN_INT (-INTVAL (operands[2]));
5634           return "sub{l}\t{%2, %0|%0, %2}";
5635         }
5636       return "add{l}\t{%2, %0|%0, %2}";
5637     }
5639   [(set (attr "type")
5640      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5641         (const_string "incdec")
5642         (const_string "alu")))
5643    (set_attr "mode" "SI")])
5645 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5646 (define_insn "*addsi_2_zext"
5647   [(set (reg FLAGS_REG)
5648         (compare
5649           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5650                    (match_operand:SI 2 "general_operand" "rmni"))
5651           (const_int 0)))
5652    (set (match_operand:DI 0 "register_operand" "=r")
5653         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5654   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5655    && ix86_binary_operator_ok (PLUS, SImode, operands)
5656    /* Current assemblers are broken and do not allow @GOTOFF in
5657       ought but a memory context.  */
5658    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5660   switch (get_attr_type (insn))
5661     {
5662     case TYPE_INCDEC:
5663       if (operands[2] == const1_rtx)
5664         return "inc{l}\t%k0";
5665       else
5666         {
5667           gcc_assert (operands[2] == constm1_rtx);
5668           return "dec{l}\t%k0";
5669         }
5671     default:
5672       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5673          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5674       if (GET_CODE (operands[2]) == CONST_INT
5675           && (INTVAL (operands[2]) == 128
5676               || (INTVAL (operands[2]) < 0
5677                   && INTVAL (operands[2]) != -128)))
5678         {
5679           operands[2] = GEN_INT (-INTVAL (operands[2]));
5680           return "sub{l}\t{%2, %k0|%k0, %2}";
5681         }
5682       return "add{l}\t{%2, %k0|%k0, %2}";
5683     }
5685   [(set (attr "type")
5686      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5687         (const_string "incdec")
5688         (const_string "alu")))
5689    (set_attr "mode" "SI")])
5691 (define_insn "*addsi_3"
5692   [(set (reg FLAGS_REG)
5693         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5694                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5695    (clobber (match_scratch:SI 0 "=r"))]
5696   "ix86_match_ccmode (insn, CCZmode)
5697    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5698    /* Current assemblers are broken and do not allow @GOTOFF in
5699       ought but a memory context.  */
5700    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5702   switch (get_attr_type (insn))
5703     {
5704     case TYPE_INCDEC:
5705       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5706       if (operands[2] == const1_rtx)
5707         return "inc{l}\t%0";
5708       else
5709         {
5710           gcc_assert (operands[2] == constm1_rtx);
5711           return "dec{l}\t%0";
5712         }
5714     default:
5715       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5716       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5717          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5718       if (GET_CODE (operands[2]) == CONST_INT
5719           && (INTVAL (operands[2]) == 128
5720               || (INTVAL (operands[2]) < 0
5721                   && INTVAL (operands[2]) != -128)))
5722         {
5723           operands[2] = GEN_INT (-INTVAL (operands[2]));
5724           return "sub{l}\t{%2, %0|%0, %2}";
5725         }
5726       return "add{l}\t{%2, %0|%0, %2}";
5727     }
5729   [(set (attr "type")
5730      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5731         (const_string "incdec")
5732         (const_string "alu")))
5733    (set_attr "mode" "SI")])
5735 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5736 (define_insn "*addsi_3_zext"
5737   [(set (reg FLAGS_REG)
5738         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5739                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5740    (set (match_operand:DI 0 "register_operand" "=r")
5741         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5742   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5743    && ix86_binary_operator_ok (PLUS, SImode, operands)
5744    /* Current assemblers are broken and do not allow @GOTOFF in
5745       ought but a memory context.  */
5746    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5748   switch (get_attr_type (insn))
5749     {
5750     case TYPE_INCDEC:
5751       if (operands[2] == const1_rtx)
5752         return "inc{l}\t%k0";
5753       else
5754         {
5755           gcc_assert (operands[2] == constm1_rtx);
5756           return "dec{l}\t%k0";
5757         }
5759     default:
5760       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5761          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5762       if (GET_CODE (operands[2]) == CONST_INT
5763           && (INTVAL (operands[2]) == 128
5764               || (INTVAL (operands[2]) < 0
5765                   && INTVAL (operands[2]) != -128)))
5766         {
5767           operands[2] = GEN_INT (-INTVAL (operands[2]));
5768           return "sub{l}\t{%2, %k0|%k0, %2}";
5769         }
5770       return "add{l}\t{%2, %k0|%k0, %2}";
5771     }
5773   [(set (attr "type")
5774      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5775         (const_string "incdec")
5776         (const_string "alu")))
5777    (set_attr "mode" "SI")])
5779 ; For comparisons against 1, -1 and 128, we may generate better code
5780 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5781 ; is matched then.  We can't accept general immediate, because for
5782 ; case of overflows,  the result is messed up.
5783 ; This pattern also don't hold of 0x80000000, since the value overflows
5784 ; when negated.
5785 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5786 ; only for comparisons not depending on it.
5787 (define_insn "*addsi_4"
5788   [(set (reg FLAGS_REG)
5789         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5790                  (match_operand:SI 2 "const_int_operand" "n")))
5791    (clobber (match_scratch:SI 0 "=rm"))]
5792   "ix86_match_ccmode (insn, CCGCmode)
5793    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5795   switch (get_attr_type (insn))
5796     {
5797     case TYPE_INCDEC:
5798       if (operands[2] == constm1_rtx)
5799         return "inc{l}\t%0";
5800       else
5801         {
5802           gcc_assert (operands[2] == const1_rtx);
5803           return "dec{l}\t%0";
5804         }
5806     default:
5807       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5808       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5809          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5810       if ((INTVAL (operands[2]) == -128
5811            || (INTVAL (operands[2]) > 0
5812                && INTVAL (operands[2]) != 128)))
5813         return "sub{l}\t{%2, %0|%0, %2}";
5814       operands[2] = GEN_INT (-INTVAL (operands[2]));
5815       return "add{l}\t{%2, %0|%0, %2}";
5816     }
5818   [(set (attr "type")
5819      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5820         (const_string "incdec")
5821         (const_string "alu")))
5822    (set_attr "mode" "SI")])
5824 (define_insn "*addsi_5"
5825   [(set (reg FLAGS_REG)
5826         (compare
5827           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5828                    (match_operand:SI 2 "general_operand" "rmni"))
5829           (const_int 0)))
5830    (clobber (match_scratch:SI 0 "=r"))]
5831   "ix86_match_ccmode (insn, CCGOCmode)
5832    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5833    /* Current assemblers are broken and do not allow @GOTOFF in
5834       ought but a memory context.  */
5835    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5837   switch (get_attr_type (insn))
5838     {
5839     case TYPE_INCDEC:
5840       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5841       if (operands[2] == const1_rtx)
5842         return "inc{l}\t%0";
5843       else
5844         {
5845           gcc_assert (operands[2] == constm1_rtx);
5846           return "dec{l}\t%0";
5847         }
5849     default:
5850       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5851       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5852          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5853       if (GET_CODE (operands[2]) == CONST_INT
5854           && (INTVAL (operands[2]) == 128
5855               || (INTVAL (operands[2]) < 0
5856                   && INTVAL (operands[2]) != -128)))
5857         {
5858           operands[2] = GEN_INT (-INTVAL (operands[2]));
5859           return "sub{l}\t{%2, %0|%0, %2}";
5860         }
5861       return "add{l}\t{%2, %0|%0, %2}";
5862     }
5864   [(set (attr "type")
5865      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5866         (const_string "incdec")
5867         (const_string "alu")))
5868    (set_attr "mode" "SI")])
5870 (define_expand "addhi3"
5871   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5872                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5873                             (match_operand:HI 2 "general_operand" "")))
5874               (clobber (reg:CC FLAGS_REG))])]
5875   "TARGET_HIMODE_MATH"
5876   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5878 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5879 ;; type optimizations enabled by define-splits.  This is not important
5880 ;; for PII, and in fact harmful because of partial register stalls.
5882 (define_insn "*addhi_1_lea"
5883   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5884         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5885                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5886    (clobber (reg:CC FLAGS_REG))]
5887   "!TARGET_PARTIAL_REG_STALL
5888    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5890   switch (get_attr_type (insn))
5891     {
5892     case TYPE_LEA:
5893       return "#";
5894     case TYPE_INCDEC:
5895       if (operands[2] == const1_rtx)
5896         return "inc{w}\t%0";
5897       else
5898         {
5899           gcc_assert (operands[2] == constm1_rtx);
5900           return "dec{w}\t%0";
5901         }
5903     default:
5904       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5905          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5906       if (GET_CODE (operands[2]) == CONST_INT
5907           && (INTVAL (operands[2]) == 128
5908               || (INTVAL (operands[2]) < 0
5909                   && INTVAL (operands[2]) != -128)))
5910         {
5911           operands[2] = GEN_INT (-INTVAL (operands[2]));
5912           return "sub{w}\t{%2, %0|%0, %2}";
5913         }
5914       return "add{w}\t{%2, %0|%0, %2}";
5915     }
5917   [(set (attr "type")
5918      (if_then_else (eq_attr "alternative" "2")
5919         (const_string "lea")
5920         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5921            (const_string "incdec")
5922            (const_string "alu"))))
5923    (set_attr "mode" "HI,HI,SI")])
5925 (define_insn "*addhi_1"
5926   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5927         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5928                  (match_operand:HI 2 "general_operand" "ri,rm")))
5929    (clobber (reg:CC FLAGS_REG))]
5930   "TARGET_PARTIAL_REG_STALL
5931    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5933   switch (get_attr_type (insn))
5934     {
5935     case TYPE_INCDEC:
5936       if (operands[2] == const1_rtx)
5937         return "inc{w}\t%0";
5938       else
5939         {
5940           gcc_assert (operands[2] == constm1_rtx);
5941           return "dec{w}\t%0";
5942         }
5944     default:
5945       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5946          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5947       if (GET_CODE (operands[2]) == CONST_INT
5948           && (INTVAL (operands[2]) == 128
5949               || (INTVAL (operands[2]) < 0
5950                   && INTVAL (operands[2]) != -128)))
5951         {
5952           operands[2] = GEN_INT (-INTVAL (operands[2]));
5953           return "sub{w}\t{%2, %0|%0, %2}";
5954         }
5955       return "add{w}\t{%2, %0|%0, %2}";
5956     }
5958   [(set (attr "type")
5959      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5960         (const_string "incdec")
5961         (const_string "alu")))
5962    (set_attr "mode" "HI")])
5964 (define_insn "*addhi_2"
5965   [(set (reg FLAGS_REG)
5966         (compare
5967           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5968                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5969           (const_int 0)))
5970    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5971         (plus:HI (match_dup 1) (match_dup 2)))]
5972   "ix86_match_ccmode (insn, CCGOCmode)
5973    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5975   switch (get_attr_type (insn))
5976     {
5977     case TYPE_INCDEC:
5978       if (operands[2] == const1_rtx)
5979         return "inc{w}\t%0";
5980       else
5981         {
5982           gcc_assert (operands[2] == constm1_rtx);
5983           return "dec{w}\t%0";
5984         }
5986     default:
5987       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5988          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5989       if (GET_CODE (operands[2]) == CONST_INT
5990           && (INTVAL (operands[2]) == 128
5991               || (INTVAL (operands[2]) < 0
5992                   && INTVAL (operands[2]) != -128)))
5993         {
5994           operands[2] = GEN_INT (-INTVAL (operands[2]));
5995           return "sub{w}\t{%2, %0|%0, %2}";
5996         }
5997       return "add{w}\t{%2, %0|%0, %2}";
5998     }
6000   [(set (attr "type")
6001      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6002         (const_string "incdec")
6003         (const_string "alu")))
6004    (set_attr "mode" "HI")])
6006 (define_insn "*addhi_3"
6007   [(set (reg FLAGS_REG)
6008         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6009                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6010    (clobber (match_scratch:HI 0 "=r"))]
6011   "ix86_match_ccmode (insn, CCZmode)
6012    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6014   switch (get_attr_type (insn))
6015     {
6016     case TYPE_INCDEC:
6017       if (operands[2] == const1_rtx)
6018         return "inc{w}\t%0";
6019       else
6020         {
6021           gcc_assert (operands[2] == constm1_rtx);
6022           return "dec{w}\t%0";
6023         }
6025     default:
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 (GET_CODE (operands[2]) == CONST_INT
6029           && (INTVAL (operands[2]) == 128
6030               || (INTVAL (operands[2]) < 0
6031                   && INTVAL (operands[2]) != -128)))
6032         {
6033           operands[2] = GEN_INT (-INTVAL (operands[2]));
6034           return "sub{w}\t{%2, %0|%0, %2}";
6035         }
6036       return "add{w}\t{%2, %0|%0, %2}";
6037     }
6039   [(set (attr "type")
6040      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6041         (const_string "incdec")
6042         (const_string "alu")))
6043    (set_attr "mode" "HI")])
6045 ; See comments above addsi_4 for details.
6046 (define_insn "*addhi_4"
6047   [(set (reg FLAGS_REG)
6048         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6049                  (match_operand:HI 2 "const_int_operand" "n")))
6050    (clobber (match_scratch:HI 0 "=rm"))]
6051   "ix86_match_ccmode (insn, CCGCmode)
6052    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6054   switch (get_attr_type (insn))
6055     {
6056     case TYPE_INCDEC:
6057       if (operands[2] == constm1_rtx)
6058         return "inc{w}\t%0";
6059       else
6060         {
6061           gcc_assert (operands[2] == const1_rtx);
6062           return "dec{w}\t%0";
6063         }
6065     default:
6066       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6067       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6068          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6069       if ((INTVAL (operands[2]) == -128
6070            || (INTVAL (operands[2]) > 0
6071                && INTVAL (operands[2]) != 128)))
6072         return "sub{w}\t{%2, %0|%0, %2}";
6073       operands[2] = GEN_INT (-INTVAL (operands[2]));
6074       return "add{w}\t{%2, %0|%0, %2}";
6075     }
6077   [(set (attr "type")
6078      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6079         (const_string "incdec")
6080         (const_string "alu")))
6081    (set_attr "mode" "SI")])
6084 (define_insn "*addhi_5"
6085   [(set (reg FLAGS_REG)
6086         (compare
6087           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6088                    (match_operand:HI 2 "general_operand" "rmni"))
6089           (const_int 0)))
6090    (clobber (match_scratch:HI 0 "=r"))]
6091   "ix86_match_ccmode (insn, CCGOCmode)
6092    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6094   switch (get_attr_type (insn))
6095     {
6096     case TYPE_INCDEC:
6097       if (operands[2] == const1_rtx)
6098         return "inc{w}\t%0";
6099       else
6100         {
6101           gcc_assert (operands[2] == constm1_rtx);
6102           return "dec{w}\t%0";
6103         }
6105     default:
6106       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6107          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6108       if (GET_CODE (operands[2]) == CONST_INT
6109           && (INTVAL (operands[2]) == 128
6110               || (INTVAL (operands[2]) < 0
6111                   && INTVAL (operands[2]) != -128)))
6112         {
6113           operands[2] = GEN_INT (-INTVAL (operands[2]));
6114           return "sub{w}\t{%2, %0|%0, %2}";
6115         }
6116       return "add{w}\t{%2, %0|%0, %2}";
6117     }
6119   [(set (attr "type")
6120      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6121         (const_string "incdec")
6122         (const_string "alu")))
6123    (set_attr "mode" "HI")])
6125 (define_expand "addqi3"
6126   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6127                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6128                             (match_operand:QI 2 "general_operand" "")))
6129               (clobber (reg:CC FLAGS_REG))])]
6130   "TARGET_QIMODE_MATH"
6131   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6133 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6134 (define_insn "*addqi_1_lea"
6135   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6136         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6137                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6138    (clobber (reg:CC FLAGS_REG))]
6139   "!TARGET_PARTIAL_REG_STALL
6140    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6142   int widen = (which_alternative == 2);
6143   switch (get_attr_type (insn))
6144     {
6145     case TYPE_LEA:
6146       return "#";
6147     case TYPE_INCDEC:
6148       if (operands[2] == const1_rtx)
6149         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6150       else
6151         {
6152           gcc_assert (operands[2] == constm1_rtx);
6153           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6154         }
6156     default:
6157       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6158          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6159       if (GET_CODE (operands[2]) == CONST_INT
6160           && (INTVAL (operands[2]) == 128
6161               || (INTVAL (operands[2]) < 0
6162                   && INTVAL (operands[2]) != -128)))
6163         {
6164           operands[2] = GEN_INT (-INTVAL (operands[2]));
6165           if (widen)
6166             return "sub{l}\t{%2, %k0|%k0, %2}";
6167           else
6168             return "sub{b}\t{%2, %0|%0, %2}";
6169         }
6170       if (widen)
6171         return "add{l}\t{%k2, %k0|%k0, %k2}";
6172       else
6173         return "add{b}\t{%2, %0|%0, %2}";
6174     }
6176   [(set (attr "type")
6177      (if_then_else (eq_attr "alternative" "3")
6178         (const_string "lea")
6179         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6180            (const_string "incdec")
6181            (const_string "alu"))))
6182    (set_attr "mode" "QI,QI,SI,SI")])
6184 (define_insn "*addqi_1"
6185   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6186         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6187                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6188    (clobber (reg:CC FLAGS_REG))]
6189   "TARGET_PARTIAL_REG_STALL
6190    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6192   int widen = (which_alternative == 2);
6193   switch (get_attr_type (insn))
6194     {
6195     case TYPE_INCDEC:
6196       if (operands[2] == const1_rtx)
6197         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6198       else
6199         {
6200           gcc_assert (operands[2] == constm1_rtx);
6201           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6202         }
6204     default:
6205       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6206          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6207       if (GET_CODE (operands[2]) == CONST_INT
6208           && (INTVAL (operands[2]) == 128
6209               || (INTVAL (operands[2]) < 0
6210                   && INTVAL (operands[2]) != -128)))
6211         {
6212           operands[2] = GEN_INT (-INTVAL (operands[2]));
6213           if (widen)
6214             return "sub{l}\t{%2, %k0|%k0, %2}";
6215           else
6216             return "sub{b}\t{%2, %0|%0, %2}";
6217         }
6218       if (widen)
6219         return "add{l}\t{%k2, %k0|%k0, %k2}";
6220       else
6221         return "add{b}\t{%2, %0|%0, %2}";
6222     }
6224   [(set (attr "type")
6225      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6226         (const_string "incdec")
6227         (const_string "alu")))
6228    (set_attr "mode" "QI,QI,SI")])
6230 (define_insn "*addqi_1_slp"
6231   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6232         (plus:QI (match_dup 0)
6233                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6234    (clobber (reg:CC FLAGS_REG))]
6235   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6236    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6238   switch (get_attr_type (insn))
6239     {
6240     case TYPE_INCDEC:
6241       if (operands[1] == const1_rtx)
6242         return "inc{b}\t%0";
6243       else
6244         {
6245           gcc_assert (operands[1] == constm1_rtx);
6246           return "dec{b}\t%0";
6247         }
6249     default:
6250       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6251       if (GET_CODE (operands[1]) == CONST_INT
6252           && INTVAL (operands[1]) < 0)
6253         {
6254           operands[1] = GEN_INT (-INTVAL (operands[1]));
6255           return "sub{b}\t{%1, %0|%0, %1}";
6256         }
6257       return "add{b}\t{%1, %0|%0, %1}";
6258     }
6260   [(set (attr "type")
6261      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6262         (const_string "incdec")
6263         (const_string "alu1")))
6264    (set (attr "memory")
6265      (if_then_else (match_operand 1 "memory_operand" "")
6266         (const_string "load")
6267         (const_string "none")))
6268    (set_attr "mode" "QI")])
6270 (define_insn "*addqi_2"
6271   [(set (reg FLAGS_REG)
6272         (compare
6273           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6274                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6275           (const_int 0)))
6276    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6277         (plus:QI (match_dup 1) (match_dup 2)))]
6278   "ix86_match_ccmode (insn, CCGOCmode)
6279    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6281   switch (get_attr_type (insn))
6282     {
6283     case TYPE_INCDEC:
6284       if (operands[2] == const1_rtx)
6285         return "inc{b}\t%0";
6286       else
6287         {
6288           gcc_assert (operands[2] == constm1_rtx
6289                       || (GET_CODE (operands[2]) == CONST_INT
6290                           && INTVAL (operands[2]) == 255));
6291           return "dec{b}\t%0";
6292         }
6294     default:
6295       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6296       if (GET_CODE (operands[2]) == CONST_INT
6297           && INTVAL (operands[2]) < 0)
6298         {
6299           operands[2] = GEN_INT (-INTVAL (operands[2]));
6300           return "sub{b}\t{%2, %0|%0, %2}";
6301         }
6302       return "add{b}\t{%2, %0|%0, %2}";
6303     }
6305   [(set (attr "type")
6306      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6307         (const_string "incdec")
6308         (const_string "alu")))
6309    (set_attr "mode" "QI")])
6311 (define_insn "*addqi_3"
6312   [(set (reg FLAGS_REG)
6313         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6314                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6315    (clobber (match_scratch:QI 0 "=q"))]
6316   "ix86_match_ccmode (insn, CCZmode)
6317    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6319   switch (get_attr_type (insn))
6320     {
6321     case TYPE_INCDEC:
6322       if (operands[2] == const1_rtx)
6323         return "inc{b}\t%0";
6324       else
6325         {
6326           gcc_assert (operands[2] == constm1_rtx
6327                       || (GET_CODE (operands[2]) == CONST_INT
6328                           && INTVAL (operands[2]) == 255));
6329           return "dec{b}\t%0";
6330         }
6332     default:
6333       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6334       if (GET_CODE (operands[2]) == CONST_INT
6335           && INTVAL (operands[2]) < 0)
6336         {
6337           operands[2] = GEN_INT (-INTVAL (operands[2]));
6338           return "sub{b}\t{%2, %0|%0, %2}";
6339         }
6340       return "add{b}\t{%2, %0|%0, %2}";
6341     }
6343   [(set (attr "type")
6344      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6345         (const_string "incdec")
6346         (const_string "alu")))
6347    (set_attr "mode" "QI")])
6349 ; See comments above addsi_4 for details.
6350 (define_insn "*addqi_4"
6351   [(set (reg FLAGS_REG)
6352         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6353                  (match_operand:QI 2 "const_int_operand" "n")))
6354    (clobber (match_scratch:QI 0 "=qm"))]
6355   "ix86_match_ccmode (insn, CCGCmode)
6356    && (INTVAL (operands[2]) & 0xff) != 0x80"
6358   switch (get_attr_type (insn))
6359     {
6360     case TYPE_INCDEC:
6361       if (operands[2] == constm1_rtx
6362           || (GET_CODE (operands[2]) == CONST_INT
6363               && INTVAL (operands[2]) == 255))
6364         return "inc{b}\t%0";
6365       else
6366         {
6367           gcc_assert (operands[2] == const1_rtx);
6368           return "dec{b}\t%0";
6369         }
6371     default:
6372       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6373       if (INTVAL (operands[2]) < 0)
6374         {
6375           operands[2] = GEN_INT (-INTVAL (operands[2]));
6376           return "add{b}\t{%2, %0|%0, %2}";
6377         }
6378       return "sub{b}\t{%2, %0|%0, %2}";
6379     }
6381   [(set (attr "type")
6382      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6383         (const_string "incdec")
6384         (const_string "alu")))
6385    (set_attr "mode" "QI")])
6388 (define_insn "*addqi_5"
6389   [(set (reg FLAGS_REG)
6390         (compare
6391           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6392                    (match_operand:QI 2 "general_operand" "qmni"))
6393           (const_int 0)))
6394    (clobber (match_scratch:QI 0 "=q"))]
6395   "ix86_match_ccmode (insn, CCGOCmode)
6396    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6398   switch (get_attr_type (insn))
6399     {
6400     case TYPE_INCDEC:
6401       if (operands[2] == const1_rtx)
6402         return "inc{b}\t%0";
6403       else
6404         {
6405           gcc_assert (operands[2] == constm1_rtx
6406                       || (GET_CODE (operands[2]) == CONST_INT
6407                           && INTVAL (operands[2]) == 255));
6408           return "dec{b}\t%0";
6409         }
6411     default:
6412       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6413       if (GET_CODE (operands[2]) == CONST_INT
6414           && INTVAL (operands[2]) < 0)
6415         {
6416           operands[2] = GEN_INT (-INTVAL (operands[2]));
6417           return "sub{b}\t{%2, %0|%0, %2}";
6418         }
6419       return "add{b}\t{%2, %0|%0, %2}";
6420     }
6422   [(set (attr "type")
6423      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6424         (const_string "incdec")
6425         (const_string "alu")))
6426    (set_attr "mode" "QI")])
6429 (define_insn "addqi_ext_1"
6430   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6431                          (const_int 8)
6432                          (const_int 8))
6433         (plus:SI
6434           (zero_extract:SI
6435             (match_operand 1 "ext_register_operand" "0")
6436             (const_int 8)
6437             (const_int 8))
6438           (match_operand:QI 2 "general_operand" "Qmn")))
6439    (clobber (reg:CC FLAGS_REG))]
6440   "!TARGET_64BIT"
6442   switch (get_attr_type (insn))
6443     {
6444     case TYPE_INCDEC:
6445       if (operands[2] == const1_rtx)
6446         return "inc{b}\t%h0";
6447       else
6448         {
6449           gcc_assert (operands[2] == constm1_rtx
6450                       || (GET_CODE (operands[2]) == CONST_INT
6451                           && INTVAL (operands[2]) == 255));
6452           return "dec{b}\t%h0";
6453         }
6455     default:
6456       return "add{b}\t{%2, %h0|%h0, %2}";
6457     }
6459   [(set (attr "type")
6460      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6461         (const_string "incdec")
6462         (const_string "alu")))
6463    (set_attr "mode" "QI")])
6465 (define_insn "*addqi_ext_1_rex64"
6466   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6467                          (const_int 8)
6468                          (const_int 8))
6469         (plus:SI
6470           (zero_extract:SI
6471             (match_operand 1 "ext_register_operand" "0")
6472             (const_int 8)
6473             (const_int 8))
6474           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6475    (clobber (reg:CC FLAGS_REG))]
6476   "TARGET_64BIT"
6478   switch (get_attr_type (insn))
6479     {
6480     case TYPE_INCDEC:
6481       if (operands[2] == const1_rtx)
6482         return "inc{b}\t%h0";
6483       else
6484         {
6485           gcc_assert (operands[2] == constm1_rtx
6486                       || (GET_CODE (operands[2]) == CONST_INT
6487                           && INTVAL (operands[2]) == 255));
6488           return "dec{b}\t%h0";
6489         }
6491     default:
6492       return "add{b}\t{%2, %h0|%h0, %2}";
6493     }
6495   [(set (attr "type")
6496      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6497         (const_string "incdec")
6498         (const_string "alu")))
6499    (set_attr "mode" "QI")])
6501 (define_insn "*addqi_ext_2"
6502   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6503                          (const_int 8)
6504                          (const_int 8))
6505         (plus:SI
6506           (zero_extract:SI
6507             (match_operand 1 "ext_register_operand" "%0")
6508             (const_int 8)
6509             (const_int 8))
6510           (zero_extract:SI
6511             (match_operand 2 "ext_register_operand" "Q")
6512             (const_int 8)
6513             (const_int 8))))
6514    (clobber (reg:CC FLAGS_REG))]
6515   ""
6516   "add{b}\t{%h2, %h0|%h0, %h2}"
6517   [(set_attr "type" "alu")
6518    (set_attr "mode" "QI")])
6520 ;; The patterns that match these are at the end of this file.
6522 (define_expand "addxf3"
6523   [(set (match_operand:XF 0 "register_operand" "")
6524         (plus:XF (match_operand:XF 1 "register_operand" "")
6525                  (match_operand:XF 2 "register_operand" "")))]
6526   "TARGET_80387"
6527   "")
6529 (define_expand "adddf3"
6530   [(set (match_operand:DF 0 "register_operand" "")
6531         (plus:DF (match_operand:DF 1 "register_operand" "")
6532                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6533   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6534   "")
6536 (define_expand "addsf3"
6537   [(set (match_operand:SF 0 "register_operand" "")
6538         (plus:SF (match_operand:SF 1 "register_operand" "")
6539                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6540   "TARGET_80387 || TARGET_SSE_MATH"
6541   "")
6543 ;; Subtract instructions
6545 ;; %%% splits for subditi3
6547 (define_expand "subti3"
6548   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6549                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6550                              (match_operand:TI 2 "x86_64_general_operand" "")))
6551               (clobber (reg:CC FLAGS_REG))])]
6552   "TARGET_64BIT"
6553   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6555 (define_insn "*subti3_1"
6556   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6557         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6558                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6559    (clobber (reg:CC FLAGS_REG))]
6560   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6561   "#")
6563 (define_split
6564   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6565         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6566                   (match_operand:TI 2 "general_operand" "")))
6567    (clobber (reg:CC FLAGS_REG))]
6568   "TARGET_64BIT && reload_completed"
6569   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6570               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6571    (parallel [(set (match_dup 3)
6572                    (minus:DI (match_dup 4)
6573                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6574                                       (match_dup 5))))
6575               (clobber (reg:CC FLAGS_REG))])]
6576   "split_ti (operands+0, 1, operands+0, operands+3);
6577    split_ti (operands+1, 1, operands+1, operands+4);
6578    split_ti (operands+2, 1, operands+2, operands+5);")
6580 ;; %%% splits for subsidi3
6582 (define_expand "subdi3"
6583   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6584                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6585                              (match_operand:DI 2 "x86_64_general_operand" "")))
6586               (clobber (reg:CC FLAGS_REG))])]
6587   ""
6588   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6590 (define_insn "*subdi3_1"
6591   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6592         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6593                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6594    (clobber (reg:CC FLAGS_REG))]
6595   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6596   "#")
6598 (define_split
6599   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6600         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6601                   (match_operand:DI 2 "general_operand" "")))
6602    (clobber (reg:CC FLAGS_REG))]
6603   "!TARGET_64BIT && reload_completed"
6604   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6605               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6606    (parallel [(set (match_dup 3)
6607                    (minus:SI (match_dup 4)
6608                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6609                                       (match_dup 5))))
6610               (clobber (reg:CC FLAGS_REG))])]
6611   "split_di (operands+0, 1, operands+0, operands+3);
6612    split_di (operands+1, 1, operands+1, operands+4);
6613    split_di (operands+2, 1, operands+2, operands+5);")
6615 (define_insn "subdi3_carry_rex64"
6616   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6617           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6618             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6619                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6620    (clobber (reg:CC FLAGS_REG))]
6621   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6622   "sbb{q}\t{%2, %0|%0, %2}"
6623   [(set_attr "type" "alu")
6624    (set_attr "pent_pair" "pu")
6625    (set_attr "mode" "DI")])
6627 (define_insn "*subdi_1_rex64"
6628   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6629         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6630                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6631    (clobber (reg:CC FLAGS_REG))]
6632   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6633   "sub{q}\t{%2, %0|%0, %2}"
6634   [(set_attr "type" "alu")
6635    (set_attr "mode" "DI")])
6637 (define_insn "*subdi_2_rex64"
6638   [(set (reg FLAGS_REG)
6639         (compare
6640           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6641                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6642           (const_int 0)))
6643    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6644         (minus:DI (match_dup 1) (match_dup 2)))]
6645   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6646    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6647   "sub{q}\t{%2, %0|%0, %2}"
6648   [(set_attr "type" "alu")
6649    (set_attr "mode" "DI")])
6651 (define_insn "*subdi_3_rex63"
6652   [(set (reg FLAGS_REG)
6653         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6654                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6655    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6656         (minus:DI (match_dup 1) (match_dup 2)))]
6657   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6658    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6659   "sub{q}\t{%2, %0|%0, %2}"
6660   [(set_attr "type" "alu")
6661    (set_attr "mode" "DI")])
6663 (define_insn "subqi3_carry"
6664   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6665           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6666             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6667                (match_operand:QI 2 "general_operand" "qi,qm"))))
6668    (clobber (reg:CC FLAGS_REG))]
6669   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6670   "sbb{b}\t{%2, %0|%0, %2}"
6671   [(set_attr "type" "alu")
6672    (set_attr "pent_pair" "pu")
6673    (set_attr "mode" "QI")])
6675 (define_insn "subhi3_carry"
6676   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6677           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6678             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6679                (match_operand:HI 2 "general_operand" "ri,rm"))))
6680    (clobber (reg:CC FLAGS_REG))]
6681   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6682   "sbb{w}\t{%2, %0|%0, %2}"
6683   [(set_attr "type" "alu")
6684    (set_attr "pent_pair" "pu")
6685    (set_attr "mode" "HI")])
6687 (define_insn "subsi3_carry"
6688   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6689           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6690             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6691                (match_operand:SI 2 "general_operand" "ri,rm"))))
6692    (clobber (reg:CC FLAGS_REG))]
6693   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6694   "sbb{l}\t{%2, %0|%0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "pent_pair" "pu")
6697    (set_attr "mode" "SI")])
6699 (define_insn "subsi3_carry_zext"
6700   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6701           (zero_extend:DI
6702             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6703               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6704                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6705    (clobber (reg:CC FLAGS_REG))]
6706   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707   "sbb{l}\t{%2, %k0|%k0, %2}"
6708   [(set_attr "type" "alu")
6709    (set_attr "pent_pair" "pu")
6710    (set_attr "mode" "SI")])
6712 (define_expand "subsi3"
6713   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6714                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6715                              (match_operand:SI 2 "general_operand" "")))
6716               (clobber (reg:CC FLAGS_REG))])]
6717   ""
6718   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6720 (define_insn "*subsi_1"
6721   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6722         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6723                   (match_operand:SI 2 "general_operand" "ri,rm")))
6724    (clobber (reg:CC FLAGS_REG))]
6725   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6726   "sub{l}\t{%2, %0|%0, %2}"
6727   [(set_attr "type" "alu")
6728    (set_attr "mode" "SI")])
6730 (define_insn "*subsi_1_zext"
6731   [(set (match_operand:DI 0 "register_operand" "=r")
6732         (zero_extend:DI
6733           (minus:SI (match_operand:SI 1 "register_operand" "0")
6734                     (match_operand:SI 2 "general_operand" "rim"))))
6735    (clobber (reg:CC FLAGS_REG))]
6736   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6737   "sub{l}\t{%2, %k0|%k0, %2}"
6738   [(set_attr "type" "alu")
6739    (set_attr "mode" "SI")])
6741 (define_insn "*subsi_2"
6742   [(set (reg FLAGS_REG)
6743         (compare
6744           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6745                     (match_operand:SI 2 "general_operand" "ri,rm"))
6746           (const_int 0)))
6747    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6748         (minus:SI (match_dup 1) (match_dup 2)))]
6749   "ix86_match_ccmode (insn, CCGOCmode)
6750    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6751   "sub{l}\t{%2, %0|%0, %2}"
6752   [(set_attr "type" "alu")
6753    (set_attr "mode" "SI")])
6755 (define_insn "*subsi_2_zext"
6756   [(set (reg FLAGS_REG)
6757         (compare
6758           (minus:SI (match_operand:SI 1 "register_operand" "0")
6759                     (match_operand:SI 2 "general_operand" "rim"))
6760           (const_int 0)))
6761    (set (match_operand:DI 0 "register_operand" "=r")
6762         (zero_extend:DI
6763           (minus:SI (match_dup 1)
6764                     (match_dup 2))))]
6765   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6766    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6767   "sub{l}\t{%2, %k0|%k0, %2}"
6768   [(set_attr "type" "alu")
6769    (set_attr "mode" "SI")])
6771 (define_insn "*subsi_3"
6772   [(set (reg FLAGS_REG)
6773         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6774                  (match_operand:SI 2 "general_operand" "ri,rm")))
6775    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6776         (minus:SI (match_dup 1) (match_dup 2)))]
6777   "ix86_match_ccmode (insn, CCmode)
6778    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6779   "sub{l}\t{%2, %0|%0, %2}"
6780   [(set_attr "type" "alu")
6781    (set_attr "mode" "SI")])
6783 (define_insn "*subsi_3_zext"
6784   [(set (reg FLAGS_REG)
6785         (compare (match_operand:SI 1 "register_operand" "0")
6786                  (match_operand:SI 2 "general_operand" "rim")))
6787    (set (match_operand:DI 0 "register_operand" "=r")
6788         (zero_extend:DI
6789           (minus:SI (match_dup 1)
6790                     (match_dup 2))))]
6791   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6792    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6793   "sub{l}\t{%2, %1|%1, %2}"
6794   [(set_attr "type" "alu")
6795    (set_attr "mode" "DI")])
6797 (define_expand "subhi3"
6798   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6799                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6800                              (match_operand:HI 2 "general_operand" "")))
6801               (clobber (reg:CC FLAGS_REG))])]
6802   "TARGET_HIMODE_MATH"
6803   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6805 (define_insn "*subhi_1"
6806   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6807         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6808                   (match_operand:HI 2 "general_operand" "ri,rm")))
6809    (clobber (reg:CC FLAGS_REG))]
6810   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6811   "sub{w}\t{%2, %0|%0, %2}"
6812   [(set_attr "type" "alu")
6813    (set_attr "mode" "HI")])
6815 (define_insn "*subhi_2"
6816   [(set (reg FLAGS_REG)
6817         (compare
6818           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6819                     (match_operand:HI 2 "general_operand" "ri,rm"))
6820           (const_int 0)))
6821    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6822         (minus:HI (match_dup 1) (match_dup 2)))]
6823   "ix86_match_ccmode (insn, CCGOCmode)
6824    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6825   "sub{w}\t{%2, %0|%0, %2}"
6826   [(set_attr "type" "alu")
6827    (set_attr "mode" "HI")])
6829 (define_insn "*subhi_3"
6830   [(set (reg FLAGS_REG)
6831         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6832                  (match_operand:HI 2 "general_operand" "ri,rm")))
6833    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6834         (minus:HI (match_dup 1) (match_dup 2)))]
6835   "ix86_match_ccmode (insn, CCmode)
6836    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6837   "sub{w}\t{%2, %0|%0, %2}"
6838   [(set_attr "type" "alu")
6839    (set_attr "mode" "HI")])
6841 (define_expand "subqi3"
6842   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6843                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6844                              (match_operand:QI 2 "general_operand" "")))
6845               (clobber (reg:CC FLAGS_REG))])]
6846   "TARGET_QIMODE_MATH"
6847   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6849 (define_insn "*subqi_1"
6850   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6851         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6852                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6853    (clobber (reg:CC FLAGS_REG))]
6854   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6855   "sub{b}\t{%2, %0|%0, %2}"
6856   [(set_attr "type" "alu")
6857    (set_attr "mode" "QI")])
6859 (define_insn "*subqi_1_slp"
6860   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6861         (minus:QI (match_dup 0)
6862                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6863    (clobber (reg:CC FLAGS_REG))]
6864   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6865    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6866   "sub{b}\t{%1, %0|%0, %1}"
6867   [(set_attr "type" "alu1")
6868    (set_attr "mode" "QI")])
6870 (define_insn "*subqi_2"
6871   [(set (reg FLAGS_REG)
6872         (compare
6873           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6874                     (match_operand:QI 2 "general_operand" "qi,qm"))
6875           (const_int 0)))
6876    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6877         (minus:HI (match_dup 1) (match_dup 2)))]
6878   "ix86_match_ccmode (insn, CCGOCmode)
6879    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6880   "sub{b}\t{%2, %0|%0, %2}"
6881   [(set_attr "type" "alu")
6882    (set_attr "mode" "QI")])
6884 (define_insn "*subqi_3"
6885   [(set (reg FLAGS_REG)
6886         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6887                  (match_operand:QI 2 "general_operand" "qi,qm")))
6888    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6889         (minus:HI (match_dup 1) (match_dup 2)))]
6890   "ix86_match_ccmode (insn, CCmode)
6891    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6892   "sub{b}\t{%2, %0|%0, %2}"
6893   [(set_attr "type" "alu")
6894    (set_attr "mode" "QI")])
6896 ;; The patterns that match these are at the end of this file.
6898 (define_expand "subxf3"
6899   [(set (match_operand:XF 0 "register_operand" "")
6900         (minus:XF (match_operand:XF 1 "register_operand" "")
6901                   (match_operand:XF 2 "register_operand" "")))]
6902   "TARGET_80387"
6903   "")
6905 (define_expand "subdf3"
6906   [(set (match_operand:DF 0 "register_operand" "")
6907         (minus:DF (match_operand:DF 1 "register_operand" "")
6908                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6909   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6910   "")
6912 (define_expand "subsf3"
6913   [(set (match_operand:SF 0 "register_operand" "")
6914         (minus:SF (match_operand:SF 1 "register_operand" "")
6915                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6916   "TARGET_80387 || TARGET_SSE_MATH"
6917   "")
6919 ;; Multiply instructions
6921 (define_expand "muldi3"
6922   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6923                    (mult:DI (match_operand:DI 1 "register_operand" "")
6924                             (match_operand:DI 2 "x86_64_general_operand" "")))
6925               (clobber (reg:CC FLAGS_REG))])]
6926   "TARGET_64BIT"
6927   "")
6929 (define_insn "*muldi3_1_rex64"
6930   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6931         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6932                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6933    (clobber (reg:CC FLAGS_REG))]
6934   "TARGET_64BIT
6935    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6936   "@
6937    imul{q}\t{%2, %1, %0|%0, %1, %2}
6938    imul{q}\t{%2, %1, %0|%0, %1, %2}
6939    imul{q}\t{%2, %0|%0, %2}"
6940   [(set_attr "type" "imul")
6941    (set_attr "prefix_0f" "0,0,1")
6942    (set (attr "athlon_decode")
6943         (cond [(eq_attr "cpu" "athlon")
6944                   (const_string "vector")
6945                (eq_attr "alternative" "1")
6946                   (const_string "vector")
6947                (and (eq_attr "alternative" "2")
6948                     (match_operand 1 "memory_operand" ""))
6949                   (const_string "vector")]
6950               (const_string "direct")))
6951    (set_attr "mode" "DI")])
6953 (define_expand "mulsi3"
6954   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6955                    (mult:SI (match_operand:SI 1 "register_operand" "")
6956                             (match_operand:SI 2 "general_operand" "")))
6957               (clobber (reg:CC FLAGS_REG))])]
6958   ""
6959   "")
6961 (define_insn "*mulsi3_1"
6962   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6963         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6964                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6965    (clobber (reg:CC FLAGS_REG))]
6966   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6967   "@
6968    imul{l}\t{%2, %1, %0|%0, %1, %2}
6969    imul{l}\t{%2, %1, %0|%0, %1, %2}
6970    imul{l}\t{%2, %0|%0, %2}"
6971   [(set_attr "type" "imul")
6972    (set_attr "prefix_0f" "0,0,1")
6973    (set (attr "athlon_decode")
6974         (cond [(eq_attr "cpu" "athlon")
6975                   (const_string "vector")
6976                (eq_attr "alternative" "1")
6977                   (const_string "vector")
6978                (and (eq_attr "alternative" "2")
6979                     (match_operand 1 "memory_operand" ""))
6980                   (const_string "vector")]
6981               (const_string "direct")))
6982    (set_attr "mode" "SI")])
6984 (define_insn "*mulsi3_1_zext"
6985   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6986         (zero_extend:DI
6987           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6988                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6989    (clobber (reg:CC FLAGS_REG))]
6990   "TARGET_64BIT
6991    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6992   "@
6993    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6994    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6995    imul{l}\t{%2, %k0|%k0, %2}"
6996   [(set_attr "type" "imul")
6997    (set_attr "prefix_0f" "0,0,1")
6998    (set (attr "athlon_decode")
6999         (cond [(eq_attr "cpu" "athlon")
7000                   (const_string "vector")
7001                (eq_attr "alternative" "1")
7002                   (const_string "vector")
7003                (and (eq_attr "alternative" "2")
7004                     (match_operand 1 "memory_operand" ""))
7005                   (const_string "vector")]
7006               (const_string "direct")))
7007    (set_attr "mode" "SI")])
7009 (define_expand "mulhi3"
7010   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7011                    (mult:HI (match_operand:HI 1 "register_operand" "")
7012                             (match_operand:HI 2 "general_operand" "")))
7013               (clobber (reg:CC FLAGS_REG))])]
7014   "TARGET_HIMODE_MATH"
7015   "")
7017 (define_insn "*mulhi3_1"
7018   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7019         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7020                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7021    (clobber (reg:CC FLAGS_REG))]
7022   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7023   "@
7024    imul{w}\t{%2, %1, %0|%0, %1, %2}
7025    imul{w}\t{%2, %1, %0|%0, %1, %2}
7026    imul{w}\t{%2, %0|%0, %2}"
7027   [(set_attr "type" "imul")
7028    (set_attr "prefix_0f" "0,0,1")
7029    (set (attr "athlon_decode")
7030         (cond [(eq_attr "cpu" "athlon")
7031                   (const_string "vector")
7032                (eq_attr "alternative" "1,2")
7033                   (const_string "vector")]
7034               (const_string "direct")))
7035    (set_attr "mode" "HI")])
7037 (define_expand "mulqi3"
7038   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7039                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7040                             (match_operand:QI 2 "register_operand" "")))
7041               (clobber (reg:CC FLAGS_REG))])]
7042   "TARGET_QIMODE_MATH"
7043   "")
7045 (define_insn "*mulqi3_1"
7046   [(set (match_operand:QI 0 "register_operand" "=a")
7047         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7048                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7049    (clobber (reg:CC FLAGS_REG))]
7050   "TARGET_QIMODE_MATH
7051    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7052   "mul{b}\t%2"
7053   [(set_attr "type" "imul")
7054    (set_attr "length_immediate" "0")
7055    (set (attr "athlon_decode")
7056      (if_then_else (eq_attr "cpu" "athlon")
7057         (const_string "vector")
7058         (const_string "direct")))
7059    (set_attr "mode" "QI")])
7061 (define_expand "umulqihi3"
7062   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7063                    (mult:HI (zero_extend:HI
7064                               (match_operand:QI 1 "nonimmediate_operand" ""))
7065                             (zero_extend:HI
7066                               (match_operand:QI 2 "register_operand" ""))))
7067               (clobber (reg:CC FLAGS_REG))])]
7068   "TARGET_QIMODE_MATH"
7069   "")
7071 (define_insn "*umulqihi3_1"
7072   [(set (match_operand:HI 0 "register_operand" "=a")
7073         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7074                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7075    (clobber (reg:CC FLAGS_REG))]
7076   "TARGET_QIMODE_MATH
7077    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7078   "mul{b}\t%2"
7079   [(set_attr "type" "imul")
7080    (set_attr "length_immediate" "0")
7081    (set (attr "athlon_decode")
7082      (if_then_else (eq_attr "cpu" "athlon")
7083         (const_string "vector")
7084         (const_string "direct")))
7085    (set_attr "mode" "QI")])
7087 (define_expand "mulqihi3"
7088   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7089                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7090                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7091               (clobber (reg:CC FLAGS_REG))])]
7092   "TARGET_QIMODE_MATH"
7093   "")
7095 (define_insn "*mulqihi3_insn"
7096   [(set (match_operand:HI 0 "register_operand" "=a")
7097         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7098                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7099    (clobber (reg:CC FLAGS_REG))]
7100   "TARGET_QIMODE_MATH
7101    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7102   "imul{b}\t%2"
7103   [(set_attr "type" "imul")
7104    (set_attr "length_immediate" "0")
7105    (set (attr "athlon_decode")
7106      (if_then_else (eq_attr "cpu" "athlon")
7107         (const_string "vector")
7108         (const_string "direct")))
7109    (set_attr "mode" "QI")])
7111 (define_expand "umulditi3"
7112   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7113                    (mult:TI (zero_extend:TI
7114                               (match_operand:DI 1 "nonimmediate_operand" ""))
7115                             (zero_extend:TI
7116                               (match_operand:DI 2 "register_operand" ""))))
7117               (clobber (reg:CC FLAGS_REG))])]
7118   "TARGET_64BIT"
7119   "")
7121 (define_insn "*umulditi3_insn"
7122   [(set (match_operand:TI 0 "register_operand" "=A")
7123         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7124                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7125    (clobber (reg:CC FLAGS_REG))]
7126   "TARGET_64BIT
7127    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7128   "mul{q}\t%2"
7129   [(set_attr "type" "imul")
7130    (set_attr "length_immediate" "0")
7131    (set (attr "athlon_decode")
7132      (if_then_else (eq_attr "cpu" "athlon")
7133         (const_string "vector")
7134         (const_string "double")))
7135    (set_attr "mode" "DI")])
7137 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7138 (define_expand "umulsidi3"
7139   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7140                    (mult:DI (zero_extend:DI
7141                               (match_operand:SI 1 "nonimmediate_operand" ""))
7142                             (zero_extend:DI
7143                               (match_operand:SI 2 "register_operand" ""))))
7144               (clobber (reg:CC FLAGS_REG))])]
7145   "!TARGET_64BIT"
7146   "")
7148 (define_insn "*umulsidi3_insn"
7149   [(set (match_operand:DI 0 "register_operand" "=A")
7150         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7151                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7152    (clobber (reg:CC FLAGS_REG))]
7153   "!TARGET_64BIT
7154    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7155   "mul{l}\t%2"
7156   [(set_attr "type" "imul")
7157    (set_attr "length_immediate" "0")
7158    (set (attr "athlon_decode")
7159      (if_then_else (eq_attr "cpu" "athlon")
7160         (const_string "vector")
7161         (const_string "double")))
7162    (set_attr "mode" "SI")])
7164 (define_expand "mulditi3"
7165   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7166                    (mult:TI (sign_extend:TI
7167                               (match_operand:DI 1 "nonimmediate_operand" ""))
7168                             (sign_extend:TI
7169                               (match_operand:DI 2 "register_operand" ""))))
7170               (clobber (reg:CC FLAGS_REG))])]
7171   "TARGET_64BIT"
7172   "")
7174 (define_insn "*mulditi3_insn"
7175   [(set (match_operand:TI 0 "register_operand" "=A")
7176         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7177                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7178    (clobber (reg:CC FLAGS_REG))]
7179   "TARGET_64BIT
7180    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7181   "imul{q}\t%2"
7182   [(set_attr "type" "imul")
7183    (set_attr "length_immediate" "0")
7184    (set (attr "athlon_decode")
7185      (if_then_else (eq_attr "cpu" "athlon")
7186         (const_string "vector")
7187         (const_string "double")))
7188    (set_attr "mode" "DI")])
7190 (define_expand "mulsidi3"
7191   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7192                    (mult:DI (sign_extend:DI
7193                               (match_operand:SI 1 "nonimmediate_operand" ""))
7194                             (sign_extend:DI
7195                               (match_operand:SI 2 "register_operand" ""))))
7196               (clobber (reg:CC FLAGS_REG))])]
7197   "!TARGET_64BIT"
7198   "")
7200 (define_insn "*mulsidi3_insn"
7201   [(set (match_operand:DI 0 "register_operand" "=A")
7202         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7203                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7204    (clobber (reg:CC FLAGS_REG))]
7205   "!TARGET_64BIT
7206    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7207   "imul{l}\t%2"
7208   [(set_attr "type" "imul")
7209    (set_attr "length_immediate" "0")
7210    (set (attr "athlon_decode")
7211      (if_then_else (eq_attr "cpu" "athlon")
7212         (const_string "vector")
7213         (const_string "double")))
7214    (set_attr "mode" "SI")])
7216 (define_expand "umuldi3_highpart"
7217   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7218                    (truncate:DI
7219                      (lshiftrt:TI
7220                        (mult:TI (zero_extend:TI
7221                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7222                                 (zero_extend:TI
7223                                   (match_operand:DI 2 "register_operand" "")))
7224                        (const_int 64))))
7225               (clobber (match_scratch:DI 3 ""))
7226               (clobber (reg:CC FLAGS_REG))])]
7227   "TARGET_64BIT"
7228   "")
7230 (define_insn "*umuldi3_highpart_rex64"
7231   [(set (match_operand:DI 0 "register_operand" "=d")
7232         (truncate:DI
7233           (lshiftrt:TI
7234             (mult:TI (zero_extend:TI
7235                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7236                      (zero_extend:TI
7237                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7238             (const_int 64))))
7239    (clobber (match_scratch:DI 3 "=1"))
7240    (clobber (reg:CC FLAGS_REG))]
7241   "TARGET_64BIT
7242    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7243   "mul{q}\t%2"
7244   [(set_attr "type" "imul")
7245    (set_attr "length_immediate" "0")
7246    (set (attr "athlon_decode")
7247      (if_then_else (eq_attr "cpu" "athlon")
7248         (const_string "vector")
7249         (const_string "double")))
7250    (set_attr "mode" "DI")])
7252 (define_expand "umulsi3_highpart"
7253   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7254                    (truncate:SI
7255                      (lshiftrt:DI
7256                        (mult:DI (zero_extend:DI
7257                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7258                                 (zero_extend:DI
7259                                   (match_operand:SI 2 "register_operand" "")))
7260                        (const_int 32))))
7261               (clobber (match_scratch:SI 3 ""))
7262               (clobber (reg:CC FLAGS_REG))])]
7263   ""
7264   "")
7266 (define_insn "*umulsi3_highpart_insn"
7267   [(set (match_operand:SI 0 "register_operand" "=d")
7268         (truncate:SI
7269           (lshiftrt:DI
7270             (mult:DI (zero_extend:DI
7271                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7272                      (zero_extend:DI
7273                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7274             (const_int 32))))
7275    (clobber (match_scratch:SI 3 "=1"))
7276    (clobber (reg:CC FLAGS_REG))]
7277   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7278   "mul{l}\t%2"
7279   [(set_attr "type" "imul")
7280    (set_attr "length_immediate" "0")
7281    (set (attr "athlon_decode")
7282      (if_then_else (eq_attr "cpu" "athlon")
7283         (const_string "vector")
7284         (const_string "double")))
7285    (set_attr "mode" "SI")])
7287 (define_insn "*umulsi3_highpart_zext"
7288   [(set (match_operand:DI 0 "register_operand" "=d")
7289         (zero_extend:DI (truncate:SI
7290           (lshiftrt:DI
7291             (mult:DI (zero_extend:DI
7292                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7293                      (zero_extend:DI
7294                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7295             (const_int 32)))))
7296    (clobber (match_scratch:SI 3 "=1"))
7297    (clobber (reg:CC FLAGS_REG))]
7298   "TARGET_64BIT
7299    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7300   "mul{l}\t%2"
7301   [(set_attr "type" "imul")
7302    (set_attr "length_immediate" "0")
7303    (set (attr "athlon_decode")
7304      (if_then_else (eq_attr "cpu" "athlon")
7305         (const_string "vector")
7306         (const_string "double")))
7307    (set_attr "mode" "SI")])
7309 (define_expand "smuldi3_highpart"
7310   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7311                    (truncate:DI
7312                      (lshiftrt:TI
7313                        (mult:TI (sign_extend:TI
7314                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7315                                 (sign_extend:TI
7316                                   (match_operand:DI 2 "register_operand" "")))
7317                        (const_int 64))))
7318               (clobber (match_scratch:DI 3 ""))
7319               (clobber (reg:CC FLAGS_REG))])]
7320   "TARGET_64BIT"
7321   "")
7323 (define_insn "*smuldi3_highpart_rex64"
7324   [(set (match_operand:DI 0 "register_operand" "=d")
7325         (truncate:DI
7326           (lshiftrt:TI
7327             (mult:TI (sign_extend:TI
7328                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7329                      (sign_extend:TI
7330                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7331             (const_int 64))))
7332    (clobber (match_scratch:DI 3 "=1"))
7333    (clobber (reg:CC FLAGS_REG))]
7334   "TARGET_64BIT
7335    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7336   "imul{q}\t%2"
7337   [(set_attr "type" "imul")
7338    (set (attr "athlon_decode")
7339      (if_then_else (eq_attr "cpu" "athlon")
7340         (const_string "vector")
7341         (const_string "double")))
7342    (set_attr "mode" "DI")])
7344 (define_expand "smulsi3_highpart"
7345   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7346                    (truncate:SI
7347                      (lshiftrt:DI
7348                        (mult:DI (sign_extend:DI
7349                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7350                                 (sign_extend:DI
7351                                   (match_operand:SI 2 "register_operand" "")))
7352                        (const_int 32))))
7353               (clobber (match_scratch:SI 3 ""))
7354               (clobber (reg:CC FLAGS_REG))])]
7355   ""
7356   "")
7358 (define_insn "*smulsi3_highpart_insn"
7359   [(set (match_operand:SI 0 "register_operand" "=d")
7360         (truncate:SI
7361           (lshiftrt:DI
7362             (mult:DI (sign_extend:DI
7363                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7364                      (sign_extend:DI
7365                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7366             (const_int 32))))
7367    (clobber (match_scratch:SI 3 "=1"))
7368    (clobber (reg:CC FLAGS_REG))]
7369   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7370   "imul{l}\t%2"
7371   [(set_attr "type" "imul")
7372    (set (attr "athlon_decode")
7373      (if_then_else (eq_attr "cpu" "athlon")
7374         (const_string "vector")
7375         (const_string "double")))
7376    (set_attr "mode" "SI")])
7378 (define_insn "*smulsi3_highpart_zext"
7379   [(set (match_operand:DI 0 "register_operand" "=d")
7380         (zero_extend:DI (truncate:SI
7381           (lshiftrt:DI
7382             (mult:DI (sign_extend:DI
7383                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7384                      (sign_extend:DI
7385                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7386             (const_int 32)))))
7387    (clobber (match_scratch:SI 3 "=1"))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "TARGET_64BIT
7390    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7391   "imul{l}\t%2"
7392   [(set_attr "type" "imul")
7393    (set (attr "athlon_decode")
7394      (if_then_else (eq_attr "cpu" "athlon")
7395         (const_string "vector")
7396         (const_string "double")))
7397    (set_attr "mode" "SI")])
7399 ;; The patterns that match these are at the end of this file.
7401 (define_expand "mulxf3"
7402   [(set (match_operand:XF 0 "register_operand" "")
7403         (mult:XF (match_operand:XF 1 "register_operand" "")
7404                  (match_operand:XF 2 "register_operand" "")))]
7405   "TARGET_80387"
7406   "")
7408 (define_expand "muldf3"
7409   [(set (match_operand:DF 0 "register_operand" "")
7410         (mult:DF (match_operand:DF 1 "register_operand" "")
7411                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7412   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7413   "")
7415 (define_expand "mulsf3"
7416   [(set (match_operand:SF 0 "register_operand" "")
7417         (mult:SF (match_operand:SF 1 "register_operand" "")
7418                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7419   "TARGET_80387 || TARGET_SSE_MATH"
7420   "")
7422 ;; Divide instructions
7424 (define_insn "divqi3"
7425   [(set (match_operand:QI 0 "register_operand" "=a")
7426         (div:QI (match_operand:HI 1 "register_operand" "0")
7427                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7428    (clobber (reg:CC FLAGS_REG))]
7429   "TARGET_QIMODE_MATH"
7430   "idiv{b}\t%2"
7431   [(set_attr "type" "idiv")
7432    (set_attr "mode" "QI")])
7434 (define_insn "udivqi3"
7435   [(set (match_operand:QI 0 "register_operand" "=a")
7436         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7437                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7438    (clobber (reg:CC FLAGS_REG))]
7439   "TARGET_QIMODE_MATH"
7440   "div{b}\t%2"
7441   [(set_attr "type" "idiv")
7442    (set_attr "mode" "QI")])
7444 ;; The patterns that match these are at the end of this file.
7446 (define_expand "divxf3"
7447   [(set (match_operand:XF 0 "register_operand" "")
7448         (div:XF (match_operand:XF 1 "register_operand" "")
7449                 (match_operand:XF 2 "register_operand" "")))]
7450   "TARGET_80387"
7451   "")
7453 (define_expand "divdf3"
7454   [(set (match_operand:DF 0 "register_operand" "")
7455         (div:DF (match_operand:DF 1 "register_operand" "")
7456                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7457    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7458    "")
7460 (define_expand "divsf3"
7461   [(set (match_operand:SF 0 "register_operand" "")
7462         (div:SF (match_operand:SF 1 "register_operand" "")
7463                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7464   "TARGET_80387 || TARGET_SSE_MATH"
7465   "")
7467 ;; Remainder instructions.
7469 (define_expand "divmoddi4"
7470   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7471                    (div:DI (match_operand:DI 1 "register_operand" "")
7472                            (match_operand:DI 2 "nonimmediate_operand" "")))
7473               (set (match_operand:DI 3 "register_operand" "")
7474                    (mod:DI (match_dup 1) (match_dup 2)))
7475               (clobber (reg:CC FLAGS_REG))])]
7476   "TARGET_64BIT"
7477   "")
7479 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7480 ;; Penalize eax case slightly because it results in worse scheduling
7481 ;; of code.
7482 (define_insn "*divmoddi4_nocltd_rex64"
7483   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7484         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7485                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7486    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7487         (mod:DI (match_dup 2) (match_dup 3)))
7488    (clobber (reg:CC FLAGS_REG))]
7489   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7490   "#"
7491   [(set_attr "type" "multi")])
7493 (define_insn "*divmoddi4_cltd_rex64"
7494   [(set (match_operand:DI 0 "register_operand" "=a")
7495         (div:DI (match_operand:DI 2 "register_operand" "a")
7496                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7497    (set (match_operand:DI 1 "register_operand" "=&d")
7498         (mod:DI (match_dup 2) (match_dup 3)))
7499    (clobber (reg:CC FLAGS_REG))]
7500   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7501   "#"
7502   [(set_attr "type" "multi")])
7504 (define_insn "*divmoddi_noext_rex64"
7505   [(set (match_operand:DI 0 "register_operand" "=a")
7506         (div:DI (match_operand:DI 1 "register_operand" "0")
7507                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7508    (set (match_operand:DI 3 "register_operand" "=d")
7509         (mod:DI (match_dup 1) (match_dup 2)))
7510    (use (match_operand:DI 4 "register_operand" "3"))
7511    (clobber (reg:CC FLAGS_REG))]
7512   "TARGET_64BIT"
7513   "idiv{q}\t%2"
7514   [(set_attr "type" "idiv")
7515    (set_attr "mode" "DI")])
7517 (define_split
7518   [(set (match_operand:DI 0 "register_operand" "")
7519         (div:DI (match_operand:DI 1 "register_operand" "")
7520                 (match_operand:DI 2 "nonimmediate_operand" "")))
7521    (set (match_operand:DI 3 "register_operand" "")
7522         (mod:DI (match_dup 1) (match_dup 2)))
7523    (clobber (reg:CC FLAGS_REG))]
7524   "TARGET_64BIT && reload_completed"
7525   [(parallel [(set (match_dup 3)
7526                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7527               (clobber (reg:CC FLAGS_REG))])
7528    (parallel [(set (match_dup 0)
7529                    (div:DI (reg:DI 0) (match_dup 2)))
7530               (set (match_dup 3)
7531                    (mod:DI (reg:DI 0) (match_dup 2)))
7532               (use (match_dup 3))
7533               (clobber (reg:CC FLAGS_REG))])]
7535   /* Avoid use of cltd in favor of a mov+shift.  */
7536   if (!TARGET_USE_CLTD && !optimize_size)
7537     {
7538       if (true_regnum (operands[1]))
7539         emit_move_insn (operands[0], operands[1]);
7540       else
7541         emit_move_insn (operands[3], operands[1]);
7542       operands[4] = operands[3];
7543     }
7544   else
7545     {
7546       gcc_assert (!true_regnum (operands[1]));
7547       operands[4] = operands[1];
7548     }
7552 (define_expand "divmodsi4"
7553   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7554                    (div:SI (match_operand:SI 1 "register_operand" "")
7555                            (match_operand:SI 2 "nonimmediate_operand" "")))
7556               (set (match_operand:SI 3 "register_operand" "")
7557                    (mod:SI (match_dup 1) (match_dup 2)))
7558               (clobber (reg:CC FLAGS_REG))])]
7559   ""
7560   "")
7562 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7563 ;; Penalize eax case slightly because it results in worse scheduling
7564 ;; of code.
7565 (define_insn "*divmodsi4_nocltd"
7566   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7567         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7568                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7569    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7570         (mod:SI (match_dup 2) (match_dup 3)))
7571    (clobber (reg:CC FLAGS_REG))]
7572   "!optimize_size && !TARGET_USE_CLTD"
7573   "#"
7574   [(set_attr "type" "multi")])
7576 (define_insn "*divmodsi4_cltd"
7577   [(set (match_operand:SI 0 "register_operand" "=a")
7578         (div:SI (match_operand:SI 2 "register_operand" "a")
7579                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7580    (set (match_operand:SI 1 "register_operand" "=&d")
7581         (mod:SI (match_dup 2) (match_dup 3)))
7582    (clobber (reg:CC FLAGS_REG))]
7583   "optimize_size || TARGET_USE_CLTD"
7584   "#"
7585   [(set_attr "type" "multi")])
7587 (define_insn "*divmodsi_noext"
7588   [(set (match_operand:SI 0 "register_operand" "=a")
7589         (div:SI (match_operand:SI 1 "register_operand" "0")
7590                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7591    (set (match_operand:SI 3 "register_operand" "=d")
7592         (mod:SI (match_dup 1) (match_dup 2)))
7593    (use (match_operand:SI 4 "register_operand" "3"))
7594    (clobber (reg:CC FLAGS_REG))]
7595   ""
7596   "idiv{l}\t%2"
7597   [(set_attr "type" "idiv")
7598    (set_attr "mode" "SI")])
7600 (define_split
7601   [(set (match_operand:SI 0 "register_operand" "")
7602         (div:SI (match_operand:SI 1 "register_operand" "")
7603                 (match_operand:SI 2 "nonimmediate_operand" "")))
7604    (set (match_operand:SI 3 "register_operand" "")
7605         (mod:SI (match_dup 1) (match_dup 2)))
7606    (clobber (reg:CC FLAGS_REG))]
7607   "reload_completed"
7608   [(parallel [(set (match_dup 3)
7609                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7610               (clobber (reg:CC FLAGS_REG))])
7611    (parallel [(set (match_dup 0)
7612                    (div:SI (reg:SI 0) (match_dup 2)))
7613               (set (match_dup 3)
7614                    (mod:SI (reg:SI 0) (match_dup 2)))
7615               (use (match_dup 3))
7616               (clobber (reg:CC FLAGS_REG))])]
7618   /* Avoid use of cltd in favor of a mov+shift.  */
7619   if (!TARGET_USE_CLTD && !optimize_size)
7620     {
7621       if (true_regnum (operands[1]))
7622         emit_move_insn (operands[0], operands[1]);
7623       else
7624         emit_move_insn (operands[3], operands[1]);
7625       operands[4] = operands[3];
7626     }
7627   else
7628     {
7629       gcc_assert (!true_regnum (operands[1]));
7630       operands[4] = operands[1];
7631     }
7633 ;; %%% Split me.
7634 (define_insn "divmodhi4"
7635   [(set (match_operand:HI 0 "register_operand" "=a")
7636         (div:HI (match_operand:HI 1 "register_operand" "0")
7637                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7638    (set (match_operand:HI 3 "register_operand" "=&d")
7639         (mod:HI (match_dup 1) (match_dup 2)))
7640    (clobber (reg:CC FLAGS_REG))]
7641   "TARGET_HIMODE_MATH"
7642   "cwtd\;idiv{w}\t%2"
7643   [(set_attr "type" "multi")
7644    (set_attr "length_immediate" "0")
7645    (set_attr "mode" "SI")])
7647 (define_insn "udivmoddi4"
7648   [(set (match_operand:DI 0 "register_operand" "=a")
7649         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7650                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7651    (set (match_operand:DI 3 "register_operand" "=&d")
7652         (umod:DI (match_dup 1) (match_dup 2)))
7653    (clobber (reg:CC FLAGS_REG))]
7654   "TARGET_64BIT"
7655   "xor{q}\t%3, %3\;div{q}\t%2"
7656   [(set_attr "type" "multi")
7657    (set_attr "length_immediate" "0")
7658    (set_attr "mode" "DI")])
7660 (define_insn "*udivmoddi4_noext"
7661   [(set (match_operand:DI 0 "register_operand" "=a")
7662         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7663                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7664    (set (match_operand:DI 3 "register_operand" "=d")
7665         (umod:DI (match_dup 1) (match_dup 2)))
7666    (use (match_dup 3))
7667    (clobber (reg:CC FLAGS_REG))]
7668   "TARGET_64BIT"
7669   "div{q}\t%2"
7670   [(set_attr "type" "idiv")
7671    (set_attr "mode" "DI")])
7673 (define_split
7674   [(set (match_operand:DI 0 "register_operand" "")
7675         (udiv:DI (match_operand:DI 1 "register_operand" "")
7676                  (match_operand:DI 2 "nonimmediate_operand" "")))
7677    (set (match_operand:DI 3 "register_operand" "")
7678         (umod:DI (match_dup 1) (match_dup 2)))
7679    (clobber (reg:CC FLAGS_REG))]
7680   "TARGET_64BIT && reload_completed"
7681   [(set (match_dup 3) (const_int 0))
7682    (parallel [(set (match_dup 0)
7683                    (udiv:DI (match_dup 1) (match_dup 2)))
7684               (set (match_dup 3)
7685                    (umod:DI (match_dup 1) (match_dup 2)))
7686               (use (match_dup 3))
7687               (clobber (reg:CC FLAGS_REG))])]
7688   "")
7690 (define_insn "udivmodsi4"
7691   [(set (match_operand:SI 0 "register_operand" "=a")
7692         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7693                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7694    (set (match_operand:SI 3 "register_operand" "=&d")
7695         (umod:SI (match_dup 1) (match_dup 2)))
7696    (clobber (reg:CC FLAGS_REG))]
7697   ""
7698   "xor{l}\t%3, %3\;div{l}\t%2"
7699   [(set_attr "type" "multi")
7700    (set_attr "length_immediate" "0")
7701    (set_attr "mode" "SI")])
7703 (define_insn "*udivmodsi4_noext"
7704   [(set (match_operand:SI 0 "register_operand" "=a")
7705         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7706                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7707    (set (match_operand:SI 3 "register_operand" "=d")
7708         (umod:SI (match_dup 1) (match_dup 2)))
7709    (use (match_dup 3))
7710    (clobber (reg:CC FLAGS_REG))]
7711   ""
7712   "div{l}\t%2"
7713   [(set_attr "type" "idiv")
7714    (set_attr "mode" "SI")])
7716 (define_split
7717   [(set (match_operand:SI 0 "register_operand" "")
7718         (udiv:SI (match_operand:SI 1 "register_operand" "")
7719                  (match_operand:SI 2 "nonimmediate_operand" "")))
7720    (set (match_operand:SI 3 "register_operand" "")
7721         (umod:SI (match_dup 1) (match_dup 2)))
7722    (clobber (reg:CC FLAGS_REG))]
7723   "reload_completed"
7724   [(set (match_dup 3) (const_int 0))
7725    (parallel [(set (match_dup 0)
7726                    (udiv:SI (match_dup 1) (match_dup 2)))
7727               (set (match_dup 3)
7728                    (umod:SI (match_dup 1) (match_dup 2)))
7729               (use (match_dup 3))
7730               (clobber (reg:CC FLAGS_REG))])]
7731   "")
7733 (define_expand "udivmodhi4"
7734   [(set (match_dup 4) (const_int 0))
7735    (parallel [(set (match_operand:HI 0 "register_operand" "")
7736                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7737                             (match_operand:HI 2 "nonimmediate_operand" "")))
7738               (set (match_operand:HI 3 "register_operand" "")
7739                    (umod:HI (match_dup 1) (match_dup 2)))
7740               (use (match_dup 4))
7741               (clobber (reg:CC FLAGS_REG))])]
7742   "TARGET_HIMODE_MATH"
7743   "operands[4] = gen_reg_rtx (HImode);")
7745 (define_insn "*udivmodhi_noext"
7746   [(set (match_operand:HI 0 "register_operand" "=a")
7747         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7748                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7749    (set (match_operand:HI 3 "register_operand" "=d")
7750         (umod:HI (match_dup 1) (match_dup 2)))
7751    (use (match_operand:HI 4 "register_operand" "3"))
7752    (clobber (reg:CC FLAGS_REG))]
7753   ""
7754   "div{w}\t%2"
7755   [(set_attr "type" "idiv")
7756    (set_attr "mode" "HI")])
7758 ;; We cannot use div/idiv for double division, because it causes
7759 ;; "division by zero" on the overflow and that's not what we expect
7760 ;; from truncate.  Because true (non truncating) double division is
7761 ;; never generated, we can't create this insn anyway.
7763 ;(define_insn ""
7764 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7765 ;       (truncate:SI
7766 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7767 ;                  (zero_extend:DI
7768 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7769 ;   (set (match_operand:SI 3 "register_operand" "=d")
7770 ;       (truncate:SI
7771 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7772 ;   (clobber (reg:CC FLAGS_REG))]
7773 ;  ""
7774 ;  "div{l}\t{%2, %0|%0, %2}"
7775 ;  [(set_attr "type" "idiv")])
7777 ;;- Logical AND instructions
7779 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7780 ;; Note that this excludes ah.
7782 (define_insn "*testdi_1_rex64"
7783   [(set (reg FLAGS_REG)
7784         (compare
7785           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7786                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7787           (const_int 0)))]
7788   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7789    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7790   "@
7791    test{l}\t{%k1, %k0|%k0, %k1}
7792    test{l}\t{%k1, %k0|%k0, %k1}
7793    test{q}\t{%1, %0|%0, %1}
7794    test{q}\t{%1, %0|%0, %1}
7795    test{q}\t{%1, %0|%0, %1}"
7796   [(set_attr "type" "test")
7797    (set_attr "modrm" "0,1,0,1,1")
7798    (set_attr "mode" "SI,SI,DI,DI,DI")
7799    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7801 (define_insn "testsi_1"
7802   [(set (reg FLAGS_REG)
7803         (compare
7804           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7805                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7806           (const_int 0)))]
7807   "ix86_match_ccmode (insn, CCNOmode)
7808    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7809   "test{l}\t{%1, %0|%0, %1}"
7810   [(set_attr "type" "test")
7811    (set_attr "modrm" "0,1,1")
7812    (set_attr "mode" "SI")
7813    (set_attr "pent_pair" "uv,np,uv")])
7815 (define_expand "testsi_ccno_1"
7816   [(set (reg:CCNO FLAGS_REG)
7817         (compare:CCNO
7818           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7819                   (match_operand:SI 1 "nonmemory_operand" ""))
7820           (const_int 0)))]
7821   ""
7822   "")
7824 (define_insn "*testhi_1"
7825   [(set (reg FLAGS_REG)
7826         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7827                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7828                  (const_int 0)))]
7829   "ix86_match_ccmode (insn, CCNOmode)
7830    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7831   "test{w}\t{%1, %0|%0, %1}"
7832   [(set_attr "type" "test")
7833    (set_attr "modrm" "0,1,1")
7834    (set_attr "mode" "HI")
7835    (set_attr "pent_pair" "uv,np,uv")])
7837 (define_expand "testqi_ccz_1"
7838   [(set (reg:CCZ FLAGS_REG)
7839         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7840                              (match_operand:QI 1 "nonmemory_operand" ""))
7841                  (const_int 0)))]
7842   ""
7843   "")
7845 (define_insn "*testqi_1_maybe_si"
7846   [(set (reg FLAGS_REG)
7847         (compare
7848           (and:QI
7849             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7850             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7851           (const_int 0)))]
7852    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7853     && ix86_match_ccmode (insn,
7854                          GET_CODE (operands[1]) == CONST_INT
7855                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7857   if (which_alternative == 3)
7858     {
7859       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7860         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7861       return "test{l}\t{%1, %k0|%k0, %1}";
7862     }
7863   return "test{b}\t{%1, %0|%0, %1}";
7865   [(set_attr "type" "test")
7866    (set_attr "modrm" "0,1,1,1")
7867    (set_attr "mode" "QI,QI,QI,SI")
7868    (set_attr "pent_pair" "uv,np,uv,np")])
7870 (define_insn "*testqi_1"
7871   [(set (reg FLAGS_REG)
7872         (compare
7873           (and:QI
7874             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7875             (match_operand:QI 1 "general_operand" "n,n,qn"))
7876           (const_int 0)))]
7877   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7878    && ix86_match_ccmode (insn, CCNOmode)"
7879   "test{b}\t{%1, %0|%0, %1}"
7880   [(set_attr "type" "test")
7881    (set_attr "modrm" "0,1,1")
7882    (set_attr "mode" "QI")
7883    (set_attr "pent_pair" "uv,np,uv")])
7885 (define_expand "testqi_ext_ccno_0"
7886   [(set (reg:CCNO FLAGS_REG)
7887         (compare:CCNO
7888           (and:SI
7889             (zero_extract:SI
7890               (match_operand 0 "ext_register_operand" "")
7891               (const_int 8)
7892               (const_int 8))
7893             (match_operand 1 "const_int_operand" ""))
7894           (const_int 0)))]
7895   ""
7896   "")
7898 (define_insn "*testqi_ext_0"
7899   [(set (reg FLAGS_REG)
7900         (compare
7901           (and:SI
7902             (zero_extract:SI
7903               (match_operand 0 "ext_register_operand" "Q")
7904               (const_int 8)
7905               (const_int 8))
7906             (match_operand 1 "const_int_operand" "n"))
7907           (const_int 0)))]
7908   "ix86_match_ccmode (insn, CCNOmode)"
7909   "test{b}\t{%1, %h0|%h0, %1}"
7910   [(set_attr "type" "test")
7911    (set_attr "mode" "QI")
7912    (set_attr "length_immediate" "1")
7913    (set_attr "pent_pair" "np")])
7915 (define_insn "*testqi_ext_1"
7916   [(set (reg FLAGS_REG)
7917         (compare
7918           (and:SI
7919             (zero_extract:SI
7920               (match_operand 0 "ext_register_operand" "Q")
7921               (const_int 8)
7922               (const_int 8))
7923             (zero_extend:SI
7924               (match_operand:QI 1 "general_operand" "Qm")))
7925           (const_int 0)))]
7926   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7927    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7928   "test{b}\t{%1, %h0|%h0, %1}"
7929   [(set_attr "type" "test")
7930    (set_attr "mode" "QI")])
7932 (define_insn "*testqi_ext_1_rex64"
7933   [(set (reg FLAGS_REG)
7934         (compare
7935           (and:SI
7936             (zero_extract:SI
7937               (match_operand 0 "ext_register_operand" "Q")
7938               (const_int 8)
7939               (const_int 8))
7940             (zero_extend:SI
7941               (match_operand:QI 1 "register_operand" "Q")))
7942           (const_int 0)))]
7943   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7944   "test{b}\t{%1, %h0|%h0, %1}"
7945   [(set_attr "type" "test")
7946    (set_attr "mode" "QI")])
7948 (define_insn "*testqi_ext_2"
7949   [(set (reg FLAGS_REG)
7950         (compare
7951           (and:SI
7952             (zero_extract:SI
7953               (match_operand 0 "ext_register_operand" "Q")
7954               (const_int 8)
7955               (const_int 8))
7956             (zero_extract:SI
7957               (match_operand 1 "ext_register_operand" "Q")
7958               (const_int 8)
7959               (const_int 8)))
7960           (const_int 0)))]
7961   "ix86_match_ccmode (insn, CCNOmode)"
7962   "test{b}\t{%h1, %h0|%h0, %h1}"
7963   [(set_attr "type" "test")
7964    (set_attr "mode" "QI")])
7966 ;; Combine likes to form bit extractions for some tests.  Humor it.
7967 (define_insn "*testqi_ext_3"
7968   [(set (reg FLAGS_REG)
7969         (compare (zero_extract:SI
7970                    (match_operand 0 "nonimmediate_operand" "rm")
7971                    (match_operand:SI 1 "const_int_operand" "")
7972                    (match_operand:SI 2 "const_int_operand" ""))
7973                  (const_int 0)))]
7974   "ix86_match_ccmode (insn, CCNOmode)
7975    && INTVAL (operands[1]) > 0
7976    && INTVAL (operands[2]) >= 0
7977    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7978    && (GET_MODE (operands[0]) == SImode
7979        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7980        || GET_MODE (operands[0]) == HImode
7981        || GET_MODE (operands[0]) == QImode)"
7982   "#")
7984 (define_insn "*testqi_ext_3_rex64"
7985   [(set (reg FLAGS_REG)
7986         (compare (zero_extract:DI
7987                    (match_operand 0 "nonimmediate_operand" "rm")
7988                    (match_operand:DI 1 "const_int_operand" "")
7989                    (match_operand:DI 2 "const_int_operand" ""))
7990                  (const_int 0)))]
7991   "TARGET_64BIT
7992    && ix86_match_ccmode (insn, CCNOmode)
7993    && INTVAL (operands[1]) > 0
7994    && INTVAL (operands[2]) >= 0
7995    /* Ensure that resulting mask is zero or sign extended operand.  */
7996    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7997        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7998            && INTVAL (operands[1]) > 32))
7999    && (GET_MODE (operands[0]) == SImode
8000        || GET_MODE (operands[0]) == DImode
8001        || GET_MODE (operands[0]) == HImode
8002        || GET_MODE (operands[0]) == QImode)"
8003   "#")
8005 (define_split
8006   [(set (match_operand 0 "flags_reg_operand" "")
8007         (match_operator 1 "compare_operator"
8008           [(zero_extract
8009              (match_operand 2 "nonimmediate_operand" "")
8010              (match_operand 3 "const_int_operand" "")
8011              (match_operand 4 "const_int_operand" ""))
8012            (const_int 0)]))]
8013   "ix86_match_ccmode (insn, CCNOmode)"
8014   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8016   rtx val = operands[2];
8017   HOST_WIDE_INT len = INTVAL (operands[3]);
8018   HOST_WIDE_INT pos = INTVAL (operands[4]);
8019   HOST_WIDE_INT mask;
8020   enum machine_mode mode, submode;
8022   mode = GET_MODE (val);
8023   if (GET_CODE (val) == MEM)
8024     {
8025       /* ??? Combine likes to put non-volatile mem extractions in QImode
8026          no matter the size of the test.  So find a mode that works.  */
8027       if (! MEM_VOLATILE_P (val))
8028         {
8029           mode = smallest_mode_for_size (pos + len, MODE_INT);
8030           val = adjust_address (val, mode, 0);
8031         }
8032     }
8033   else if (GET_CODE (val) == SUBREG
8034            && (submode = GET_MODE (SUBREG_REG (val)),
8035                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8036            && pos + len <= GET_MODE_BITSIZE (submode))
8037     {
8038       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8039       mode = submode;
8040       val = SUBREG_REG (val);
8041     }
8042   else if (mode == HImode && pos + len <= 8)
8043     {
8044       /* Small HImode tests can be converted to QImode.  */
8045       mode = QImode;
8046       val = gen_lowpart (QImode, val);
8047     }
8049   if (len == HOST_BITS_PER_WIDE_INT)
8050     mask = -1;
8051   else
8052     mask = ((HOST_WIDE_INT)1 << len) - 1;
8053   mask <<= pos;
8055   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8058 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8059 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8060 ;; this is relatively important trick.
8061 ;; Do the conversion only post-reload to avoid limiting of the register class
8062 ;; to QI regs.
8063 (define_split
8064   [(set (match_operand 0 "flags_reg_operand" "")
8065         (match_operator 1 "compare_operator"
8066           [(and (match_operand 2 "register_operand" "")
8067                 (match_operand 3 "const_int_operand" ""))
8068            (const_int 0)]))]
8069    "reload_completed
8070     && QI_REG_P (operands[2])
8071     && GET_MODE (operands[2]) != QImode
8072     && ((ix86_match_ccmode (insn, CCZmode)
8073          && !(INTVAL (operands[3]) & ~(255 << 8)))
8074         || (ix86_match_ccmode (insn, CCNOmode)
8075             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8076   [(set (match_dup 0)
8077         (match_op_dup 1
8078           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8079                    (match_dup 3))
8080            (const_int 0)]))]
8081   "operands[2] = gen_lowpart (SImode, operands[2]);
8082    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8084 (define_split
8085   [(set (match_operand 0 "flags_reg_operand" "")
8086         (match_operator 1 "compare_operator"
8087           [(and (match_operand 2 "nonimmediate_operand" "")
8088                 (match_operand 3 "const_int_operand" ""))
8089            (const_int 0)]))]
8090    "reload_completed
8091     && GET_MODE (operands[2]) != QImode
8092     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8093     && ((ix86_match_ccmode (insn, CCZmode)
8094          && !(INTVAL (operands[3]) & ~255))
8095         || (ix86_match_ccmode (insn, CCNOmode)
8096             && !(INTVAL (operands[3]) & ~127)))"
8097   [(set (match_dup 0)
8098         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8099                          (const_int 0)]))]
8100   "operands[2] = gen_lowpart (QImode, operands[2]);
8101    operands[3] = gen_lowpart (QImode, operands[3]);")
8104 ;; %%% This used to optimize known byte-wide and operations to memory,
8105 ;; and sometimes to QImode registers.  If this is considered useful,
8106 ;; it should be done with splitters.
8108 (define_expand "anddi3"
8109   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8110         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8111                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8112    (clobber (reg:CC FLAGS_REG))]
8113   "TARGET_64BIT"
8114   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8116 (define_insn "*anddi_1_rex64"
8117   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8118         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8119                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8120    (clobber (reg:CC FLAGS_REG))]
8121   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8123   switch (get_attr_type (insn))
8124     {
8125     case TYPE_IMOVX:
8126       {
8127         enum machine_mode mode;
8129         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8130         if (INTVAL (operands[2]) == 0xff)
8131           mode = QImode;
8132         else
8133           {
8134             gcc_assert (INTVAL (operands[2]) == 0xffff);
8135             mode = HImode;
8136           }
8138         operands[1] = gen_lowpart (mode, operands[1]);
8139         if (mode == QImode)
8140           return "movz{bq|x}\t{%1,%0|%0, %1}";
8141         else
8142           return "movz{wq|x}\t{%1,%0|%0, %1}";
8143       }
8145     default:
8146       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8147       if (get_attr_mode (insn) == MODE_SI)
8148         return "and{l}\t{%k2, %k0|%k0, %k2}";
8149       else
8150         return "and{q}\t{%2, %0|%0, %2}";
8151     }
8153   [(set_attr "type" "alu,alu,alu,imovx")
8154    (set_attr "length_immediate" "*,*,*,0")
8155    (set_attr "mode" "SI,DI,DI,DI")])
8157 (define_insn "*anddi_2"
8158   [(set (reg FLAGS_REG)
8159         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8160                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8161                  (const_int 0)))
8162    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8163         (and:DI (match_dup 1) (match_dup 2)))]
8164   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8165    && ix86_binary_operator_ok (AND, DImode, operands)"
8166   "@
8167    and{l}\t{%k2, %k0|%k0, %k2}
8168    and{q}\t{%2, %0|%0, %2}
8169    and{q}\t{%2, %0|%0, %2}"
8170   [(set_attr "type" "alu")
8171    (set_attr "mode" "SI,DI,DI")])
8173 (define_expand "andsi3"
8174   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8175         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8176                 (match_operand:SI 2 "general_operand" "")))
8177    (clobber (reg:CC FLAGS_REG))]
8178   ""
8179   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8181 (define_insn "*andsi_1"
8182   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8183         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8184                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8185    (clobber (reg:CC FLAGS_REG))]
8186   "ix86_binary_operator_ok (AND, SImode, operands)"
8188   switch (get_attr_type (insn))
8189     {
8190     case TYPE_IMOVX:
8191       {
8192         enum machine_mode mode;
8194         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8195         if (INTVAL (operands[2]) == 0xff)
8196           mode = QImode;
8197         else
8198           {
8199             gcc_assert (INTVAL (operands[2]) == 0xffff);
8200             mode = HImode;
8201           }
8203         operands[1] = gen_lowpart (mode, operands[1]);
8204         if (mode == QImode)
8205           return "movz{bl|x}\t{%1,%0|%0, %1}";
8206         else
8207           return "movz{wl|x}\t{%1,%0|%0, %1}";
8208       }
8210     default:
8211       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8212       return "and{l}\t{%2, %0|%0, %2}";
8213     }
8215   [(set_attr "type" "alu,alu,imovx")
8216    (set_attr "length_immediate" "*,*,0")
8217    (set_attr "mode" "SI")])
8219 (define_split
8220   [(set (match_operand 0 "register_operand" "")
8221         (and (match_dup 0)
8222              (const_int -65536)))
8223    (clobber (reg:CC FLAGS_REG))]
8224   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8225   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8226   "operands[1] = gen_lowpart (HImode, operands[0]);")
8228 (define_split
8229   [(set (match_operand 0 "ext_register_operand" "")
8230         (and (match_dup 0)
8231              (const_int -256)))
8232    (clobber (reg:CC FLAGS_REG))]
8233   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8234   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8235   "operands[1] = gen_lowpart (QImode, operands[0]);")
8237 (define_split
8238   [(set (match_operand 0 "ext_register_operand" "")
8239         (and (match_dup 0)
8240              (const_int -65281)))
8241    (clobber (reg:CC FLAGS_REG))]
8242   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8243   [(parallel [(set (zero_extract:SI (match_dup 0)
8244                                     (const_int 8)
8245                                     (const_int 8))
8246                    (xor:SI
8247                      (zero_extract:SI (match_dup 0)
8248                                       (const_int 8)
8249                                       (const_int 8))
8250                      (zero_extract:SI (match_dup 0)
8251                                       (const_int 8)
8252                                       (const_int 8))))
8253               (clobber (reg:CC FLAGS_REG))])]
8254   "operands[0] = gen_lowpart (SImode, operands[0]);")
8256 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8257 (define_insn "*andsi_1_zext"
8258   [(set (match_operand:DI 0 "register_operand" "=r")
8259         (zero_extend:DI
8260           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8261                   (match_operand:SI 2 "general_operand" "rim"))))
8262    (clobber (reg:CC FLAGS_REG))]
8263   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8264   "and{l}\t{%2, %k0|%k0, %2}"
8265   [(set_attr "type" "alu")
8266    (set_attr "mode" "SI")])
8268 (define_insn "*andsi_2"
8269   [(set (reg FLAGS_REG)
8270         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8271                          (match_operand:SI 2 "general_operand" "rim,ri"))
8272                  (const_int 0)))
8273    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8274         (and:SI (match_dup 1) (match_dup 2)))]
8275   "ix86_match_ccmode (insn, CCNOmode)
8276    && ix86_binary_operator_ok (AND, SImode, operands)"
8277   "and{l}\t{%2, %0|%0, %2}"
8278   [(set_attr "type" "alu")
8279    (set_attr "mode" "SI")])
8281 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8282 (define_insn "*andsi_2_zext"
8283   [(set (reg FLAGS_REG)
8284         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8285                          (match_operand:SI 2 "general_operand" "rim"))
8286                  (const_int 0)))
8287    (set (match_operand:DI 0 "register_operand" "=r")
8288         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8289   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8290    && ix86_binary_operator_ok (AND, SImode, operands)"
8291   "and{l}\t{%2, %k0|%k0, %2}"
8292   [(set_attr "type" "alu")
8293    (set_attr "mode" "SI")])
8295 (define_expand "andhi3"
8296   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8297         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8298                 (match_operand:HI 2 "general_operand" "")))
8299    (clobber (reg:CC FLAGS_REG))]
8300   "TARGET_HIMODE_MATH"
8301   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8303 (define_insn "*andhi_1"
8304   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8305         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8306                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8307    (clobber (reg:CC FLAGS_REG))]
8308   "ix86_binary_operator_ok (AND, HImode, operands)"
8310   switch (get_attr_type (insn))
8311     {
8312     case TYPE_IMOVX:
8313       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8314       gcc_assert (INTVAL (operands[2]) == 0xff);
8315       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8317     default:
8318       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8320       return "and{w}\t{%2, %0|%0, %2}";
8321     }
8323   [(set_attr "type" "alu,alu,imovx")
8324    (set_attr "length_immediate" "*,*,0")
8325    (set_attr "mode" "HI,HI,SI")])
8327 (define_insn "*andhi_2"
8328   [(set (reg FLAGS_REG)
8329         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8330                          (match_operand:HI 2 "general_operand" "rim,ri"))
8331                  (const_int 0)))
8332    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8333         (and:HI (match_dup 1) (match_dup 2)))]
8334   "ix86_match_ccmode (insn, CCNOmode)
8335    && ix86_binary_operator_ok (AND, HImode, operands)"
8336   "and{w}\t{%2, %0|%0, %2}"
8337   [(set_attr "type" "alu")
8338    (set_attr "mode" "HI")])
8340 (define_expand "andqi3"
8341   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8342         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8343                 (match_operand:QI 2 "general_operand" "")))
8344    (clobber (reg:CC FLAGS_REG))]
8345   "TARGET_QIMODE_MATH"
8346   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8348 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8349 (define_insn "*andqi_1"
8350   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8351         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8352                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8353    (clobber (reg:CC FLAGS_REG))]
8354   "ix86_binary_operator_ok (AND, QImode, operands)"
8355   "@
8356    and{b}\t{%2, %0|%0, %2}
8357    and{b}\t{%2, %0|%0, %2}
8358    and{l}\t{%k2, %k0|%k0, %k2}"
8359   [(set_attr "type" "alu")
8360    (set_attr "mode" "QI,QI,SI")])
8362 (define_insn "*andqi_1_slp"
8363   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8364         (and:QI (match_dup 0)
8365                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8366    (clobber (reg:CC FLAGS_REG))]
8367   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8368    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8369   "and{b}\t{%1, %0|%0, %1}"
8370   [(set_attr "type" "alu1")
8371    (set_attr "mode" "QI")])
8373 (define_insn "*andqi_2_maybe_si"
8374   [(set (reg FLAGS_REG)
8375         (compare (and:QI
8376                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8377                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8378                  (const_int 0)))
8379    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8380         (and:QI (match_dup 1) (match_dup 2)))]
8381   "ix86_binary_operator_ok (AND, QImode, operands)
8382    && ix86_match_ccmode (insn,
8383                          GET_CODE (operands[2]) == CONST_INT
8384                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8386   if (which_alternative == 2)
8387     {
8388       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8389         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8390       return "and{l}\t{%2, %k0|%k0, %2}";
8391     }
8392   return "and{b}\t{%2, %0|%0, %2}";
8394   [(set_attr "type" "alu")
8395    (set_attr "mode" "QI,QI,SI")])
8397 (define_insn "*andqi_2"
8398   [(set (reg FLAGS_REG)
8399         (compare (and:QI
8400                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8401                    (match_operand:QI 2 "general_operand" "qim,qi"))
8402                  (const_int 0)))
8403    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8404         (and:QI (match_dup 1) (match_dup 2)))]
8405   "ix86_match_ccmode (insn, CCNOmode)
8406    && ix86_binary_operator_ok (AND, QImode, operands)"
8407   "and{b}\t{%2, %0|%0, %2}"
8408   [(set_attr "type" "alu")
8409    (set_attr "mode" "QI")])
8411 (define_insn "*andqi_2_slp"
8412   [(set (reg FLAGS_REG)
8413         (compare (and:QI
8414                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8415                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8416                  (const_int 0)))
8417    (set (strict_low_part (match_dup 0))
8418         (and:QI (match_dup 0) (match_dup 1)))]
8419   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8420    && ix86_match_ccmode (insn, CCNOmode)
8421    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8422   "and{b}\t{%1, %0|%0, %1}"
8423   [(set_attr "type" "alu1")
8424    (set_attr "mode" "QI")])
8426 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8427 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8428 ;; for a QImode operand, which of course failed.
8430 (define_insn "andqi_ext_0"
8431   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8432                          (const_int 8)
8433                          (const_int 8))
8434         (and:SI
8435           (zero_extract:SI
8436             (match_operand 1 "ext_register_operand" "0")
8437             (const_int 8)
8438             (const_int 8))
8439           (match_operand 2 "const_int_operand" "n")))
8440    (clobber (reg:CC FLAGS_REG))]
8441   ""
8442   "and{b}\t{%2, %h0|%h0, %2}"
8443   [(set_attr "type" "alu")
8444    (set_attr "length_immediate" "1")
8445    (set_attr "mode" "QI")])
8447 ;; Generated by peephole translating test to and.  This shows up
8448 ;; often in fp comparisons.
8450 (define_insn "*andqi_ext_0_cc"
8451   [(set (reg FLAGS_REG)
8452         (compare
8453           (and:SI
8454             (zero_extract:SI
8455               (match_operand 1 "ext_register_operand" "0")
8456               (const_int 8)
8457               (const_int 8))
8458             (match_operand 2 "const_int_operand" "n"))
8459           (const_int 0)))
8460    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8461                          (const_int 8)
8462                          (const_int 8))
8463         (and:SI
8464           (zero_extract:SI
8465             (match_dup 1)
8466             (const_int 8)
8467             (const_int 8))
8468           (match_dup 2)))]
8469   "ix86_match_ccmode (insn, CCNOmode)"
8470   "and{b}\t{%2, %h0|%h0, %2}"
8471   [(set_attr "type" "alu")
8472    (set_attr "length_immediate" "1")
8473    (set_attr "mode" "QI")])
8475 (define_insn "*andqi_ext_1"
8476   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8477                          (const_int 8)
8478                          (const_int 8))
8479         (and:SI
8480           (zero_extract:SI
8481             (match_operand 1 "ext_register_operand" "0")
8482             (const_int 8)
8483             (const_int 8))
8484           (zero_extend:SI
8485             (match_operand:QI 2 "general_operand" "Qm"))))
8486    (clobber (reg:CC FLAGS_REG))]
8487   "!TARGET_64BIT"
8488   "and{b}\t{%2, %h0|%h0, %2}"
8489   [(set_attr "type" "alu")
8490    (set_attr "length_immediate" "0")
8491    (set_attr "mode" "QI")])
8493 (define_insn "*andqi_ext_1_rex64"
8494   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8495                          (const_int 8)
8496                          (const_int 8))
8497         (and:SI
8498           (zero_extract:SI
8499             (match_operand 1 "ext_register_operand" "0")
8500             (const_int 8)
8501             (const_int 8))
8502           (zero_extend:SI
8503             (match_operand 2 "ext_register_operand" "Q"))))
8504    (clobber (reg:CC FLAGS_REG))]
8505   "TARGET_64BIT"
8506   "and{b}\t{%2, %h0|%h0, %2}"
8507   [(set_attr "type" "alu")
8508    (set_attr "length_immediate" "0")
8509    (set_attr "mode" "QI")])
8511 (define_insn "*andqi_ext_2"
8512   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8513                          (const_int 8)
8514                          (const_int 8))
8515         (and:SI
8516           (zero_extract:SI
8517             (match_operand 1 "ext_register_operand" "%0")
8518             (const_int 8)
8519             (const_int 8))
8520           (zero_extract:SI
8521             (match_operand 2 "ext_register_operand" "Q")
8522             (const_int 8)
8523             (const_int 8))))
8524    (clobber (reg:CC FLAGS_REG))]
8525   ""
8526   "and{b}\t{%h2, %h0|%h0, %h2}"
8527   [(set_attr "type" "alu")
8528    (set_attr "length_immediate" "0")
8529    (set_attr "mode" "QI")])
8531 ;; Convert wide AND instructions with immediate operand to shorter QImode
8532 ;; equivalents when possible.
8533 ;; Don't do the splitting with memory operands, since it introduces risk
8534 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8535 ;; for size, but that can (should?) be handled by generic code instead.
8536 (define_split
8537   [(set (match_operand 0 "register_operand" "")
8538         (and (match_operand 1 "register_operand" "")
8539              (match_operand 2 "const_int_operand" "")))
8540    (clobber (reg:CC FLAGS_REG))]
8541    "reload_completed
8542     && QI_REG_P (operands[0])
8543     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8544     && !(~INTVAL (operands[2]) & ~(255 << 8))
8545     && GET_MODE (operands[0]) != QImode"
8546   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8547                    (and:SI (zero_extract:SI (match_dup 1)
8548                                             (const_int 8) (const_int 8))
8549                            (match_dup 2)))
8550               (clobber (reg:CC FLAGS_REG))])]
8551   "operands[0] = gen_lowpart (SImode, operands[0]);
8552    operands[1] = gen_lowpart (SImode, operands[1]);
8553    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8555 ;; Since AND can be encoded with sign extended immediate, this is only
8556 ;; profitable when 7th bit is not set.
8557 (define_split
8558   [(set (match_operand 0 "register_operand" "")
8559         (and (match_operand 1 "general_operand" "")
8560              (match_operand 2 "const_int_operand" "")))
8561    (clobber (reg:CC FLAGS_REG))]
8562    "reload_completed
8563     && ANY_QI_REG_P (operands[0])
8564     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8565     && !(~INTVAL (operands[2]) & ~255)
8566     && !(INTVAL (operands[2]) & 128)
8567     && GET_MODE (operands[0]) != QImode"
8568   [(parallel [(set (strict_low_part (match_dup 0))
8569                    (and:QI (match_dup 1)
8570                            (match_dup 2)))
8571               (clobber (reg:CC FLAGS_REG))])]
8572   "operands[0] = gen_lowpart (QImode, operands[0]);
8573    operands[1] = gen_lowpart (QImode, operands[1]);
8574    operands[2] = gen_lowpart (QImode, operands[2]);")
8576 ;; Logical inclusive OR instructions
8578 ;; %%% This used to optimize known byte-wide and operations to memory.
8579 ;; If this is considered useful, it should be done with splitters.
8581 (define_expand "iordi3"
8582   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8583         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8584                 (match_operand:DI 2 "x86_64_general_operand" "")))
8585    (clobber (reg:CC FLAGS_REG))]
8586   "TARGET_64BIT"
8587   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8589 (define_insn "*iordi_1_rex64"
8590   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8591         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8592                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8593    (clobber (reg:CC FLAGS_REG))]
8594   "TARGET_64BIT
8595    && ix86_binary_operator_ok (IOR, DImode, operands)"
8596   "or{q}\t{%2, %0|%0, %2}"
8597   [(set_attr "type" "alu")
8598    (set_attr "mode" "DI")])
8600 (define_insn "*iordi_2_rex64"
8601   [(set (reg FLAGS_REG)
8602         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8603                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8604                  (const_int 0)))
8605    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8606         (ior:DI (match_dup 1) (match_dup 2)))]
8607   "TARGET_64BIT
8608    && ix86_match_ccmode (insn, CCNOmode)
8609    && ix86_binary_operator_ok (IOR, DImode, operands)"
8610   "or{q}\t{%2, %0|%0, %2}"
8611   [(set_attr "type" "alu")
8612    (set_attr "mode" "DI")])
8614 (define_insn "*iordi_3_rex64"
8615   [(set (reg FLAGS_REG)
8616         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8617                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8618                  (const_int 0)))
8619    (clobber (match_scratch:DI 0 "=r"))]
8620   "TARGET_64BIT
8621    && ix86_match_ccmode (insn, CCNOmode)
8622    && ix86_binary_operator_ok (IOR, DImode, operands)"
8623   "or{q}\t{%2, %0|%0, %2}"
8624   [(set_attr "type" "alu")
8625    (set_attr "mode" "DI")])
8628 (define_expand "iorsi3"
8629   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8630         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8631                 (match_operand:SI 2 "general_operand" "")))
8632    (clobber (reg:CC FLAGS_REG))]
8633   ""
8634   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8636 (define_insn "*iorsi_1"
8637   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8638         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8639                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8640    (clobber (reg:CC FLAGS_REG))]
8641   "ix86_binary_operator_ok (IOR, SImode, operands)"
8642   "or{l}\t{%2, %0|%0, %2}"
8643   [(set_attr "type" "alu")
8644    (set_attr "mode" "SI")])
8646 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8647 (define_insn "*iorsi_1_zext"
8648   [(set (match_operand:DI 0 "register_operand" "=rm")
8649         (zero_extend:DI
8650           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8651                   (match_operand:SI 2 "general_operand" "rim"))))
8652    (clobber (reg:CC FLAGS_REG))]
8653   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8654   "or{l}\t{%2, %k0|%k0, %2}"
8655   [(set_attr "type" "alu")
8656    (set_attr "mode" "SI")])
8658 (define_insn "*iorsi_1_zext_imm"
8659   [(set (match_operand:DI 0 "register_operand" "=rm")
8660         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8661                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8662    (clobber (reg:CC FLAGS_REG))]
8663   "TARGET_64BIT"
8664   "or{l}\t{%2, %k0|%k0, %2}"
8665   [(set_attr "type" "alu")
8666    (set_attr "mode" "SI")])
8668 (define_insn "*iorsi_2"
8669   [(set (reg FLAGS_REG)
8670         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8671                          (match_operand:SI 2 "general_operand" "rim,ri"))
8672                  (const_int 0)))
8673    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8674         (ior:SI (match_dup 1) (match_dup 2)))]
8675   "ix86_match_ccmode (insn, CCNOmode)
8676    && ix86_binary_operator_ok (IOR, SImode, operands)"
8677   "or{l}\t{%2, %0|%0, %2}"
8678   [(set_attr "type" "alu")
8679    (set_attr "mode" "SI")])
8681 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8682 ;; ??? Special case for immediate operand is missing - it is tricky.
8683 (define_insn "*iorsi_2_zext"
8684   [(set (reg FLAGS_REG)
8685         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8686                          (match_operand:SI 2 "general_operand" "rim"))
8687                  (const_int 0)))
8688    (set (match_operand:DI 0 "register_operand" "=r")
8689         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8690   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8691    && ix86_binary_operator_ok (IOR, SImode, operands)"
8692   "or{l}\t{%2, %k0|%k0, %2}"
8693   [(set_attr "type" "alu")
8694    (set_attr "mode" "SI")])
8696 (define_insn "*iorsi_2_zext_imm"
8697   [(set (reg FLAGS_REG)
8698         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8699                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8700                  (const_int 0)))
8701    (set (match_operand:DI 0 "register_operand" "=r")
8702         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8703   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8704    && ix86_binary_operator_ok (IOR, SImode, operands)"
8705   "or{l}\t{%2, %k0|%k0, %2}"
8706   [(set_attr "type" "alu")
8707    (set_attr "mode" "SI")])
8709 (define_insn "*iorsi_3"
8710   [(set (reg FLAGS_REG)
8711         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8712                          (match_operand:SI 2 "general_operand" "rim"))
8713                  (const_int 0)))
8714    (clobber (match_scratch:SI 0 "=r"))]
8715   "ix86_match_ccmode (insn, CCNOmode)
8716    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8717   "or{l}\t{%2, %0|%0, %2}"
8718   [(set_attr "type" "alu")
8719    (set_attr "mode" "SI")])
8721 (define_expand "iorhi3"
8722   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8723         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8724                 (match_operand:HI 2 "general_operand" "")))
8725    (clobber (reg:CC FLAGS_REG))]
8726   "TARGET_HIMODE_MATH"
8727   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8729 (define_insn "*iorhi_1"
8730   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8731         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8732                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8733    (clobber (reg:CC FLAGS_REG))]
8734   "ix86_binary_operator_ok (IOR, HImode, operands)"
8735   "or{w}\t{%2, %0|%0, %2}"
8736   [(set_attr "type" "alu")
8737    (set_attr "mode" "HI")])
8739 (define_insn "*iorhi_2"
8740   [(set (reg FLAGS_REG)
8741         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8742                          (match_operand:HI 2 "general_operand" "rim,ri"))
8743                  (const_int 0)))
8744    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8745         (ior:HI (match_dup 1) (match_dup 2)))]
8746   "ix86_match_ccmode (insn, CCNOmode)
8747    && ix86_binary_operator_ok (IOR, HImode, operands)"
8748   "or{w}\t{%2, %0|%0, %2}"
8749   [(set_attr "type" "alu")
8750    (set_attr "mode" "HI")])
8752 (define_insn "*iorhi_3"
8753   [(set (reg FLAGS_REG)
8754         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8755                          (match_operand:HI 2 "general_operand" "rim"))
8756                  (const_int 0)))
8757    (clobber (match_scratch:HI 0 "=r"))]
8758   "ix86_match_ccmode (insn, CCNOmode)
8759    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8760   "or{w}\t{%2, %0|%0, %2}"
8761   [(set_attr "type" "alu")
8762    (set_attr "mode" "HI")])
8764 (define_expand "iorqi3"
8765   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8766         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8767                 (match_operand:QI 2 "general_operand" "")))
8768    (clobber (reg:CC FLAGS_REG))]
8769   "TARGET_QIMODE_MATH"
8770   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8772 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8773 (define_insn "*iorqi_1"
8774   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8775         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8776                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8777    (clobber (reg:CC FLAGS_REG))]
8778   "ix86_binary_operator_ok (IOR, QImode, operands)"
8779   "@
8780    or{b}\t{%2, %0|%0, %2}
8781    or{b}\t{%2, %0|%0, %2}
8782    or{l}\t{%k2, %k0|%k0, %k2}"
8783   [(set_attr "type" "alu")
8784    (set_attr "mode" "QI,QI,SI")])
8786 (define_insn "*iorqi_1_slp"
8787   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8788         (ior:QI (match_dup 0)
8789                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8790    (clobber (reg:CC FLAGS_REG))]
8791   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8792    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8793   "or{b}\t{%1, %0|%0, %1}"
8794   [(set_attr "type" "alu1")
8795    (set_attr "mode" "QI")])
8797 (define_insn "*iorqi_2"
8798   [(set (reg FLAGS_REG)
8799         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8800                          (match_operand:QI 2 "general_operand" "qim,qi"))
8801                  (const_int 0)))
8802    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8803         (ior:QI (match_dup 1) (match_dup 2)))]
8804   "ix86_match_ccmode (insn, CCNOmode)
8805    && ix86_binary_operator_ok (IOR, QImode, operands)"
8806   "or{b}\t{%2, %0|%0, %2}"
8807   [(set_attr "type" "alu")
8808    (set_attr "mode" "QI")])
8810 (define_insn "*iorqi_2_slp"
8811   [(set (reg FLAGS_REG)
8812         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8813                          (match_operand:QI 1 "general_operand" "qim,qi"))
8814                  (const_int 0)))
8815    (set (strict_low_part (match_dup 0))
8816         (ior:QI (match_dup 0) (match_dup 1)))]
8817   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8818    && ix86_match_ccmode (insn, CCNOmode)
8819    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8820   "or{b}\t{%1, %0|%0, %1}"
8821   [(set_attr "type" "alu1")
8822    (set_attr "mode" "QI")])
8824 (define_insn "*iorqi_3"
8825   [(set (reg FLAGS_REG)
8826         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8827                          (match_operand:QI 2 "general_operand" "qim"))
8828                  (const_int 0)))
8829    (clobber (match_scratch:QI 0 "=q"))]
8830   "ix86_match_ccmode (insn, CCNOmode)
8831    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8832   "or{b}\t{%2, %0|%0, %2}"
8833   [(set_attr "type" "alu")
8834    (set_attr "mode" "QI")])
8836 (define_insn "iorqi_ext_0"
8837   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8838                          (const_int 8)
8839                          (const_int 8))
8840         (ior:SI
8841           (zero_extract:SI
8842             (match_operand 1 "ext_register_operand" "0")
8843             (const_int 8)
8844             (const_int 8))
8845           (match_operand 2 "const_int_operand" "n")))
8846    (clobber (reg:CC FLAGS_REG))]
8847   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8848   "or{b}\t{%2, %h0|%h0, %2}"
8849   [(set_attr "type" "alu")
8850    (set_attr "length_immediate" "1")
8851    (set_attr "mode" "QI")])
8853 (define_insn "*iorqi_ext_1"
8854   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8855                          (const_int 8)
8856                          (const_int 8))
8857         (ior:SI
8858           (zero_extract:SI
8859             (match_operand 1 "ext_register_operand" "0")
8860             (const_int 8)
8861             (const_int 8))
8862           (zero_extend:SI
8863             (match_operand:QI 2 "general_operand" "Qm"))))
8864    (clobber (reg:CC FLAGS_REG))]
8865   "!TARGET_64BIT
8866    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8867   "or{b}\t{%2, %h0|%h0, %2}"
8868   [(set_attr "type" "alu")
8869    (set_attr "length_immediate" "0")
8870    (set_attr "mode" "QI")])
8872 (define_insn "*iorqi_ext_1_rex64"
8873   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8874                          (const_int 8)
8875                          (const_int 8))
8876         (ior:SI
8877           (zero_extract:SI
8878             (match_operand 1 "ext_register_operand" "0")
8879             (const_int 8)
8880             (const_int 8))
8881           (zero_extend:SI
8882             (match_operand 2 "ext_register_operand" "Q"))))
8883    (clobber (reg:CC FLAGS_REG))]
8884   "TARGET_64BIT
8885    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8886   "or{b}\t{%2, %h0|%h0, %2}"
8887   [(set_attr "type" "alu")
8888    (set_attr "length_immediate" "0")
8889    (set_attr "mode" "QI")])
8891 (define_insn "*iorqi_ext_2"
8892   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8893                          (const_int 8)
8894                          (const_int 8))
8895         (ior:SI
8896           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8897                            (const_int 8)
8898                            (const_int 8))
8899           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8900                            (const_int 8)
8901                            (const_int 8))))
8902    (clobber (reg:CC FLAGS_REG))]
8903   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8904   "ior{b}\t{%h2, %h0|%h0, %h2}"
8905   [(set_attr "type" "alu")
8906    (set_attr "length_immediate" "0")
8907    (set_attr "mode" "QI")])
8909 (define_split
8910   [(set (match_operand 0 "register_operand" "")
8911         (ior (match_operand 1 "register_operand" "")
8912              (match_operand 2 "const_int_operand" "")))
8913    (clobber (reg:CC FLAGS_REG))]
8914    "reload_completed
8915     && QI_REG_P (operands[0])
8916     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8917     && !(INTVAL (operands[2]) & ~(255 << 8))
8918     && GET_MODE (operands[0]) != QImode"
8919   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8920                    (ior:SI (zero_extract:SI (match_dup 1)
8921                                             (const_int 8) (const_int 8))
8922                            (match_dup 2)))
8923               (clobber (reg:CC FLAGS_REG))])]
8924   "operands[0] = gen_lowpart (SImode, operands[0]);
8925    operands[1] = gen_lowpart (SImode, operands[1]);
8926    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8928 ;; Since OR can be encoded with sign extended immediate, this is only
8929 ;; profitable when 7th bit is set.
8930 (define_split
8931   [(set (match_operand 0 "register_operand" "")
8932         (ior (match_operand 1 "general_operand" "")
8933              (match_operand 2 "const_int_operand" "")))
8934    (clobber (reg:CC FLAGS_REG))]
8935    "reload_completed
8936     && ANY_QI_REG_P (operands[0])
8937     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8938     && !(INTVAL (operands[2]) & ~255)
8939     && (INTVAL (operands[2]) & 128)
8940     && GET_MODE (operands[0]) != QImode"
8941   [(parallel [(set (strict_low_part (match_dup 0))
8942                    (ior:QI (match_dup 1)
8943                            (match_dup 2)))
8944               (clobber (reg:CC FLAGS_REG))])]
8945   "operands[0] = gen_lowpart (QImode, operands[0]);
8946    operands[1] = gen_lowpart (QImode, operands[1]);
8947    operands[2] = gen_lowpart (QImode, operands[2]);")
8949 ;; Logical XOR instructions
8951 ;; %%% This used to optimize known byte-wide and operations to memory.
8952 ;; If this is considered useful, it should be done with splitters.
8954 (define_expand "xordi3"
8955   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8956         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8957                 (match_operand:DI 2 "x86_64_general_operand" "")))
8958    (clobber (reg:CC FLAGS_REG))]
8959   "TARGET_64BIT"
8960   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8962 (define_insn "*xordi_1_rex64"
8963   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8964         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8965                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8966    (clobber (reg:CC FLAGS_REG))]
8967   "TARGET_64BIT
8968    && ix86_binary_operator_ok (XOR, DImode, operands)"
8969   "@
8970    xor{q}\t{%2, %0|%0, %2}
8971    xor{q}\t{%2, %0|%0, %2}"
8972   [(set_attr "type" "alu")
8973    (set_attr "mode" "DI,DI")])
8975 (define_insn "*xordi_2_rex64"
8976   [(set (reg FLAGS_REG)
8977         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8978                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8979                  (const_int 0)))
8980    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8981         (xor:DI (match_dup 1) (match_dup 2)))]
8982   "TARGET_64BIT
8983    && ix86_match_ccmode (insn, CCNOmode)
8984    && ix86_binary_operator_ok (XOR, DImode, operands)"
8985   "@
8986    xor{q}\t{%2, %0|%0, %2}
8987    xor{q}\t{%2, %0|%0, %2}"
8988   [(set_attr "type" "alu")
8989    (set_attr "mode" "DI,DI")])
8991 (define_insn "*xordi_3_rex64"
8992   [(set (reg FLAGS_REG)
8993         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8994                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8995                  (const_int 0)))
8996    (clobber (match_scratch:DI 0 "=r"))]
8997   "TARGET_64BIT
8998    && ix86_match_ccmode (insn, CCNOmode)
8999    && ix86_binary_operator_ok (XOR, DImode, operands)"
9000   "xor{q}\t{%2, %0|%0, %2}"
9001   [(set_attr "type" "alu")
9002    (set_attr "mode" "DI")])
9004 (define_expand "xorsi3"
9005   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9006         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9007                 (match_operand:SI 2 "general_operand" "")))
9008    (clobber (reg:CC FLAGS_REG))]
9009   ""
9010   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9012 (define_insn "*xorsi_1"
9013   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9014         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9015                 (match_operand:SI 2 "general_operand" "ri,rm")))
9016    (clobber (reg:CC FLAGS_REG))]
9017   "ix86_binary_operator_ok (XOR, SImode, operands)"
9018   "xor{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 ;; Add speccase for immediates
9024 (define_insn "*xorsi_1_zext"
9025   [(set (match_operand:DI 0 "register_operand" "=r")
9026         (zero_extend:DI
9027           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9028                   (match_operand:SI 2 "general_operand" "rim"))))
9029    (clobber (reg:CC FLAGS_REG))]
9030   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9031   "xor{l}\t{%2, %k0|%k0, %2}"
9032   [(set_attr "type" "alu")
9033    (set_attr "mode" "SI")])
9035 (define_insn "*xorsi_1_zext_imm"
9036   [(set (match_operand:DI 0 "register_operand" "=r")
9037         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9038                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9039    (clobber (reg:CC FLAGS_REG))]
9040   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9041   "xor{l}\t{%2, %k0|%k0, %2}"
9042   [(set_attr "type" "alu")
9043    (set_attr "mode" "SI")])
9045 (define_insn "*xorsi_2"
9046   [(set (reg FLAGS_REG)
9047         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9048                          (match_operand:SI 2 "general_operand" "rim,ri"))
9049                  (const_int 0)))
9050    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9051         (xor:SI (match_dup 1) (match_dup 2)))]
9052   "ix86_match_ccmode (insn, CCNOmode)
9053    && ix86_binary_operator_ok (XOR, SImode, operands)"
9054   "xor{l}\t{%2, %0|%0, %2}"
9055   [(set_attr "type" "alu")
9056    (set_attr "mode" "SI")])
9058 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9059 ;; ??? Special case for immediate operand is missing - it is tricky.
9060 (define_insn "*xorsi_2_zext"
9061   [(set (reg FLAGS_REG)
9062         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9063                          (match_operand:SI 2 "general_operand" "rim"))
9064                  (const_int 0)))
9065    (set (match_operand:DI 0 "register_operand" "=r")
9066         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9067   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9068    && ix86_binary_operator_ok (XOR, SImode, operands)"
9069   "xor{l}\t{%2, %k0|%k0, %2}"
9070   [(set_attr "type" "alu")
9071    (set_attr "mode" "SI")])
9073 (define_insn "*xorsi_2_zext_imm"
9074   [(set (reg FLAGS_REG)
9075         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9076                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9077                  (const_int 0)))
9078    (set (match_operand:DI 0 "register_operand" "=r")
9079         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9080   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9081    && ix86_binary_operator_ok (XOR, SImode, operands)"
9082   "xor{l}\t{%2, %k0|%k0, %2}"
9083   [(set_attr "type" "alu")
9084    (set_attr "mode" "SI")])
9086 (define_insn "*xorsi_3"
9087   [(set (reg FLAGS_REG)
9088         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9089                          (match_operand:SI 2 "general_operand" "rim"))
9090                  (const_int 0)))
9091    (clobber (match_scratch:SI 0 "=r"))]
9092   "ix86_match_ccmode (insn, CCNOmode)
9093    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9094   "xor{l}\t{%2, %0|%0, %2}"
9095   [(set_attr "type" "alu")
9096    (set_attr "mode" "SI")])
9098 (define_expand "xorhi3"
9099   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9100         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9101                 (match_operand:HI 2 "general_operand" "")))
9102    (clobber (reg:CC FLAGS_REG))]
9103   "TARGET_HIMODE_MATH"
9104   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9106 (define_insn "*xorhi_1"
9107   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9108         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9109                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9110    (clobber (reg:CC FLAGS_REG))]
9111   "ix86_binary_operator_ok (XOR, HImode, operands)"
9112   "xor{w}\t{%2, %0|%0, %2}"
9113   [(set_attr "type" "alu")
9114    (set_attr "mode" "HI")])
9116 (define_insn "*xorhi_2"
9117   [(set (reg FLAGS_REG)
9118         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9119                          (match_operand:HI 2 "general_operand" "rim,ri"))
9120                  (const_int 0)))
9121    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9122         (xor:HI (match_dup 1) (match_dup 2)))]
9123   "ix86_match_ccmode (insn, CCNOmode)
9124    && ix86_binary_operator_ok (XOR, HImode, operands)"
9125   "xor{w}\t{%2, %0|%0, %2}"
9126   [(set_attr "type" "alu")
9127    (set_attr "mode" "HI")])
9129 (define_insn "*xorhi_3"
9130   [(set (reg FLAGS_REG)
9131         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9132                          (match_operand:HI 2 "general_operand" "rim"))
9133                  (const_int 0)))
9134    (clobber (match_scratch:HI 0 "=r"))]
9135   "ix86_match_ccmode (insn, CCNOmode)
9136    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9137   "xor{w}\t{%2, %0|%0, %2}"
9138   [(set_attr "type" "alu")
9139    (set_attr "mode" "HI")])
9141 (define_expand "xorqi3"
9142   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9143         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9144                 (match_operand:QI 2 "general_operand" "")))
9145    (clobber (reg:CC FLAGS_REG))]
9146   "TARGET_QIMODE_MATH"
9147   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9149 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9150 (define_insn "*xorqi_1"
9151   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9152         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9153                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9154    (clobber (reg:CC FLAGS_REG))]
9155   "ix86_binary_operator_ok (XOR, QImode, operands)"
9156   "@
9157    xor{b}\t{%2, %0|%0, %2}
9158    xor{b}\t{%2, %0|%0, %2}
9159    xor{l}\t{%k2, %k0|%k0, %k2}"
9160   [(set_attr "type" "alu")
9161    (set_attr "mode" "QI,QI,SI")])
9163 (define_insn "*xorqi_1_slp"
9164   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9165         (xor:QI (match_dup 0)
9166                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9167    (clobber (reg:CC FLAGS_REG))]
9168   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9169    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9170   "xor{b}\t{%1, %0|%0, %1}"
9171   [(set_attr "type" "alu1")
9172    (set_attr "mode" "QI")])
9174 (define_insn "xorqi_ext_0"
9175   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9176                          (const_int 8)
9177                          (const_int 8))
9178         (xor:SI
9179           (zero_extract:SI
9180             (match_operand 1 "ext_register_operand" "0")
9181             (const_int 8)
9182             (const_int 8))
9183           (match_operand 2 "const_int_operand" "n")))
9184    (clobber (reg:CC FLAGS_REG))]
9185   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9186   "xor{b}\t{%2, %h0|%h0, %2}"
9187   [(set_attr "type" "alu")
9188    (set_attr "length_immediate" "1")
9189    (set_attr "mode" "QI")])
9191 (define_insn "*xorqi_ext_1"
9192   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9193                          (const_int 8)
9194                          (const_int 8))
9195         (xor:SI
9196           (zero_extract:SI
9197             (match_operand 1 "ext_register_operand" "0")
9198             (const_int 8)
9199             (const_int 8))
9200           (zero_extend:SI
9201             (match_operand:QI 2 "general_operand" "Qm"))))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "!TARGET_64BIT
9204    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9205   "xor{b}\t{%2, %h0|%h0, %2}"
9206   [(set_attr "type" "alu")
9207    (set_attr "length_immediate" "0")
9208    (set_attr "mode" "QI")])
9210 (define_insn "*xorqi_ext_1_rex64"
9211   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9212                          (const_int 8)
9213                          (const_int 8))
9214         (xor:SI
9215           (zero_extract:SI
9216             (match_operand 1 "ext_register_operand" "0")
9217             (const_int 8)
9218             (const_int 8))
9219           (zero_extend:SI
9220             (match_operand 2 "ext_register_operand" "Q"))))
9221    (clobber (reg:CC FLAGS_REG))]
9222   "TARGET_64BIT
9223    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9224   "xor{b}\t{%2, %h0|%h0, %2}"
9225   [(set_attr "type" "alu")
9226    (set_attr "length_immediate" "0")
9227    (set_attr "mode" "QI")])
9229 (define_insn "*xorqi_ext_2"
9230   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9231                          (const_int 8)
9232                          (const_int 8))
9233         (xor:SI
9234           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9235                            (const_int 8)
9236                            (const_int 8))
9237           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9238                            (const_int 8)
9239                            (const_int 8))))
9240    (clobber (reg:CC FLAGS_REG))]
9241   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9242   "xor{b}\t{%h2, %h0|%h0, %h2}"
9243   [(set_attr "type" "alu")
9244    (set_attr "length_immediate" "0")
9245    (set_attr "mode" "QI")])
9247 (define_insn "*xorqi_cc_1"
9248   [(set (reg FLAGS_REG)
9249         (compare
9250           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9251                   (match_operand:QI 2 "general_operand" "qim,qi"))
9252           (const_int 0)))
9253    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9254         (xor:QI (match_dup 1) (match_dup 2)))]
9255   "ix86_match_ccmode (insn, CCNOmode)
9256    && ix86_binary_operator_ok (XOR, QImode, operands)"
9257   "xor{b}\t{%2, %0|%0, %2}"
9258   [(set_attr "type" "alu")
9259    (set_attr "mode" "QI")])
9261 (define_insn "*xorqi_2_slp"
9262   [(set (reg FLAGS_REG)
9263         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9264                          (match_operand:QI 1 "general_operand" "qim,qi"))
9265                  (const_int 0)))
9266    (set (strict_low_part (match_dup 0))
9267         (xor:QI (match_dup 0) (match_dup 1)))]
9268   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9269    && ix86_match_ccmode (insn, CCNOmode)
9270    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9271   "xor{b}\t{%1, %0|%0, %1}"
9272   [(set_attr "type" "alu1")
9273    (set_attr "mode" "QI")])
9275 (define_insn "*xorqi_cc_2"
9276   [(set (reg FLAGS_REG)
9277         (compare
9278           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9279                   (match_operand:QI 2 "general_operand" "qim"))
9280           (const_int 0)))
9281    (clobber (match_scratch:QI 0 "=q"))]
9282   "ix86_match_ccmode (insn, CCNOmode)
9283    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9284   "xor{b}\t{%2, %0|%0, %2}"
9285   [(set_attr "type" "alu")
9286    (set_attr "mode" "QI")])
9288 (define_insn "*xorqi_cc_ext_1"
9289   [(set (reg FLAGS_REG)
9290         (compare
9291           (xor:SI
9292             (zero_extract:SI
9293               (match_operand 1 "ext_register_operand" "0")
9294               (const_int 8)
9295               (const_int 8))
9296             (match_operand:QI 2 "general_operand" "qmn"))
9297           (const_int 0)))
9298    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9299                          (const_int 8)
9300                          (const_int 8))
9301         (xor:SI
9302           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9303           (match_dup 2)))]
9304   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9305   "xor{b}\t{%2, %h0|%h0, %2}"
9306   [(set_attr "type" "alu")
9307    (set_attr "mode" "QI")])
9309 (define_insn "*xorqi_cc_ext_1_rex64"
9310   [(set (reg FLAGS_REG)
9311         (compare
9312           (xor:SI
9313             (zero_extract:SI
9314               (match_operand 1 "ext_register_operand" "0")
9315               (const_int 8)
9316               (const_int 8))
9317             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9318           (const_int 0)))
9319    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9320                          (const_int 8)
9321                          (const_int 8))
9322         (xor:SI
9323           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9324           (match_dup 2)))]
9325   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9326   "xor{b}\t{%2, %h0|%h0, %2}"
9327   [(set_attr "type" "alu")
9328    (set_attr "mode" "QI")])
9330 (define_expand "xorqi_cc_ext_1"
9331   [(parallel [
9332      (set (reg:CCNO FLAGS_REG)
9333           (compare:CCNO
9334             (xor:SI
9335               (zero_extract:SI
9336                 (match_operand 1 "ext_register_operand" "")
9337                 (const_int 8)
9338                 (const_int 8))
9339               (match_operand:QI 2 "general_operand" ""))
9340             (const_int 0)))
9341      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9342                            (const_int 8)
9343                            (const_int 8))
9344           (xor:SI
9345             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9346             (match_dup 2)))])]
9347   ""
9348   "")
9350 (define_split
9351   [(set (match_operand 0 "register_operand" "")
9352         (xor (match_operand 1 "register_operand" "")
9353              (match_operand 2 "const_int_operand" "")))
9354    (clobber (reg:CC FLAGS_REG))]
9355    "reload_completed
9356     && QI_REG_P (operands[0])
9357     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9358     && !(INTVAL (operands[2]) & ~(255 << 8))
9359     && GET_MODE (operands[0]) != QImode"
9360   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9361                    (xor:SI (zero_extract:SI (match_dup 1)
9362                                             (const_int 8) (const_int 8))
9363                            (match_dup 2)))
9364               (clobber (reg:CC FLAGS_REG))])]
9365   "operands[0] = gen_lowpart (SImode, operands[0]);
9366    operands[1] = gen_lowpart (SImode, operands[1]);
9367    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9369 ;; Since XOR can be encoded with sign extended immediate, this is only
9370 ;; profitable when 7th bit is set.
9371 (define_split
9372   [(set (match_operand 0 "register_operand" "")
9373         (xor (match_operand 1 "general_operand" "")
9374              (match_operand 2 "const_int_operand" "")))
9375    (clobber (reg:CC FLAGS_REG))]
9376    "reload_completed
9377     && ANY_QI_REG_P (operands[0])
9378     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9379     && !(INTVAL (operands[2]) & ~255)
9380     && (INTVAL (operands[2]) & 128)
9381     && GET_MODE (operands[0]) != QImode"
9382   [(parallel [(set (strict_low_part (match_dup 0))
9383                    (xor:QI (match_dup 1)
9384                            (match_dup 2)))
9385               (clobber (reg:CC FLAGS_REG))])]
9386   "operands[0] = gen_lowpart (QImode, operands[0]);
9387    operands[1] = gen_lowpart (QImode, operands[1]);
9388    operands[2] = gen_lowpart (QImode, operands[2]);")
9390 ;; Negation instructions
9392 (define_expand "negti2"
9393   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9394                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9395               (clobber (reg:CC FLAGS_REG))])]
9396   "TARGET_64BIT"
9397   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9399 (define_insn "*negti2_1"
9400   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9401         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "TARGET_64BIT
9404    && ix86_unary_operator_ok (NEG, TImode, operands)"
9405   "#")
9407 (define_split
9408   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9409         (neg:TI (match_operand:TI 1 "general_operand" "")))
9410    (clobber (reg:CC FLAGS_REG))]
9411   "TARGET_64BIT && reload_completed"
9412   [(parallel
9413     [(set (reg:CCZ FLAGS_REG)
9414           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9415      (set (match_dup 0) (neg:DI (match_dup 2)))])
9416    (parallel
9417     [(set (match_dup 1)
9418           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9419                             (match_dup 3))
9420                    (const_int 0)))
9421      (clobber (reg:CC FLAGS_REG))])
9422    (parallel
9423     [(set (match_dup 1)
9424           (neg:DI (match_dup 1)))
9425      (clobber (reg:CC FLAGS_REG))])]
9426   "split_ti (operands+1, 1, operands+2, operands+3);
9427    split_ti (operands+0, 1, operands+0, operands+1);")
9429 (define_expand "negdi2"
9430   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9431                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9432               (clobber (reg:CC FLAGS_REG))])]
9433   ""
9434   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9436 (define_insn "*negdi2_1"
9437   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9438         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9439    (clobber (reg:CC FLAGS_REG))]
9440   "!TARGET_64BIT
9441    && ix86_unary_operator_ok (NEG, DImode, operands)"
9442   "#")
9444 (define_split
9445   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9446         (neg:DI (match_operand:DI 1 "general_operand" "")))
9447    (clobber (reg:CC FLAGS_REG))]
9448   "!TARGET_64BIT && reload_completed"
9449   [(parallel
9450     [(set (reg:CCZ FLAGS_REG)
9451           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9452      (set (match_dup 0) (neg:SI (match_dup 2)))])
9453    (parallel
9454     [(set (match_dup 1)
9455           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9456                             (match_dup 3))
9457                    (const_int 0)))
9458      (clobber (reg:CC FLAGS_REG))])
9459    (parallel
9460     [(set (match_dup 1)
9461           (neg:SI (match_dup 1)))
9462      (clobber (reg:CC FLAGS_REG))])]
9463   "split_di (operands+1, 1, operands+2, operands+3);
9464    split_di (operands+0, 1, operands+0, operands+1);")
9466 (define_insn "*negdi2_1_rex64"
9467   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9468         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9469    (clobber (reg:CC FLAGS_REG))]
9470   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9471   "neg{q}\t%0"
9472   [(set_attr "type" "negnot")
9473    (set_attr "mode" "DI")])
9475 ;; The problem with neg is that it does not perform (compare x 0),
9476 ;; it really performs (compare 0 x), which leaves us with the zero
9477 ;; flag being the only useful item.
9479 (define_insn "*negdi2_cmpz_rex64"
9480   [(set (reg:CCZ FLAGS_REG)
9481         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9482                      (const_int 0)))
9483    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9484         (neg:DI (match_dup 1)))]
9485   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9486   "neg{q}\t%0"
9487   [(set_attr "type" "negnot")
9488    (set_attr "mode" "DI")])
9491 (define_expand "negsi2"
9492   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9493                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9494               (clobber (reg:CC FLAGS_REG))])]
9495   ""
9496   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9498 (define_insn "*negsi2_1"
9499   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9500         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9501    (clobber (reg:CC FLAGS_REG))]
9502   "ix86_unary_operator_ok (NEG, SImode, operands)"
9503   "neg{l}\t%0"
9504   [(set_attr "type" "negnot")
9505    (set_attr "mode" "SI")])
9507 ;; Combine is quite creative about this pattern.
9508 (define_insn "*negsi2_1_zext"
9509   [(set (match_operand:DI 0 "register_operand" "=r")
9510         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9511                                         (const_int 32)))
9512                      (const_int 32)))
9513    (clobber (reg:CC FLAGS_REG))]
9514   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9515   "neg{l}\t%k0"
9516   [(set_attr "type" "negnot")
9517    (set_attr "mode" "SI")])
9519 ;; The problem with neg is that it does not perform (compare x 0),
9520 ;; it really performs (compare 0 x), which leaves us with the zero
9521 ;; flag being the only useful item.
9523 (define_insn "*negsi2_cmpz"
9524   [(set (reg:CCZ FLAGS_REG)
9525         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9526                      (const_int 0)))
9527    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9528         (neg:SI (match_dup 1)))]
9529   "ix86_unary_operator_ok (NEG, SImode, operands)"
9530   "neg{l}\t%0"
9531   [(set_attr "type" "negnot")
9532    (set_attr "mode" "SI")])
9534 (define_insn "*negsi2_cmpz_zext"
9535   [(set (reg:CCZ FLAGS_REG)
9536         (compare:CCZ (lshiftrt:DI
9537                        (neg:DI (ashift:DI
9538                                  (match_operand:DI 1 "register_operand" "0")
9539                                  (const_int 32)))
9540                        (const_int 32))
9541                      (const_int 0)))
9542    (set (match_operand:DI 0 "register_operand" "=r")
9543         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9544                                         (const_int 32)))
9545                      (const_int 32)))]
9546   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9547   "neg{l}\t%k0"
9548   [(set_attr "type" "negnot")
9549    (set_attr "mode" "SI")])
9551 (define_expand "neghi2"
9552   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9553                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9554               (clobber (reg:CC FLAGS_REG))])]
9555   "TARGET_HIMODE_MATH"
9556   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9558 (define_insn "*neghi2_1"
9559   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9560         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9561    (clobber (reg:CC FLAGS_REG))]
9562   "ix86_unary_operator_ok (NEG, HImode, operands)"
9563   "neg{w}\t%0"
9564   [(set_attr "type" "negnot")
9565    (set_attr "mode" "HI")])
9567 (define_insn "*neghi2_cmpz"
9568   [(set (reg:CCZ FLAGS_REG)
9569         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9570                      (const_int 0)))
9571    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9572         (neg:HI (match_dup 1)))]
9573   "ix86_unary_operator_ok (NEG, HImode, operands)"
9574   "neg{w}\t%0"
9575   [(set_attr "type" "negnot")
9576    (set_attr "mode" "HI")])
9578 (define_expand "negqi2"
9579   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9580                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9581               (clobber (reg:CC FLAGS_REG))])]
9582   "TARGET_QIMODE_MATH"
9583   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9585 (define_insn "*negqi2_1"
9586   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9587         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9588    (clobber (reg:CC FLAGS_REG))]
9589   "ix86_unary_operator_ok (NEG, QImode, operands)"
9590   "neg{b}\t%0"
9591   [(set_attr "type" "negnot")
9592    (set_attr "mode" "QI")])
9594 (define_insn "*negqi2_cmpz"
9595   [(set (reg:CCZ FLAGS_REG)
9596         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9597                      (const_int 0)))
9598    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9599         (neg:QI (match_dup 1)))]
9600   "ix86_unary_operator_ok (NEG, QImode, operands)"
9601   "neg{b}\t%0"
9602   [(set_attr "type" "negnot")
9603    (set_attr "mode" "QI")])
9605 ;; Changing of sign for FP values is doable using integer unit too.
9607 (define_expand "negsf2"
9608   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9609         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9610   "TARGET_80387 || TARGET_SSE_MATH"
9611   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9613 (define_expand "abssf2"
9614   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9615         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9616   "TARGET_80387 || TARGET_SSE_MATH"
9617   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9619 (define_insn "*absnegsf2_mixed"
9620   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9621         (match_operator:SF 3 "absneg_operator"
9622           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9623    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9624    (clobber (reg:CC FLAGS_REG))]
9625   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9626    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9627   "#")
9629 (define_insn "*absnegsf2_sse"
9630   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9631         (match_operator:SF 3 "absneg_operator"
9632           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9633    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9634    (clobber (reg:CC FLAGS_REG))]
9635   "TARGET_SSE_MATH
9636    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9637   "#")
9639 (define_insn "*absnegsf2_i387"
9640   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9641         (match_operator:SF 3 "absneg_operator"
9642           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9643    (use (match_operand 2 "" ""))
9644    (clobber (reg:CC FLAGS_REG))]
9645   "TARGET_80387 && !TARGET_SSE_MATH
9646    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9647   "#")
9649 (define_expand "copysignsf3"
9650   [(match_operand:SF 0 "register_operand" "")
9651    (match_operand:SF 1 "nonmemory_operand" "")
9652    (match_operand:SF 2 "register_operand" "")]
9653   "TARGET_SSE_MATH"
9655   ix86_expand_copysign (operands);
9656   DONE;
9659 (define_insn_and_split "copysignsf3_const"
9660   [(set (match_operand:SF 0 "register_operand"          "=x")
9661         (unspec:SF
9662           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9663            (match_operand:SF 2 "register_operand"       "0")
9664            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9665           UNSPEC_COPYSIGN))]
9666   "TARGET_SSE_MATH"
9667   "#"
9668   "&& reload_completed"
9669   [(const_int 0)]
9671   ix86_split_copysign_const (operands);
9672   DONE;
9675 (define_insn "copysignsf3_var"
9676   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9677         (unspec:SF
9678           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9679            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9680            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9681            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9682           UNSPEC_COPYSIGN))
9683    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9684   "TARGET_SSE_MATH"
9685   "#")
9687 (define_split
9688   [(set (match_operand:SF 0 "register_operand" "")
9689         (unspec:SF
9690           [(match_operand:SF 2 "register_operand" "")
9691            (match_operand:SF 3 "register_operand" "")
9692            (match_operand:V4SF 4 "" "")
9693            (match_operand:V4SF 5 "" "")]
9694           UNSPEC_COPYSIGN))
9695    (clobber (match_scratch:V4SF 1 ""))]
9696   "TARGET_SSE_MATH && reload_completed"
9697   [(const_int 0)]
9699   ix86_split_copysign_var (operands);
9700   DONE;
9703 (define_expand "negdf2"
9704   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9705         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9706   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9707   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9709 (define_expand "absdf2"
9710   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9711         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9712   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9713   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9715 (define_insn "*absnegdf2_mixed"
9716   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9717         (match_operator:DF 3 "absneg_operator"
9718           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9719    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9720    (clobber (reg:CC FLAGS_REG))]
9721   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9722    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9723   "#")
9725 (define_insn "*absnegdf2_sse"
9726   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9727         (match_operator:DF 3 "absneg_operator"
9728           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9729    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9730    (clobber (reg:CC FLAGS_REG))]
9731   "TARGET_SSE2 && TARGET_SSE_MATH
9732    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9733   "#")
9735 (define_insn "*absnegdf2_i387"
9736   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9737         (match_operator:DF 3 "absneg_operator"
9738           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9739    (use (match_operand 2 "" ""))
9740    (clobber (reg:CC FLAGS_REG))]
9741   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9742    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9743   "#")
9745 (define_expand "copysigndf3"
9746   [(match_operand:DF 0 "register_operand" "")
9747    (match_operand:DF 1 "nonmemory_operand" "")
9748    (match_operand:DF 2 "register_operand" "")]
9749   "TARGET_SSE2 && TARGET_SSE_MATH"
9751   ix86_expand_copysign (operands);
9752   DONE;
9755 (define_insn_and_split "copysigndf3_const"
9756   [(set (match_operand:DF 0 "register_operand"          "=x")
9757         (unspec:DF
9758           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9759            (match_operand:DF 2 "register_operand"       "0")
9760            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9761           UNSPEC_COPYSIGN))]
9762   "TARGET_SSE2 && TARGET_SSE_MATH"
9763   "#"
9764   "&& reload_completed"
9765   [(const_int 0)]
9767   ix86_split_copysign_const (operands);
9768   DONE;
9771 (define_insn "copysigndf3_var"
9772   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9773         (unspec:DF
9774           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9775            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9776            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9777            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9778           UNSPEC_COPYSIGN))
9779    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9780   "TARGET_SSE2 && TARGET_SSE_MATH"
9781   "#")
9783 (define_split
9784   [(set (match_operand:DF 0 "register_operand" "")
9785         (unspec:DF
9786           [(match_operand:DF 2 "register_operand" "")
9787            (match_operand:DF 3 "register_operand" "")
9788            (match_operand:V2DF 4 "" "")
9789            (match_operand:V2DF 5 "" "")]
9790           UNSPEC_COPYSIGN))
9791    (clobber (match_scratch:V2DF 1 ""))]
9792   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9793   [(const_int 0)]
9795   ix86_split_copysign_var (operands);
9796   DONE;
9799 (define_expand "negxf2"
9800   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9801         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9802   "TARGET_80387"
9803   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9805 (define_expand "absxf2"
9806   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9807         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9808   "TARGET_80387"
9809   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9811 (define_insn "*absnegxf2_i387"
9812   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9813         (match_operator:XF 3 "absneg_operator"
9814           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9815    (use (match_operand 2 "" ""))
9816    (clobber (reg:CC FLAGS_REG))]
9817   "TARGET_80387
9818    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9819   "#")
9821 ;; Splitters for fp abs and neg.
9823 (define_split
9824   [(set (match_operand 0 "fp_register_operand" "")
9825         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9826    (use (match_operand 2 "" ""))
9827    (clobber (reg:CC FLAGS_REG))]
9828   "reload_completed"
9829   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9831 (define_split
9832   [(set (match_operand 0 "register_operand" "")
9833         (match_operator 3 "absneg_operator"
9834           [(match_operand 1 "register_operand" "")]))
9835    (use (match_operand 2 "nonimmediate_operand" ""))
9836    (clobber (reg:CC FLAGS_REG))]
9837   "reload_completed && SSE_REG_P (operands[0])"
9838   [(set (match_dup 0) (match_dup 3))]
9840   enum machine_mode mode = GET_MODE (operands[0]);
9841   enum machine_mode vmode = GET_MODE (operands[2]);
9842   rtx tmp;
9844   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9845   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9846   if (operands_match_p (operands[0], operands[2]))
9847     {
9848       tmp = operands[1];
9849       operands[1] = operands[2];
9850       operands[2] = tmp;
9851     }
9852   if (GET_CODE (operands[3]) == ABS)
9853     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9854   else
9855     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9856   operands[3] = tmp;
9859 (define_split
9860   [(set (match_operand:SF 0 "register_operand" "")
9861         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9862    (use (match_operand:V4SF 2 "" ""))
9863    (clobber (reg:CC FLAGS_REG))]
9864   "reload_completed"
9865   [(parallel [(set (match_dup 0) (match_dup 1))
9866               (clobber (reg:CC FLAGS_REG))])]
9868   rtx tmp;
9869   operands[0] = gen_lowpart (SImode, operands[0]);
9870   if (GET_CODE (operands[1]) == ABS)
9871     {
9872       tmp = gen_int_mode (0x7fffffff, SImode);
9873       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9874     }
9875   else
9876     {
9877       tmp = gen_int_mode (0x80000000, SImode);
9878       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9879     }
9880   operands[1] = tmp;
9883 (define_split
9884   [(set (match_operand:DF 0 "register_operand" "")
9885         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9886    (use (match_operand 2 "" ""))
9887    (clobber (reg:CC FLAGS_REG))]
9888   "reload_completed"
9889   [(parallel [(set (match_dup 0) (match_dup 1))
9890               (clobber (reg:CC FLAGS_REG))])]
9892   rtx tmp;
9893   if (TARGET_64BIT)
9894     {
9895       tmp = gen_lowpart (DImode, operands[0]);
9896       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9897       operands[0] = tmp;
9899       if (GET_CODE (operands[1]) == ABS)
9900         tmp = const0_rtx;
9901       else
9902         tmp = gen_rtx_NOT (DImode, tmp);
9903     }
9904   else
9905     {
9906       operands[0] = gen_highpart (SImode, operands[0]);
9907       if (GET_CODE (operands[1]) == ABS)
9908         {
9909           tmp = gen_int_mode (0x7fffffff, SImode);
9910           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9911         }
9912       else
9913         {
9914           tmp = gen_int_mode (0x80000000, SImode);
9915           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9916         }
9917     }
9918   operands[1] = tmp;
9921 (define_split
9922   [(set (match_operand:XF 0 "register_operand" "")
9923         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9924    (use (match_operand 2 "" ""))
9925    (clobber (reg:CC FLAGS_REG))]
9926   "reload_completed"
9927   [(parallel [(set (match_dup 0) (match_dup 1))
9928               (clobber (reg:CC FLAGS_REG))])]
9930   rtx tmp;
9931   operands[0] = gen_rtx_REG (SImode,
9932                              true_regnum (operands[0])
9933                              + (TARGET_64BIT ? 1 : 2));
9934   if (GET_CODE (operands[1]) == ABS)
9935     {
9936       tmp = GEN_INT (0x7fff);
9937       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9938     }
9939   else
9940     {
9941       tmp = GEN_INT (0x8000);
9942       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9943     }
9944   operands[1] = tmp;
9947 (define_split
9948   [(set (match_operand 0 "memory_operand" "")
9949         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9950    (use (match_operand 2 "" ""))
9951    (clobber (reg:CC FLAGS_REG))]
9952   "reload_completed"
9953   [(parallel [(set (match_dup 0) (match_dup 1))
9954               (clobber (reg:CC FLAGS_REG))])]
9956   enum machine_mode mode = GET_MODE (operands[0]);
9957   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9958   rtx tmp;
9960   operands[0] = adjust_address (operands[0], QImode, size - 1);
9961   if (GET_CODE (operands[1]) == ABS)
9962     {
9963       tmp = gen_int_mode (0x7f, QImode);
9964       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9965     }
9966   else
9967     {
9968       tmp = gen_int_mode (0x80, QImode);
9969       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9970     }
9971   operands[1] = tmp;
9974 ;; Conditionalize these after reload. If they match before reload, we
9975 ;; lose the clobber and ability to use integer instructions.
9977 (define_insn "*negsf2_1"
9978   [(set (match_operand:SF 0 "register_operand" "=f")
9979         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9980   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9981   "fchs"
9982   [(set_attr "type" "fsgn")
9983    (set_attr "mode" "SF")])
9985 (define_insn "*negdf2_1"
9986   [(set (match_operand:DF 0 "register_operand" "=f")
9987         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9988   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9989   "fchs"
9990   [(set_attr "type" "fsgn")
9991    (set_attr "mode" "DF")])
9993 (define_insn "*negxf2_1"
9994   [(set (match_operand:XF 0 "register_operand" "=f")
9995         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9996   "TARGET_80387"
9997   "fchs"
9998   [(set_attr "type" "fsgn")
9999    (set_attr "mode" "XF")])
10001 (define_insn "*abssf2_1"
10002   [(set (match_operand:SF 0 "register_operand" "=f")
10003         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10004   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10005   "fabs"
10006   [(set_attr "type" "fsgn")
10007    (set_attr "mode" "SF")])
10009 (define_insn "*absdf2_1"
10010   [(set (match_operand:DF 0 "register_operand" "=f")
10011         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10012   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10013   "fabs"
10014   [(set_attr "type" "fsgn")
10015    (set_attr "mode" "DF")])
10017 (define_insn "*absxf2_1"
10018   [(set (match_operand:XF 0 "register_operand" "=f")
10019         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10020   "TARGET_80387"
10021   "fabs"
10022   [(set_attr "type" "fsgn")
10023    (set_attr "mode" "DF")])
10025 (define_insn "*negextendsfdf2"
10026   [(set (match_operand:DF 0 "register_operand" "=f")
10027         (neg:DF (float_extend:DF
10028                   (match_operand:SF 1 "register_operand" "0"))))]
10029   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10030   "fchs"
10031   [(set_attr "type" "fsgn")
10032    (set_attr "mode" "DF")])
10034 (define_insn "*negextenddfxf2"
10035   [(set (match_operand:XF 0 "register_operand" "=f")
10036         (neg:XF (float_extend:XF
10037                   (match_operand:DF 1 "register_operand" "0"))))]
10038   "TARGET_80387"
10039   "fchs"
10040   [(set_attr "type" "fsgn")
10041    (set_attr "mode" "XF")])
10043 (define_insn "*negextendsfxf2"
10044   [(set (match_operand:XF 0 "register_operand" "=f")
10045         (neg:XF (float_extend:XF
10046                   (match_operand:SF 1 "register_operand" "0"))))]
10047   "TARGET_80387"
10048   "fchs"
10049   [(set_attr "type" "fsgn")
10050    (set_attr "mode" "XF")])
10052 (define_insn "*absextendsfdf2"
10053   [(set (match_operand:DF 0 "register_operand" "=f")
10054         (abs:DF (float_extend:DF
10055                   (match_operand:SF 1 "register_operand" "0"))))]
10056   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10057   "fabs"
10058   [(set_attr "type" "fsgn")
10059    (set_attr "mode" "DF")])
10061 (define_insn "*absextenddfxf2"
10062   [(set (match_operand:XF 0 "register_operand" "=f")
10063         (abs:XF (float_extend:XF
10064           (match_operand:DF 1 "register_operand" "0"))))]
10065   "TARGET_80387"
10066   "fabs"
10067   [(set_attr "type" "fsgn")
10068    (set_attr "mode" "XF")])
10070 (define_insn "*absextendsfxf2"
10071   [(set (match_operand:XF 0 "register_operand" "=f")
10072         (abs:XF (float_extend:XF
10073           (match_operand:SF 1 "register_operand" "0"))))]
10074   "TARGET_80387"
10075   "fabs"
10076   [(set_attr "type" "fsgn")
10077    (set_attr "mode" "XF")])
10079 ;; One complement instructions
10081 (define_expand "one_cmpldi2"
10082   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10083         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10084   "TARGET_64BIT"
10085   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10087 (define_insn "*one_cmpldi2_1_rex64"
10088   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10089         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10090   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10091   "not{q}\t%0"
10092   [(set_attr "type" "negnot")
10093    (set_attr "mode" "DI")])
10095 (define_insn "*one_cmpldi2_2_rex64"
10096   [(set (reg FLAGS_REG)
10097         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10098                  (const_int 0)))
10099    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10100         (not:DI (match_dup 1)))]
10101   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10102    && ix86_unary_operator_ok (NOT, DImode, operands)"
10103   "#"
10104   [(set_attr "type" "alu1")
10105    (set_attr "mode" "DI")])
10107 (define_split
10108   [(set (match_operand 0 "flags_reg_operand" "")
10109         (match_operator 2 "compare_operator"
10110           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10111            (const_int 0)]))
10112    (set (match_operand:DI 1 "nonimmediate_operand" "")
10113         (not:DI (match_dup 3)))]
10114   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10115   [(parallel [(set (match_dup 0)
10116                    (match_op_dup 2
10117                      [(xor:DI (match_dup 3) (const_int -1))
10118                       (const_int 0)]))
10119               (set (match_dup 1)
10120                    (xor:DI (match_dup 3) (const_int -1)))])]
10121   "")
10123 (define_expand "one_cmplsi2"
10124   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10125         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10126   ""
10127   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10129 (define_insn "*one_cmplsi2_1"
10130   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10131         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10132   "ix86_unary_operator_ok (NOT, SImode, operands)"
10133   "not{l}\t%0"
10134   [(set_attr "type" "negnot")
10135    (set_attr "mode" "SI")])
10137 ;; ??? Currently never generated - xor is used instead.
10138 (define_insn "*one_cmplsi2_1_zext"
10139   [(set (match_operand:DI 0 "register_operand" "=r")
10140         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10141   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10142   "not{l}\t%k0"
10143   [(set_attr "type" "negnot")
10144    (set_attr "mode" "SI")])
10146 (define_insn "*one_cmplsi2_2"
10147   [(set (reg FLAGS_REG)
10148         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10149                  (const_int 0)))
10150    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10151         (not:SI (match_dup 1)))]
10152   "ix86_match_ccmode (insn, CCNOmode)
10153    && ix86_unary_operator_ok (NOT, SImode, operands)"
10154   "#"
10155   [(set_attr "type" "alu1")
10156    (set_attr "mode" "SI")])
10158 (define_split
10159   [(set (match_operand 0 "flags_reg_operand" "")
10160         (match_operator 2 "compare_operator"
10161           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10162            (const_int 0)]))
10163    (set (match_operand:SI 1 "nonimmediate_operand" "")
10164         (not:SI (match_dup 3)))]
10165   "ix86_match_ccmode (insn, CCNOmode)"
10166   [(parallel [(set (match_dup 0)
10167                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10168                                     (const_int 0)]))
10169               (set (match_dup 1)
10170                    (xor:SI (match_dup 3) (const_int -1)))])]
10171   "")
10173 ;; ??? Currently never generated - xor is used instead.
10174 (define_insn "*one_cmplsi2_2_zext"
10175   [(set (reg FLAGS_REG)
10176         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10177                  (const_int 0)))
10178    (set (match_operand:DI 0 "register_operand" "=r")
10179         (zero_extend:DI (not:SI (match_dup 1))))]
10180   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10181    && ix86_unary_operator_ok (NOT, SImode, operands)"
10182   "#"
10183   [(set_attr "type" "alu1")
10184    (set_attr "mode" "SI")])
10186 (define_split
10187   [(set (match_operand 0 "flags_reg_operand" "")
10188         (match_operator 2 "compare_operator"
10189           [(not:SI (match_operand:SI 3 "register_operand" ""))
10190            (const_int 0)]))
10191    (set (match_operand:DI 1 "register_operand" "")
10192         (zero_extend:DI (not:SI (match_dup 3))))]
10193   "ix86_match_ccmode (insn, CCNOmode)"
10194   [(parallel [(set (match_dup 0)
10195                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10196                                     (const_int 0)]))
10197               (set (match_dup 1)
10198                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10199   "")
10201 (define_expand "one_cmplhi2"
10202   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10203         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10204   "TARGET_HIMODE_MATH"
10205   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10207 (define_insn "*one_cmplhi2_1"
10208   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10209         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10210   "ix86_unary_operator_ok (NOT, HImode, operands)"
10211   "not{w}\t%0"
10212   [(set_attr "type" "negnot")
10213    (set_attr "mode" "HI")])
10215 (define_insn "*one_cmplhi2_2"
10216   [(set (reg FLAGS_REG)
10217         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10218                  (const_int 0)))
10219    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10220         (not:HI (match_dup 1)))]
10221   "ix86_match_ccmode (insn, CCNOmode)
10222    && ix86_unary_operator_ok (NEG, HImode, operands)"
10223   "#"
10224   [(set_attr "type" "alu1")
10225    (set_attr "mode" "HI")])
10227 (define_split
10228   [(set (match_operand 0 "flags_reg_operand" "")
10229         (match_operator 2 "compare_operator"
10230           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10231            (const_int 0)]))
10232    (set (match_operand:HI 1 "nonimmediate_operand" "")
10233         (not:HI (match_dup 3)))]
10234   "ix86_match_ccmode (insn, CCNOmode)"
10235   [(parallel [(set (match_dup 0)
10236                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10237                                     (const_int 0)]))
10238               (set (match_dup 1)
10239                    (xor:HI (match_dup 3) (const_int -1)))])]
10240   "")
10242 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10243 (define_expand "one_cmplqi2"
10244   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10245         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10246   "TARGET_QIMODE_MATH"
10247   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10249 (define_insn "*one_cmplqi2_1"
10250   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10251         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10252   "ix86_unary_operator_ok (NOT, QImode, operands)"
10253   "@
10254    not{b}\t%0
10255    not{l}\t%k0"
10256   [(set_attr "type" "negnot")
10257    (set_attr "mode" "QI,SI")])
10259 (define_insn "*one_cmplqi2_2"
10260   [(set (reg FLAGS_REG)
10261         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10262                  (const_int 0)))
10263    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10264         (not:QI (match_dup 1)))]
10265   "ix86_match_ccmode (insn, CCNOmode)
10266    && ix86_unary_operator_ok (NOT, QImode, operands)"
10267   "#"
10268   [(set_attr "type" "alu1")
10269    (set_attr "mode" "QI")])
10271 (define_split
10272   [(set (match_operand 0 "flags_reg_operand" "")
10273         (match_operator 2 "compare_operator"
10274           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10275            (const_int 0)]))
10276    (set (match_operand:QI 1 "nonimmediate_operand" "")
10277         (not:QI (match_dup 3)))]
10278   "ix86_match_ccmode (insn, CCNOmode)"
10279   [(parallel [(set (match_dup 0)
10280                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10281                                     (const_int 0)]))
10282               (set (match_dup 1)
10283                    (xor:QI (match_dup 3) (const_int -1)))])]
10284   "")
10286 ;; Arithmetic shift instructions
10288 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10289 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10290 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10291 ;; from the assembler input.
10293 ;; This instruction shifts the target reg/mem as usual, but instead of
10294 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10295 ;; is a left shift double, bits are taken from the high order bits of
10296 ;; reg, else if the insn is a shift right double, bits are taken from the
10297 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10298 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10300 ;; Since sh[lr]d does not change the `reg' operand, that is done
10301 ;; separately, making all shifts emit pairs of shift double and normal
10302 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10303 ;; support a 63 bit shift, each shift where the count is in a reg expands
10304 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10306 ;; If the shift count is a constant, we need never emit more than one
10307 ;; shift pair, instead using moves and sign extension for counts greater
10308 ;; than 31.
10310 (define_expand "ashlti3"
10311   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10312                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10313                               (match_operand:QI 2 "nonmemory_operand" "")))
10314               (clobber (reg:CC FLAGS_REG))])]
10315   "TARGET_64BIT"
10317   if (! immediate_operand (operands[2], QImode))
10318     {
10319       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10320       DONE;
10321     }
10322   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10323   DONE;
10326 (define_insn "ashlti3_1"
10327   [(set (match_operand:TI 0 "register_operand" "=r")
10328         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10329                    (match_operand:QI 2 "register_operand" "c")))
10330    (clobber (match_scratch:DI 3 "=&r"))
10331    (clobber (reg:CC FLAGS_REG))]
10332   "TARGET_64BIT"
10333   "#"
10334   [(set_attr "type" "multi")])
10336 (define_insn "*ashlti3_2"
10337   [(set (match_operand:TI 0 "register_operand" "=r")
10338         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10339                    (match_operand:QI 2 "immediate_operand" "O")))
10340    (clobber (reg:CC FLAGS_REG))]
10341   "TARGET_64BIT"
10342   "#"
10343   [(set_attr "type" "multi")])
10345 (define_split
10346   [(set (match_operand:TI 0 "register_operand" "")
10347         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10348                    (match_operand:QI 2 "register_operand" "")))
10349    (clobber (match_scratch:DI 3 ""))
10350    (clobber (reg:CC FLAGS_REG))]
10351   "TARGET_64BIT && reload_completed"
10352   [(const_int 0)]
10353   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10355 (define_split
10356   [(set (match_operand:TI 0 "register_operand" "")
10357         (ashift:TI (match_operand:TI 1 "register_operand" "")
10358                    (match_operand:QI 2 "immediate_operand" "")))
10359    (clobber (reg:CC FLAGS_REG))]
10360   "TARGET_64BIT && reload_completed"
10361   [(const_int 0)]
10362   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10364 (define_insn "x86_64_shld"
10365   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10366         (ior:DI (ashift:DI (match_dup 0)
10367                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10368                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10369                   (minus:QI (const_int 64) (match_dup 2)))))
10370    (clobber (reg:CC FLAGS_REG))]
10371   "TARGET_64BIT"
10372   "@
10373    shld{q}\t{%2, %1, %0|%0, %1, %2}
10374    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10375   [(set_attr "type" "ishift")
10376    (set_attr "prefix_0f" "1")
10377    (set_attr "mode" "DI")
10378    (set_attr "athlon_decode" "vector")])
10380 (define_expand "x86_64_shift_adj"
10381   [(set (reg:CCZ FLAGS_REG)
10382         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10383                              (const_int 64))
10384                      (const_int 0)))
10385    (set (match_operand:DI 0 "register_operand" "")
10386         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10387                          (match_operand:DI 1 "register_operand" "")
10388                          (match_dup 0)))
10389    (set (match_dup 1)
10390         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10391                          (match_operand:DI 3 "register_operand" "r")
10392                          (match_dup 1)))]
10393   "TARGET_64BIT"
10394   "")
10396 (define_expand "ashldi3"
10397   [(set (match_operand:DI 0 "shiftdi_operand" "")
10398         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10399                    (match_operand:QI 2 "nonmemory_operand" "")))]
10400   ""
10401   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10403 (define_insn "*ashldi3_1_rex64"
10404   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10405         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10406                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10407    (clobber (reg:CC FLAGS_REG))]
10408   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10410   switch (get_attr_type (insn))
10411     {
10412     case TYPE_ALU:
10413       gcc_assert (operands[2] == const1_rtx);
10414       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10415       return "add{q}\t{%0, %0|%0, %0}";
10417     case TYPE_LEA:
10418       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10419       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10420       operands[1] = gen_rtx_MULT (DImode, operands[1],
10421                                   GEN_INT (1 << INTVAL (operands[2])));
10422       return "lea{q}\t{%a1, %0|%0, %a1}";
10424     default:
10425       if (REG_P (operands[2]))
10426         return "sal{q}\t{%b2, %0|%0, %b2}";
10427       else if (operands[2] == const1_rtx
10428                && (TARGET_SHIFT1 || optimize_size))
10429         return "sal{q}\t%0";
10430       else
10431         return "sal{q}\t{%2, %0|%0, %2}";
10432     }
10434   [(set (attr "type")
10435      (cond [(eq_attr "alternative" "1")
10436               (const_string "lea")
10437             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10438                           (const_int 0))
10439                       (match_operand 0 "register_operand" ""))
10440                  (match_operand 2 "const1_operand" ""))
10441               (const_string "alu")
10442            ]
10443            (const_string "ishift")))
10444    (set_attr "mode" "DI")])
10446 ;; Convert lea to the lea pattern to avoid flags dependency.
10447 (define_split
10448   [(set (match_operand:DI 0 "register_operand" "")
10449         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10450                    (match_operand:QI 2 "immediate_operand" "")))
10451    (clobber (reg:CC FLAGS_REG))]
10452   "TARGET_64BIT && reload_completed
10453    && true_regnum (operands[0]) != true_regnum (operands[1])"
10454   [(set (match_dup 0)
10455         (mult:DI (match_dup 1)
10456                  (match_dup 2)))]
10457   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10459 ;; This pattern can't accept a variable shift count, since shifts by
10460 ;; zero don't affect the flags.  We assume that shifts by constant
10461 ;; zero are optimized away.
10462 (define_insn "*ashldi3_cmp_rex64"
10463   [(set (reg FLAGS_REG)
10464         (compare
10465           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10466                      (match_operand:QI 2 "immediate_operand" "e"))
10467           (const_int 0)))
10468    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10469         (ashift:DI (match_dup 1) (match_dup 2)))]
10470   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10471    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10472    && (optimize_size
10473        || !TARGET_PARTIAL_FLAG_REG_STALL
10474        || (operands[2] == const1_rtx
10475            && (TARGET_SHIFT1
10476                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10478   switch (get_attr_type (insn))
10479     {
10480     case TYPE_ALU:
10481       gcc_assert (operands[2] == const1_rtx);
10482       return "add{q}\t{%0, %0|%0, %0}";
10484     default:
10485       if (REG_P (operands[2]))
10486         return "sal{q}\t{%b2, %0|%0, %b2}";
10487       else if (operands[2] == const1_rtx
10488                && (TARGET_SHIFT1 || optimize_size))
10489         return "sal{q}\t%0";
10490       else
10491         return "sal{q}\t{%2, %0|%0, %2}";
10492     }
10494   [(set (attr "type")
10495      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10496                           (const_int 0))
10497                       (match_operand 0 "register_operand" ""))
10498                  (match_operand 2 "const1_operand" ""))
10499               (const_string "alu")
10500            ]
10501            (const_string "ishift")))
10502    (set_attr "mode" "DI")])
10504 (define_insn "*ashldi3_cconly_rex64"
10505   [(set (reg FLAGS_REG)
10506         (compare
10507           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10508                      (match_operand:QI 2 "immediate_operand" "e"))
10509           (const_int 0)))
10510    (clobber (match_scratch:DI 0 "=r"))]
10511   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10512    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10513    && (optimize_size
10514        || !TARGET_PARTIAL_FLAG_REG_STALL
10515        || (operands[2] == const1_rtx
10516            && (TARGET_SHIFT1
10517                || TARGET_DOUBLE_WITH_ADD)))"
10519   switch (get_attr_type (insn))
10520     {
10521     case TYPE_ALU:
10522       gcc_assert (operands[2] == const1_rtx);
10523       return "add{q}\t{%0, %0|%0, %0}";
10525     default:
10526       if (REG_P (operands[2]))
10527         return "sal{q}\t{%b2, %0|%0, %b2}";
10528       else if (operands[2] == const1_rtx
10529                && (TARGET_SHIFT1 || optimize_size))
10530         return "sal{q}\t%0";
10531       else
10532         return "sal{q}\t{%2, %0|%0, %2}";
10533     }
10535   [(set (attr "type")
10536      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10537                           (const_int 0))
10538                       (match_operand 0 "register_operand" ""))
10539                  (match_operand 2 "const1_operand" ""))
10540               (const_string "alu")
10541            ]
10542            (const_string "ishift")))
10543    (set_attr "mode" "DI")])
10545 (define_insn "*ashldi3_1"
10546   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10547         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10548                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10549    (clobber (reg:CC FLAGS_REG))]
10550   "!TARGET_64BIT"
10551   "#"
10552   [(set_attr "type" "multi")])
10554 ;; By default we don't ask for a scratch register, because when DImode
10555 ;; values are manipulated, registers are already at a premium.  But if
10556 ;; we have one handy, we won't turn it away.
10557 (define_peephole2
10558   [(match_scratch:SI 3 "r")
10559    (parallel [(set (match_operand:DI 0 "register_operand" "")
10560                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10561                               (match_operand:QI 2 "nonmemory_operand" "")))
10562               (clobber (reg:CC FLAGS_REG))])
10563    (match_dup 3)]
10564   "!TARGET_64BIT && TARGET_CMOVE"
10565   [(const_int 0)]
10566   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10568 (define_split
10569   [(set (match_operand:DI 0 "register_operand" "")
10570         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10571                    (match_operand:QI 2 "nonmemory_operand" "")))
10572    (clobber (reg:CC FLAGS_REG))]
10573   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10574                      ? flow2_completed : reload_completed)"
10575   [(const_int 0)]
10576   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10578 (define_insn "x86_shld_1"
10579   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10580         (ior:SI (ashift:SI (match_dup 0)
10581                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10582                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10583                   (minus:QI (const_int 32) (match_dup 2)))))
10584    (clobber (reg:CC FLAGS_REG))]
10585   ""
10586   "@
10587    shld{l}\t{%2, %1, %0|%0, %1, %2}
10588    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10589   [(set_attr "type" "ishift")
10590    (set_attr "prefix_0f" "1")
10591    (set_attr "mode" "SI")
10592    (set_attr "pent_pair" "np")
10593    (set_attr "athlon_decode" "vector")])
10595 (define_expand "x86_shift_adj_1"
10596   [(set (reg:CCZ FLAGS_REG)
10597         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10598                              (const_int 32))
10599                      (const_int 0)))
10600    (set (match_operand:SI 0 "register_operand" "")
10601         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10602                          (match_operand:SI 1 "register_operand" "")
10603                          (match_dup 0)))
10604    (set (match_dup 1)
10605         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10606                          (match_operand:SI 3 "register_operand" "r")
10607                          (match_dup 1)))]
10608   "TARGET_CMOVE"
10609   "")
10611 (define_expand "x86_shift_adj_2"
10612   [(use (match_operand:SI 0 "register_operand" ""))
10613    (use (match_operand:SI 1 "register_operand" ""))
10614    (use (match_operand:QI 2 "register_operand" ""))]
10615   ""
10617   rtx label = gen_label_rtx ();
10618   rtx tmp;
10620   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10622   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10623   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10624   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10625                               gen_rtx_LABEL_REF (VOIDmode, label),
10626                               pc_rtx);
10627   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10628   JUMP_LABEL (tmp) = label;
10630   emit_move_insn (operands[0], operands[1]);
10631   ix86_expand_clear (operands[1]);
10633   emit_label (label);
10634   LABEL_NUSES (label) = 1;
10636   DONE;
10639 (define_expand "ashlsi3"
10640   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10641         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10642                    (match_operand:QI 2 "nonmemory_operand" "")))
10643    (clobber (reg:CC FLAGS_REG))]
10644   ""
10645   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10647 (define_insn "*ashlsi3_1"
10648   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10649         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10650                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10651    (clobber (reg:CC FLAGS_REG))]
10652   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10654   switch (get_attr_type (insn))
10655     {
10656     case TYPE_ALU:
10657       gcc_assert (operands[2] == const1_rtx);
10658       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10659       return "add{l}\t{%0, %0|%0, %0}";
10661     case TYPE_LEA:
10662       return "#";
10664     default:
10665       if (REG_P (operands[2]))
10666         return "sal{l}\t{%b2, %0|%0, %b2}";
10667       else if (operands[2] == const1_rtx
10668                && (TARGET_SHIFT1 || optimize_size))
10669         return "sal{l}\t%0";
10670       else
10671         return "sal{l}\t{%2, %0|%0, %2}";
10672     }
10674   [(set (attr "type")
10675      (cond [(eq_attr "alternative" "1")
10676               (const_string "lea")
10677             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10678                           (const_int 0))
10679                       (match_operand 0 "register_operand" ""))
10680                  (match_operand 2 "const1_operand" ""))
10681               (const_string "alu")
10682            ]
10683            (const_string "ishift")))
10684    (set_attr "mode" "SI")])
10686 ;; Convert lea to the lea pattern to avoid flags dependency.
10687 (define_split
10688   [(set (match_operand 0 "register_operand" "")
10689         (ashift (match_operand 1 "index_register_operand" "")
10690                 (match_operand:QI 2 "const_int_operand" "")))
10691    (clobber (reg:CC FLAGS_REG))]
10692   "reload_completed
10693    && true_regnum (operands[0]) != true_regnum (operands[1])
10694    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10695   [(const_int 0)]
10697   rtx pat;
10698   enum machine_mode mode = GET_MODE (operands[0]);
10700   if (GET_MODE_SIZE (mode) < 4)
10701     operands[0] = gen_lowpart (SImode, operands[0]);
10702   if (mode != Pmode)
10703     operands[1] = gen_lowpart (Pmode, operands[1]);
10704   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10706   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10707   if (Pmode != SImode)
10708     pat = gen_rtx_SUBREG (SImode, pat, 0);
10709   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10710   DONE;
10713 ;; Rare case of shifting RSP is handled by generating move and shift
10714 (define_split
10715   [(set (match_operand 0 "register_operand" "")
10716         (ashift (match_operand 1 "register_operand" "")
10717                 (match_operand:QI 2 "const_int_operand" "")))
10718    (clobber (reg:CC FLAGS_REG))]
10719   "reload_completed
10720    && true_regnum (operands[0]) != true_regnum (operands[1])"
10721   [(const_int 0)]
10723   rtx pat, clob;
10724   emit_move_insn (operands[0], operands[1]);
10725   pat = gen_rtx_SET (VOIDmode, operands[0],
10726                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10727                                      operands[0], operands[2]));
10728   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10729   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10730   DONE;
10733 (define_insn "*ashlsi3_1_zext"
10734   [(set (match_operand:DI 0 "register_operand" "=r,r")
10735         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10736                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10737    (clobber (reg:CC FLAGS_REG))]
10738   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10740   switch (get_attr_type (insn))
10741     {
10742     case TYPE_ALU:
10743       gcc_assert (operands[2] == const1_rtx);
10744       return "add{l}\t{%k0, %k0|%k0, %k0}";
10746     case TYPE_LEA:
10747       return "#";
10749     default:
10750       if (REG_P (operands[2]))
10751         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10752       else if (operands[2] == const1_rtx
10753                && (TARGET_SHIFT1 || optimize_size))
10754         return "sal{l}\t%k0";
10755       else
10756         return "sal{l}\t{%2, %k0|%k0, %2}";
10757     }
10759   [(set (attr "type")
10760      (cond [(eq_attr "alternative" "1")
10761               (const_string "lea")
10762             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10763                      (const_int 0))
10764                  (match_operand 2 "const1_operand" ""))
10765               (const_string "alu")
10766            ]
10767            (const_string "ishift")))
10768    (set_attr "mode" "SI")])
10770 ;; Convert lea to the lea pattern to avoid flags dependency.
10771 (define_split
10772   [(set (match_operand:DI 0 "register_operand" "")
10773         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10774                                 (match_operand:QI 2 "const_int_operand" ""))))
10775    (clobber (reg:CC FLAGS_REG))]
10776   "TARGET_64BIT && reload_completed
10777    && true_regnum (operands[0]) != true_regnum (operands[1])"
10778   [(set (match_dup 0) (zero_extend:DI
10779                         (subreg:SI (mult:SI (match_dup 1)
10780                                             (match_dup 2)) 0)))]
10782   operands[1] = gen_lowpart (Pmode, operands[1]);
10783   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10786 ;; This pattern can't accept a variable shift count, since shifts by
10787 ;; zero don't affect the flags.  We assume that shifts by constant
10788 ;; zero are optimized away.
10789 (define_insn "*ashlsi3_cmp"
10790   [(set (reg FLAGS_REG)
10791         (compare
10792           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10793                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10794           (const_int 0)))
10795    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10796         (ashift:SI (match_dup 1) (match_dup 2)))]
10797   "ix86_match_ccmode (insn, CCGOCmode)
10798    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10799    && (optimize_size
10800        || !TARGET_PARTIAL_FLAG_REG_STALL
10801        || (operands[2] == const1_rtx
10802            && (TARGET_SHIFT1
10803                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10805   switch (get_attr_type (insn))
10806     {
10807     case TYPE_ALU:
10808       gcc_assert (operands[2] == const1_rtx);
10809       return "add{l}\t{%0, %0|%0, %0}";
10811     default:
10812       if (REG_P (operands[2]))
10813         return "sal{l}\t{%b2, %0|%0, %b2}";
10814       else if (operands[2] == const1_rtx
10815                && (TARGET_SHIFT1 || optimize_size))
10816         return "sal{l}\t%0";
10817       else
10818         return "sal{l}\t{%2, %0|%0, %2}";
10819     }
10821   [(set (attr "type")
10822      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10823                           (const_int 0))
10824                       (match_operand 0 "register_operand" ""))
10825                  (match_operand 2 "const1_operand" ""))
10826               (const_string "alu")
10827            ]
10828            (const_string "ishift")))
10829    (set_attr "mode" "SI")])
10831 (define_insn "*ashlsi3_cconly"
10832   [(set (reg FLAGS_REG)
10833         (compare
10834           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10835                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10836           (const_int 0)))
10837    (clobber (match_scratch:SI 0 "=r"))]
10838   "ix86_match_ccmode (insn, CCGOCmode)
10839    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10840    && (optimize_size
10841        || !TARGET_PARTIAL_FLAG_REG_STALL
10842        || (operands[2] == const1_rtx
10843            && (TARGET_SHIFT1
10844                || TARGET_DOUBLE_WITH_ADD)))"
10846   switch (get_attr_type (insn))
10847     {
10848     case TYPE_ALU:
10849       gcc_assert (operands[2] == const1_rtx);
10850       return "add{l}\t{%0, %0|%0, %0}";
10852     default:
10853       if (REG_P (operands[2]))
10854         return "sal{l}\t{%b2, %0|%0, %b2}";
10855       else if (operands[2] == const1_rtx
10856                && (TARGET_SHIFT1 || optimize_size))
10857         return "sal{l}\t%0";
10858       else
10859         return "sal{l}\t{%2, %0|%0, %2}";
10860     }
10862   [(set (attr "type")
10863      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10864                           (const_int 0))
10865                       (match_operand 0 "register_operand" ""))
10866                  (match_operand 2 "const1_operand" ""))
10867               (const_string "alu")
10868            ]
10869            (const_string "ishift")))
10870    (set_attr "mode" "SI")])
10872 (define_insn "*ashlsi3_cmp_zext"
10873   [(set (reg FLAGS_REG)
10874         (compare
10875           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10876                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10877           (const_int 0)))
10878    (set (match_operand:DI 0 "register_operand" "=r")
10879         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10880   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10881    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10882    && (optimize_size
10883        || !TARGET_PARTIAL_FLAG_REG_STALL
10884        || (operands[2] == const1_rtx
10885            && (TARGET_SHIFT1
10886                || TARGET_DOUBLE_WITH_ADD)))"
10888   switch (get_attr_type (insn))
10889     {
10890     case TYPE_ALU:
10891       gcc_assert (operands[2] == const1_rtx);
10892       return "add{l}\t{%k0, %k0|%k0, %k0}";
10894     default:
10895       if (REG_P (operands[2]))
10896         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10897       else if (operands[2] == const1_rtx
10898                && (TARGET_SHIFT1 || optimize_size))
10899         return "sal{l}\t%k0";
10900       else
10901         return "sal{l}\t{%2, %k0|%k0, %2}";
10902     }
10904   [(set (attr "type")
10905      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10906                      (const_int 0))
10907                  (match_operand 2 "const1_operand" ""))
10908               (const_string "alu")
10909            ]
10910            (const_string "ishift")))
10911    (set_attr "mode" "SI")])
10913 (define_expand "ashlhi3"
10914   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10915         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10916                    (match_operand:QI 2 "nonmemory_operand" "")))
10917    (clobber (reg:CC FLAGS_REG))]
10918   "TARGET_HIMODE_MATH"
10919   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10921 (define_insn "*ashlhi3_1_lea"
10922   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10923         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10924                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10925    (clobber (reg:CC FLAGS_REG))]
10926   "!TARGET_PARTIAL_REG_STALL
10927    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10929   switch (get_attr_type (insn))
10930     {
10931     case TYPE_LEA:
10932       return "#";
10933     case TYPE_ALU:
10934       gcc_assert (operands[2] == const1_rtx);
10935       return "add{w}\t{%0, %0|%0, %0}";
10937     default:
10938       if (REG_P (operands[2]))
10939         return "sal{w}\t{%b2, %0|%0, %b2}";
10940       else if (operands[2] == const1_rtx
10941                && (TARGET_SHIFT1 || optimize_size))
10942         return "sal{w}\t%0";
10943       else
10944         return "sal{w}\t{%2, %0|%0, %2}";
10945     }
10947   [(set (attr "type")
10948      (cond [(eq_attr "alternative" "1")
10949               (const_string "lea")
10950             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10951                           (const_int 0))
10952                       (match_operand 0 "register_operand" ""))
10953                  (match_operand 2 "const1_operand" ""))
10954               (const_string "alu")
10955            ]
10956            (const_string "ishift")))
10957    (set_attr "mode" "HI,SI")])
10959 (define_insn "*ashlhi3_1"
10960   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10961         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10962                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10963    (clobber (reg:CC FLAGS_REG))]
10964   "TARGET_PARTIAL_REG_STALL
10965    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10967   switch (get_attr_type (insn))
10968     {
10969     case TYPE_ALU:
10970       gcc_assert (operands[2] == const1_rtx);
10971       return "add{w}\t{%0, %0|%0, %0}";
10973     default:
10974       if (REG_P (operands[2]))
10975         return "sal{w}\t{%b2, %0|%0, %b2}";
10976       else if (operands[2] == const1_rtx
10977                && (TARGET_SHIFT1 || optimize_size))
10978         return "sal{w}\t%0";
10979       else
10980         return "sal{w}\t{%2, %0|%0, %2}";
10981     }
10983   [(set (attr "type")
10984      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10985                           (const_int 0))
10986                       (match_operand 0 "register_operand" ""))
10987                  (match_operand 2 "const1_operand" ""))
10988               (const_string "alu")
10989            ]
10990            (const_string "ishift")))
10991    (set_attr "mode" "HI")])
10993 ;; This pattern can't accept a variable shift count, since shifts by
10994 ;; zero don't affect the flags.  We assume that shifts by constant
10995 ;; zero are optimized away.
10996 (define_insn "*ashlhi3_cmp"
10997   [(set (reg FLAGS_REG)
10998         (compare
10999           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11000                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11001           (const_int 0)))
11002    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11003         (ashift:HI (match_dup 1) (match_dup 2)))]
11004   "ix86_match_ccmode (insn, CCGOCmode)
11005    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11006    && (optimize_size
11007        || !TARGET_PARTIAL_FLAG_REG_STALL
11008        || (operands[2] == const1_rtx
11009            && (TARGET_SHIFT1
11010                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11012   switch (get_attr_type (insn))
11013     {
11014     case TYPE_ALU:
11015       gcc_assert (operands[2] == const1_rtx);
11016       return "add{w}\t{%0, %0|%0, %0}";
11018     default:
11019       if (REG_P (operands[2]))
11020         return "sal{w}\t{%b2, %0|%0, %b2}";
11021       else if (operands[2] == const1_rtx
11022                && (TARGET_SHIFT1 || optimize_size))
11023         return "sal{w}\t%0";
11024       else
11025         return "sal{w}\t{%2, %0|%0, %2}";
11026     }
11028   [(set (attr "type")
11029      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11030                           (const_int 0))
11031                       (match_operand 0 "register_operand" ""))
11032                  (match_operand 2 "const1_operand" ""))
11033               (const_string "alu")
11034            ]
11035            (const_string "ishift")))
11036    (set_attr "mode" "HI")])
11038 (define_insn "*ashlhi3_cconly"
11039   [(set (reg FLAGS_REG)
11040         (compare
11041           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11042                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11043           (const_int 0)))
11044    (clobber (match_scratch:HI 0 "=r"))]
11045   "ix86_match_ccmode (insn, CCGOCmode)
11046    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11047    && (optimize_size
11048        || !TARGET_PARTIAL_FLAG_REG_STALL
11049        || (operands[2] == const1_rtx
11050            && (TARGET_SHIFT1
11051                || TARGET_DOUBLE_WITH_ADD)))"
11053   switch (get_attr_type (insn))
11054     {
11055     case TYPE_ALU:
11056       gcc_assert (operands[2] == const1_rtx);
11057       return "add{w}\t{%0, %0|%0, %0}";
11059     default:
11060       if (REG_P (operands[2]))
11061         return "sal{w}\t{%b2, %0|%0, %b2}";
11062       else if (operands[2] == const1_rtx
11063                && (TARGET_SHIFT1 || optimize_size))
11064         return "sal{w}\t%0";
11065       else
11066         return "sal{w}\t{%2, %0|%0, %2}";
11067     }
11069   [(set (attr "type")
11070      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11071                           (const_int 0))
11072                       (match_operand 0 "register_operand" ""))
11073                  (match_operand 2 "const1_operand" ""))
11074               (const_string "alu")
11075            ]
11076            (const_string "ishift")))
11077    (set_attr "mode" "HI")])
11079 (define_expand "ashlqi3"
11080   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11081         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11082                    (match_operand:QI 2 "nonmemory_operand" "")))
11083    (clobber (reg:CC FLAGS_REG))]
11084   "TARGET_QIMODE_MATH"
11085   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11087 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11089 (define_insn "*ashlqi3_1_lea"
11090   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11091         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11092                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11093    (clobber (reg:CC FLAGS_REG))]
11094   "!TARGET_PARTIAL_REG_STALL
11095    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11097   switch (get_attr_type (insn))
11098     {
11099     case TYPE_LEA:
11100       return "#";
11101     case TYPE_ALU:
11102       gcc_assert (operands[2] == const1_rtx);
11103       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11104         return "add{l}\t{%k0, %k0|%k0, %k0}";
11105       else
11106         return "add{b}\t{%0, %0|%0, %0}";
11108     default:
11109       if (REG_P (operands[2]))
11110         {
11111           if (get_attr_mode (insn) == MODE_SI)
11112             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11113           else
11114             return "sal{b}\t{%b2, %0|%0, %b2}";
11115         }
11116       else if (operands[2] == const1_rtx
11117                && (TARGET_SHIFT1 || optimize_size))
11118         {
11119           if (get_attr_mode (insn) == MODE_SI)
11120             return "sal{l}\t%0";
11121           else
11122             return "sal{b}\t%0";
11123         }
11124       else
11125         {
11126           if (get_attr_mode (insn) == MODE_SI)
11127             return "sal{l}\t{%2, %k0|%k0, %2}";
11128           else
11129             return "sal{b}\t{%2, %0|%0, %2}";
11130         }
11131     }
11133   [(set (attr "type")
11134      (cond [(eq_attr "alternative" "2")
11135               (const_string "lea")
11136             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11137                           (const_int 0))
11138                       (match_operand 0 "register_operand" ""))
11139                  (match_operand 2 "const1_operand" ""))
11140               (const_string "alu")
11141            ]
11142            (const_string "ishift")))
11143    (set_attr "mode" "QI,SI,SI")])
11145 (define_insn "*ashlqi3_1"
11146   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11147         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11148                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11149    (clobber (reg:CC FLAGS_REG))]
11150   "TARGET_PARTIAL_REG_STALL
11151    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11153   switch (get_attr_type (insn))
11154     {
11155     case TYPE_ALU:
11156       gcc_assert (operands[2] == const1_rtx);
11157       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11158         return "add{l}\t{%k0, %k0|%k0, %k0}";
11159       else
11160         return "add{b}\t{%0, %0|%0, %0}";
11162     default:
11163       if (REG_P (operands[2]))
11164         {
11165           if (get_attr_mode (insn) == MODE_SI)
11166             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11167           else
11168             return "sal{b}\t{%b2, %0|%0, %b2}";
11169         }
11170       else if (operands[2] == const1_rtx
11171                && (TARGET_SHIFT1 || optimize_size))
11172         {
11173           if (get_attr_mode (insn) == MODE_SI)
11174             return "sal{l}\t%0";
11175           else
11176             return "sal{b}\t%0";
11177         }
11178       else
11179         {
11180           if (get_attr_mode (insn) == MODE_SI)
11181             return "sal{l}\t{%2, %k0|%k0, %2}";
11182           else
11183             return "sal{b}\t{%2, %0|%0, %2}";
11184         }
11185     }
11187   [(set (attr "type")
11188      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11189                           (const_int 0))
11190                       (match_operand 0 "register_operand" ""))
11191                  (match_operand 2 "const1_operand" ""))
11192               (const_string "alu")
11193            ]
11194            (const_string "ishift")))
11195    (set_attr "mode" "QI,SI")])
11197 ;; This pattern can't accept a variable shift count, since shifts by
11198 ;; zero don't affect the flags.  We assume that shifts by constant
11199 ;; zero are optimized away.
11200 (define_insn "*ashlqi3_cmp"
11201   [(set (reg FLAGS_REG)
11202         (compare
11203           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11204                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11205           (const_int 0)))
11206    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11207         (ashift:QI (match_dup 1) (match_dup 2)))]
11208   "ix86_match_ccmode (insn, CCGOCmode)
11209    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11210    && (optimize_size
11211        || !TARGET_PARTIAL_FLAG_REG_STALL
11212        || (operands[2] == const1_rtx
11213            && (TARGET_SHIFT1
11214                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11216   switch (get_attr_type (insn))
11217     {
11218     case TYPE_ALU:
11219       gcc_assert (operands[2] == const1_rtx);
11220       return "add{b}\t{%0, %0|%0, %0}";
11222     default:
11223       if (REG_P (operands[2]))
11224         return "sal{b}\t{%b2, %0|%0, %b2}";
11225       else if (operands[2] == const1_rtx
11226                && (TARGET_SHIFT1 || optimize_size))
11227         return "sal{b}\t%0";
11228       else
11229         return "sal{b}\t{%2, %0|%0, %2}";
11230     }
11232   [(set (attr "type")
11233      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11234                           (const_int 0))
11235                       (match_operand 0 "register_operand" ""))
11236                  (match_operand 2 "const1_operand" ""))
11237               (const_string "alu")
11238            ]
11239            (const_string "ishift")))
11240    (set_attr "mode" "QI")])
11242 (define_insn "*ashlqi3_cconly"
11243   [(set (reg FLAGS_REG)
11244         (compare
11245           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11246                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11247           (const_int 0)))
11248    (clobber (match_scratch:QI 0 "=q"))]
11249   "ix86_match_ccmode (insn, CCGOCmode)
11250    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11251    && (optimize_size
11252        || !TARGET_PARTIAL_FLAG_REG_STALL
11253        || (operands[2] == const1_rtx
11254            && (TARGET_SHIFT1
11255                || TARGET_DOUBLE_WITH_ADD)))"
11257   switch (get_attr_type (insn))
11258     {
11259     case TYPE_ALU:
11260       gcc_assert (operands[2] == const1_rtx);
11261       return "add{b}\t{%0, %0|%0, %0}";
11263     default:
11264       if (REG_P (operands[2]))
11265         return "sal{b}\t{%b2, %0|%0, %b2}";
11266       else if (operands[2] == const1_rtx
11267                && (TARGET_SHIFT1 || optimize_size))
11268         return "sal{b}\t%0";
11269       else
11270         return "sal{b}\t{%2, %0|%0, %2}";
11271     }
11273   [(set (attr "type")
11274      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11275                           (const_int 0))
11276                       (match_operand 0 "register_operand" ""))
11277                  (match_operand 2 "const1_operand" ""))
11278               (const_string "alu")
11279            ]
11280            (const_string "ishift")))
11281    (set_attr "mode" "QI")])
11283 ;; See comment above `ashldi3' about how this works.
11285 (define_expand "ashrti3"
11286   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11287                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11288                                 (match_operand:QI 2 "nonmemory_operand" "")))
11289               (clobber (reg:CC FLAGS_REG))])]
11290   "TARGET_64BIT"
11292   if (! immediate_operand (operands[2], QImode))
11293     {
11294       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11295       DONE;
11296     }
11297   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11298   DONE;
11301 (define_insn "ashrti3_1"
11302   [(set (match_operand:TI 0 "register_operand" "=r")
11303         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11304                      (match_operand:QI 2 "register_operand" "c")))
11305    (clobber (match_scratch:DI 3 "=&r"))
11306    (clobber (reg:CC FLAGS_REG))]
11307   "TARGET_64BIT"
11308   "#"
11309   [(set_attr "type" "multi")])
11311 (define_insn "*ashrti3_2"
11312   [(set (match_operand:TI 0 "register_operand" "=r")
11313         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11314                      (match_operand:QI 2 "immediate_operand" "O")))
11315    (clobber (reg:CC FLAGS_REG))]
11316   "TARGET_64BIT"
11317   "#"
11318   [(set_attr "type" "multi")])
11320 (define_split
11321   [(set (match_operand:TI 0 "register_operand" "")
11322         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11323                      (match_operand:QI 2 "register_operand" "")))
11324    (clobber (match_scratch:DI 3 ""))
11325    (clobber (reg:CC FLAGS_REG))]
11326   "TARGET_64BIT && reload_completed"
11327   [(const_int 0)]
11328   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11330 (define_split
11331   [(set (match_operand:TI 0 "register_operand" "")
11332         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11333                      (match_operand:QI 2 "immediate_operand" "")))
11334    (clobber (reg:CC FLAGS_REG))]
11335   "TARGET_64BIT && reload_completed"
11336   [(const_int 0)]
11337   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11339 (define_insn "x86_64_shrd"
11340   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11341         (ior:DI (ashiftrt:DI (match_dup 0)
11342                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11343                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11344                   (minus:QI (const_int 64) (match_dup 2)))))
11345    (clobber (reg:CC FLAGS_REG))]
11346   "TARGET_64BIT"
11347   "@
11348    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11349    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11350   [(set_attr "type" "ishift")
11351    (set_attr "prefix_0f" "1")
11352    (set_attr "mode" "DI")
11353    (set_attr "athlon_decode" "vector")])
11355 (define_expand "ashrdi3"
11356   [(set (match_operand:DI 0 "shiftdi_operand" "")
11357         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11358                      (match_operand:QI 2 "nonmemory_operand" "")))]
11359   ""
11360   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11362 (define_insn "*ashrdi3_63_rex64"
11363   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11364         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11365                      (match_operand:DI 2 "const_int_operand" "i,i")))
11366    (clobber (reg:CC FLAGS_REG))]
11367   "TARGET_64BIT && INTVAL (operands[2]) == 63
11368    && (TARGET_USE_CLTD || optimize_size)
11369    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11370   "@
11371    {cqto|cqo}
11372    sar{q}\t{%2, %0|%0, %2}"
11373   [(set_attr "type" "imovx,ishift")
11374    (set_attr "prefix_0f" "0,*")
11375    (set_attr "length_immediate" "0,*")
11376    (set_attr "modrm" "0,1")
11377    (set_attr "mode" "DI")])
11379 (define_insn "*ashrdi3_1_one_bit_rex64"
11380   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11381         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11382                      (match_operand:QI 2 "const1_operand" "")))
11383    (clobber (reg:CC FLAGS_REG))]
11384   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11385    && (TARGET_SHIFT1 || optimize_size)"
11386   "sar{q}\t%0"
11387   [(set_attr "type" "ishift")
11388    (set (attr "length")
11389      (if_then_else (match_operand:DI 0 "register_operand" "")
11390         (const_string "2")
11391         (const_string "*")))])
11393 (define_insn "*ashrdi3_1_rex64"
11394   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11395         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11396                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11397    (clobber (reg:CC FLAGS_REG))]
11398   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11399   "@
11400    sar{q}\t{%2, %0|%0, %2}
11401    sar{q}\t{%b2, %0|%0, %b2}"
11402   [(set_attr "type" "ishift")
11403    (set_attr "mode" "DI")])
11405 ;; This pattern can't accept a variable shift count, since shifts by
11406 ;; zero don't affect the flags.  We assume that shifts by constant
11407 ;; zero are optimized away.
11408 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11409   [(set (reg FLAGS_REG)
11410         (compare
11411           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412                        (match_operand:QI 2 "const1_operand" ""))
11413           (const_int 0)))
11414    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11415         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11416   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11417    && (TARGET_SHIFT1 || optimize_size)
11418    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11419   "sar{q}\t%0"
11420   [(set_attr "type" "ishift")
11421    (set (attr "length")
11422      (if_then_else (match_operand:DI 0 "register_operand" "")
11423         (const_string "2")
11424         (const_string "*")))])
11426 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11427   [(set (reg FLAGS_REG)
11428         (compare
11429           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11430                        (match_operand:QI 2 "const1_operand" ""))
11431           (const_int 0)))
11432    (clobber (match_scratch:DI 0 "=r"))]
11433   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11434    && (TARGET_SHIFT1 || optimize_size)
11435    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11436   "sar{q}\t%0"
11437   [(set_attr "type" "ishift")
11438    (set_attr "length" "2")])
11440 ;; This pattern can't accept a variable shift count, since shifts by
11441 ;; zero don't affect the flags.  We assume that shifts by constant
11442 ;; zero are optimized away.
11443 (define_insn "*ashrdi3_cmp_rex64"
11444   [(set (reg FLAGS_REG)
11445         (compare
11446           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11447                        (match_operand:QI 2 "const_int_operand" "n"))
11448           (const_int 0)))
11449    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11450         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11451   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11452    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11453    && (optimize_size
11454        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11455   "sar{q}\t{%2, %0|%0, %2}"
11456   [(set_attr "type" "ishift")
11457    (set_attr "mode" "DI")])
11459 (define_insn "*ashrdi3_cconly_rex64"
11460   [(set (reg FLAGS_REG)
11461         (compare
11462           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11463                        (match_operand:QI 2 "const_int_operand" "n"))
11464           (const_int 0)))
11465    (clobber (match_scratch:DI 0 "=r"))]
11466   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11467    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11468    && (optimize_size
11469        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11470   "sar{q}\t{%2, %0|%0, %2}"
11471   [(set_attr "type" "ishift")
11472    (set_attr "mode" "DI")])
11474 (define_insn "*ashrdi3_1"
11475   [(set (match_operand:DI 0 "register_operand" "=r")
11476         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11477                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11478    (clobber (reg:CC FLAGS_REG))]
11479   "!TARGET_64BIT"
11480   "#"
11481   [(set_attr "type" "multi")])
11483 ;; By default we don't ask for a scratch register, because when DImode
11484 ;; values are manipulated, registers are already at a premium.  But if
11485 ;; we have one handy, we won't turn it away.
11486 (define_peephole2
11487   [(match_scratch:SI 3 "r")
11488    (parallel [(set (match_operand:DI 0 "register_operand" "")
11489                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11490                                 (match_operand:QI 2 "nonmemory_operand" "")))
11491               (clobber (reg:CC FLAGS_REG))])
11492    (match_dup 3)]
11493   "!TARGET_64BIT && TARGET_CMOVE"
11494   [(const_int 0)]
11495   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11497 (define_split
11498   [(set (match_operand:DI 0 "register_operand" "")
11499         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11500                      (match_operand:QI 2 "nonmemory_operand" "")))
11501    (clobber (reg:CC FLAGS_REG))]
11502   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11503                      ? flow2_completed : reload_completed)"
11504   [(const_int 0)]
11505   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11507 (define_insn "x86_shrd_1"
11508   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11509         (ior:SI (ashiftrt:SI (match_dup 0)
11510                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11511                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11512                   (minus:QI (const_int 32) (match_dup 2)))))
11513    (clobber (reg:CC FLAGS_REG))]
11514   ""
11515   "@
11516    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11517    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11518   [(set_attr "type" "ishift")
11519    (set_attr "prefix_0f" "1")
11520    (set_attr "pent_pair" "np")
11521    (set_attr "mode" "SI")])
11523 (define_expand "x86_shift_adj_3"
11524   [(use (match_operand:SI 0 "register_operand" ""))
11525    (use (match_operand:SI 1 "register_operand" ""))
11526    (use (match_operand:QI 2 "register_operand" ""))]
11527   ""
11529   rtx label = gen_label_rtx ();
11530   rtx tmp;
11532   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11534   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11535   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11536   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11537                               gen_rtx_LABEL_REF (VOIDmode, label),
11538                               pc_rtx);
11539   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11540   JUMP_LABEL (tmp) = label;
11542   emit_move_insn (operands[0], operands[1]);
11543   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11545   emit_label (label);
11546   LABEL_NUSES (label) = 1;
11548   DONE;
11551 (define_insn "ashrsi3_31"
11552   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11553         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11554                      (match_operand:SI 2 "const_int_operand" "i,i")))
11555    (clobber (reg:CC FLAGS_REG))]
11556   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11557    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11558   "@
11559    {cltd|cdq}
11560    sar{l}\t{%2, %0|%0, %2}"
11561   [(set_attr "type" "imovx,ishift")
11562    (set_attr "prefix_0f" "0,*")
11563    (set_attr "length_immediate" "0,*")
11564    (set_attr "modrm" "0,1")
11565    (set_attr "mode" "SI")])
11567 (define_insn "*ashrsi3_31_zext"
11568   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11569         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11570                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11571    (clobber (reg:CC FLAGS_REG))]
11572   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11573    && INTVAL (operands[2]) == 31
11574    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11575   "@
11576    {cltd|cdq}
11577    sar{l}\t{%2, %k0|%k0, %2}"
11578   [(set_attr "type" "imovx,ishift")
11579    (set_attr "prefix_0f" "0,*")
11580    (set_attr "length_immediate" "0,*")
11581    (set_attr "modrm" "0,1")
11582    (set_attr "mode" "SI")])
11584 (define_expand "ashrsi3"
11585   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11586         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11587                      (match_operand:QI 2 "nonmemory_operand" "")))
11588    (clobber (reg:CC FLAGS_REG))]
11589   ""
11590   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11592 (define_insn "*ashrsi3_1_one_bit"
11593   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11594         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11595                      (match_operand:QI 2 "const1_operand" "")))
11596    (clobber (reg:CC FLAGS_REG))]
11597   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11598    && (TARGET_SHIFT1 || optimize_size)"
11599   "sar{l}\t%0"
11600   [(set_attr "type" "ishift")
11601    (set (attr "length")
11602      (if_then_else (match_operand:SI 0 "register_operand" "")
11603         (const_string "2")
11604         (const_string "*")))])
11606 (define_insn "*ashrsi3_1_one_bit_zext"
11607   [(set (match_operand:DI 0 "register_operand" "=r")
11608         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11609                                      (match_operand:QI 2 "const1_operand" ""))))
11610    (clobber (reg:CC FLAGS_REG))]
11611   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11612    && (TARGET_SHIFT1 || optimize_size)"
11613   "sar{l}\t%k0"
11614   [(set_attr "type" "ishift")
11615    (set_attr "length" "2")])
11617 (define_insn "*ashrsi3_1"
11618   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11619         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11620                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11621    (clobber (reg:CC FLAGS_REG))]
11622   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11623   "@
11624    sar{l}\t{%2, %0|%0, %2}
11625    sar{l}\t{%b2, %0|%0, %b2}"
11626   [(set_attr "type" "ishift")
11627    (set_attr "mode" "SI")])
11629 (define_insn "*ashrsi3_1_zext"
11630   [(set (match_operand:DI 0 "register_operand" "=r,r")
11631         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11632                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11633    (clobber (reg:CC FLAGS_REG))]
11634   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11635   "@
11636    sar{l}\t{%2, %k0|%k0, %2}
11637    sar{l}\t{%b2, %k0|%k0, %b2}"
11638   [(set_attr "type" "ishift")
11639    (set_attr "mode" "SI")])
11641 ;; This pattern can't accept a variable shift count, since shifts by
11642 ;; zero don't affect the flags.  We assume that shifts by constant
11643 ;; zero are optimized away.
11644 (define_insn "*ashrsi3_one_bit_cmp"
11645   [(set (reg FLAGS_REG)
11646         (compare
11647           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11648                        (match_operand:QI 2 "const1_operand" ""))
11649           (const_int 0)))
11650    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11651         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11652   "ix86_match_ccmode (insn, CCGOCmode)
11653    && (TARGET_SHIFT1 || optimize_size)
11654    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11655   "sar{l}\t%0"
11656   [(set_attr "type" "ishift")
11657    (set (attr "length")
11658      (if_then_else (match_operand:SI 0 "register_operand" "")
11659         (const_string "2")
11660         (const_string "*")))])
11662 (define_insn "*ashrsi3_one_bit_cconly"
11663   [(set (reg FLAGS_REG)
11664         (compare
11665           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11666                        (match_operand:QI 2 "const1_operand" ""))
11667           (const_int 0)))
11668    (clobber (match_scratch:SI 0 "=r"))]
11669   "ix86_match_ccmode (insn, CCGOCmode)
11670    && (TARGET_SHIFT1 || optimize_size)
11671    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11672   "sar{l}\t%0"
11673   [(set_attr "type" "ishift")
11674    (set_attr "length" "2")])
11676 (define_insn "*ashrsi3_one_bit_cmp_zext"
11677   [(set (reg FLAGS_REG)
11678         (compare
11679           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11680                        (match_operand:QI 2 "const1_operand" ""))
11681           (const_int 0)))
11682    (set (match_operand:DI 0 "register_operand" "=r")
11683         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11684   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11685    && (TARGET_SHIFT1 || optimize_size)
11686    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11687   "sar{l}\t%k0"
11688   [(set_attr "type" "ishift")
11689    (set_attr "length" "2")])
11691 ;; This pattern can't accept a variable shift count, since shifts by
11692 ;; zero don't affect the flags.  We assume that shifts by constant
11693 ;; zero are optimized away.
11694 (define_insn "*ashrsi3_cmp"
11695   [(set (reg FLAGS_REG)
11696         (compare
11697           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11698                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11699           (const_int 0)))
11700    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11701         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11702   "ix86_match_ccmode (insn, CCGOCmode)
11703    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11704    && (optimize_size
11705        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11706   "sar{l}\t{%2, %0|%0, %2}"
11707   [(set_attr "type" "ishift")
11708    (set_attr "mode" "SI")])
11710 (define_insn "*ashrsi3_cconly"
11711   [(set (reg FLAGS_REG)
11712         (compare
11713           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11714                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11715           (const_int 0)))
11716    (clobber (match_scratch:SI 0 "=r"))]
11717   "ix86_match_ccmode (insn, CCGOCmode)
11718    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11719    && (optimize_size
11720        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11721   "sar{l}\t{%2, %0|%0, %2}"
11722   [(set_attr "type" "ishift")
11723    (set_attr "mode" "SI")])
11725 (define_insn "*ashrsi3_cmp_zext"
11726   [(set (reg FLAGS_REG)
11727         (compare
11728           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11729                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11730           (const_int 0)))
11731    (set (match_operand:DI 0 "register_operand" "=r")
11732         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11733   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11734    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11735    && (optimize_size
11736        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11737   "sar{l}\t{%2, %k0|%k0, %2}"
11738   [(set_attr "type" "ishift")
11739    (set_attr "mode" "SI")])
11741 (define_expand "ashrhi3"
11742   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11743         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11744                      (match_operand:QI 2 "nonmemory_operand" "")))
11745    (clobber (reg:CC FLAGS_REG))]
11746   "TARGET_HIMODE_MATH"
11747   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11749 (define_insn "*ashrhi3_1_one_bit"
11750   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11751         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11752                      (match_operand:QI 2 "const1_operand" "")))
11753    (clobber (reg:CC FLAGS_REG))]
11754   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11755    && (TARGET_SHIFT1 || optimize_size)"
11756   "sar{w}\t%0"
11757   [(set_attr "type" "ishift")
11758    (set (attr "length")
11759      (if_then_else (match_operand 0 "register_operand" "")
11760         (const_string "2")
11761         (const_string "*")))])
11763 (define_insn "*ashrhi3_1"
11764   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11765         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11766                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11767    (clobber (reg:CC FLAGS_REG))]
11768   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11769   "@
11770    sar{w}\t{%2, %0|%0, %2}
11771    sar{w}\t{%b2, %0|%0, %b2}"
11772   [(set_attr "type" "ishift")
11773    (set_attr "mode" "HI")])
11775 ;; This pattern can't accept a variable shift count, since shifts by
11776 ;; zero don't affect the flags.  We assume that shifts by constant
11777 ;; zero are optimized away.
11778 (define_insn "*ashrhi3_one_bit_cmp"
11779   [(set (reg FLAGS_REG)
11780         (compare
11781           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11782                        (match_operand:QI 2 "const1_operand" ""))
11783           (const_int 0)))
11784    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11785         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11786   "ix86_match_ccmode (insn, CCGOCmode)
11787    && (TARGET_SHIFT1 || optimize_size)
11788    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11789   "sar{w}\t%0"
11790   [(set_attr "type" "ishift")
11791    (set (attr "length")
11792      (if_then_else (match_operand 0 "register_operand" "")
11793         (const_string "2")
11794         (const_string "*")))])
11796 (define_insn "*ashrhi3_one_bit_cconly"
11797   [(set (reg FLAGS_REG)
11798         (compare
11799           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11800                        (match_operand:QI 2 "const1_operand" ""))
11801           (const_int 0)))
11802    (clobber (match_scratch:HI 0 "=r"))]
11803   "ix86_match_ccmode (insn, CCGOCmode)
11804    && (TARGET_SHIFT1 || optimize_size)
11805    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11806   "sar{w}\t%0"
11807   [(set_attr "type" "ishift")
11808    (set_attr "length" "2")])
11810 ;; This pattern can't accept a variable shift count, since shifts by
11811 ;; zero don't affect the flags.  We assume that shifts by constant
11812 ;; zero are optimized away.
11813 (define_insn "*ashrhi3_cmp"
11814   [(set (reg FLAGS_REG)
11815         (compare
11816           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11817                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11818           (const_int 0)))
11819    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11820         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11821   "ix86_match_ccmode (insn, CCGOCmode)
11822    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11823    && (optimize_size
11824        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11825   "sar{w}\t{%2, %0|%0, %2}"
11826   [(set_attr "type" "ishift")
11827    (set_attr "mode" "HI")])
11829 (define_insn "*ashrhi3_cconly"
11830   [(set (reg FLAGS_REG)
11831         (compare
11832           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11833                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11834           (const_int 0)))
11835    (clobber (match_scratch:HI 0 "=r"))]
11836   "ix86_match_ccmode (insn, CCGOCmode)
11837    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11838    && (optimize_size
11839        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11840   "sar{w}\t{%2, %0|%0, %2}"
11841   [(set_attr "type" "ishift")
11842    (set_attr "mode" "HI")])
11844 (define_expand "ashrqi3"
11845   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11846         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11847                      (match_operand:QI 2 "nonmemory_operand" "")))
11848    (clobber (reg:CC FLAGS_REG))]
11849   "TARGET_QIMODE_MATH"
11850   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11852 (define_insn "*ashrqi3_1_one_bit"
11853   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11854         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11855                      (match_operand:QI 2 "const1_operand" "")))
11856    (clobber (reg:CC FLAGS_REG))]
11857   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11858    && (TARGET_SHIFT1 || optimize_size)"
11859   "sar{b}\t%0"
11860   [(set_attr "type" "ishift")
11861    (set (attr "length")
11862      (if_then_else (match_operand 0 "register_operand" "")
11863         (const_string "2")
11864         (const_string "*")))])
11866 (define_insn "*ashrqi3_1_one_bit_slp"
11867   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11868         (ashiftrt:QI (match_dup 0)
11869                      (match_operand:QI 1 "const1_operand" "")))
11870    (clobber (reg:CC FLAGS_REG))]
11871   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11872    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11873    && (TARGET_SHIFT1 || optimize_size)"
11874   "sar{b}\t%0"
11875   [(set_attr "type" "ishift1")
11876    (set (attr "length")
11877      (if_then_else (match_operand 0 "register_operand" "")
11878         (const_string "2")
11879         (const_string "*")))])
11881 (define_insn "*ashrqi3_1"
11882   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11883         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11884                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11885    (clobber (reg:CC FLAGS_REG))]
11886   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11887   "@
11888    sar{b}\t{%2, %0|%0, %2}
11889    sar{b}\t{%b2, %0|%0, %b2}"
11890   [(set_attr "type" "ishift")
11891    (set_attr "mode" "QI")])
11893 (define_insn "*ashrqi3_1_slp"
11894   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11895         (ashiftrt:QI (match_dup 0)
11896                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11897    (clobber (reg:CC FLAGS_REG))]
11898   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11899    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11900   "@
11901    sar{b}\t{%1, %0|%0, %1}
11902    sar{b}\t{%b1, %0|%0, %b1}"
11903   [(set_attr "type" "ishift1")
11904    (set_attr "mode" "QI")])
11906 ;; This pattern can't accept a variable shift count, since shifts by
11907 ;; zero don't affect the flags.  We assume that shifts by constant
11908 ;; zero are optimized away.
11909 (define_insn "*ashrqi3_one_bit_cmp"
11910   [(set (reg FLAGS_REG)
11911         (compare
11912           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11913                        (match_operand:QI 2 "const1_operand" "I"))
11914           (const_int 0)))
11915    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11916         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11917   "ix86_match_ccmode (insn, CCGOCmode)
11918    && (TARGET_SHIFT1 || optimize_size)
11919    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11920   "sar{b}\t%0"
11921   [(set_attr "type" "ishift")
11922    (set (attr "length")
11923      (if_then_else (match_operand 0 "register_operand" "")
11924         (const_string "2")
11925         (const_string "*")))])
11927 (define_insn "*ashrqi3_one_bit_cconly"
11928   [(set (reg FLAGS_REG)
11929         (compare
11930           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11931                        (match_operand:QI 2 "const1_operand" "I"))
11932           (const_int 0)))
11933    (clobber (match_scratch:QI 0 "=q"))]
11934   "ix86_match_ccmode (insn, CCGOCmode)
11935    && (TARGET_SHIFT1 || optimize_size)
11936    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11937   "sar{b}\t%0"
11938   [(set_attr "type" "ishift")
11939    (set_attr "length" "2")])
11941 ;; This pattern can't accept a variable shift count, since shifts by
11942 ;; zero don't affect the flags.  We assume that shifts by constant
11943 ;; zero are optimized away.
11944 (define_insn "*ashrqi3_cmp"
11945   [(set (reg FLAGS_REG)
11946         (compare
11947           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11948                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11949           (const_int 0)))
11950    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11951         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11952   "ix86_match_ccmode (insn, CCGOCmode)
11953    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11954    && (optimize_size
11955        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11956   "sar{b}\t{%2, %0|%0, %2}"
11957   [(set_attr "type" "ishift")
11958    (set_attr "mode" "QI")])
11960 (define_insn "*ashrqi3_cconly"
11961   [(set (reg FLAGS_REG)
11962         (compare
11963           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11964                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11965           (const_int 0)))
11966    (clobber (match_scratch:QI 0 "=q"))]
11967   "ix86_match_ccmode (insn, CCGOCmode)
11968    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11969    && (optimize_size
11970        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11971   "sar{b}\t{%2, %0|%0, %2}"
11972   [(set_attr "type" "ishift")
11973    (set_attr "mode" "QI")])
11976 ;; Logical shift instructions
11978 ;; See comment above `ashldi3' about how this works.
11980 (define_expand "lshrti3"
11981   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11982                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11983                                 (match_operand:QI 2 "nonmemory_operand" "")))
11984               (clobber (reg:CC FLAGS_REG))])]
11985   "TARGET_64BIT"
11987   if (! immediate_operand (operands[2], QImode))
11988     {
11989       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11990       DONE;
11991     }
11992   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11993   DONE;
11996 (define_insn "lshrti3_1"
11997   [(set (match_operand:TI 0 "register_operand" "=r")
11998         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11999                      (match_operand:QI 2 "register_operand" "c")))
12000    (clobber (match_scratch:DI 3 "=&r"))
12001    (clobber (reg:CC FLAGS_REG))]
12002   "TARGET_64BIT"
12003   "#"
12004   [(set_attr "type" "multi")])
12006 (define_insn "*lshrti3_2"
12007   [(set (match_operand:TI 0 "register_operand" "=r")
12008         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12009                      (match_operand:QI 2 "immediate_operand" "O")))
12010    (clobber (reg:CC FLAGS_REG))]
12011   "TARGET_64BIT"
12012   "#"
12013   [(set_attr "type" "multi")])
12015 (define_split
12016   [(set (match_operand:TI 0 "register_operand" "")
12017         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12018                      (match_operand:QI 2 "register_operand" "")))
12019    (clobber (match_scratch:DI 3 ""))
12020    (clobber (reg:CC FLAGS_REG))]
12021   "TARGET_64BIT && reload_completed"
12022   [(const_int 0)]
12023   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12025 (define_split
12026   [(set (match_operand:TI 0 "register_operand" "")
12027         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12028                      (match_operand:QI 2 "immediate_operand" "")))
12029    (clobber (reg:CC FLAGS_REG))]
12030   "TARGET_64BIT && reload_completed"
12031   [(const_int 0)]
12032   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12034 (define_expand "lshrdi3"
12035   [(set (match_operand:DI 0 "shiftdi_operand" "")
12036         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12037                      (match_operand:QI 2 "nonmemory_operand" "")))]
12038   ""
12039   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12041 (define_insn "*lshrdi3_1_one_bit_rex64"
12042   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12043         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12044                      (match_operand:QI 2 "const1_operand" "")))
12045    (clobber (reg:CC FLAGS_REG))]
12046   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12047    && (TARGET_SHIFT1 || optimize_size)"
12048   "shr{q}\t%0"
12049   [(set_attr "type" "ishift")
12050    (set (attr "length")
12051      (if_then_else (match_operand:DI 0 "register_operand" "")
12052         (const_string "2")
12053         (const_string "*")))])
12055 (define_insn "*lshrdi3_1_rex64"
12056   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12057         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12058                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12059    (clobber (reg:CC FLAGS_REG))]
12060   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12061   "@
12062    shr{q}\t{%2, %0|%0, %2}
12063    shr{q}\t{%b2, %0|%0, %b2}"
12064   [(set_attr "type" "ishift")
12065    (set_attr "mode" "DI")])
12067 ;; This pattern can't accept a variable shift count, since shifts by
12068 ;; zero don't affect the flags.  We assume that shifts by constant
12069 ;; zero are optimized away.
12070 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12071   [(set (reg FLAGS_REG)
12072         (compare
12073           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074                        (match_operand:QI 2 "const1_operand" ""))
12075           (const_int 0)))
12076    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12077         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12078   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12079    && (TARGET_SHIFT1 || optimize_size)
12080    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12081   "shr{q}\t%0"
12082   [(set_attr "type" "ishift")
12083    (set (attr "length")
12084      (if_then_else (match_operand:DI 0 "register_operand" "")
12085         (const_string "2")
12086         (const_string "*")))])
12088 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12089   [(set (reg FLAGS_REG)
12090         (compare
12091           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12092                        (match_operand:QI 2 "const1_operand" ""))
12093           (const_int 0)))
12094    (clobber (match_scratch:DI 0 "=r"))]
12095   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12096    && (TARGET_SHIFT1 || optimize_size)
12097    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12098   "shr{q}\t%0"
12099   [(set_attr "type" "ishift")
12100    (set_attr "length" "2")])
12102 ;; This pattern can't accept a variable shift count, since shifts by
12103 ;; zero don't affect the flags.  We assume that shifts by constant
12104 ;; zero are optimized away.
12105 (define_insn "*lshrdi3_cmp_rex64"
12106   [(set (reg FLAGS_REG)
12107         (compare
12108           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12109                        (match_operand:QI 2 "const_int_operand" "e"))
12110           (const_int 0)))
12111    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12112         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12113   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12114    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12115    && (optimize_size
12116        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12117   "shr{q}\t{%2, %0|%0, %2}"
12118   [(set_attr "type" "ishift")
12119    (set_attr "mode" "DI")])
12121 (define_insn "*lshrdi3_cconly_rex64"
12122   [(set (reg FLAGS_REG)
12123         (compare
12124           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12125                        (match_operand:QI 2 "const_int_operand" "e"))
12126           (const_int 0)))
12127    (clobber (match_scratch:DI 0 "=r"))]
12128   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12129    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12130    && (optimize_size
12131        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12132   "shr{q}\t{%2, %0|%0, %2}"
12133   [(set_attr "type" "ishift")
12134    (set_attr "mode" "DI")])
12136 (define_insn "*lshrdi3_1"
12137   [(set (match_operand:DI 0 "register_operand" "=r")
12138         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12139                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12140    (clobber (reg:CC FLAGS_REG))]
12141   "!TARGET_64BIT"
12142   "#"
12143   [(set_attr "type" "multi")])
12145 ;; By default we don't ask for a scratch register, because when DImode
12146 ;; values are manipulated, registers are already at a premium.  But if
12147 ;; we have one handy, we won't turn it away.
12148 (define_peephole2
12149   [(match_scratch:SI 3 "r")
12150    (parallel [(set (match_operand:DI 0 "register_operand" "")
12151                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12152                                 (match_operand:QI 2 "nonmemory_operand" "")))
12153               (clobber (reg:CC FLAGS_REG))])
12154    (match_dup 3)]
12155   "!TARGET_64BIT && TARGET_CMOVE"
12156   [(const_int 0)]
12157   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12159 (define_split
12160   [(set (match_operand:DI 0 "register_operand" "")
12161         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12162                      (match_operand:QI 2 "nonmemory_operand" "")))
12163    (clobber (reg:CC FLAGS_REG))]
12164   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12165                      ? flow2_completed : reload_completed)"
12166   [(const_int 0)]
12167   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12169 (define_expand "lshrsi3"
12170   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12171         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12172                      (match_operand:QI 2 "nonmemory_operand" "")))
12173    (clobber (reg:CC FLAGS_REG))]
12174   ""
12175   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12177 (define_insn "*lshrsi3_1_one_bit"
12178   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12179         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12180                      (match_operand:QI 2 "const1_operand" "")))
12181    (clobber (reg:CC FLAGS_REG))]
12182   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12183    && (TARGET_SHIFT1 || optimize_size)"
12184   "shr{l}\t%0"
12185   [(set_attr "type" "ishift")
12186    (set (attr "length")
12187      (if_then_else (match_operand:SI 0 "register_operand" "")
12188         (const_string "2")
12189         (const_string "*")))])
12191 (define_insn "*lshrsi3_1_one_bit_zext"
12192   [(set (match_operand:DI 0 "register_operand" "=r")
12193         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12194                      (match_operand:QI 2 "const1_operand" "")))
12195    (clobber (reg:CC FLAGS_REG))]
12196   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12197    && (TARGET_SHIFT1 || optimize_size)"
12198   "shr{l}\t%k0"
12199   [(set_attr "type" "ishift")
12200    (set_attr "length" "2")])
12202 (define_insn "*lshrsi3_1"
12203   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12204         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12205                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12206    (clobber (reg:CC FLAGS_REG))]
12207   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12208   "@
12209    shr{l}\t{%2, %0|%0, %2}
12210    shr{l}\t{%b2, %0|%0, %b2}"
12211   [(set_attr "type" "ishift")
12212    (set_attr "mode" "SI")])
12214 (define_insn "*lshrsi3_1_zext"
12215   [(set (match_operand:DI 0 "register_operand" "=r,r")
12216         (zero_extend:DI
12217           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12218                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12219    (clobber (reg:CC FLAGS_REG))]
12220   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12221   "@
12222    shr{l}\t{%2, %k0|%k0, %2}
12223    shr{l}\t{%b2, %k0|%k0, %b2}"
12224   [(set_attr "type" "ishift")
12225    (set_attr "mode" "SI")])
12227 ;; This pattern can't accept a variable shift count, since shifts by
12228 ;; zero don't affect the flags.  We assume that shifts by constant
12229 ;; zero are optimized away.
12230 (define_insn "*lshrsi3_one_bit_cmp"
12231   [(set (reg FLAGS_REG)
12232         (compare
12233           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12234                        (match_operand:QI 2 "const1_operand" ""))
12235           (const_int 0)))
12236    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12237         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12238   "ix86_match_ccmode (insn, CCGOCmode)
12239    && (TARGET_SHIFT1 || optimize_size)
12240    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12241   "shr{l}\t%0"
12242   [(set_attr "type" "ishift")
12243    (set (attr "length")
12244      (if_then_else (match_operand:SI 0 "register_operand" "")
12245         (const_string "2")
12246         (const_string "*")))])
12248 (define_insn "*lshrsi3_one_bit_cconly"
12249   [(set (reg FLAGS_REG)
12250         (compare
12251           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12252                        (match_operand:QI 2 "const1_operand" ""))
12253           (const_int 0)))
12254    (clobber (match_scratch:SI 0 "=r"))]
12255   "ix86_match_ccmode (insn, CCGOCmode)
12256    && (TARGET_SHIFT1 || optimize_size)
12257    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12258   "shr{l}\t%0"
12259   [(set_attr "type" "ishift")
12260    (set_attr "length" "2")])
12262 (define_insn "*lshrsi3_cmp_one_bit_zext"
12263   [(set (reg FLAGS_REG)
12264         (compare
12265           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12266                        (match_operand:QI 2 "const1_operand" ""))
12267           (const_int 0)))
12268    (set (match_operand:DI 0 "register_operand" "=r")
12269         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12270   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12271    && (TARGET_SHIFT1 || optimize_size)
12272    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12273   "shr{l}\t%k0"
12274   [(set_attr "type" "ishift")
12275    (set_attr "length" "2")])
12277 ;; This pattern can't accept a variable shift count, since shifts by
12278 ;; zero don't affect the flags.  We assume that shifts by constant
12279 ;; zero are optimized away.
12280 (define_insn "*lshrsi3_cmp"
12281   [(set (reg FLAGS_REG)
12282         (compare
12283           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12284                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12285           (const_int 0)))
12286    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12287         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12288   "ix86_match_ccmode (insn, CCGOCmode)
12289    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12290    && (optimize_size
12291        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12292   "shr{l}\t{%2, %0|%0, %2}"
12293   [(set_attr "type" "ishift")
12294    (set_attr "mode" "SI")])
12296 (define_insn "*lshrsi3_cconly"
12297   [(set (reg FLAGS_REG)
12298       (compare
12299         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12300                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12301         (const_int 0)))
12302    (clobber (match_scratch:SI 0 "=r"))]
12303   "ix86_match_ccmode (insn, CCGOCmode)
12304    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12305    && (optimize_size
12306        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12307   "shr{l}\t{%2, %0|%0, %2}"
12308   [(set_attr "type" "ishift")
12309    (set_attr "mode" "SI")])
12311 (define_insn "*lshrsi3_cmp_zext"
12312   [(set (reg FLAGS_REG)
12313         (compare
12314           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12315                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12316           (const_int 0)))
12317    (set (match_operand:DI 0 "register_operand" "=r")
12318         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12319   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12320    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12321    && (optimize_size
12322        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12323   "shr{l}\t{%2, %k0|%k0, %2}"
12324   [(set_attr "type" "ishift")
12325    (set_attr "mode" "SI")])
12327 (define_expand "lshrhi3"
12328   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12329         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12330                      (match_operand:QI 2 "nonmemory_operand" "")))
12331    (clobber (reg:CC FLAGS_REG))]
12332   "TARGET_HIMODE_MATH"
12333   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12335 (define_insn "*lshrhi3_1_one_bit"
12336   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12337         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12338                      (match_operand:QI 2 "const1_operand" "")))
12339    (clobber (reg:CC FLAGS_REG))]
12340   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12341    && (TARGET_SHIFT1 || optimize_size)"
12342   "shr{w}\t%0"
12343   [(set_attr "type" "ishift")
12344    (set (attr "length")
12345      (if_then_else (match_operand 0 "register_operand" "")
12346         (const_string "2")
12347         (const_string "*")))])
12349 (define_insn "*lshrhi3_1"
12350   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12351         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12352                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12353    (clobber (reg:CC FLAGS_REG))]
12354   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12355   "@
12356    shr{w}\t{%2, %0|%0, %2}
12357    shr{w}\t{%b2, %0|%0, %b2}"
12358   [(set_attr "type" "ishift")
12359    (set_attr "mode" "HI")])
12361 ;; This pattern can't accept a variable shift count, since shifts by
12362 ;; zero don't affect the flags.  We assume that shifts by constant
12363 ;; zero are optimized away.
12364 (define_insn "*lshrhi3_one_bit_cmp"
12365   [(set (reg FLAGS_REG)
12366         (compare
12367           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368                        (match_operand:QI 2 "const1_operand" ""))
12369           (const_int 0)))
12370    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12371         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12372   "ix86_match_ccmode (insn, CCGOCmode)
12373    && (TARGET_SHIFT1 || optimize_size)
12374    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12375   "shr{w}\t%0"
12376   [(set_attr "type" "ishift")
12377    (set (attr "length")
12378      (if_then_else (match_operand:SI 0 "register_operand" "")
12379         (const_string "2")
12380         (const_string "*")))])
12382 (define_insn "*lshrhi3_one_bit_cconly"
12383   [(set (reg FLAGS_REG)
12384         (compare
12385           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12386                        (match_operand:QI 2 "const1_operand" ""))
12387           (const_int 0)))
12388    (clobber (match_scratch:HI 0 "=r"))]
12389   "ix86_match_ccmode (insn, CCGOCmode)
12390    && (TARGET_SHIFT1 || optimize_size)
12391    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12392   "shr{w}\t%0"
12393   [(set_attr "type" "ishift")
12394    (set_attr "length" "2")])
12396 ;; This pattern can't accept a variable shift count, since shifts by
12397 ;; zero don't affect the flags.  We assume that shifts by constant
12398 ;; zero are optimized away.
12399 (define_insn "*lshrhi3_cmp"
12400   [(set (reg FLAGS_REG)
12401         (compare
12402           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12403                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12404           (const_int 0)))
12405    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12406         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12407   "ix86_match_ccmode (insn, CCGOCmode)
12408    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12409    && (optimize_size
12410        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12411   "shr{w}\t{%2, %0|%0, %2}"
12412   [(set_attr "type" "ishift")
12413    (set_attr "mode" "HI")])
12415 (define_insn "*lshrhi3_cconly"
12416   [(set (reg FLAGS_REG)
12417         (compare
12418           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12419                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12420           (const_int 0)))
12421    (clobber (match_scratch:HI 0 "=r"))]
12422   "ix86_match_ccmode (insn, CCGOCmode)
12423    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12424    && (optimize_size
12425        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12426   "shr{w}\t{%2, %0|%0, %2}"
12427   [(set_attr "type" "ishift")
12428    (set_attr "mode" "HI")])
12430 (define_expand "lshrqi3"
12431   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12432         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12433                      (match_operand:QI 2 "nonmemory_operand" "")))
12434    (clobber (reg:CC FLAGS_REG))]
12435   "TARGET_QIMODE_MATH"
12436   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12438 (define_insn "*lshrqi3_1_one_bit"
12439   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12440         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12441                      (match_operand:QI 2 "const1_operand" "")))
12442    (clobber (reg:CC FLAGS_REG))]
12443   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12444    && (TARGET_SHIFT1 || optimize_size)"
12445   "shr{b}\t%0"
12446   [(set_attr "type" "ishift")
12447    (set (attr "length")
12448      (if_then_else (match_operand 0 "register_operand" "")
12449         (const_string "2")
12450         (const_string "*")))])
12452 (define_insn "*lshrqi3_1_one_bit_slp"
12453   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12454         (lshiftrt:QI (match_dup 0)
12455                      (match_operand:QI 1 "const1_operand" "")))
12456    (clobber (reg:CC FLAGS_REG))]
12457   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12458    && (TARGET_SHIFT1 || optimize_size)"
12459   "shr{b}\t%0"
12460   [(set_attr "type" "ishift1")
12461    (set (attr "length")
12462      (if_then_else (match_operand 0 "register_operand" "")
12463         (const_string "2")
12464         (const_string "*")))])
12466 (define_insn "*lshrqi3_1"
12467   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12468         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12469                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12470    (clobber (reg:CC FLAGS_REG))]
12471   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12472   "@
12473    shr{b}\t{%2, %0|%0, %2}
12474    shr{b}\t{%b2, %0|%0, %b2}"
12475   [(set_attr "type" "ishift")
12476    (set_attr "mode" "QI")])
12478 (define_insn "*lshrqi3_1_slp"
12479   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12480         (lshiftrt:QI (match_dup 0)
12481                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12482    (clobber (reg:CC FLAGS_REG))]
12483   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12484    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12485   "@
12486    shr{b}\t{%1, %0|%0, %1}
12487    shr{b}\t{%b1, %0|%0, %b1}"
12488   [(set_attr "type" "ishift1")
12489    (set_attr "mode" "QI")])
12491 ;; This pattern can't accept a variable shift count, since shifts by
12492 ;; zero don't affect the flags.  We assume that shifts by constant
12493 ;; zero are optimized away.
12494 (define_insn "*lshrqi2_one_bit_cmp"
12495   [(set (reg FLAGS_REG)
12496         (compare
12497           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12498                        (match_operand:QI 2 "const1_operand" ""))
12499           (const_int 0)))
12500    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12501         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12502   "ix86_match_ccmode (insn, CCGOCmode)
12503    && (TARGET_SHIFT1 || optimize_size)
12504    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12505   "shr{b}\t%0"
12506   [(set_attr "type" "ishift")
12507    (set (attr "length")
12508      (if_then_else (match_operand:SI 0 "register_operand" "")
12509         (const_string "2")
12510         (const_string "*")))])
12512 (define_insn "*lshrqi2_one_bit_cconly"
12513   [(set (reg FLAGS_REG)
12514         (compare
12515           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12516                        (match_operand:QI 2 "const1_operand" ""))
12517           (const_int 0)))
12518    (clobber (match_scratch:QI 0 "=q"))]
12519   "ix86_match_ccmode (insn, CCGOCmode)
12520    && (TARGET_SHIFT1 || optimize_size)
12521    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12522   "shr{b}\t%0"
12523   [(set_attr "type" "ishift")
12524    (set_attr "length" "2")])
12526 ;; This pattern can't accept a variable shift count, since shifts by
12527 ;; zero don't affect the flags.  We assume that shifts by constant
12528 ;; zero are optimized away.
12529 (define_insn "*lshrqi2_cmp"
12530   [(set (reg FLAGS_REG)
12531         (compare
12532           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12533                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12534           (const_int 0)))
12535    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12536         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12537   "ix86_match_ccmode (insn, CCGOCmode)
12538    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12539    && (optimize_size
12540        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12541   "shr{b}\t{%2, %0|%0, %2}"
12542   [(set_attr "type" "ishift")
12543    (set_attr "mode" "QI")])
12545 (define_insn "*lshrqi2_cconly"
12546   [(set (reg FLAGS_REG)
12547         (compare
12548           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12549                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12550           (const_int 0)))
12551    (clobber (match_scratch:QI 0 "=q"))]
12552   "ix86_match_ccmode (insn, CCGOCmode)
12553    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12554    && (optimize_size
12555        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12556   "shr{b}\t{%2, %0|%0, %2}"
12557   [(set_attr "type" "ishift")
12558    (set_attr "mode" "QI")])
12560 ;; Rotate instructions
12562 (define_expand "rotldi3"
12563   [(set (match_operand:DI 0 "shiftdi_operand" "")
12564         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12565                    (match_operand:QI 2 "nonmemory_operand" "")))
12566    (clobber (reg:CC FLAGS_REG))]
12567  ""
12569   if (TARGET_64BIT)
12570     {
12571       ix86_expand_binary_operator (ROTATE, DImode, operands);
12572       DONE;
12573     }
12574   if (!const_1_to_31_operand (operands[2], VOIDmode))
12575     FAIL;
12576   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12577   DONE;
12580 ;; Implement rotation using two double-precision shift instructions
12581 ;; and a scratch register.
12582 (define_insn_and_split "ix86_rotldi3"
12583  [(set (match_operand:DI 0 "register_operand" "=r")
12584        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12585                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12586   (clobber (reg:CC FLAGS_REG))
12587   (clobber (match_scratch:SI 3 "=&r"))]
12588  "!TARGET_64BIT"
12589  ""
12590  "&& reload_completed"
12591  [(set (match_dup 3) (match_dup 4))
12592   (parallel
12593    [(set (match_dup 4)
12594          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12595                  (lshiftrt:SI (match_dup 5)
12596                               (minus:QI (const_int 32) (match_dup 2)))))
12597     (clobber (reg:CC FLAGS_REG))])
12598   (parallel
12599    [(set (match_dup 5)
12600          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12601                  (lshiftrt:SI (match_dup 3)
12602                               (minus:QI (const_int 32) (match_dup 2)))))
12603     (clobber (reg:CC FLAGS_REG))])]
12604  "split_di (operands, 1, operands + 4, operands + 5);")
12606 (define_insn "*rotlsi3_1_one_bit_rex64"
12607   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12608         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12609                    (match_operand:QI 2 "const1_operand" "")))
12610    (clobber (reg:CC FLAGS_REG))]
12611   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12612    && (TARGET_SHIFT1 || optimize_size)"
12613   "rol{q}\t%0"
12614   [(set_attr "type" "rotate")
12615    (set (attr "length")
12616      (if_then_else (match_operand:DI 0 "register_operand" "")
12617         (const_string "2")
12618         (const_string "*")))])
12620 (define_insn "*rotldi3_1_rex64"
12621   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12622         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12623                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12624    (clobber (reg:CC FLAGS_REG))]
12625   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12626   "@
12627    rol{q}\t{%2, %0|%0, %2}
12628    rol{q}\t{%b2, %0|%0, %b2}"
12629   [(set_attr "type" "rotate")
12630    (set_attr "mode" "DI")])
12632 (define_expand "rotlsi3"
12633   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12634         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12635                    (match_operand:QI 2 "nonmemory_operand" "")))
12636    (clobber (reg:CC FLAGS_REG))]
12637   ""
12638   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12640 (define_insn "*rotlsi3_1_one_bit"
12641   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12642         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12643                    (match_operand:QI 2 "const1_operand" "")))
12644    (clobber (reg:CC FLAGS_REG))]
12645   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12646    && (TARGET_SHIFT1 || optimize_size)"
12647   "rol{l}\t%0"
12648   [(set_attr "type" "rotate")
12649    (set (attr "length")
12650      (if_then_else (match_operand:SI 0 "register_operand" "")
12651         (const_string "2")
12652         (const_string "*")))])
12654 (define_insn "*rotlsi3_1_one_bit_zext"
12655   [(set (match_operand:DI 0 "register_operand" "=r")
12656         (zero_extend:DI
12657           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12658                      (match_operand:QI 2 "const1_operand" ""))))
12659    (clobber (reg:CC FLAGS_REG))]
12660   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12661    && (TARGET_SHIFT1 || optimize_size)"
12662   "rol{l}\t%k0"
12663   [(set_attr "type" "rotate")
12664    (set_attr "length" "2")])
12666 (define_insn "*rotlsi3_1"
12667   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12668         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12669                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12670    (clobber (reg:CC FLAGS_REG))]
12671   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12672   "@
12673    rol{l}\t{%2, %0|%0, %2}
12674    rol{l}\t{%b2, %0|%0, %b2}"
12675   [(set_attr "type" "rotate")
12676    (set_attr "mode" "SI")])
12678 (define_insn "*rotlsi3_1_zext"
12679   [(set (match_operand:DI 0 "register_operand" "=r,r")
12680         (zero_extend:DI
12681           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12682                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12683    (clobber (reg:CC FLAGS_REG))]
12684   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12685   "@
12686    rol{l}\t{%2, %k0|%k0, %2}
12687    rol{l}\t{%b2, %k0|%k0, %b2}"
12688   [(set_attr "type" "rotate")
12689    (set_attr "mode" "SI")])
12691 (define_expand "rotlhi3"
12692   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12693         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12694                    (match_operand:QI 2 "nonmemory_operand" "")))
12695    (clobber (reg:CC FLAGS_REG))]
12696   "TARGET_HIMODE_MATH"
12697   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12699 (define_insn "*rotlhi3_1_one_bit"
12700   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12701         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12702                    (match_operand:QI 2 "const1_operand" "")))
12703    (clobber (reg:CC FLAGS_REG))]
12704   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12705    && (TARGET_SHIFT1 || optimize_size)"
12706   "rol{w}\t%0"
12707   [(set_attr "type" "rotate")
12708    (set (attr "length")
12709      (if_then_else (match_operand 0 "register_operand" "")
12710         (const_string "2")
12711         (const_string "*")))])
12713 (define_insn "*rotlhi3_1"
12714   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12715         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12716                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12717    (clobber (reg:CC FLAGS_REG))]
12718   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12719   "@
12720    rol{w}\t{%2, %0|%0, %2}
12721    rol{w}\t{%b2, %0|%0, %b2}"
12722   [(set_attr "type" "rotate")
12723    (set_attr "mode" "HI")])
12725 (define_expand "rotlqi3"
12726   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12727         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12728                    (match_operand:QI 2 "nonmemory_operand" "")))
12729    (clobber (reg:CC FLAGS_REG))]
12730   "TARGET_QIMODE_MATH"
12731   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12733 (define_insn "*rotlqi3_1_one_bit_slp"
12734   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12735         (rotate:QI (match_dup 0)
12736                    (match_operand:QI 1 "const1_operand" "")))
12737    (clobber (reg:CC FLAGS_REG))]
12738   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12739    && (TARGET_SHIFT1 || optimize_size)"
12740   "rol{b}\t%0"
12741   [(set_attr "type" "rotate1")
12742    (set (attr "length")
12743      (if_then_else (match_operand 0 "register_operand" "")
12744         (const_string "2")
12745         (const_string "*")))])
12747 (define_insn "*rotlqi3_1_one_bit"
12748   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12749         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12750                    (match_operand:QI 2 "const1_operand" "")))
12751    (clobber (reg:CC FLAGS_REG))]
12752   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12753    && (TARGET_SHIFT1 || optimize_size)"
12754   "rol{b}\t%0"
12755   [(set_attr "type" "rotate")
12756    (set (attr "length")
12757      (if_then_else (match_operand 0 "register_operand" "")
12758         (const_string "2")
12759         (const_string "*")))])
12761 (define_insn "*rotlqi3_1_slp"
12762   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12763         (rotate:QI (match_dup 0)
12764                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12765    (clobber (reg:CC FLAGS_REG))]
12766   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12767    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12768   "@
12769    rol{b}\t{%1, %0|%0, %1}
12770    rol{b}\t{%b1, %0|%0, %b1}"
12771   [(set_attr "type" "rotate1")
12772    (set_attr "mode" "QI")])
12774 (define_insn "*rotlqi3_1"
12775   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12776         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12777                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12778    (clobber (reg:CC FLAGS_REG))]
12779   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12780   "@
12781    rol{b}\t{%2, %0|%0, %2}
12782    rol{b}\t{%b2, %0|%0, %b2}"
12783   [(set_attr "type" "rotate")
12784    (set_attr "mode" "QI")])
12786 (define_expand "rotrdi3"
12787   [(set (match_operand:DI 0 "shiftdi_operand" "")
12788         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12789                    (match_operand:QI 2 "nonmemory_operand" "")))
12790    (clobber (reg:CC FLAGS_REG))]
12791  ""
12793   if (TARGET_64BIT)
12794     {
12795       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12796       DONE;
12797     }
12798   if (!const_1_to_31_operand (operands[2], VOIDmode))
12799     FAIL;
12800   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12801   DONE;
12804 ;; Implement rotation using two double-precision shift instructions
12805 ;; and a scratch register.
12806 (define_insn_and_split "ix86_rotrdi3"
12807  [(set (match_operand:DI 0 "register_operand" "=r")
12808        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12809                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12810   (clobber (reg:CC FLAGS_REG))
12811   (clobber (match_scratch:SI 3 "=&r"))]
12812  "!TARGET_64BIT"
12813  ""
12814  "&& reload_completed"
12815  [(set (match_dup 3) (match_dup 4))
12816   (parallel
12817    [(set (match_dup 4)
12818          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12819                  (ashift:SI (match_dup 5)
12820                             (minus:QI (const_int 32) (match_dup 2)))))
12821     (clobber (reg:CC FLAGS_REG))])
12822   (parallel
12823    [(set (match_dup 5)
12824          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12825                  (ashift:SI (match_dup 3)
12826                             (minus:QI (const_int 32) (match_dup 2)))))
12827     (clobber (reg:CC FLAGS_REG))])]
12828  "split_di (operands, 1, operands + 4, operands + 5);")
12830 (define_insn "*rotrdi3_1_one_bit_rex64"
12831   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12832         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12833                      (match_operand:QI 2 "const1_operand" "")))
12834    (clobber (reg:CC FLAGS_REG))]
12835   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12836    && (TARGET_SHIFT1 || optimize_size)"
12837   "ror{q}\t%0"
12838   [(set_attr "type" "rotate")
12839    (set (attr "length")
12840      (if_then_else (match_operand:DI 0 "register_operand" "")
12841         (const_string "2")
12842         (const_string "*")))])
12844 (define_insn "*rotrdi3_1_rex64"
12845   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12846         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12847                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12848    (clobber (reg:CC FLAGS_REG))]
12849   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12850   "@
12851    ror{q}\t{%2, %0|%0, %2}
12852    ror{q}\t{%b2, %0|%0, %b2}"
12853   [(set_attr "type" "rotate")
12854    (set_attr "mode" "DI")])
12856 (define_expand "rotrsi3"
12857   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12858         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12859                      (match_operand:QI 2 "nonmemory_operand" "")))
12860    (clobber (reg:CC FLAGS_REG))]
12861   ""
12862   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12864 (define_insn "*rotrsi3_1_one_bit"
12865   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12866         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12867                      (match_operand:QI 2 "const1_operand" "")))
12868    (clobber (reg:CC FLAGS_REG))]
12869   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12870    && (TARGET_SHIFT1 || optimize_size)"
12871   "ror{l}\t%0"
12872   [(set_attr "type" "rotate")
12873    (set (attr "length")
12874      (if_then_else (match_operand:SI 0 "register_operand" "")
12875         (const_string "2")
12876         (const_string "*")))])
12878 (define_insn "*rotrsi3_1_one_bit_zext"
12879   [(set (match_operand:DI 0 "register_operand" "=r")
12880         (zero_extend:DI
12881           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12882                        (match_operand:QI 2 "const1_operand" ""))))
12883    (clobber (reg:CC FLAGS_REG))]
12884   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12885    && (TARGET_SHIFT1 || optimize_size)"
12886   "ror{l}\t%k0"
12887   [(set_attr "type" "rotate")
12888    (set (attr "length")
12889      (if_then_else (match_operand:SI 0 "register_operand" "")
12890         (const_string "2")
12891         (const_string "*")))])
12893 (define_insn "*rotrsi3_1"
12894   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12895         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12896                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12897    (clobber (reg:CC FLAGS_REG))]
12898   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12899   "@
12900    ror{l}\t{%2, %0|%0, %2}
12901    ror{l}\t{%b2, %0|%0, %b2}"
12902   [(set_attr "type" "rotate")
12903    (set_attr "mode" "SI")])
12905 (define_insn "*rotrsi3_1_zext"
12906   [(set (match_operand:DI 0 "register_operand" "=r,r")
12907         (zero_extend:DI
12908           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12909                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12910    (clobber (reg:CC FLAGS_REG))]
12911   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12912   "@
12913    ror{l}\t{%2, %k0|%k0, %2}
12914    ror{l}\t{%b2, %k0|%k0, %b2}"
12915   [(set_attr "type" "rotate")
12916    (set_attr "mode" "SI")])
12918 (define_expand "rotrhi3"
12919   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12920         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12921                      (match_operand:QI 2 "nonmemory_operand" "")))
12922    (clobber (reg:CC FLAGS_REG))]
12923   "TARGET_HIMODE_MATH"
12924   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12926 (define_insn "*rotrhi3_one_bit"
12927   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12928         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12929                      (match_operand:QI 2 "const1_operand" "")))
12930    (clobber (reg:CC FLAGS_REG))]
12931   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12932    && (TARGET_SHIFT1 || optimize_size)"
12933   "ror{w}\t%0"
12934   [(set_attr "type" "rotate")
12935    (set (attr "length")
12936      (if_then_else (match_operand 0 "register_operand" "")
12937         (const_string "2")
12938         (const_string "*")))])
12940 (define_insn "*rotrhi3"
12941   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12942         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12943                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12944    (clobber (reg:CC FLAGS_REG))]
12945   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12946   "@
12947    ror{w}\t{%2, %0|%0, %2}
12948    ror{w}\t{%b2, %0|%0, %b2}"
12949   [(set_attr "type" "rotate")
12950    (set_attr "mode" "HI")])
12952 (define_expand "rotrqi3"
12953   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12954         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12955                      (match_operand:QI 2 "nonmemory_operand" "")))
12956    (clobber (reg:CC FLAGS_REG))]
12957   "TARGET_QIMODE_MATH"
12958   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12960 (define_insn "*rotrqi3_1_one_bit"
12961   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12962         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12963                      (match_operand:QI 2 "const1_operand" "")))
12964    (clobber (reg:CC FLAGS_REG))]
12965   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12966    && (TARGET_SHIFT1 || optimize_size)"
12967   "ror{b}\t%0"
12968   [(set_attr "type" "rotate")
12969    (set (attr "length")
12970      (if_then_else (match_operand 0 "register_operand" "")
12971         (const_string "2")
12972         (const_string "*")))])
12974 (define_insn "*rotrqi3_1_one_bit_slp"
12975   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12976         (rotatert:QI (match_dup 0)
12977                      (match_operand:QI 1 "const1_operand" "")))
12978    (clobber (reg:CC FLAGS_REG))]
12979   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12980    && (TARGET_SHIFT1 || optimize_size)"
12981   "ror{b}\t%0"
12982   [(set_attr "type" "rotate1")
12983    (set (attr "length")
12984      (if_then_else (match_operand 0 "register_operand" "")
12985         (const_string "2")
12986         (const_string "*")))])
12988 (define_insn "*rotrqi3_1"
12989   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12990         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12991                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12992    (clobber (reg:CC FLAGS_REG))]
12993   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12994   "@
12995    ror{b}\t{%2, %0|%0, %2}
12996    ror{b}\t{%b2, %0|%0, %b2}"
12997   [(set_attr "type" "rotate")
12998    (set_attr "mode" "QI")])
13000 (define_insn "*rotrqi3_1_slp"
13001   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13002         (rotatert:QI (match_dup 0)
13003                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13004    (clobber (reg:CC FLAGS_REG))]
13005   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13006    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13007   "@
13008    ror{b}\t{%1, %0|%0, %1}
13009    ror{b}\t{%b1, %0|%0, %b1}"
13010   [(set_attr "type" "rotate1")
13011    (set_attr "mode" "QI")])
13013 ;; Bit set / bit test instructions
13015 (define_expand "extv"
13016   [(set (match_operand:SI 0 "register_operand" "")
13017         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13018                          (match_operand:SI 2 "const8_operand" "")
13019                          (match_operand:SI 3 "const8_operand" "")))]
13020   ""
13022   /* Handle extractions from %ah et al.  */
13023   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13024     FAIL;
13026   /* From mips.md: extract_bit_field doesn't verify that our source
13027      matches the predicate, so check it again here.  */
13028   if (! ext_register_operand (operands[1], VOIDmode))
13029     FAIL;
13032 (define_expand "extzv"
13033   [(set (match_operand:SI 0 "register_operand" "")
13034         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13035                          (match_operand:SI 2 "const8_operand" "")
13036                          (match_operand:SI 3 "const8_operand" "")))]
13037   ""
13039   /* Handle extractions from %ah et al.  */
13040   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13041     FAIL;
13043   /* From mips.md: extract_bit_field doesn't verify that our source
13044      matches the predicate, so check it again here.  */
13045   if (! ext_register_operand (operands[1], VOIDmode))
13046     FAIL;
13049 (define_expand "insv"
13050   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13051                       (match_operand 1 "const8_operand" "")
13052                       (match_operand 2 "const8_operand" ""))
13053         (match_operand 3 "register_operand" ""))]
13054   ""
13056   /* Handle insertions to %ah et al.  */
13057   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13058     FAIL;
13060   /* From mips.md: insert_bit_field doesn't verify that our source
13061      matches the predicate, so check it again here.  */
13062   if (! ext_register_operand (operands[0], VOIDmode))
13063     FAIL;
13065   if (TARGET_64BIT)
13066     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13067   else
13068     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13070   DONE;
13073 ;; %%% bts, btr, btc, bt.
13074 ;; In general these instructions are *slow* when applied to memory,
13075 ;; since they enforce atomic operation.  When applied to registers,
13076 ;; it depends on the cpu implementation.  They're never faster than
13077 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13078 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13079 ;; within the instruction itself, so operating on bits in the high
13080 ;; 32-bits of a register becomes easier.
13082 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13083 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13084 ;; negdf respectively, so they can never be disabled entirely.
13086 (define_insn "*btsq"
13087   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13088                          (const_int 1)
13089                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13090         (const_int 1))
13091    (clobber (reg:CC FLAGS_REG))]
13092   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13093   "bts{q} %1,%0"
13094   [(set_attr "type" "alu1")])
13096 (define_insn "*btrq"
13097   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13098                          (const_int 1)
13099                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13100         (const_int 0))
13101    (clobber (reg:CC FLAGS_REG))]
13102   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13103   "btr{q} %1,%0"
13104   [(set_attr "type" "alu1")])
13106 (define_insn "*btcq"
13107   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13108                          (const_int 1)
13109                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13110         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13111    (clobber (reg:CC FLAGS_REG))]
13112   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13113   "btc{q} %1,%0"
13114   [(set_attr "type" "alu1")])
13116 ;; Allow Nocona to avoid these instructions if a register is available.
13118 (define_peephole2
13119   [(match_scratch:DI 2 "r")
13120    (parallel [(set (zero_extract:DI
13121                      (match_operand:DI 0 "register_operand" "")
13122                      (const_int 1)
13123                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13124                    (const_int 1))
13125               (clobber (reg:CC FLAGS_REG))])]
13126   "TARGET_64BIT && !TARGET_USE_BT"
13127   [(const_int 0)]
13129   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13130   rtx op1;
13132   if (HOST_BITS_PER_WIDE_INT >= 64)
13133     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13134   else if (i < HOST_BITS_PER_WIDE_INT)
13135     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13136   else
13137     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13139   op1 = immed_double_const (lo, hi, DImode);
13140   if (i >= 31)
13141     {
13142       emit_move_insn (operands[2], op1);
13143       op1 = operands[2];
13144     }
13146   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13147   DONE;
13150 (define_peephole2
13151   [(match_scratch:DI 2 "r")
13152    (parallel [(set (zero_extract:DI
13153                      (match_operand:DI 0 "register_operand" "")
13154                      (const_int 1)
13155                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13156                    (const_int 0))
13157               (clobber (reg:CC FLAGS_REG))])]
13158   "TARGET_64BIT && !TARGET_USE_BT"
13159   [(const_int 0)]
13161   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13162   rtx op1;
13164   if (HOST_BITS_PER_WIDE_INT >= 64)
13165     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13166   else if (i < HOST_BITS_PER_WIDE_INT)
13167     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13168   else
13169     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13171   op1 = immed_double_const (~lo, ~hi, DImode);
13172   if (i >= 32)
13173     {
13174       emit_move_insn (operands[2], op1);
13175       op1 = operands[2];
13176     }
13178   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13179   DONE;
13182 (define_peephole2
13183   [(match_scratch:DI 2 "r")
13184    (parallel [(set (zero_extract:DI
13185                      (match_operand:DI 0 "register_operand" "")
13186                      (const_int 1)
13187                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13188               (not:DI (zero_extract:DI
13189                         (match_dup 0) (const_int 1) (match_dup 1))))
13190               (clobber (reg:CC FLAGS_REG))])]
13191   "TARGET_64BIT && !TARGET_USE_BT"
13192   [(const_int 0)]
13194   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13195   rtx op1;
13197   if (HOST_BITS_PER_WIDE_INT >= 64)
13198     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13199   else if (i < HOST_BITS_PER_WIDE_INT)
13200     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13201   else
13202     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13204   op1 = immed_double_const (lo, hi, DImode);
13205   if (i >= 31)
13206     {
13207       emit_move_insn (operands[2], op1);
13208       op1 = operands[2];
13209     }
13211   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13212   DONE;
13215 ;; Store-flag instructions.
13217 ;; For all sCOND expanders, also expand the compare or test insn that
13218 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13220 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13221 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13222 ;; way, which can later delete the movzx if only QImode is needed.
13224 (define_expand "seq"
13225   [(set (match_operand:QI 0 "register_operand" "")
13226         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13227   ""
13228   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13230 (define_expand "sne"
13231   [(set (match_operand:QI 0 "register_operand" "")
13232         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13233   ""
13234   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13236 (define_expand "sgt"
13237   [(set (match_operand:QI 0 "register_operand" "")
13238         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13239   ""
13240   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13242 (define_expand "sgtu"
13243   [(set (match_operand:QI 0 "register_operand" "")
13244         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13245   ""
13246   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13248 (define_expand "slt"
13249   [(set (match_operand:QI 0 "register_operand" "")
13250         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13251   ""
13252   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13254 (define_expand "sltu"
13255   [(set (match_operand:QI 0 "register_operand" "")
13256         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257   ""
13258   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13260 (define_expand "sge"
13261   [(set (match_operand:QI 0 "register_operand" "")
13262         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263   ""
13264   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13266 (define_expand "sgeu"
13267   [(set (match_operand:QI 0 "register_operand" "")
13268         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13269   ""
13270   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13272 (define_expand "sle"
13273   [(set (match_operand:QI 0 "register_operand" "")
13274         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13275   ""
13276   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13278 (define_expand "sleu"
13279   [(set (match_operand:QI 0 "register_operand" "")
13280         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13281   ""
13282   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13284 (define_expand "sunordered"
13285   [(set (match_operand:QI 0 "register_operand" "")
13286         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13287   "TARGET_80387 || TARGET_SSE"
13288   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13290 (define_expand "sordered"
13291   [(set (match_operand:QI 0 "register_operand" "")
13292         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13293   "TARGET_80387"
13294   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13296 (define_expand "suneq"
13297   [(set (match_operand:QI 0 "register_operand" "")
13298         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13299   "TARGET_80387 || TARGET_SSE"
13300   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13302 (define_expand "sunge"
13303   [(set (match_operand:QI 0 "register_operand" "")
13304         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13305   "TARGET_80387 || TARGET_SSE"
13306   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13308 (define_expand "sungt"
13309   [(set (match_operand:QI 0 "register_operand" "")
13310         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13311   "TARGET_80387 || TARGET_SSE"
13312   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13314 (define_expand "sunle"
13315   [(set (match_operand:QI 0 "register_operand" "")
13316         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13317   "TARGET_80387 || TARGET_SSE"
13318   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13320 (define_expand "sunlt"
13321   [(set (match_operand:QI 0 "register_operand" "")
13322         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13323   "TARGET_80387 || TARGET_SSE"
13324   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13326 (define_expand "sltgt"
13327   [(set (match_operand:QI 0 "register_operand" "")
13328         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13329   "TARGET_80387 || TARGET_SSE"
13330   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13332 (define_insn "*setcc_1"
13333   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13334         (match_operator:QI 1 "ix86_comparison_operator"
13335           [(reg FLAGS_REG) (const_int 0)]))]
13336   ""
13337   "set%C1\t%0"
13338   [(set_attr "type" "setcc")
13339    (set_attr "mode" "QI")])
13341 (define_insn "*setcc_2"
13342   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13343         (match_operator:QI 1 "ix86_comparison_operator"
13344           [(reg FLAGS_REG) (const_int 0)]))]
13345   ""
13346   "set%C1\t%0"
13347   [(set_attr "type" "setcc")
13348    (set_attr "mode" "QI")])
13350 ;; In general it is not safe to assume too much about CCmode registers,
13351 ;; so simplify-rtx stops when it sees a second one.  Under certain
13352 ;; conditions this is safe on x86, so help combine not create
13354 ;;      seta    %al
13355 ;;      testb   %al, %al
13356 ;;      sete    %al
13358 (define_split
13359   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13360         (ne:QI (match_operator 1 "ix86_comparison_operator"
13361                  [(reg FLAGS_REG) (const_int 0)])
13362             (const_int 0)))]
13363   ""
13364   [(set (match_dup 0) (match_dup 1))]
13366   PUT_MODE (operands[1], QImode);
13369 (define_split
13370   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13371         (ne:QI (match_operator 1 "ix86_comparison_operator"
13372                  [(reg FLAGS_REG) (const_int 0)])
13373             (const_int 0)))]
13374   ""
13375   [(set (match_dup 0) (match_dup 1))]
13377   PUT_MODE (operands[1], QImode);
13380 (define_split
13381   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13382         (eq:QI (match_operator 1 "ix86_comparison_operator"
13383                  [(reg FLAGS_REG) (const_int 0)])
13384             (const_int 0)))]
13385   ""
13386   [(set (match_dup 0) (match_dup 1))]
13388   rtx new_op1 = copy_rtx (operands[1]);
13389   operands[1] = new_op1;
13390   PUT_MODE (new_op1, QImode);
13391   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13392                                              GET_MODE (XEXP (new_op1, 0))));
13394   /* Make sure that (a) the CCmode we have for the flags is strong
13395      enough for the reversed compare or (b) we have a valid FP compare.  */
13396   if (! ix86_comparison_operator (new_op1, VOIDmode))
13397     FAIL;
13400 (define_split
13401   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13402         (eq:QI (match_operator 1 "ix86_comparison_operator"
13403                  [(reg FLAGS_REG) (const_int 0)])
13404             (const_int 0)))]
13405   ""
13406   [(set (match_dup 0) (match_dup 1))]
13408   rtx new_op1 = copy_rtx (operands[1]);
13409   operands[1] = new_op1;
13410   PUT_MODE (new_op1, QImode);
13411   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13412                                              GET_MODE (XEXP (new_op1, 0))));
13414   /* Make sure that (a) the CCmode we have for the flags is strong
13415      enough for the reversed compare or (b) we have a valid FP compare.  */
13416   if (! ix86_comparison_operator (new_op1, VOIDmode))
13417     FAIL;
13420 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13421 ;; subsequent logical operations are used to imitate conditional moves.
13422 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13423 ;; it directly.
13425 (define_insn "*sse_setccsf"
13426   [(set (match_operand:SF 0 "register_operand" "=x")
13427         (match_operator:SF 1 "sse_comparison_operator"
13428           [(match_operand:SF 2 "register_operand" "0")
13429            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13430   "TARGET_SSE"
13431   "cmp%D1ss\t{%3, %0|%0, %3}"
13432   [(set_attr "type" "ssecmp")
13433    (set_attr "mode" "SF")])
13435 (define_insn "*sse_setccdf"
13436   [(set (match_operand:DF 0 "register_operand" "=Y")
13437         (match_operator:DF 1 "sse_comparison_operator"
13438           [(match_operand:DF 2 "register_operand" "0")
13439            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13440   "TARGET_SSE2"
13441   "cmp%D1sd\t{%3, %0|%0, %3}"
13442   [(set_attr "type" "ssecmp")
13443    (set_attr "mode" "DF")])
13445 ;; Basic conditional jump instructions.
13446 ;; We ignore the overflow flag for signed branch instructions.
13448 ;; For all bCOND expanders, also expand the compare or test insn that
13449 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13451 (define_expand "beq"
13452   [(set (pc)
13453         (if_then_else (match_dup 1)
13454                       (label_ref (match_operand 0 "" ""))
13455                       (pc)))]
13456   ""
13457   "ix86_expand_branch (EQ, operands[0]); DONE;")
13459 (define_expand "bne"
13460   [(set (pc)
13461         (if_then_else (match_dup 1)
13462                       (label_ref (match_operand 0 "" ""))
13463                       (pc)))]
13464   ""
13465   "ix86_expand_branch (NE, operands[0]); DONE;")
13467 (define_expand "bgt"
13468   [(set (pc)
13469         (if_then_else (match_dup 1)
13470                       (label_ref (match_operand 0 "" ""))
13471                       (pc)))]
13472   ""
13473   "ix86_expand_branch (GT, operands[0]); DONE;")
13475 (define_expand "bgtu"
13476   [(set (pc)
13477         (if_then_else (match_dup 1)
13478                       (label_ref (match_operand 0 "" ""))
13479                       (pc)))]
13480   ""
13481   "ix86_expand_branch (GTU, operands[0]); DONE;")
13483 (define_expand "blt"
13484   [(set (pc)
13485         (if_then_else (match_dup 1)
13486                       (label_ref (match_operand 0 "" ""))
13487                       (pc)))]
13488   ""
13489   "ix86_expand_branch (LT, operands[0]); DONE;")
13491 (define_expand "bltu"
13492   [(set (pc)
13493         (if_then_else (match_dup 1)
13494                       (label_ref (match_operand 0 "" ""))
13495                       (pc)))]
13496   ""
13497   "ix86_expand_branch (LTU, operands[0]); DONE;")
13499 (define_expand "bge"
13500   [(set (pc)
13501         (if_then_else (match_dup 1)
13502                       (label_ref (match_operand 0 "" ""))
13503                       (pc)))]
13504   ""
13505   "ix86_expand_branch (GE, operands[0]); DONE;")
13507 (define_expand "bgeu"
13508   [(set (pc)
13509         (if_then_else (match_dup 1)
13510                       (label_ref (match_operand 0 "" ""))
13511                       (pc)))]
13512   ""
13513   "ix86_expand_branch (GEU, operands[0]); DONE;")
13515 (define_expand "ble"
13516   [(set (pc)
13517         (if_then_else (match_dup 1)
13518                       (label_ref (match_operand 0 "" ""))
13519                       (pc)))]
13520   ""
13521   "ix86_expand_branch (LE, operands[0]); DONE;")
13523 (define_expand "bleu"
13524   [(set (pc)
13525         (if_then_else (match_dup 1)
13526                       (label_ref (match_operand 0 "" ""))
13527                       (pc)))]
13528   ""
13529   "ix86_expand_branch (LEU, operands[0]); DONE;")
13531 (define_expand "bunordered"
13532   [(set (pc)
13533         (if_then_else (match_dup 1)
13534                       (label_ref (match_operand 0 "" ""))
13535                       (pc)))]
13536   "TARGET_80387 || TARGET_SSE_MATH"
13537   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13539 (define_expand "bordered"
13540   [(set (pc)
13541         (if_then_else (match_dup 1)
13542                       (label_ref (match_operand 0 "" ""))
13543                       (pc)))]
13544   "TARGET_80387 || TARGET_SSE_MATH"
13545   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13547 (define_expand "buneq"
13548   [(set (pc)
13549         (if_then_else (match_dup 1)
13550                       (label_ref (match_operand 0 "" ""))
13551                       (pc)))]
13552   "TARGET_80387 || TARGET_SSE_MATH"
13553   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13555 (define_expand "bunge"
13556   [(set (pc)
13557         (if_then_else (match_dup 1)
13558                       (label_ref (match_operand 0 "" ""))
13559                       (pc)))]
13560   "TARGET_80387 || TARGET_SSE_MATH"
13561   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13563 (define_expand "bungt"
13564   [(set (pc)
13565         (if_then_else (match_dup 1)
13566                       (label_ref (match_operand 0 "" ""))
13567                       (pc)))]
13568   "TARGET_80387 || TARGET_SSE_MATH"
13569   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13571 (define_expand "bunle"
13572   [(set (pc)
13573         (if_then_else (match_dup 1)
13574                       (label_ref (match_operand 0 "" ""))
13575                       (pc)))]
13576   "TARGET_80387 || TARGET_SSE_MATH"
13577   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13579 (define_expand "bunlt"
13580   [(set (pc)
13581         (if_then_else (match_dup 1)
13582                       (label_ref (match_operand 0 "" ""))
13583                       (pc)))]
13584   "TARGET_80387 || TARGET_SSE_MATH"
13585   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13587 (define_expand "bltgt"
13588   [(set (pc)
13589         (if_then_else (match_dup 1)
13590                       (label_ref (match_operand 0 "" ""))
13591                       (pc)))]
13592   "TARGET_80387 || TARGET_SSE_MATH"
13593   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13595 (define_insn "*jcc_1"
13596   [(set (pc)
13597         (if_then_else (match_operator 1 "ix86_comparison_operator"
13598                                       [(reg FLAGS_REG) (const_int 0)])
13599                       (label_ref (match_operand 0 "" ""))
13600                       (pc)))]
13601   ""
13602   "%+j%C1\t%l0"
13603   [(set_attr "type" "ibr")
13604    (set_attr "modrm" "0")
13605    (set (attr "length")
13606            (if_then_else (and (ge (minus (match_dup 0) (pc))
13607                                   (const_int -126))
13608                               (lt (minus (match_dup 0) (pc))
13609                                   (const_int 128)))
13610              (const_int 2)
13611              (const_int 6)))])
13613 (define_insn "*jcc_2"
13614   [(set (pc)
13615         (if_then_else (match_operator 1 "ix86_comparison_operator"
13616                                       [(reg FLAGS_REG) (const_int 0)])
13617                       (pc)
13618                       (label_ref (match_operand 0 "" ""))))]
13619   ""
13620   "%+j%c1\t%l0"
13621   [(set_attr "type" "ibr")
13622    (set_attr "modrm" "0")
13623    (set (attr "length")
13624            (if_then_else (and (ge (minus (match_dup 0) (pc))
13625                                   (const_int -126))
13626                               (lt (minus (match_dup 0) (pc))
13627                                   (const_int 128)))
13628              (const_int 2)
13629              (const_int 6)))])
13631 ;; In general it is not safe to assume too much about CCmode registers,
13632 ;; so simplify-rtx stops when it sees a second one.  Under certain
13633 ;; conditions this is safe on x86, so help combine not create
13635 ;;      seta    %al
13636 ;;      testb   %al, %al
13637 ;;      je      Lfoo
13639 (define_split
13640   [(set (pc)
13641         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13642                                       [(reg FLAGS_REG) (const_int 0)])
13643                           (const_int 0))
13644                       (label_ref (match_operand 1 "" ""))
13645                       (pc)))]
13646   ""
13647   [(set (pc)
13648         (if_then_else (match_dup 0)
13649                       (label_ref (match_dup 1))
13650                       (pc)))]
13652   PUT_MODE (operands[0], VOIDmode);
13655 (define_split
13656   [(set (pc)
13657         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13658                                       [(reg FLAGS_REG) (const_int 0)])
13659                           (const_int 0))
13660                       (label_ref (match_operand 1 "" ""))
13661                       (pc)))]
13662   ""
13663   [(set (pc)
13664         (if_then_else (match_dup 0)
13665                       (label_ref (match_dup 1))
13666                       (pc)))]
13668   rtx new_op0 = copy_rtx (operands[0]);
13669   operands[0] = new_op0;
13670   PUT_MODE (new_op0, VOIDmode);
13671   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13672                                              GET_MODE (XEXP (new_op0, 0))));
13674   /* Make sure that (a) the CCmode we have for the flags is strong
13675      enough for the reversed compare or (b) we have a valid FP compare.  */
13676   if (! ix86_comparison_operator (new_op0, VOIDmode))
13677     FAIL;
13680 ;; Define combination compare-and-branch fp compare instructions to use
13681 ;; during early optimization.  Splitting the operation apart early makes
13682 ;; for bad code when we want to reverse the operation.
13684 (define_insn "*fp_jcc_1_mixed"
13685   [(set (pc)
13686         (if_then_else (match_operator 0 "comparison_operator"
13687                         [(match_operand 1 "register_operand" "f,x")
13688                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13689           (label_ref (match_operand 3 "" ""))
13690           (pc)))
13691    (clobber (reg:CCFP FPSR_REG))
13692    (clobber (reg:CCFP FLAGS_REG))]
13693   "TARGET_MIX_SSE_I387
13694    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13695    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13696    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13697   "#")
13699 (define_insn "*fp_jcc_1_sse"
13700   [(set (pc)
13701         (if_then_else (match_operator 0 "comparison_operator"
13702                         [(match_operand 1 "register_operand" "x")
13703                          (match_operand 2 "nonimmediate_operand" "xm")])
13704           (label_ref (match_operand 3 "" ""))
13705           (pc)))
13706    (clobber (reg:CCFP FPSR_REG))
13707    (clobber (reg:CCFP FLAGS_REG))]
13708   "TARGET_SSE_MATH
13709    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13710    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13711    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13712   "#")
13714 (define_insn "*fp_jcc_1_387"
13715   [(set (pc)
13716         (if_then_else (match_operator 0 "comparison_operator"
13717                         [(match_operand 1 "register_operand" "f")
13718                          (match_operand 2 "register_operand" "f")])
13719           (label_ref (match_operand 3 "" ""))
13720           (pc)))
13721    (clobber (reg:CCFP FPSR_REG))
13722    (clobber (reg:CCFP FLAGS_REG))]
13723   "TARGET_CMOVE && TARGET_80387
13724    && FLOAT_MODE_P (GET_MODE (operands[1]))
13725    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13726    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13727   "#")
13729 (define_insn "*fp_jcc_2_mixed"
13730   [(set (pc)
13731         (if_then_else (match_operator 0 "comparison_operator"
13732                         [(match_operand 1 "register_operand" "f,x")
13733                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13734           (pc)
13735           (label_ref (match_operand 3 "" ""))))
13736    (clobber (reg:CCFP FPSR_REG))
13737    (clobber (reg:CCFP FLAGS_REG))]
13738   "TARGET_MIX_SSE_I387
13739    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13740    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13741    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13742   "#")
13744 (define_insn "*fp_jcc_2_sse"
13745   [(set (pc)
13746         (if_then_else (match_operator 0 "comparison_operator"
13747                         [(match_operand 1 "register_operand" "x")
13748                          (match_operand 2 "nonimmediate_operand" "xm")])
13749           (pc)
13750           (label_ref (match_operand 3 "" ""))))
13751    (clobber (reg:CCFP FPSR_REG))
13752    (clobber (reg:CCFP FLAGS_REG))]
13753   "TARGET_SSE_MATH
13754    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13755    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13756    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13757   "#")
13759 (define_insn "*fp_jcc_2_387"
13760   [(set (pc)
13761         (if_then_else (match_operator 0 "comparison_operator"
13762                         [(match_operand 1 "register_operand" "f")
13763                          (match_operand 2 "register_operand" "f")])
13764           (pc)
13765           (label_ref (match_operand 3 "" ""))))
13766    (clobber (reg:CCFP FPSR_REG))
13767    (clobber (reg:CCFP FLAGS_REG))]
13768   "TARGET_CMOVE && TARGET_80387
13769    && FLOAT_MODE_P (GET_MODE (operands[1]))
13770    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13772   "#")
13774 (define_insn "*fp_jcc_3_387"
13775   [(set (pc)
13776         (if_then_else (match_operator 0 "comparison_operator"
13777                         [(match_operand 1 "register_operand" "f")
13778                          (match_operand 2 "nonimmediate_operand" "fm")])
13779           (label_ref (match_operand 3 "" ""))
13780           (pc)))
13781    (clobber (reg:CCFP FPSR_REG))
13782    (clobber (reg:CCFP FLAGS_REG))
13783    (clobber (match_scratch:HI 4 "=a"))]
13784   "TARGET_80387
13785    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13786    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13787    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13788    && SELECT_CC_MODE (GET_CODE (operands[0]),
13789                       operands[1], operands[2]) == CCFPmode
13790    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13791   "#")
13793 (define_insn "*fp_jcc_4_387"
13794   [(set (pc)
13795         (if_then_else (match_operator 0 "comparison_operator"
13796                         [(match_operand 1 "register_operand" "f")
13797                          (match_operand 2 "nonimmediate_operand" "fm")])
13798           (pc)
13799           (label_ref (match_operand 3 "" ""))))
13800    (clobber (reg:CCFP FPSR_REG))
13801    (clobber (reg:CCFP FLAGS_REG))
13802    (clobber (match_scratch:HI 4 "=a"))]
13803   "TARGET_80387
13804    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13805    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13806    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13807    && SELECT_CC_MODE (GET_CODE (operands[0]),
13808                       operands[1], operands[2]) == CCFPmode
13809    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13810   "#")
13812 (define_insn "*fp_jcc_5_387"
13813   [(set (pc)
13814         (if_then_else (match_operator 0 "comparison_operator"
13815                         [(match_operand 1 "register_operand" "f")
13816                          (match_operand 2 "register_operand" "f")])
13817           (label_ref (match_operand 3 "" ""))
13818           (pc)))
13819    (clobber (reg:CCFP FPSR_REG))
13820    (clobber (reg:CCFP FLAGS_REG))
13821    (clobber (match_scratch:HI 4 "=a"))]
13822   "TARGET_80387
13823    && FLOAT_MODE_P (GET_MODE (operands[1]))
13824    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13825    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13826   "#")
13828 (define_insn "*fp_jcc_6_387"
13829   [(set (pc)
13830         (if_then_else (match_operator 0 "comparison_operator"
13831                         [(match_operand 1 "register_operand" "f")
13832                          (match_operand 2 "register_operand" "f")])
13833           (pc)
13834           (label_ref (match_operand 3 "" ""))))
13835    (clobber (reg:CCFP FPSR_REG))
13836    (clobber (reg:CCFP FLAGS_REG))
13837    (clobber (match_scratch:HI 4 "=a"))]
13838   "TARGET_80387
13839    && FLOAT_MODE_P (GET_MODE (operands[1]))
13840    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13841    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13842   "#")
13844 (define_insn "*fp_jcc_7_387"
13845   [(set (pc)
13846         (if_then_else (match_operator 0 "comparison_operator"
13847                         [(match_operand 1 "register_operand" "f")
13848                          (match_operand 2 "const0_operand" "X")])
13849           (label_ref (match_operand 3 "" ""))
13850           (pc)))
13851    (clobber (reg:CCFP FPSR_REG))
13852    (clobber (reg:CCFP FLAGS_REG))
13853    (clobber (match_scratch:HI 4 "=a"))]
13854   "TARGET_80387
13855    && FLOAT_MODE_P (GET_MODE (operands[1]))
13856    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13857    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13858    && SELECT_CC_MODE (GET_CODE (operands[0]),
13859                       operands[1], operands[2]) == CCFPmode
13860    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13861   "#")
13863 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13864 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13865 ;; with a precedence over other operators and is always put in the first
13866 ;; place. Swap condition and operands to match ficom instruction.
13868 (define_insn "*fp_jcc_8<mode>_387"
13869   [(set (pc)
13870         (if_then_else (match_operator 0 "comparison_operator"
13871                         [(match_operator 1 "float_operator"
13872                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13873                            (match_operand 3 "register_operand" "f,f")])
13874           (label_ref (match_operand 4 "" ""))
13875           (pc)))
13876    (clobber (reg:CCFP FPSR_REG))
13877    (clobber (reg:CCFP FLAGS_REG))
13878    (clobber (match_scratch:HI 5 "=a,a"))]
13879   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13880    && FLOAT_MODE_P (GET_MODE (operands[3]))
13881    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13882    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13883    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13884    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13885   "#")
13887 (define_split
13888   [(set (pc)
13889         (if_then_else (match_operator 0 "comparison_operator"
13890                         [(match_operand 1 "register_operand" "")
13891                          (match_operand 2 "nonimmediate_operand" "")])
13892           (match_operand 3 "" "")
13893           (match_operand 4 "" "")))
13894    (clobber (reg:CCFP FPSR_REG))
13895    (clobber (reg:CCFP FLAGS_REG))]
13896   "reload_completed"
13897   [(const_int 0)]
13899   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13900                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13901   DONE;
13904 (define_split
13905   [(set (pc)
13906         (if_then_else (match_operator 0 "comparison_operator"
13907                         [(match_operand 1 "register_operand" "")
13908                          (match_operand 2 "general_operand" "")])
13909           (match_operand 3 "" "")
13910           (match_operand 4 "" "")))
13911    (clobber (reg:CCFP FPSR_REG))
13912    (clobber (reg:CCFP FLAGS_REG))
13913    (clobber (match_scratch:HI 5 "=a"))]
13914   "reload_completed"
13915   [(const_int 0)]
13917   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13918                         operands[3], operands[4], operands[5], NULL_RTX);
13919   DONE;
13922 (define_split
13923   [(set (pc)
13924         (if_then_else (match_operator 0 "comparison_operator"
13925                         [(match_operator 1 "float_operator"
13926                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13927                            (match_operand 3 "register_operand" "")])
13928           (match_operand 4 "" "")
13929           (match_operand 5 "" "")))
13930    (clobber (reg:CCFP FPSR_REG))
13931    (clobber (reg:CCFP FLAGS_REG))
13932    (clobber (match_scratch:HI 6 "=a"))]
13933   "reload_completed"
13934   [(const_int 0)]
13936   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13937   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13938                         operands[3], operands[7],
13939                         operands[4], operands[5], operands[6], NULL_RTX);
13940   DONE;
13943 ;; %%% Kill this when reload knows how to do it.
13944 (define_split
13945   [(set (pc)
13946         (if_then_else (match_operator 0 "comparison_operator"
13947                         [(match_operator 1 "float_operator"
13948                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13949                            (match_operand 3 "register_operand" "")])
13950           (match_operand 4 "" "")
13951           (match_operand 5 "" "")))
13952    (clobber (reg:CCFP FPSR_REG))
13953    (clobber (reg:CCFP FLAGS_REG))
13954    (clobber (match_scratch:HI 6 "=a"))]
13955   "reload_completed"
13956   [(const_int 0)]
13958   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13959   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13960   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13961                         operands[3], operands[7],
13962                         operands[4], operands[5], operands[6], operands[2]);
13963   DONE;
13966 ;; Unconditional and other jump instructions
13968 (define_insn "jump"
13969   [(set (pc)
13970         (label_ref (match_operand 0 "" "")))]
13971   ""
13972   "jmp\t%l0"
13973   [(set_attr "type" "ibr")
13974    (set (attr "length")
13975            (if_then_else (and (ge (minus (match_dup 0) (pc))
13976                                   (const_int -126))
13977                               (lt (minus (match_dup 0) (pc))
13978                                   (const_int 128)))
13979              (const_int 2)
13980              (const_int 5)))
13981    (set_attr "modrm" "0")])
13983 (define_expand "indirect_jump"
13984   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13985   ""
13986   "")
13988 (define_insn "*indirect_jump"
13989   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13990   "!TARGET_64BIT"
13991   "jmp\t%A0"
13992   [(set_attr "type" "ibr")
13993    (set_attr "length_immediate" "0")])
13995 (define_insn "*indirect_jump_rtx64"
13996   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13997   "TARGET_64BIT"
13998   "jmp\t%A0"
13999   [(set_attr "type" "ibr")
14000    (set_attr "length_immediate" "0")])
14002 (define_expand "tablejump"
14003   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14004               (use (label_ref (match_operand 1 "" "")))])]
14005   ""
14007   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14008      relative.  Convert the relative address to an absolute address.  */
14009   if (flag_pic)
14010     {
14011       rtx op0, op1;
14012       enum rtx_code code;
14014       if (TARGET_64BIT)
14015         {
14016           code = PLUS;
14017           op0 = operands[0];
14018           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14019         }
14020       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14021         {
14022           code = PLUS;
14023           op0 = operands[0];
14024           op1 = pic_offset_table_rtx;
14025         }
14026       else
14027         {
14028           code = MINUS;
14029           op0 = pic_offset_table_rtx;
14030           op1 = operands[0];
14031         }
14033       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14034                                          OPTAB_DIRECT);
14035     }
14038 (define_insn "*tablejump_1"
14039   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14040    (use (label_ref (match_operand 1 "" "")))]
14041   "!TARGET_64BIT"
14042   "jmp\t%A0"
14043   [(set_attr "type" "ibr")
14044    (set_attr "length_immediate" "0")])
14046 (define_insn "*tablejump_1_rtx64"
14047   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14048    (use (label_ref (match_operand 1 "" "")))]
14049   "TARGET_64BIT"
14050   "jmp\t%A0"
14051   [(set_attr "type" "ibr")
14052    (set_attr "length_immediate" "0")])
14054 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14056 (define_peephole2
14057   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14058    (set (match_operand:QI 1 "register_operand" "")
14059         (match_operator:QI 2 "ix86_comparison_operator"
14060           [(reg FLAGS_REG) (const_int 0)]))
14061    (set (match_operand 3 "q_regs_operand" "")
14062         (zero_extend (match_dup 1)))]
14063   "(peep2_reg_dead_p (3, operands[1])
14064     || operands_match_p (operands[1], operands[3]))
14065    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14066   [(set (match_dup 4) (match_dup 0))
14067    (set (strict_low_part (match_dup 5))
14068         (match_dup 2))]
14070   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14071   operands[5] = gen_lowpart (QImode, operands[3]);
14072   ix86_expand_clear (operands[3]);
14075 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14077 (define_peephole2
14078   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14079    (set (match_operand:QI 1 "register_operand" "")
14080         (match_operator:QI 2 "ix86_comparison_operator"
14081           [(reg FLAGS_REG) (const_int 0)]))
14082    (parallel [(set (match_operand 3 "q_regs_operand" "")
14083                    (zero_extend (match_dup 1)))
14084               (clobber (reg:CC FLAGS_REG))])]
14085   "(peep2_reg_dead_p (3, operands[1])
14086     || operands_match_p (operands[1], operands[3]))
14087    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14088   [(set (match_dup 4) (match_dup 0))
14089    (set (strict_low_part (match_dup 5))
14090         (match_dup 2))]
14092   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14093   operands[5] = gen_lowpart (QImode, operands[3]);
14094   ix86_expand_clear (operands[3]);
14097 ;; Call instructions.
14099 ;; The predicates normally associated with named expanders are not properly
14100 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14101 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14103 ;; Call subroutine returning no value.
14105 (define_expand "call_pop"
14106   [(parallel [(call (match_operand:QI 0 "" "")
14107                     (match_operand:SI 1 "" ""))
14108               (set (reg:SI SP_REG)
14109                    (plus:SI (reg:SI SP_REG)
14110                             (match_operand:SI 3 "" "")))])]
14111   "!TARGET_64BIT"
14113   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14114   DONE;
14117 (define_insn "*call_pop_0"
14118   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14119          (match_operand:SI 1 "" ""))
14120    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14121                             (match_operand:SI 2 "immediate_operand" "")))]
14122   "!TARGET_64BIT"
14124   if (SIBLING_CALL_P (insn))
14125     return "jmp\t%P0";
14126   else
14127     return "call\t%P0";
14129   [(set_attr "type" "call")])
14131 (define_insn "*call_pop_1"
14132   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14133          (match_operand:SI 1 "" ""))
14134    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14135                             (match_operand:SI 2 "immediate_operand" "i")))]
14136   "!TARGET_64BIT"
14138   if (constant_call_address_operand (operands[0], Pmode))
14139     {
14140       if (SIBLING_CALL_P (insn))
14141         return "jmp\t%P0";
14142       else
14143         return "call\t%P0";
14144     }
14145   if (SIBLING_CALL_P (insn))
14146     return "jmp\t%A0";
14147   else
14148     return "call\t%A0";
14150   [(set_attr "type" "call")])
14152 (define_expand "call"
14153   [(call (match_operand:QI 0 "" "")
14154          (match_operand 1 "" ""))
14155    (use (match_operand 2 "" ""))]
14156   ""
14158   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14159   DONE;
14162 (define_expand "sibcall"
14163   [(call (match_operand:QI 0 "" "")
14164          (match_operand 1 "" ""))
14165    (use (match_operand 2 "" ""))]
14166   ""
14168   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14169   DONE;
14172 (define_insn "*call_0"
14173   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14174          (match_operand 1 "" ""))]
14175   ""
14177   if (SIBLING_CALL_P (insn))
14178     return "jmp\t%P0";
14179   else
14180     return "call\t%P0";
14182   [(set_attr "type" "call")])
14184 (define_insn "*call_1"
14185   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14186          (match_operand 1 "" ""))]
14187   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14189   if (constant_call_address_operand (operands[0], Pmode))
14190     return "call\t%P0";
14191   return "call\t%A0";
14193   [(set_attr "type" "call")])
14195 (define_insn "*sibcall_1"
14196   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14197          (match_operand 1 "" ""))]
14198   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14200   if (constant_call_address_operand (operands[0], Pmode))
14201     return "jmp\t%P0";
14202   return "jmp\t%A0";
14204   [(set_attr "type" "call")])
14206 (define_insn "*call_1_rex64"
14207   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14208          (match_operand 1 "" ""))]
14209   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14211   if (constant_call_address_operand (operands[0], Pmode))
14212     return "call\t%P0";
14213   return "call\t%A0";
14215   [(set_attr "type" "call")])
14217 (define_insn "*sibcall_1_rex64"
14218   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14219          (match_operand 1 "" ""))]
14220   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14221   "jmp\t%P0"
14222   [(set_attr "type" "call")])
14224 (define_insn "*sibcall_1_rex64_v"
14225   [(call (mem:QI (reg:DI R11_REG))
14226          (match_operand 0 "" ""))]
14227   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14228   "jmp\t*%%r11"
14229   [(set_attr "type" "call")])
14232 ;; Call subroutine, returning value in operand 0
14234 (define_expand "call_value_pop"
14235   [(parallel [(set (match_operand 0 "" "")
14236                    (call (match_operand:QI 1 "" "")
14237                          (match_operand:SI 2 "" "")))
14238               (set (reg:SI SP_REG)
14239                    (plus:SI (reg:SI SP_REG)
14240                             (match_operand:SI 4 "" "")))])]
14241   "!TARGET_64BIT"
14243   ix86_expand_call (operands[0], operands[1], operands[2],
14244                     operands[3], operands[4], 0);
14245   DONE;
14248 (define_expand "call_value"
14249   [(set (match_operand 0 "" "")
14250         (call (match_operand:QI 1 "" "")
14251               (match_operand:SI 2 "" "")))
14252    (use (match_operand:SI 3 "" ""))]
14253   ;; Operand 2 not used on the i386.
14254   ""
14256   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14257   DONE;
14260 (define_expand "sibcall_value"
14261   [(set (match_operand 0 "" "")
14262         (call (match_operand:QI 1 "" "")
14263               (match_operand:SI 2 "" "")))
14264    (use (match_operand:SI 3 "" ""))]
14265   ;; Operand 2 not used on the i386.
14266   ""
14268   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14269   DONE;
14272 ;; Call subroutine returning any type.
14274 (define_expand "untyped_call"
14275   [(parallel [(call (match_operand 0 "" "")
14276                     (const_int 0))
14277               (match_operand 1 "" "")
14278               (match_operand 2 "" "")])]
14279   ""
14281   int i;
14283   /* In order to give reg-stack an easier job in validating two
14284      coprocessor registers as containing a possible return value,
14285      simply pretend the untyped call returns a complex long double
14286      value.  */
14288   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14289                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14290                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14291                     NULL, 0);
14293   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14294     {
14295       rtx set = XVECEXP (operands[2], 0, i);
14296       emit_move_insn (SET_DEST (set), SET_SRC (set));
14297     }
14299   /* The optimizer does not know that the call sets the function value
14300      registers we stored in the result block.  We avoid problems by
14301      claiming that all hard registers are used and clobbered at this
14302      point.  */
14303   emit_insn (gen_blockage (const0_rtx));
14305   DONE;
14308 ;; Prologue and epilogue instructions
14310 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14311 ;; all of memory.  This blocks insns from being moved across this point.
14313 (define_insn "blockage"
14314   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14315   ""
14316   ""
14317   [(set_attr "length" "0")])
14319 ;; Insn emitted into the body of a function to return from a function.
14320 ;; This is only done if the function's epilogue is known to be simple.
14321 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14323 (define_expand "return"
14324   [(return)]
14325   "ix86_can_use_return_insn_p ()"
14327   if (current_function_pops_args)
14328     {
14329       rtx popc = GEN_INT (current_function_pops_args);
14330       emit_jump_insn (gen_return_pop_internal (popc));
14331       DONE;
14332     }
14335 (define_insn "return_internal"
14336   [(return)]
14337   "reload_completed"
14338   "ret"
14339   [(set_attr "length" "1")
14340    (set_attr "length_immediate" "0")
14341    (set_attr "modrm" "0")])
14343 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14344 ;; instruction Athlon and K8 have.
14346 (define_insn "return_internal_long"
14347   [(return)
14348    (unspec [(const_int 0)] UNSPEC_REP)]
14349   "reload_completed"
14350   "rep {;} ret"
14351   [(set_attr "length" "1")
14352    (set_attr "length_immediate" "0")
14353    (set_attr "prefix_rep" "1")
14354    (set_attr "modrm" "0")])
14356 (define_insn "return_pop_internal"
14357   [(return)
14358    (use (match_operand:SI 0 "const_int_operand" ""))]
14359   "reload_completed"
14360   "ret\t%0"
14361   [(set_attr "length" "3")
14362    (set_attr "length_immediate" "2")
14363    (set_attr "modrm" "0")])
14365 (define_insn "return_indirect_internal"
14366   [(return)
14367    (use (match_operand:SI 0 "register_operand" "r"))]
14368   "reload_completed"
14369   "jmp\t%A0"
14370   [(set_attr "type" "ibr")
14371    (set_attr "length_immediate" "0")])
14373 (define_insn "nop"
14374   [(const_int 0)]
14375   ""
14376   "nop"
14377   [(set_attr "length" "1")
14378    (set_attr "length_immediate" "0")
14379    (set_attr "modrm" "0")])
14381 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14382 ;; branch prediction penalty for the third jump in a 16-byte
14383 ;; block on K8.
14385 (define_insn "align"
14386   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14387   ""
14389 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14390   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14391 #else
14392   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14393      The align insn is used to avoid 3 jump instructions in the row to improve
14394      branch prediction and the benefits hardly outweigh the cost of extra 8
14395      nops on the average inserted by full alignment pseudo operation.  */
14396 #endif
14397   return "";
14399   [(set_attr "length" "16")])
14401 (define_expand "prologue"
14402   [(const_int 1)]
14403   ""
14404   "ix86_expand_prologue (); DONE;")
14406 (define_insn "set_got"
14407   [(set (match_operand:SI 0 "register_operand" "=r")
14408         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14409    (clobber (reg:CC FLAGS_REG))]
14410   "!TARGET_64BIT"
14411   { return output_set_got (operands[0], NULL_RTX); }
14412   [(set_attr "type" "multi")
14413    (set_attr "length" "12")])
14415 (define_insn "set_got_labelled"
14416   [(set (match_operand:SI 0 "register_operand" "=r")
14417         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14418          UNSPEC_SET_GOT))
14419    (clobber (reg:CC FLAGS_REG))]
14420   "!TARGET_64BIT"
14421   { return output_set_got (operands[0], operands[1]); }
14422   [(set_attr "type" "multi")
14423    (set_attr "length" "12")])
14425 (define_insn "set_got_rex64"
14426   [(set (match_operand:DI 0 "register_operand" "=r")
14427         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14428   "TARGET_64BIT"
14429   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14430   [(set_attr "type" "lea")
14431    (set_attr "length" "6")])
14433 (define_expand "epilogue"
14434   [(const_int 1)]
14435   ""
14436   "ix86_expand_epilogue (1); DONE;")
14438 (define_expand "sibcall_epilogue"
14439   [(const_int 1)]
14440   ""
14441   "ix86_expand_epilogue (0); DONE;")
14443 (define_expand "eh_return"
14444   [(use (match_operand 0 "register_operand" ""))]
14445   ""
14447   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14449   /* Tricky bit: we write the address of the handler to which we will
14450      be returning into someone else's stack frame, one word below the
14451      stack address we wish to restore.  */
14452   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14453   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14454   tmp = gen_rtx_MEM (Pmode, tmp);
14455   emit_move_insn (tmp, ra);
14457   if (Pmode == SImode)
14458     emit_jump_insn (gen_eh_return_si (sa));
14459   else
14460     emit_jump_insn (gen_eh_return_di (sa));
14461   emit_barrier ();
14462   DONE;
14465 (define_insn_and_split "eh_return_si"
14466   [(set (pc)
14467         (unspec [(match_operand:SI 0 "register_operand" "c")]
14468                  UNSPEC_EH_RETURN))]
14469   "!TARGET_64BIT"
14470   "#"
14471   "reload_completed"
14472   [(const_int 1)]
14473   "ix86_expand_epilogue (2); DONE;")
14475 (define_insn_and_split "eh_return_di"
14476   [(set (pc)
14477         (unspec [(match_operand:DI 0 "register_operand" "c")]
14478                  UNSPEC_EH_RETURN))]
14479   "TARGET_64BIT"
14480   "#"
14481   "reload_completed"
14482   [(const_int 1)]
14483   "ix86_expand_epilogue (2); DONE;")
14485 (define_insn "leave"
14486   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14487    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14488    (clobber (mem:BLK (scratch)))]
14489   "!TARGET_64BIT"
14490   "leave"
14491   [(set_attr "type" "leave")])
14493 (define_insn "leave_rex64"
14494   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14495    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14496    (clobber (mem:BLK (scratch)))]
14497   "TARGET_64BIT"
14498   "leave"
14499   [(set_attr "type" "leave")])
14501 (define_expand "ffssi2"
14502   [(parallel
14503      [(set (match_operand:SI 0 "register_operand" "")
14504            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14505       (clobber (match_scratch:SI 2 ""))
14506       (clobber (reg:CC FLAGS_REG))])]
14507   ""
14508   "")
14510 (define_insn_and_split "*ffs_cmove"
14511   [(set (match_operand:SI 0 "register_operand" "=r")
14512         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14513    (clobber (match_scratch:SI 2 "=&r"))
14514    (clobber (reg:CC FLAGS_REG))]
14515   "TARGET_CMOVE"
14516   "#"
14517   "&& reload_completed"
14518   [(set (match_dup 2) (const_int -1))
14519    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14520               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14521    (set (match_dup 0) (if_then_else:SI
14522                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14523                         (match_dup 2)
14524                         (match_dup 0)))
14525    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14526               (clobber (reg:CC FLAGS_REG))])]
14527   "")
14529 (define_insn_and_split "*ffs_no_cmove"
14530   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14531         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14532    (clobber (match_scratch:SI 2 "=&q"))
14533    (clobber (reg:CC FLAGS_REG))]
14534   ""
14535   "#"
14536   "reload_completed"
14537   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14538               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14539    (set (strict_low_part (match_dup 3))
14540         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14541    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14542               (clobber (reg:CC FLAGS_REG))])
14543    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14544               (clobber (reg:CC FLAGS_REG))])
14545    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14546               (clobber (reg:CC FLAGS_REG))])]
14548   operands[3] = gen_lowpart (QImode, operands[2]);
14549   ix86_expand_clear (operands[2]);
14552 (define_insn "*ffssi_1"
14553   [(set (reg:CCZ FLAGS_REG)
14554         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14555                      (const_int 0)))
14556    (set (match_operand:SI 0 "register_operand" "=r")
14557         (ctz:SI (match_dup 1)))]
14558   ""
14559   "bsf{l}\t{%1, %0|%0, %1}"
14560   [(set_attr "prefix_0f" "1")])
14562 (define_expand "ffsdi2"
14563   [(parallel
14564      [(set (match_operand:DI 0 "register_operand" "")
14565            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14566       (clobber (match_scratch:DI 2 ""))
14567       (clobber (reg:CC FLAGS_REG))])]
14568   "TARGET_64BIT && TARGET_CMOVE"
14569   "")
14571 (define_insn_and_split "*ffs_rex64"
14572   [(set (match_operand:DI 0 "register_operand" "=r")
14573         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14574    (clobber (match_scratch:DI 2 "=&r"))
14575    (clobber (reg:CC FLAGS_REG))]
14576   "TARGET_64BIT && TARGET_CMOVE"
14577   "#"
14578   "&& reload_completed"
14579   [(set (match_dup 2) (const_int -1))
14580    (parallel [(set (reg:CCZ FLAGS_REG)
14581                    (compare:CCZ (match_dup 1) (const_int 0)))
14582               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14583    (set (match_dup 0) (if_then_else:DI
14584                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14585                         (match_dup 2)
14586                         (match_dup 0)))
14587    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14588               (clobber (reg:CC FLAGS_REG))])]
14589   "")
14591 (define_insn "*ffsdi_1"
14592   [(set (reg:CCZ FLAGS_REG)
14593         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14594                      (const_int 0)))
14595    (set (match_operand:DI 0 "register_operand" "=r")
14596         (ctz:DI (match_dup 1)))]
14597   "TARGET_64BIT"
14598   "bsf{q}\t{%1, %0|%0, %1}"
14599   [(set_attr "prefix_0f" "1")])
14601 (define_insn "ctzsi2"
14602   [(set (match_operand:SI 0 "register_operand" "=r")
14603         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14604    (clobber (reg:CC FLAGS_REG))]
14605   ""
14606   "bsf{l}\t{%1, %0|%0, %1}"
14607   [(set_attr "prefix_0f" "1")])
14609 (define_insn "ctzdi2"
14610   [(set (match_operand:DI 0 "register_operand" "=r")
14611         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14612    (clobber (reg:CC FLAGS_REG))]
14613   "TARGET_64BIT"
14614   "bsf{q}\t{%1, %0|%0, %1}"
14615   [(set_attr "prefix_0f" "1")])
14617 (define_expand "clzsi2"
14618   [(parallel
14619      [(set (match_operand:SI 0 "register_operand" "")
14620            (minus:SI (const_int 31)
14621                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14622       (clobber (reg:CC FLAGS_REG))])
14623    (parallel
14624      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14625       (clobber (reg:CC FLAGS_REG))])]
14626   ""
14627   "")
14629 (define_insn "*bsr"
14630   [(set (match_operand:SI 0 "register_operand" "=r")
14631         (minus:SI (const_int 31)
14632                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14633    (clobber (reg:CC FLAGS_REG))]
14634   ""
14635   "bsr{l}\t{%1, %0|%0, %1}"
14636   [(set_attr "prefix_0f" "1")])
14638 (define_insn "bswapsi2"
14639   [(set (match_operand:SI 0 "register_operand" "=r")
14640         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14641    (clobber (reg:CC FLAGS_REG))]
14642   "TARGET_BSWAP"
14643   "bswap\t%k0"
14644   [(set_attr "prefix_0f" "1")
14645    (set_attr "length" "2")])
14647 (define_insn "bswapdi2"
14648   [(set (match_operand:DI 0 "register_operand" "=r")
14649         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14650    (clobber (reg:CC FLAGS_REG))]
14651   "TARGET_64BIT && TARGET_BSWAP"
14652   "bswap\t%0"
14653   [(set_attr "prefix_0f" "1")
14654    (set_attr "length" "3")])
14656 (define_expand "clzdi2"
14657   [(parallel
14658      [(set (match_operand:DI 0 "register_operand" "")
14659            (minus:DI (const_int 63)
14660                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14661       (clobber (reg:CC FLAGS_REG))])
14662    (parallel
14663      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14664       (clobber (reg:CC FLAGS_REG))])]
14665   "TARGET_64BIT"
14666   "")
14668 (define_insn "*bsr_rex64"
14669   [(set (match_operand:DI 0 "register_operand" "=r")
14670         (minus:DI (const_int 63)
14671                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14672    (clobber (reg:CC FLAGS_REG))]
14673   "TARGET_64BIT"
14674   "bsr{q}\t{%1, %0|%0, %1}"
14675   [(set_attr "prefix_0f" "1")])
14677 ;; Thread-local storage patterns for ELF.
14679 ;; Note that these code sequences must appear exactly as shown
14680 ;; in order to allow linker relaxation.
14682 (define_insn "*tls_global_dynamic_32_gnu"
14683   [(set (match_operand:SI 0 "register_operand" "=a")
14684         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14685                     (match_operand:SI 2 "tls_symbolic_operand" "")
14686                     (match_operand:SI 3 "call_insn_operand" "")]
14687                     UNSPEC_TLS_GD))
14688    (clobber (match_scratch:SI 4 "=d"))
14689    (clobber (match_scratch:SI 5 "=c"))
14690    (clobber (reg:CC FLAGS_REG))]
14691   "!TARGET_64BIT && TARGET_GNU_TLS"
14692   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14693   [(set_attr "type" "multi")
14694    (set_attr "length" "12")])
14696 (define_insn "*tls_global_dynamic_32_sun"
14697   [(set (match_operand:SI 0 "register_operand" "=a")
14698         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14699                     (match_operand:SI 2 "tls_symbolic_operand" "")
14700                     (match_operand:SI 3 "call_insn_operand" "")]
14701                     UNSPEC_TLS_GD))
14702    (clobber (match_scratch:SI 4 "=d"))
14703    (clobber (match_scratch:SI 5 "=c"))
14704    (clobber (reg:CC FLAGS_REG))]
14705   "!TARGET_64BIT && TARGET_SUN_TLS"
14706   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14707         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14708   [(set_attr "type" "multi")
14709    (set_attr "length" "14")])
14711 (define_expand "tls_global_dynamic_32"
14712   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14713                    (unspec:SI
14714                     [(match_dup 2)
14715                      (match_operand:SI 1 "tls_symbolic_operand" "")
14716                      (match_dup 3)]
14717                     UNSPEC_TLS_GD))
14718               (clobber (match_scratch:SI 4 ""))
14719               (clobber (match_scratch:SI 5 ""))
14720               (clobber (reg:CC FLAGS_REG))])]
14721   ""
14723   if (flag_pic)
14724     operands[2] = pic_offset_table_rtx;
14725   else
14726     {
14727       operands[2] = gen_reg_rtx (Pmode);
14728       emit_insn (gen_set_got (operands[2]));
14729     }
14730   if (TARGET_GNU2_TLS)
14731     {
14732        emit_insn (gen_tls_dynamic_gnu2_32
14733                   (operands[0], operands[1], operands[2]));
14734        DONE;
14735     }
14736   operands[3] = ix86_tls_get_addr ();
14739 (define_insn "*tls_global_dynamic_64"
14740   [(set (match_operand:DI 0 "register_operand" "=a")
14741         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14742                  (match_operand:DI 3 "" "")))
14743    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14744               UNSPEC_TLS_GD)]
14745   "TARGET_64BIT"
14746   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14747   [(set_attr "type" "multi")
14748    (set_attr "length" "16")])
14750 (define_expand "tls_global_dynamic_64"
14751   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14752                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14753               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14754                          UNSPEC_TLS_GD)])]
14755   ""
14757   if (TARGET_GNU2_TLS)
14758     {
14759        emit_insn (gen_tls_dynamic_gnu2_64
14760                   (operands[0], operands[1]));
14761        DONE;
14762     }
14763   operands[2] = ix86_tls_get_addr ();
14766 (define_insn "*tls_local_dynamic_base_32_gnu"
14767   [(set (match_operand:SI 0 "register_operand" "=a")
14768         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14769                     (match_operand:SI 2 "call_insn_operand" "")]
14770                    UNSPEC_TLS_LD_BASE))
14771    (clobber (match_scratch:SI 3 "=d"))
14772    (clobber (match_scratch:SI 4 "=c"))
14773    (clobber (reg:CC FLAGS_REG))]
14774   "!TARGET_64BIT && TARGET_GNU_TLS"
14775   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14776   [(set_attr "type" "multi")
14777    (set_attr "length" "11")])
14779 (define_insn "*tls_local_dynamic_base_32_sun"
14780   [(set (match_operand:SI 0 "register_operand" "=a")
14781         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14782                     (match_operand:SI 2 "call_insn_operand" "")]
14783                    UNSPEC_TLS_LD_BASE))
14784    (clobber (match_scratch:SI 3 "=d"))
14785    (clobber (match_scratch:SI 4 "=c"))
14786    (clobber (reg:CC FLAGS_REG))]
14787   "!TARGET_64BIT && TARGET_SUN_TLS"
14788   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14789         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14790   [(set_attr "type" "multi")
14791    (set_attr "length" "13")])
14793 (define_expand "tls_local_dynamic_base_32"
14794   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14795                    (unspec:SI [(match_dup 1) (match_dup 2)]
14796                               UNSPEC_TLS_LD_BASE))
14797               (clobber (match_scratch:SI 3 ""))
14798               (clobber (match_scratch:SI 4 ""))
14799               (clobber (reg:CC FLAGS_REG))])]
14800   ""
14802   if (flag_pic)
14803     operands[1] = pic_offset_table_rtx;
14804   else
14805     {
14806       operands[1] = gen_reg_rtx (Pmode);
14807       emit_insn (gen_set_got (operands[1]));
14808     }
14809   if (TARGET_GNU2_TLS)
14810     {
14811        emit_insn (gen_tls_dynamic_gnu2_32
14812                   (operands[0], ix86_tls_module_base (), operands[1]));
14813        DONE;
14814     }
14815   operands[2] = ix86_tls_get_addr ();
14818 (define_insn "*tls_local_dynamic_base_64"
14819   [(set (match_operand:DI 0 "register_operand" "=a")
14820         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14821                  (match_operand:DI 2 "" "")))
14822    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14823   "TARGET_64BIT"
14824   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14825   [(set_attr "type" "multi")
14826    (set_attr "length" "12")])
14828 (define_expand "tls_local_dynamic_base_64"
14829   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14830                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14831               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14832   ""
14834   if (TARGET_GNU2_TLS)
14835     {
14836        emit_insn (gen_tls_dynamic_gnu2_64
14837                   (operands[0], ix86_tls_module_base ()));
14838        DONE;
14839     }
14840   operands[1] = ix86_tls_get_addr ();
14843 ;; Local dynamic of a single variable is a lose.  Show combine how
14844 ;; to convert that back to global dynamic.
14846 (define_insn_and_split "*tls_local_dynamic_32_once"
14847   [(set (match_operand:SI 0 "register_operand" "=a")
14848         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14849                              (match_operand:SI 2 "call_insn_operand" "")]
14850                             UNSPEC_TLS_LD_BASE)
14851                  (const:SI (unspec:SI
14852                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14853                             UNSPEC_DTPOFF))))
14854    (clobber (match_scratch:SI 4 "=d"))
14855    (clobber (match_scratch:SI 5 "=c"))
14856    (clobber (reg:CC FLAGS_REG))]
14857   ""
14858   "#"
14859   ""
14860   [(parallel [(set (match_dup 0)
14861                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14862                               UNSPEC_TLS_GD))
14863               (clobber (match_dup 4))
14864               (clobber (match_dup 5))
14865               (clobber (reg:CC FLAGS_REG))])]
14866   "")
14868 ;; Load and add the thread base pointer from %gs:0.
14870 (define_insn "*load_tp_si"
14871   [(set (match_operand:SI 0 "register_operand" "=r")
14872         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14873   "!TARGET_64BIT"
14874   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14875   [(set_attr "type" "imov")
14876    (set_attr "modrm" "0")
14877    (set_attr "length" "7")
14878    (set_attr "memory" "load")
14879    (set_attr "imm_disp" "false")])
14881 (define_insn "*add_tp_si"
14882   [(set (match_operand:SI 0 "register_operand" "=r")
14883         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14884                  (match_operand:SI 1 "register_operand" "0")))
14885    (clobber (reg:CC FLAGS_REG))]
14886   "!TARGET_64BIT"
14887   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14888   [(set_attr "type" "alu")
14889    (set_attr "modrm" "0")
14890    (set_attr "length" "7")
14891    (set_attr "memory" "load")
14892    (set_attr "imm_disp" "false")])
14894 (define_insn "*load_tp_di"
14895   [(set (match_operand:DI 0 "register_operand" "=r")
14896         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14897   "TARGET_64BIT"
14898   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14899   [(set_attr "type" "imov")
14900    (set_attr "modrm" "0")
14901    (set_attr "length" "7")
14902    (set_attr "memory" "load")
14903    (set_attr "imm_disp" "false")])
14905 (define_insn "*add_tp_di"
14906   [(set (match_operand:DI 0 "register_operand" "=r")
14907         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14908                  (match_operand:DI 1 "register_operand" "0")))
14909    (clobber (reg:CC FLAGS_REG))]
14910   "TARGET_64BIT"
14911   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14912   [(set_attr "type" "alu")
14913    (set_attr "modrm" "0")
14914    (set_attr "length" "7")
14915    (set_attr "memory" "load")
14916    (set_attr "imm_disp" "false")])
14918 ;; GNU2 TLS patterns can be split.
14920 (define_expand "tls_dynamic_gnu2_32"
14921   [(set (match_dup 3)
14922         (plus:SI (match_operand:SI 2 "register_operand" "")
14923                  (const:SI
14924                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14925                              UNSPEC_TLSDESC))))
14926    (parallel
14927     [(set (match_operand:SI 0 "register_operand" "")
14928           (unspec:SI [(match_dup 1) (match_dup 3)
14929                       (match_dup 2) (reg:SI SP_REG)]
14930                       UNSPEC_TLSDESC))
14931      (clobber (reg:CC FLAGS_REG))])]
14932   "!TARGET_64BIT && TARGET_GNU2_TLS"
14934   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14935   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14938 (define_insn "*tls_dynamic_lea_32"
14939   [(set (match_operand:SI 0 "register_operand" "=r")
14940         (plus:SI (match_operand:SI 1 "register_operand" "b")
14941                  (const:SI
14942                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14943                               UNSPEC_TLSDESC))))]
14944   "!TARGET_64BIT && TARGET_GNU2_TLS"
14945   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14946   [(set_attr "type" "lea")
14947    (set_attr "mode" "SI")
14948    (set_attr "length" "6")
14949    (set_attr "length_address" "4")])
14951 (define_insn "*tls_dynamic_call_32"
14952   [(set (match_operand:SI 0 "register_operand" "=a")
14953         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14954                     (match_operand:SI 2 "register_operand" "0")
14955                     ;; we have to make sure %ebx still points to the GOT
14956                     (match_operand:SI 3 "register_operand" "b")
14957                     (reg:SI SP_REG)]
14958                    UNSPEC_TLSDESC))
14959    (clobber (reg:CC FLAGS_REG))]
14960   "!TARGET_64BIT && TARGET_GNU2_TLS"
14961   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14962   [(set_attr "type" "call")
14963    (set_attr "length" "2")
14964    (set_attr "length_address" "0")])
14966 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14967   [(set (match_operand:SI 0 "register_operand" "=&a")
14968         (plus:SI
14969          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14970                      (match_operand:SI 4 "" "")
14971                      (match_operand:SI 2 "register_operand" "b")
14972                      (reg:SI SP_REG)]
14973                     UNSPEC_TLSDESC)
14974          (const:SI (unspec:SI
14975                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14976                     UNSPEC_DTPOFF))))
14977    (clobber (reg:CC FLAGS_REG))]
14978   "!TARGET_64BIT && TARGET_GNU2_TLS"
14979   "#"
14980   ""
14981   [(set (match_dup 0) (match_dup 5))]
14983   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14984   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14987 (define_expand "tls_dynamic_gnu2_64"
14988   [(set (match_dup 2)
14989         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14990                    UNSPEC_TLSDESC))
14991    (parallel
14992     [(set (match_operand:DI 0 "register_operand" "")
14993           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14994                      UNSPEC_TLSDESC))
14995      (clobber (reg:CC FLAGS_REG))])]
14996   "TARGET_64BIT && TARGET_GNU2_TLS"
14998   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14999   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15002 (define_insn "*tls_dynamic_lea_64"
15003   [(set (match_operand:DI 0 "register_operand" "=r")
15004         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15005                    UNSPEC_TLSDESC))]
15006   "TARGET_64BIT && TARGET_GNU2_TLS"
15007   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15008   [(set_attr "type" "lea")
15009    (set_attr "mode" "DI")
15010    (set_attr "length" "7")
15011    (set_attr "length_address" "4")])
15013 (define_insn "*tls_dynamic_call_64"
15014   [(set (match_operand:DI 0 "register_operand" "=a")
15015         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15016                     (match_operand:DI 2 "register_operand" "0")
15017                     (reg:DI SP_REG)]
15018                    UNSPEC_TLSDESC))
15019    (clobber (reg:CC FLAGS_REG))]
15020   "TARGET_64BIT && TARGET_GNU2_TLS"
15021   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15022   [(set_attr "type" "call")
15023    (set_attr "length" "2")
15024    (set_attr "length_address" "0")])
15026 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15027   [(set (match_operand:DI 0 "register_operand" "=&a")
15028         (plus:DI
15029          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15030                      (match_operand:DI 3 "" "")
15031                      (reg:DI SP_REG)]
15032                     UNSPEC_TLSDESC)
15033          (const:DI (unspec:DI
15034                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15035                     UNSPEC_DTPOFF))))
15036    (clobber (reg:CC FLAGS_REG))]
15037   "TARGET_64BIT && TARGET_GNU2_TLS"
15038   "#"
15039   ""
15040   [(set (match_dup 0) (match_dup 4))]
15042   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15043   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15048 ;; These patterns match the binary 387 instructions for addM3, subM3,
15049 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15050 ;; SFmode.  The first is the normal insn, the second the same insn but
15051 ;; with one operand a conversion, and the third the same insn but with
15052 ;; the other operand a conversion.  The conversion may be SFmode or
15053 ;; SImode if the target mode DFmode, but only SImode if the target mode
15054 ;; is SFmode.
15056 ;; Gcc is slightly more smart about handling normal two address instructions
15057 ;; so use special patterns for add and mull.
15059 (define_insn "*fop_sf_comm_mixed"
15060   [(set (match_operand:SF 0 "register_operand" "=f,x")
15061         (match_operator:SF 3 "binary_fp_operator"
15062                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15063                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15064   "TARGET_MIX_SSE_I387
15065    && COMMUTATIVE_ARITH_P (operands[3])
15066    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15067   "* return output_387_binary_op (insn, operands);"
15068   [(set (attr "type")
15069         (if_then_else (eq_attr "alternative" "1")
15070            (if_then_else (match_operand:SF 3 "mult_operator" "")
15071               (const_string "ssemul")
15072               (const_string "sseadd"))
15073            (if_then_else (match_operand:SF 3 "mult_operator" "")
15074               (const_string "fmul")
15075               (const_string "fop"))))
15076    (set_attr "mode" "SF")])
15078 (define_insn "*fop_sf_comm_sse"
15079   [(set (match_operand:SF 0 "register_operand" "=x")
15080         (match_operator:SF 3 "binary_fp_operator"
15081                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15082                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15083   "TARGET_SSE_MATH
15084    && COMMUTATIVE_ARITH_P (operands[3])
15085    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15086   "* return output_387_binary_op (insn, operands);"
15087   [(set (attr "type")
15088         (if_then_else (match_operand:SF 3 "mult_operator" "")
15089            (const_string "ssemul")
15090            (const_string "sseadd")))
15091    (set_attr "mode" "SF")])
15093 (define_insn "*fop_sf_comm_i387"
15094   [(set (match_operand:SF 0 "register_operand" "=f")
15095         (match_operator:SF 3 "binary_fp_operator"
15096                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15097                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15098   "TARGET_80387
15099    && COMMUTATIVE_ARITH_P (operands[3])
15100    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15101   "* return output_387_binary_op (insn, operands);"
15102   [(set (attr "type")
15103         (if_then_else (match_operand:SF 3 "mult_operator" "")
15104            (const_string "fmul")
15105            (const_string "fop")))
15106    (set_attr "mode" "SF")])
15108 (define_insn "*fop_sf_1_mixed"
15109   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15110         (match_operator:SF 3 "binary_fp_operator"
15111                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15112                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15113   "TARGET_MIX_SSE_I387
15114    && !COMMUTATIVE_ARITH_P (operands[3])
15115    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15116   "* return output_387_binary_op (insn, operands);"
15117   [(set (attr "type")
15118         (cond [(and (eq_attr "alternative" "2")
15119                     (match_operand:SF 3 "mult_operator" ""))
15120                  (const_string "ssemul")
15121                (and (eq_attr "alternative" "2")
15122                     (match_operand:SF 3 "div_operator" ""))
15123                  (const_string "ssediv")
15124                (eq_attr "alternative" "2")
15125                  (const_string "sseadd")
15126                (match_operand:SF 3 "mult_operator" "")
15127                  (const_string "fmul")
15128                (match_operand:SF 3 "div_operator" "")
15129                  (const_string "fdiv")
15130               ]
15131               (const_string "fop")))
15132    (set_attr "mode" "SF")])
15134 (define_insn "*fop_sf_1_sse"
15135   [(set (match_operand:SF 0 "register_operand" "=x")
15136         (match_operator:SF 3 "binary_fp_operator"
15137                         [(match_operand:SF 1 "register_operand" "0")
15138                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15139   "TARGET_SSE_MATH
15140    && !COMMUTATIVE_ARITH_P (operands[3])"
15141   "* return output_387_binary_op (insn, operands);"
15142   [(set (attr "type")
15143         (cond [(match_operand:SF 3 "mult_operator" "")
15144                  (const_string "ssemul")
15145                (match_operand:SF 3 "div_operator" "")
15146                  (const_string "ssediv")
15147               ]
15148               (const_string "sseadd")))
15149    (set_attr "mode" "SF")])
15151 ;; This pattern is not fully shadowed by the pattern above.
15152 (define_insn "*fop_sf_1_i387"
15153   [(set (match_operand:SF 0 "register_operand" "=f,f")
15154         (match_operator:SF 3 "binary_fp_operator"
15155                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15156                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15157   "TARGET_80387 && !TARGET_SSE_MATH
15158    && !COMMUTATIVE_ARITH_P (operands[3])
15159    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15160   "* return output_387_binary_op (insn, operands);"
15161   [(set (attr "type")
15162         (cond [(match_operand:SF 3 "mult_operator" "")
15163                  (const_string "fmul")
15164                (match_operand:SF 3 "div_operator" "")
15165                  (const_string "fdiv")
15166               ]
15167               (const_string "fop")))
15168    (set_attr "mode" "SF")])
15170 ;; ??? Add SSE splitters for these!
15171 (define_insn "*fop_sf_2<mode>_i387"
15172   [(set (match_operand:SF 0 "register_operand" "=f,f")
15173         (match_operator:SF 3 "binary_fp_operator"
15174           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15175            (match_operand:SF 2 "register_operand" "0,0")]))]
15176   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15177   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15178   [(set (attr "type")
15179         (cond [(match_operand:SF 3 "mult_operator" "")
15180                  (const_string "fmul")
15181                (match_operand:SF 3 "div_operator" "")
15182                  (const_string "fdiv")
15183               ]
15184               (const_string "fop")))
15185    (set_attr "fp_int_src" "true")
15186    (set_attr "mode" "<MODE>")])
15188 (define_insn "*fop_sf_3<mode>_i387"
15189   [(set (match_operand:SF 0 "register_operand" "=f,f")
15190         (match_operator:SF 3 "binary_fp_operator"
15191           [(match_operand:SF 1 "register_operand" "0,0")
15192            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15193   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15194   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15195   [(set (attr "type")
15196         (cond [(match_operand:SF 3 "mult_operator" "")
15197                  (const_string "fmul")
15198                (match_operand:SF 3 "div_operator" "")
15199                  (const_string "fdiv")
15200               ]
15201               (const_string "fop")))
15202    (set_attr "fp_int_src" "true")
15203    (set_attr "mode" "<MODE>")])
15205 (define_insn "*fop_df_comm_mixed"
15206   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15207         (match_operator:DF 3 "binary_fp_operator"
15208                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15209                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15210   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15211    && COMMUTATIVE_ARITH_P (operands[3])
15212    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15213   "* return output_387_binary_op (insn, operands);"
15214   [(set (attr "type")
15215         (if_then_else (eq_attr "alternative" "1")
15216            (if_then_else (match_operand:DF 3 "mult_operator" "")
15217               (const_string "ssemul")
15218               (const_string "sseadd"))
15219            (if_then_else (match_operand:DF 3 "mult_operator" "")
15220               (const_string "fmul")
15221               (const_string "fop"))))
15222    (set_attr "mode" "DF")])
15224 (define_insn "*fop_df_comm_sse"
15225   [(set (match_operand:DF 0 "register_operand" "=Y")
15226         (match_operator:DF 3 "binary_fp_operator"
15227                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15228                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15229   "TARGET_SSE2 && TARGET_SSE_MATH
15230    && COMMUTATIVE_ARITH_P (operands[3])
15231    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15232   "* return output_387_binary_op (insn, operands);"
15233   [(set (attr "type")
15234         (if_then_else (match_operand:DF 3 "mult_operator" "")
15235            (const_string "ssemul")
15236            (const_string "sseadd")))
15237    (set_attr "mode" "DF")])
15239 (define_insn "*fop_df_comm_i387"
15240   [(set (match_operand:DF 0 "register_operand" "=f")
15241         (match_operator:DF 3 "binary_fp_operator"
15242                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15243                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15244   "TARGET_80387
15245    && COMMUTATIVE_ARITH_P (operands[3])
15246    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15247   "* return output_387_binary_op (insn, operands);"
15248   [(set (attr "type")
15249         (if_then_else (match_operand:DF 3 "mult_operator" "")
15250            (const_string "fmul")
15251            (const_string "fop")))
15252    (set_attr "mode" "DF")])
15254 (define_insn "*fop_df_1_mixed"
15255   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15256         (match_operator:DF 3 "binary_fp_operator"
15257                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15258                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15259   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15260    && !COMMUTATIVE_ARITH_P (operands[3])
15261    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15262   "* return output_387_binary_op (insn, operands);"
15263   [(set (attr "type")
15264         (cond [(and (eq_attr "alternative" "2")
15265                     (match_operand:DF 3 "mult_operator" ""))
15266                  (const_string "ssemul")
15267                (and (eq_attr "alternative" "2")
15268                     (match_operand:DF 3 "div_operator" ""))
15269                  (const_string "ssediv")
15270                (eq_attr "alternative" "2")
15271                  (const_string "sseadd")
15272                (match_operand:DF 3 "mult_operator" "")
15273                  (const_string "fmul")
15274                (match_operand:DF 3 "div_operator" "")
15275                  (const_string "fdiv")
15276               ]
15277               (const_string "fop")))
15278    (set_attr "mode" "DF")])
15280 (define_insn "*fop_df_1_sse"
15281   [(set (match_operand:DF 0 "register_operand" "=Y")
15282         (match_operator:DF 3 "binary_fp_operator"
15283                         [(match_operand:DF 1 "register_operand" "0")
15284                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15285   "TARGET_SSE2 && TARGET_SSE_MATH
15286    && !COMMUTATIVE_ARITH_P (operands[3])"
15287   "* return output_387_binary_op (insn, operands);"
15288   [(set_attr "mode" "DF")
15289    (set (attr "type")
15290         (cond [(match_operand:DF 3 "mult_operator" "")
15291                  (const_string "ssemul")
15292                (match_operand:DF 3 "div_operator" "")
15293                  (const_string "ssediv")
15294               ]
15295               (const_string "sseadd")))])
15297 ;; This pattern is not fully shadowed by the pattern above.
15298 (define_insn "*fop_df_1_i387"
15299   [(set (match_operand:DF 0 "register_operand" "=f,f")
15300         (match_operator:DF 3 "binary_fp_operator"
15301                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15302                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15303   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15304    && !COMMUTATIVE_ARITH_P (operands[3])
15305    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15306   "* return output_387_binary_op (insn, operands);"
15307   [(set (attr "type")
15308         (cond [(match_operand:DF 3 "mult_operator" "")
15309                  (const_string "fmul")
15310                (match_operand:DF 3 "div_operator" "")
15311                  (const_string "fdiv")
15312               ]
15313               (const_string "fop")))
15314    (set_attr "mode" "DF")])
15316 ;; ??? Add SSE splitters for these!
15317 (define_insn "*fop_df_2<mode>_i387"
15318   [(set (match_operand:DF 0 "register_operand" "=f,f")
15319         (match_operator:DF 3 "binary_fp_operator"
15320            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15321             (match_operand:DF 2 "register_operand" "0,0")]))]
15322   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15323    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15324   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15325   [(set (attr "type")
15326         (cond [(match_operand:DF 3 "mult_operator" "")
15327                  (const_string "fmul")
15328                (match_operand:DF 3 "div_operator" "")
15329                  (const_string "fdiv")
15330               ]
15331               (const_string "fop")))
15332    (set_attr "fp_int_src" "true")
15333    (set_attr "mode" "<MODE>")])
15335 (define_insn "*fop_df_3<mode>_i387"
15336   [(set (match_operand:DF 0 "register_operand" "=f,f")
15337         (match_operator:DF 3 "binary_fp_operator"
15338            [(match_operand:DF 1 "register_operand" "0,0")
15339             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15340   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15341    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15342   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15343   [(set (attr "type")
15344         (cond [(match_operand:DF 3 "mult_operator" "")
15345                  (const_string "fmul")
15346                (match_operand:DF 3 "div_operator" "")
15347                  (const_string "fdiv")
15348               ]
15349               (const_string "fop")))
15350    (set_attr "fp_int_src" "true")
15351    (set_attr "mode" "<MODE>")])
15353 (define_insn "*fop_df_4_i387"
15354   [(set (match_operand:DF 0 "register_operand" "=f,f")
15355         (match_operator:DF 3 "binary_fp_operator"
15356            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15357             (match_operand:DF 2 "register_operand" "0,f")]))]
15358   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15359    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15360   "* return output_387_binary_op (insn, operands);"
15361   [(set (attr "type")
15362         (cond [(match_operand:DF 3 "mult_operator" "")
15363                  (const_string "fmul")
15364                (match_operand:DF 3 "div_operator" "")
15365                  (const_string "fdiv")
15366               ]
15367               (const_string "fop")))
15368    (set_attr "mode" "SF")])
15370 (define_insn "*fop_df_5_i387"
15371   [(set (match_operand:DF 0 "register_operand" "=f,f")
15372         (match_operator:DF 3 "binary_fp_operator"
15373           [(match_operand:DF 1 "register_operand" "0,f")
15374            (float_extend:DF
15375             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15376   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15377   "* return output_387_binary_op (insn, operands);"
15378   [(set (attr "type")
15379         (cond [(match_operand:DF 3 "mult_operator" "")
15380                  (const_string "fmul")
15381                (match_operand:DF 3 "div_operator" "")
15382                  (const_string "fdiv")
15383               ]
15384               (const_string "fop")))
15385    (set_attr "mode" "SF")])
15387 (define_insn "*fop_df_6_i387"
15388   [(set (match_operand:DF 0 "register_operand" "=f,f")
15389         (match_operator:DF 3 "binary_fp_operator"
15390           [(float_extend:DF
15391             (match_operand:SF 1 "register_operand" "0,f"))
15392            (float_extend:DF
15393             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15394   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15395   "* return output_387_binary_op (insn, operands);"
15396   [(set (attr "type")
15397         (cond [(match_operand:DF 3 "mult_operator" "")
15398                  (const_string "fmul")
15399                (match_operand:DF 3 "div_operator" "")
15400                  (const_string "fdiv")
15401               ]
15402               (const_string "fop")))
15403    (set_attr "mode" "SF")])
15405 (define_insn "*fop_xf_comm_i387"
15406   [(set (match_operand:XF 0 "register_operand" "=f")
15407         (match_operator:XF 3 "binary_fp_operator"
15408                         [(match_operand:XF 1 "register_operand" "%0")
15409                          (match_operand:XF 2 "register_operand" "f")]))]
15410   "TARGET_80387
15411    && COMMUTATIVE_ARITH_P (operands[3])"
15412   "* return output_387_binary_op (insn, operands);"
15413   [(set (attr "type")
15414         (if_then_else (match_operand:XF 3 "mult_operator" "")
15415            (const_string "fmul")
15416            (const_string "fop")))
15417    (set_attr "mode" "XF")])
15419 (define_insn "*fop_xf_1_i387"
15420   [(set (match_operand:XF 0 "register_operand" "=f,f")
15421         (match_operator:XF 3 "binary_fp_operator"
15422                         [(match_operand:XF 1 "register_operand" "0,f")
15423                          (match_operand:XF 2 "register_operand" "f,0")]))]
15424   "TARGET_80387
15425    && !COMMUTATIVE_ARITH_P (operands[3])"
15426   "* return output_387_binary_op (insn, operands);"
15427   [(set (attr "type")
15428         (cond [(match_operand:XF 3 "mult_operator" "")
15429                  (const_string "fmul")
15430                (match_operand:XF 3 "div_operator" "")
15431                  (const_string "fdiv")
15432               ]
15433               (const_string "fop")))
15434    (set_attr "mode" "XF")])
15436 (define_insn "*fop_xf_2<mode>_i387"
15437   [(set (match_operand:XF 0 "register_operand" "=f,f")
15438         (match_operator:XF 3 "binary_fp_operator"
15439            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15440             (match_operand:XF 2 "register_operand" "0,0")]))]
15441   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15442   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15443   [(set (attr "type")
15444         (cond [(match_operand:XF 3 "mult_operator" "")
15445                  (const_string "fmul")
15446                (match_operand:XF 3 "div_operator" "")
15447                  (const_string "fdiv")
15448               ]
15449               (const_string "fop")))
15450    (set_attr "fp_int_src" "true")
15451    (set_attr "mode" "<MODE>")])
15453 (define_insn "*fop_xf_3<mode>_i387"
15454   [(set (match_operand:XF 0 "register_operand" "=f,f")
15455         (match_operator:XF 3 "binary_fp_operator"
15456           [(match_operand:XF 1 "register_operand" "0,0")
15457            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15458   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15459   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15460   [(set (attr "type")
15461         (cond [(match_operand:XF 3 "mult_operator" "")
15462                  (const_string "fmul")
15463                (match_operand:XF 3 "div_operator" "")
15464                  (const_string "fdiv")
15465               ]
15466               (const_string "fop")))
15467    (set_attr "fp_int_src" "true")
15468    (set_attr "mode" "<MODE>")])
15470 (define_insn "*fop_xf_4_i387"
15471   [(set (match_operand:XF 0 "register_operand" "=f,f")
15472         (match_operator:XF 3 "binary_fp_operator"
15473            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15474             (match_operand:XF 2 "register_operand" "0,f")]))]
15475   "TARGET_80387"
15476   "* return output_387_binary_op (insn, operands);"
15477   [(set (attr "type")
15478         (cond [(match_operand:XF 3 "mult_operator" "")
15479                  (const_string "fmul")
15480                (match_operand:XF 3 "div_operator" "")
15481                  (const_string "fdiv")
15482               ]
15483               (const_string "fop")))
15484    (set_attr "mode" "SF")])
15486 (define_insn "*fop_xf_5_i387"
15487   [(set (match_operand:XF 0 "register_operand" "=f,f")
15488         (match_operator:XF 3 "binary_fp_operator"
15489           [(match_operand:XF 1 "register_operand" "0,f")
15490            (float_extend:XF
15491             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15492   "TARGET_80387"
15493   "* return output_387_binary_op (insn, operands);"
15494   [(set (attr "type")
15495         (cond [(match_operand:XF 3 "mult_operator" "")
15496                  (const_string "fmul")
15497                (match_operand:XF 3 "div_operator" "")
15498                  (const_string "fdiv")
15499               ]
15500               (const_string "fop")))
15501    (set_attr "mode" "SF")])
15503 (define_insn "*fop_xf_6_i387"
15504   [(set (match_operand:XF 0 "register_operand" "=f,f")
15505         (match_operator:XF 3 "binary_fp_operator"
15506           [(float_extend:XF
15507             (match_operand 1 "register_operand" "0,f"))
15508            (float_extend:XF
15509             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15510   "TARGET_80387"
15511   "* return output_387_binary_op (insn, operands);"
15512   [(set (attr "type")
15513         (cond [(match_operand:XF 3 "mult_operator" "")
15514                  (const_string "fmul")
15515                (match_operand:XF 3 "div_operator" "")
15516                  (const_string "fdiv")
15517               ]
15518               (const_string "fop")))
15519    (set_attr "mode" "SF")])
15521 (define_split
15522   [(set (match_operand 0 "register_operand" "")
15523         (match_operator 3 "binary_fp_operator"
15524            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15525             (match_operand 2 "register_operand" "")]))]
15526   "TARGET_80387 && reload_completed
15527    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15528   [(const_int 0)]
15530   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15531   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15532   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15533                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15534                                           GET_MODE (operands[3]),
15535                                           operands[4],
15536                                           operands[2])));
15537   ix86_free_from_memory (GET_MODE (operands[1]));
15538   DONE;
15541 (define_split
15542   [(set (match_operand 0 "register_operand" "")
15543         (match_operator 3 "binary_fp_operator"
15544            [(match_operand 1 "register_operand" "")
15545             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15546   "TARGET_80387 && reload_completed
15547    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15548   [(const_int 0)]
15550   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15551   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15552   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15553                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15554                                           GET_MODE (operands[3]),
15555                                           operands[1],
15556                                           operands[4])));
15557   ix86_free_from_memory (GET_MODE (operands[2]));
15558   DONE;
15561 ;; FPU special functions.
15563 ;; This pattern implements a no-op XFmode truncation for
15564 ;; all fancy i386 XFmode math functions.
15566 (define_insn "truncxf<mode>2_i387_noop_unspec"
15567   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15568         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15569         UNSPEC_TRUNC_NOOP))]
15570   "TARGET_USE_FANCY_MATH_387"
15571   "* return output_387_reg_move (insn, operands);"
15572   [(set_attr "type" "fmov")
15573    (set_attr "mode" "<MODE>")])
15575 (define_insn "sqrtxf2"
15576   [(set (match_operand:XF 0 "register_operand" "=f")
15577         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15578   "TARGET_USE_FANCY_MATH_387"
15579   "fsqrt"
15580   [(set_attr "type" "fpspc")
15581    (set_attr "mode" "XF")
15582    (set_attr "athlon_decode" "direct")])
15584 (define_insn "sqrt_extend<mode>xf2_i387"
15585   [(set (match_operand:XF 0 "register_operand" "=f")
15586         (sqrt:XF
15587           (float_extend:XF
15588             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15589   "TARGET_USE_FANCY_MATH_387"
15590   "fsqrt"
15591   [(set_attr "type" "fpspc")
15592    (set_attr "mode" "XF")
15593    (set_attr "athlon_decode" "direct")])
15595 (define_insn "*sqrt<mode>2_sse"
15596   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15597         (sqrt:SSEMODEF
15598           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15599   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15600   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15601   [(set_attr "type" "sse")
15602    (set_attr "mode" "<MODE>")
15603    (set_attr "athlon_decode" "*")])
15605 (define_expand "sqrt<mode>2"
15606   [(set (match_operand:X87MODEF12 0 "register_operand" "")
15607         (sqrt:X87MODEF12
15608           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15609   "TARGET_USE_FANCY_MATH_387
15610    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15612   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15613     {
15614       rtx op0 = gen_reg_rtx (XFmode);
15615       rtx op1 = force_reg (<MODE>mode, operands[1]);
15617       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15618       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15619       DONE;
15620    }
15623 (define_insn "fpremxf4_i387"
15624   [(set (match_operand:XF 0 "register_operand" "=f")
15625         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15626                     (match_operand:XF 3 "register_operand" "1")]
15627                    UNSPEC_FPREM_F))
15628    (set (match_operand:XF 1 "register_operand" "=u")
15629         (unspec:XF [(match_dup 2) (match_dup 3)]
15630                    UNSPEC_FPREM_U))
15631    (set (reg:CCFP FPSR_REG)
15632         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15633   "TARGET_USE_FANCY_MATH_387"
15634   "fprem"
15635   [(set_attr "type" "fpspc")
15636    (set_attr "mode" "XF")])
15638 (define_expand "fmodxf3"
15639   [(use (match_operand:XF 0 "register_operand" ""))
15640    (use (match_operand:XF 1 "register_operand" ""))
15641    (use (match_operand:XF 2 "register_operand" ""))]
15642   "TARGET_USE_FANCY_MATH_387"
15644   rtx label = gen_label_rtx ();
15646   emit_label (label);
15648   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15649                                 operands[1], operands[2]));
15650   ix86_emit_fp_unordered_jump (label);
15652   emit_move_insn (operands[0], operands[1]);
15653   DONE;
15656 (define_expand "fmod<mode>3"
15657   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15658    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15659    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15660   "TARGET_USE_FANCY_MATH_387
15661    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15662        || TARGET_MIX_SSE_I387)"
15664   rtx label = gen_label_rtx ();
15666   rtx op1 = gen_reg_rtx (XFmode);
15667   rtx op2 = gen_reg_rtx (XFmode);
15669   emit_insn(gen_extend<mode>xf2 (op1, operands[1]));
15670   emit_insn(gen_extend<mode>xf2 (op2, operands[2]));
15672   emit_label (label);
15673   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15674   ix86_emit_fp_unordered_jump (label);
15676   emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15677   DONE;
15680 (define_insn "fprem1xf4_i387"
15681   [(set (match_operand:XF 0 "register_operand" "=f")
15682         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15683                     (match_operand:XF 3 "register_operand" "1")]
15684                    UNSPEC_FPREM1_F))
15685    (set (match_operand:XF 1 "register_operand" "=u")
15686         (unspec:XF [(match_dup 2) (match_dup 3)]
15687                    UNSPEC_FPREM1_U))
15688    (set (reg:CCFP FPSR_REG)
15689         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15690   "TARGET_USE_FANCY_MATH_387"
15691   "fprem1"
15692   [(set_attr "type" "fpspc")
15693    (set_attr "mode" "XF")])
15695 (define_expand "remainderxf3"
15696   [(use (match_operand:XF 0 "register_operand" ""))
15697    (use (match_operand:XF 1 "register_operand" ""))
15698    (use (match_operand:XF 2 "register_operand" ""))]
15699   "TARGET_USE_FANCY_MATH_387"
15701   rtx label = gen_label_rtx ();
15703   emit_label (label);
15705   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15706                                  operands[1], operands[2]));
15707   ix86_emit_fp_unordered_jump (label);
15709   emit_move_insn (operands[0], operands[1]);
15710   DONE;
15713 (define_expand "remainder<mode>3"
15714   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15715    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15716    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15717   "TARGET_USE_FANCY_MATH_387
15718    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15719        || TARGET_MIX_SSE_I387)"
15721   rtx label = gen_label_rtx ();
15723   rtx op1 = gen_reg_rtx (XFmode);
15724   rtx op2 = gen_reg_rtx (XFmode);
15726   emit_insn(gen_extend<mode>xf2 (op1, operands[1]));
15727   emit_insn(gen_extend<mode>xf2 (op2, operands[2]));
15729   emit_label (label);
15731   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15732   ix86_emit_fp_unordered_jump (label);
15734   emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15735   DONE;
15738 (define_insn "*sindf2"
15739   [(set (match_operand:DF 0 "register_operand" "=f")
15740         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15741   "TARGET_USE_FANCY_MATH_387
15742    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15743    && flag_unsafe_math_optimizations"
15744   "fsin"
15745   [(set_attr "type" "fpspc")
15746    (set_attr "mode" "DF")])
15748 (define_insn "*sinsf2"
15749   [(set (match_operand:SF 0 "register_operand" "=f")
15750         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15751   "TARGET_USE_FANCY_MATH_387
15752    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15753    && flag_unsafe_math_optimizations"
15754   "fsin"
15755   [(set_attr "type" "fpspc")
15756    (set_attr "mode" "SF")])
15758 (define_insn "*sinextendsfdf2"
15759   [(set (match_operand:DF 0 "register_operand" "=f")
15760         (unspec:DF [(float_extend:DF
15761                      (match_operand:SF 1 "register_operand" "0"))]
15762                    UNSPEC_SIN))]
15763   "TARGET_USE_FANCY_MATH_387
15764    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15765    && flag_unsafe_math_optimizations"
15766   "fsin"
15767   [(set_attr "type" "fpspc")
15768    (set_attr "mode" "DF")])
15770 (define_insn "*sinxf2"
15771   [(set (match_operand:XF 0 "register_operand" "=f")
15772         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15773   "TARGET_USE_FANCY_MATH_387
15774    && flag_unsafe_math_optimizations"
15775   "fsin"
15776   [(set_attr "type" "fpspc")
15777    (set_attr "mode" "XF")])
15779 (define_insn "*cosdf2"
15780   [(set (match_operand:DF 0 "register_operand" "=f")
15781         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15782   "TARGET_USE_FANCY_MATH_387
15783    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15784    && flag_unsafe_math_optimizations"
15785   "fcos"
15786   [(set_attr "type" "fpspc")
15787    (set_attr "mode" "DF")])
15789 (define_insn "*cossf2"
15790   [(set (match_operand:SF 0 "register_operand" "=f")
15791         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15792   "TARGET_USE_FANCY_MATH_387
15793    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15794    && flag_unsafe_math_optimizations"
15795   "fcos"
15796   [(set_attr "type" "fpspc")
15797    (set_attr "mode" "SF")])
15799 (define_insn "*cosextendsfdf2"
15800   [(set (match_operand:DF 0 "register_operand" "=f")
15801         (unspec:DF [(float_extend:DF
15802                      (match_operand:SF 1 "register_operand" "0"))]
15803                    UNSPEC_COS))]
15804   "TARGET_USE_FANCY_MATH_387
15805    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15806    && flag_unsafe_math_optimizations"
15807   "fcos"
15808   [(set_attr "type" "fpspc")
15809    (set_attr "mode" "DF")])
15811 (define_insn "*cosxf2"
15812   [(set (match_operand:XF 0 "register_operand" "=f")
15813         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15814   "TARGET_USE_FANCY_MATH_387
15815    && flag_unsafe_math_optimizations"
15816   "fcos"
15817   [(set_attr "type" "fpspc")
15818    (set_attr "mode" "XF")])
15820 ;; With sincos pattern defined, sin and cos builtin function will be
15821 ;; expanded to sincos pattern with one of its outputs left unused.
15822 ;; Cse pass  will detected, if two sincos patterns can be combined,
15823 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15824 ;; depending on the unused output.
15826 (define_insn "sincosdf3"
15827   [(set (match_operand:DF 0 "register_operand" "=f")
15828         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15829                    UNSPEC_SINCOS_COS))
15830    (set (match_operand:DF 1 "register_operand" "=u")
15831         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15832   "TARGET_USE_FANCY_MATH_387
15833    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15834    && flag_unsafe_math_optimizations"
15835   "fsincos"
15836   [(set_attr "type" "fpspc")
15837    (set_attr "mode" "DF")])
15839 (define_split
15840   [(set (match_operand:DF 0 "register_operand" "")
15841         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15842                    UNSPEC_SINCOS_COS))
15843    (set (match_operand:DF 1 "register_operand" "")
15844         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15845   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15846    && !reload_completed && !reload_in_progress"
15847   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15848   "")
15850 (define_split
15851   [(set (match_operand:DF 0 "register_operand" "")
15852         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15853                    UNSPEC_SINCOS_COS))
15854    (set (match_operand:DF 1 "register_operand" "")
15855         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15856   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15857    && !reload_completed && !reload_in_progress"
15858   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15859   "")
15861 (define_insn "sincossf3"
15862   [(set (match_operand:SF 0 "register_operand" "=f")
15863         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15864                    UNSPEC_SINCOS_COS))
15865    (set (match_operand:SF 1 "register_operand" "=u")
15866         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15867   "TARGET_USE_FANCY_MATH_387
15868    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15869    && flag_unsafe_math_optimizations"
15870   "fsincos"
15871   [(set_attr "type" "fpspc")
15872    (set_attr "mode" "SF")])
15874 (define_split
15875   [(set (match_operand:SF 0 "register_operand" "")
15876         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15877                    UNSPEC_SINCOS_COS))
15878    (set (match_operand:SF 1 "register_operand" "")
15879         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15880   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15881    && !reload_completed && !reload_in_progress"
15882   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15883   "")
15885 (define_split
15886   [(set (match_operand:SF 0 "register_operand" "")
15887         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15888                    UNSPEC_SINCOS_COS))
15889    (set (match_operand:SF 1 "register_operand" "")
15890         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15891   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15892    && !reload_completed && !reload_in_progress"
15893   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15894   "")
15896 (define_insn "*sincosextendsfdf3"
15897   [(set (match_operand:DF 0 "register_operand" "=f")
15898         (unspec:DF [(float_extend:DF
15899                      (match_operand:SF 2 "register_operand" "0"))]
15900                    UNSPEC_SINCOS_COS))
15901    (set (match_operand:DF 1 "register_operand" "=u")
15902         (unspec:DF [(float_extend:DF
15903                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15904   "TARGET_USE_FANCY_MATH_387
15905    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15906    && flag_unsafe_math_optimizations"
15907   "fsincos"
15908   [(set_attr "type" "fpspc")
15909    (set_attr "mode" "DF")])
15911 (define_split
15912   [(set (match_operand:DF 0 "register_operand" "")
15913         (unspec:DF [(float_extend:DF
15914                      (match_operand:SF 2 "register_operand" ""))]
15915                    UNSPEC_SINCOS_COS))
15916    (set (match_operand:DF 1 "register_operand" "")
15917         (unspec:DF [(float_extend:DF
15918                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15919   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15920    && !reload_completed && !reload_in_progress"
15921   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15922                                    (match_dup 2))] UNSPEC_SIN))]
15923   "")
15925 (define_split
15926   [(set (match_operand:DF 0 "register_operand" "")
15927         (unspec:DF [(float_extend:DF
15928                      (match_operand:SF 2 "register_operand" ""))]
15929                    UNSPEC_SINCOS_COS))
15930    (set (match_operand:DF 1 "register_operand" "")
15931         (unspec:DF [(float_extend:DF
15932                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15933   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15934    && !reload_completed && !reload_in_progress"
15935   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15936                                    (match_dup 2))] UNSPEC_COS))]
15937   "")
15939 (define_insn "sincosxf3"
15940   [(set (match_operand:XF 0 "register_operand" "=f")
15941         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15942                    UNSPEC_SINCOS_COS))
15943    (set (match_operand:XF 1 "register_operand" "=u")
15944         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15945   "TARGET_USE_FANCY_MATH_387
15946    && flag_unsafe_math_optimizations"
15947   "fsincos"
15948   [(set_attr "type" "fpspc")
15949    (set_attr "mode" "XF")])
15951 (define_split
15952   [(set (match_operand:XF 0 "register_operand" "")
15953         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15954                    UNSPEC_SINCOS_COS))
15955    (set (match_operand:XF 1 "register_operand" "")
15956         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15957   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15958    && !reload_completed && !reload_in_progress"
15959   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15960   "")
15962 (define_split
15963   [(set (match_operand:XF 0 "register_operand" "")
15964         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15965                    UNSPEC_SINCOS_COS))
15966    (set (match_operand:XF 1 "register_operand" "")
15967         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15968   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15969    && !reload_completed && !reload_in_progress"
15970   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15971   "")
15973 (define_insn "*tandf3_1"
15974   [(set (match_operand:DF 0 "register_operand" "=f")
15975         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15976                    UNSPEC_TAN_ONE))
15977    (set (match_operand:DF 1 "register_operand" "=u")
15978         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15979   "TARGET_USE_FANCY_MATH_387
15980    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15981    && flag_unsafe_math_optimizations"
15982   "fptan"
15983   [(set_attr "type" "fpspc")
15984    (set_attr "mode" "DF")])
15986 ;; optimize sequence: fptan
15987 ;;                    fstp    %st(0)
15988 ;;                    fld1
15989 ;; into fptan insn.
15991 (define_peephole2
15992   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15993                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15994                              UNSPEC_TAN_ONE))
15995              (set (match_operand:DF 1 "register_operand" "")
15996                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15997    (set (match_dup 0)
15998         (match_operand:DF 3 "immediate_operand" ""))]
15999   "standard_80387_constant_p (operands[3]) == 2"
16000   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16001              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16002   "")
16004 (define_expand "tandf2"
16005   [(parallel [(set (match_dup 2)
16006                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16007                               UNSPEC_TAN_ONE))
16008               (set (match_operand:DF 0 "register_operand" "")
16009                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16010   "TARGET_USE_FANCY_MATH_387
16011    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16012    && flag_unsafe_math_optimizations"
16014   operands[2] = gen_reg_rtx (DFmode);
16017 (define_insn "*tansf3_1"
16018   [(set (match_operand:SF 0 "register_operand" "=f")
16019         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16020                    UNSPEC_TAN_ONE))
16021    (set (match_operand:SF 1 "register_operand" "=u")
16022         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16023   "TARGET_USE_FANCY_MATH_387
16024    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16025    && flag_unsafe_math_optimizations"
16026   "fptan"
16027   [(set_attr "type" "fpspc")
16028    (set_attr "mode" "SF")])
16030 ;; optimize sequence: fptan
16031 ;;                    fstp    %st(0)
16032 ;;                    fld1
16033 ;; into fptan insn.
16035 (define_peephole2
16036   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16037                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16038                              UNSPEC_TAN_ONE))
16039              (set (match_operand:SF 1 "register_operand" "")
16040                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16041    (set (match_dup 0)
16042         (match_operand:SF 3 "immediate_operand" ""))]
16043   "standard_80387_constant_p (operands[3]) == 2"
16044   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16045              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16046   "")
16048 (define_expand "tansf2"
16049   [(parallel [(set (match_dup 2)
16050                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16051                               UNSPEC_TAN_ONE))
16052               (set (match_operand:SF 0 "register_operand" "")
16053                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16054   "TARGET_USE_FANCY_MATH_387
16055    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16056    && flag_unsafe_math_optimizations"
16058   operands[2] = gen_reg_rtx (SFmode);
16061 (define_insn "*tanxf3_1"
16062   [(set (match_operand:XF 0 "register_operand" "=f")
16063         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16064                    UNSPEC_TAN_ONE))
16065    (set (match_operand:XF 1 "register_operand" "=u")
16066         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16067   "TARGET_USE_FANCY_MATH_387
16068    && flag_unsafe_math_optimizations"
16069   "fptan"
16070   [(set_attr "type" "fpspc")
16071    (set_attr "mode" "XF")])
16073 ;; optimize sequence: fptan
16074 ;;                    fstp    %st(0)
16075 ;;                    fld1
16076 ;; into fptan insn.
16078 (define_peephole2
16079   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16080                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16081                              UNSPEC_TAN_ONE))
16082              (set (match_operand:XF 1 "register_operand" "")
16083                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16084    (set (match_dup 0)
16085         (match_operand:XF 3 "immediate_operand" ""))]
16086   "standard_80387_constant_p (operands[3]) == 2"
16087   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16088              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16089   "")
16091 (define_expand "tanxf2"
16092   [(parallel [(set (match_dup 2)
16093                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16094                               UNSPEC_TAN_ONE))
16095               (set (match_operand:XF 0 "register_operand" "")
16096                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16097   "TARGET_USE_FANCY_MATH_387
16098    && flag_unsafe_math_optimizations"
16100   operands[2] = gen_reg_rtx (XFmode);
16103 (define_insn "atan2df3_1"
16104   [(set (match_operand:DF 0 "register_operand" "=f")
16105         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16106                     (match_operand:DF 1 "register_operand" "u")]
16107                    UNSPEC_FPATAN))
16108    (clobber (match_scratch:DF 3 "=1"))]
16109   "TARGET_USE_FANCY_MATH_387
16110    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16111    && flag_unsafe_math_optimizations"
16112   "fpatan"
16113   [(set_attr "type" "fpspc")
16114    (set_attr "mode" "DF")])
16116 (define_expand "atan2df3"
16117   [(use (match_operand:DF 0 "register_operand" ""))
16118    (use (match_operand:DF 2 "register_operand" ""))
16119    (use (match_operand:DF 1 "register_operand" ""))]
16120   "TARGET_USE_FANCY_MATH_387
16121    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16122    && flag_unsafe_math_optimizations"
16124   rtx copy = gen_reg_rtx (DFmode);
16125   emit_move_insn (copy, operands[1]);
16126   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16127   DONE;
16130 (define_expand "atandf2"
16131   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16132                    (unspec:DF [(match_dup 2)
16133                                (match_operand:DF 1 "register_operand" "")]
16134                     UNSPEC_FPATAN))
16135               (clobber (match_scratch:DF 3 ""))])]
16136   "TARGET_USE_FANCY_MATH_387
16137    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16138    && flag_unsafe_math_optimizations"
16140   operands[2] = gen_reg_rtx (DFmode);
16141   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16144 (define_insn "atan2sf3_1"
16145   [(set (match_operand:SF 0 "register_operand" "=f")
16146         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16147                     (match_operand:SF 1 "register_operand" "u")]
16148                    UNSPEC_FPATAN))
16149    (clobber (match_scratch:SF 3 "=1"))]
16150   "TARGET_USE_FANCY_MATH_387
16151    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16152    && flag_unsafe_math_optimizations"
16153   "fpatan"
16154   [(set_attr "type" "fpspc")
16155    (set_attr "mode" "SF")])
16157 (define_expand "atan2sf3"
16158   [(use (match_operand:SF 0 "register_operand" ""))
16159    (use (match_operand:SF 2 "register_operand" ""))
16160    (use (match_operand:SF 1 "register_operand" ""))]
16161   "TARGET_USE_FANCY_MATH_387
16162    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16163    && flag_unsafe_math_optimizations"
16165   rtx copy = gen_reg_rtx (SFmode);
16166   emit_move_insn (copy, operands[1]);
16167   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16168   DONE;
16171 (define_expand "atansf2"
16172   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16173                    (unspec:SF [(match_dup 2)
16174                                (match_operand:SF 1 "register_operand" "")]
16175                     UNSPEC_FPATAN))
16176               (clobber (match_scratch:SF 3 ""))])]
16177   "TARGET_USE_FANCY_MATH_387
16178    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16179    && flag_unsafe_math_optimizations"
16181   operands[2] = gen_reg_rtx (SFmode);
16182   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16185 (define_insn "atan2xf3_1"
16186   [(set (match_operand:XF 0 "register_operand" "=f")
16187         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16188                     (match_operand:XF 1 "register_operand" "u")]
16189                    UNSPEC_FPATAN))
16190    (clobber (match_scratch:XF 3 "=1"))]
16191   "TARGET_USE_FANCY_MATH_387
16192    && flag_unsafe_math_optimizations"
16193   "fpatan"
16194   [(set_attr "type" "fpspc")
16195    (set_attr "mode" "XF")])
16197 (define_expand "atan2xf3"
16198   [(use (match_operand:XF 0 "register_operand" ""))
16199    (use (match_operand:XF 2 "register_operand" ""))
16200    (use (match_operand:XF 1 "register_operand" ""))]
16201   "TARGET_USE_FANCY_MATH_387
16202    && flag_unsafe_math_optimizations"
16204   rtx copy = gen_reg_rtx (XFmode);
16205   emit_move_insn (copy, operands[1]);
16206   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16207   DONE;
16210 (define_expand "atanxf2"
16211   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16212                    (unspec:XF [(match_dup 2)
16213                                (match_operand:XF 1 "register_operand" "")]
16214                     UNSPEC_FPATAN))
16215               (clobber (match_scratch:XF 3 ""))])]
16216   "TARGET_USE_FANCY_MATH_387
16217    && flag_unsafe_math_optimizations"
16219   operands[2] = gen_reg_rtx (XFmode);
16220   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16223 (define_expand "asindf2"
16224   [(set (match_dup 2)
16225         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16226    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16227    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16228    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16229    (parallel [(set (match_dup 7)
16230                    (unspec:XF [(match_dup 6) (match_dup 2)]
16231                               UNSPEC_FPATAN))
16232               (clobber (match_scratch:XF 8 ""))])
16233    (set (match_operand:DF 0 "register_operand" "")
16234         (float_truncate:DF (match_dup 7)))]
16235   "TARGET_USE_FANCY_MATH_387
16236    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16237    && flag_unsafe_math_optimizations && !optimize_size"
16239   int i;
16241   for (i=2; i<8; i++)
16242     operands[i] = gen_reg_rtx (XFmode);
16244   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16247 (define_expand "asinsf2"
16248   [(set (match_dup 2)
16249         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16250    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16251    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16252    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16253    (parallel [(set (match_dup 7)
16254                    (unspec:XF [(match_dup 6) (match_dup 2)]
16255                               UNSPEC_FPATAN))
16256               (clobber (match_scratch:XF 8 ""))])
16257    (set (match_operand:SF 0 "register_operand" "")
16258         (float_truncate:SF (match_dup 7)))]
16259   "TARGET_USE_FANCY_MATH_387
16260    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16261    && flag_unsafe_math_optimizations && !optimize_size"
16263   int i;
16265   for (i=2; i<8; i++)
16266     operands[i] = gen_reg_rtx (XFmode);
16268   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16271 (define_expand "asinxf2"
16272   [(set (match_dup 2)
16273         (mult:XF (match_operand:XF 1 "register_operand" "")
16274                  (match_dup 1)))
16275    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16276    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16277    (parallel [(set (match_operand:XF 0 "register_operand" "")
16278                    (unspec:XF [(match_dup 5) (match_dup 1)]
16279                               UNSPEC_FPATAN))
16280               (clobber (match_scratch:XF 6 ""))])]
16281   "TARGET_USE_FANCY_MATH_387
16282    && flag_unsafe_math_optimizations && !optimize_size"
16284   int i;
16286   for (i=2; i<6; i++)
16287     operands[i] = gen_reg_rtx (XFmode);
16289   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16292 (define_expand "acosdf2"
16293   [(set (match_dup 2)
16294         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16295    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16296    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16297    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16298    (parallel [(set (match_dup 7)
16299                    (unspec:XF [(match_dup 2) (match_dup 6)]
16300                               UNSPEC_FPATAN))
16301               (clobber (match_scratch:XF 8 ""))])
16302    (set (match_operand:DF 0 "register_operand" "")
16303         (float_truncate:DF (match_dup 7)))]
16304   "TARGET_USE_FANCY_MATH_387
16305    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16306    && flag_unsafe_math_optimizations && !optimize_size"
16308   int i;
16310   for (i=2; i<8; i++)
16311     operands[i] = gen_reg_rtx (XFmode);
16313   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16316 (define_expand "acossf2"
16317   [(set (match_dup 2)
16318         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16319    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16320    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16321    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16322    (parallel [(set (match_dup 7)
16323                    (unspec:XF [(match_dup 2) (match_dup 6)]
16324                               UNSPEC_FPATAN))
16325               (clobber (match_scratch:XF 8 ""))])
16326    (set (match_operand:SF 0 "register_operand" "")
16327         (float_truncate:SF (match_dup 7)))]
16328   "TARGET_USE_FANCY_MATH_387
16329    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16330    && flag_unsafe_math_optimizations && !optimize_size"
16332   int i;
16334   for (i=2; i<8; i++)
16335     operands[i] = gen_reg_rtx (XFmode);
16337   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16340 (define_expand "acosxf2"
16341   [(set (match_dup 2)
16342         (mult:XF (match_operand:XF 1 "register_operand" "")
16343                  (match_dup 1)))
16344    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16345    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16346    (parallel [(set (match_operand:XF 0 "register_operand" "")
16347                    (unspec:XF [(match_dup 1) (match_dup 5)]
16348                               UNSPEC_FPATAN))
16349               (clobber (match_scratch:XF 6 ""))])]
16350   "TARGET_USE_FANCY_MATH_387
16351    && flag_unsafe_math_optimizations && !optimize_size"
16353   int i;
16355   for (i=2; i<6; i++)
16356     operands[i] = gen_reg_rtx (XFmode);
16358   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16361 (define_insn "fyl2x_xf3"
16362   [(set (match_operand:XF 0 "register_operand" "=f")
16363         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16364                     (match_operand:XF 1 "register_operand" "u")]
16365                    UNSPEC_FYL2X))
16366    (clobber (match_scratch:XF 3 "=1"))]
16367   "TARGET_USE_FANCY_MATH_387
16368    && flag_unsafe_math_optimizations"
16369   "fyl2x"
16370   [(set_attr "type" "fpspc")
16371    (set_attr "mode" "XF")])
16373 (define_expand "logsf2"
16374   [(set (match_dup 2)
16375         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16376    (parallel [(set (match_dup 4)
16377                    (unspec:XF [(match_dup 2)
16378                                (match_dup 3)] UNSPEC_FYL2X))
16379               (clobber (match_scratch:XF 5 ""))])
16380    (set (match_operand:SF 0 "register_operand" "")
16381         (float_truncate:SF (match_dup 4)))]
16382   "TARGET_USE_FANCY_MATH_387
16383    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16384    && flag_unsafe_math_optimizations"
16386   rtx temp;
16388   operands[2] = gen_reg_rtx (XFmode);
16389   operands[3] = gen_reg_rtx (XFmode);
16390   operands[4] = gen_reg_rtx (XFmode);
16392   temp = standard_80387_constant_rtx (4); /* fldln2 */
16393   emit_move_insn (operands[3], temp);
16396 (define_expand "logdf2"
16397   [(set (match_dup 2)
16398         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16399    (parallel [(set (match_dup 4)
16400                    (unspec:XF [(match_dup 2)
16401                                (match_dup 3)] UNSPEC_FYL2X))
16402               (clobber (match_scratch:XF 5 ""))])
16403    (set (match_operand:DF 0 "register_operand" "")
16404         (float_truncate:DF (match_dup 4)))]
16405   "TARGET_USE_FANCY_MATH_387
16406    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16407    && flag_unsafe_math_optimizations"
16409   rtx temp;
16411   operands[2] = gen_reg_rtx (XFmode);
16412   operands[3] = gen_reg_rtx (XFmode);
16413   operands[4] = gen_reg_rtx (XFmode);
16415   temp = standard_80387_constant_rtx (4); /* fldln2 */
16416   emit_move_insn (operands[3], temp);
16419 (define_expand "logxf2"
16420   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16421                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16422                                (match_dup 2)] UNSPEC_FYL2X))
16423               (clobber (match_scratch:XF 3 ""))])]
16424   "TARGET_USE_FANCY_MATH_387
16425    && flag_unsafe_math_optimizations"
16427   rtx temp;
16429   operands[2] = gen_reg_rtx (XFmode);
16430   temp = standard_80387_constant_rtx (4); /* fldln2 */
16431   emit_move_insn (operands[2], temp);
16434 (define_expand "log10sf2"
16435   [(set (match_dup 2)
16436         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16437    (parallel [(set (match_dup 4)
16438                    (unspec:XF [(match_dup 2)
16439                                (match_dup 3)] UNSPEC_FYL2X))
16440               (clobber (match_scratch:XF 5 ""))])
16441    (set (match_operand:SF 0 "register_operand" "")
16442         (float_truncate:SF (match_dup 4)))]
16443   "TARGET_USE_FANCY_MATH_387
16444    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16445    && flag_unsafe_math_optimizations"
16447   rtx temp;
16449   operands[2] = gen_reg_rtx (XFmode);
16450   operands[3] = gen_reg_rtx (XFmode);
16451   operands[4] = gen_reg_rtx (XFmode);
16453   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16454   emit_move_insn (operands[3], temp);
16457 (define_expand "log10df2"
16458   [(set (match_dup 2)
16459         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16460    (parallel [(set (match_dup 4)
16461                    (unspec:XF [(match_dup 2)
16462                                (match_dup 3)] UNSPEC_FYL2X))
16463               (clobber (match_scratch:XF 5 ""))])
16464    (set (match_operand:DF 0 "register_operand" "")
16465         (float_truncate:DF (match_dup 4)))]
16466   "TARGET_USE_FANCY_MATH_387
16467    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16468    && flag_unsafe_math_optimizations"
16470   rtx temp;
16472   operands[2] = gen_reg_rtx (XFmode);
16473   operands[3] = gen_reg_rtx (XFmode);
16474   operands[4] = gen_reg_rtx (XFmode);
16476   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16477   emit_move_insn (operands[3], temp);
16480 (define_expand "log10xf2"
16481   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16482                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16483                                (match_dup 2)] UNSPEC_FYL2X))
16484               (clobber (match_scratch:XF 3 ""))])]
16485   "TARGET_USE_FANCY_MATH_387
16486    && flag_unsafe_math_optimizations"
16488   rtx temp;
16490   operands[2] = gen_reg_rtx (XFmode);
16491   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16492   emit_move_insn (operands[2], temp);
16495 (define_expand "log2sf2"
16496   [(set (match_dup 2)
16497         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16498    (parallel [(set (match_dup 4)
16499                    (unspec:XF [(match_dup 2)
16500                                (match_dup 3)] UNSPEC_FYL2X))
16501               (clobber (match_scratch:XF 5 ""))])
16502    (set (match_operand:SF 0 "register_operand" "")
16503         (float_truncate:SF (match_dup 4)))]
16504   "TARGET_USE_FANCY_MATH_387
16505    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16506    && flag_unsafe_math_optimizations"
16508   operands[2] = gen_reg_rtx (XFmode);
16509   operands[3] = gen_reg_rtx (XFmode);
16510   operands[4] = gen_reg_rtx (XFmode);
16512   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16515 (define_expand "log2df2"
16516   [(set (match_dup 2)
16517         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16518    (parallel [(set (match_dup 4)
16519                    (unspec:XF [(match_dup 2)
16520                                (match_dup 3)] UNSPEC_FYL2X))
16521               (clobber (match_scratch:XF 5 ""))])
16522    (set (match_operand:DF 0 "register_operand" "")
16523         (float_truncate:DF (match_dup 4)))]
16524   "TARGET_USE_FANCY_MATH_387
16525    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16526    && flag_unsafe_math_optimizations"
16528   operands[2] = gen_reg_rtx (XFmode);
16529   operands[3] = gen_reg_rtx (XFmode);
16530   operands[4] = gen_reg_rtx (XFmode);
16532   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16535 (define_expand "log2xf2"
16536   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16537                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16538                                (match_dup 2)] UNSPEC_FYL2X))
16539               (clobber (match_scratch:XF 3 ""))])]
16540   "TARGET_USE_FANCY_MATH_387
16541    && flag_unsafe_math_optimizations"
16543   operands[2] = gen_reg_rtx (XFmode);
16544   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16547 (define_insn "fyl2xp1_xf3"
16548   [(set (match_operand:XF 0 "register_operand" "=f")
16549         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16550                     (match_operand:XF 1 "register_operand" "u")]
16551                    UNSPEC_FYL2XP1))
16552    (clobber (match_scratch:XF 3 "=1"))]
16553   "TARGET_USE_FANCY_MATH_387
16554    && flag_unsafe_math_optimizations"
16555   "fyl2xp1"
16556   [(set_attr "type" "fpspc")
16557    (set_attr "mode" "XF")])
16559 (define_expand "log1psf2"
16560   [(use (match_operand:SF 0 "register_operand" ""))
16561    (use (match_operand:SF 1 "register_operand" ""))]
16562   "TARGET_USE_FANCY_MATH_387
16563    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16564    && flag_unsafe_math_optimizations && !optimize_size"
16566   rtx op0 = gen_reg_rtx (XFmode);
16567   rtx op1 = gen_reg_rtx (XFmode);
16569   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16570   ix86_emit_i387_log1p (op0, op1);
16571   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16572   DONE;
16575 (define_expand "log1pdf2"
16576   [(use (match_operand:DF 0 "register_operand" ""))
16577    (use (match_operand:DF 1 "register_operand" ""))]
16578   "TARGET_USE_FANCY_MATH_387
16579    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16580    && flag_unsafe_math_optimizations && !optimize_size"
16582   rtx op0 = gen_reg_rtx (XFmode);
16583   rtx op1 = gen_reg_rtx (XFmode);
16585   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16586   ix86_emit_i387_log1p (op0, op1);
16587   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16588   DONE;
16591 (define_expand "log1pxf2"
16592   [(use (match_operand:XF 0 "register_operand" ""))
16593    (use (match_operand:XF 1 "register_operand" ""))]
16594   "TARGET_USE_FANCY_MATH_387
16595    && flag_unsafe_math_optimizations && !optimize_size"
16597   ix86_emit_i387_log1p (operands[0], operands[1]);
16598   DONE;
16601 (define_insn "*fxtractxf3"
16602   [(set (match_operand:XF 0 "register_operand" "=f")
16603         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16604                    UNSPEC_XTRACT_FRACT))
16605    (set (match_operand:XF 1 "register_operand" "=u")
16606         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16607   "TARGET_USE_FANCY_MATH_387
16608    && flag_unsafe_math_optimizations"
16609   "fxtract"
16610   [(set_attr "type" "fpspc")
16611    (set_attr "mode" "XF")])
16613 (define_expand "logbsf2"
16614   [(set (match_dup 2)
16615         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16616    (parallel [(set (match_dup 3)
16617                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16618               (set (match_dup 4)
16619                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16620    (set (match_operand:SF 0 "register_operand" "")
16621         (float_truncate:SF (match_dup 4)))]
16622   "TARGET_USE_FANCY_MATH_387
16623    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16624    && flag_unsafe_math_optimizations"
16626   operands[2] = gen_reg_rtx (XFmode);
16627   operands[3] = gen_reg_rtx (XFmode);
16628   operands[4] = gen_reg_rtx (XFmode);
16631 (define_expand "logbdf2"
16632   [(set (match_dup 2)
16633         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16634    (parallel [(set (match_dup 3)
16635                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16636               (set (match_dup 4)
16637                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16638    (set (match_operand:DF 0 "register_operand" "")
16639         (float_truncate:DF (match_dup 4)))]
16640   "TARGET_USE_FANCY_MATH_387
16641    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16642    && flag_unsafe_math_optimizations"
16644   operands[2] = gen_reg_rtx (XFmode);
16645   operands[3] = gen_reg_rtx (XFmode);
16646   operands[4] = gen_reg_rtx (XFmode);
16649 (define_expand "logbxf2"
16650   [(parallel [(set (match_dup 2)
16651                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16652                               UNSPEC_XTRACT_FRACT))
16653               (set (match_operand:XF 0 "register_operand" "")
16654                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16655   "TARGET_USE_FANCY_MATH_387
16656    && flag_unsafe_math_optimizations"
16658   operands[2] = gen_reg_rtx (XFmode);
16661 (define_expand "ilogbsi2"
16662   [(parallel [(set (match_dup 2)
16663                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16664                               UNSPEC_XTRACT_FRACT))
16665               (set (match_operand:XF 3 "register_operand" "")
16666                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16667    (parallel [(set (match_operand:SI 0 "register_operand" "")
16668                    (fix:SI (match_dup 3)))
16669               (clobber (reg:CC FLAGS_REG))])]
16670   "TARGET_USE_FANCY_MATH_387
16671    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16672    && flag_unsafe_math_optimizations && !optimize_size"
16674   operands[2] = gen_reg_rtx (XFmode);
16675   operands[3] = gen_reg_rtx (XFmode);
16678 (define_insn "*f2xm1xf2"
16679   [(set (match_operand:XF 0 "register_operand" "=f")
16680         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16681          UNSPEC_F2XM1))]
16682   "TARGET_USE_FANCY_MATH_387
16683    && flag_unsafe_math_optimizations"
16684   "f2xm1"
16685   [(set_attr "type" "fpspc")
16686    (set_attr "mode" "XF")])
16688 (define_insn "*fscalexf4"
16689   [(set (match_operand:XF 0 "register_operand" "=f")
16690         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16691                     (match_operand:XF 3 "register_operand" "1")]
16692                    UNSPEC_FSCALE_FRACT))
16693    (set (match_operand:XF 1 "register_operand" "=u")
16694         (unspec:XF [(match_dup 2) (match_dup 3)]
16695                    UNSPEC_FSCALE_EXP))]
16696   "TARGET_USE_FANCY_MATH_387
16697    && flag_unsafe_math_optimizations"
16698   "fscale"
16699   [(set_attr "type" "fpspc")
16700    (set_attr "mode" "XF")])
16702 (define_expand "expsf2"
16703   [(set (match_dup 2)
16704         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16705    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16706    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16707    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16708    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16709    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16710    (parallel [(set (match_dup 10)
16711                    (unspec:XF [(match_dup 9) (match_dup 5)]
16712                               UNSPEC_FSCALE_FRACT))
16713               (set (match_dup 11)
16714                    (unspec:XF [(match_dup 9) (match_dup 5)]
16715                               UNSPEC_FSCALE_EXP))])
16716    (set (match_operand:SF 0 "register_operand" "")
16717         (float_truncate:SF (match_dup 10)))]
16718   "TARGET_USE_FANCY_MATH_387
16719    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16720    && flag_unsafe_math_optimizations && !optimize_size"
16722   rtx temp;
16723   int i;
16725   for (i=2; i<12; i++)
16726     operands[i] = gen_reg_rtx (XFmode);
16727   temp = standard_80387_constant_rtx (5); /* fldl2e */
16728   emit_move_insn (operands[3], temp);
16729   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16732 (define_expand "expdf2"
16733   [(set (match_dup 2)
16734         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16735    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16736    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16737    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16738    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16739    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16740    (parallel [(set (match_dup 10)
16741                    (unspec:XF [(match_dup 9) (match_dup 5)]
16742                               UNSPEC_FSCALE_FRACT))
16743               (set (match_dup 11)
16744                    (unspec:XF [(match_dup 9) (match_dup 5)]
16745                               UNSPEC_FSCALE_EXP))])
16746    (set (match_operand:DF 0 "register_operand" "")
16747         (float_truncate:DF (match_dup 10)))]
16748   "TARGET_USE_FANCY_MATH_387
16749    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16750    && flag_unsafe_math_optimizations && !optimize_size"
16752   rtx temp;
16753   int i;
16755   for (i=2; i<12; i++)
16756     operands[i] = gen_reg_rtx (XFmode);
16757   temp = standard_80387_constant_rtx (5); /* fldl2e */
16758   emit_move_insn (operands[3], temp);
16759   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16762 (define_expand "expxf2"
16763   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16764                                (match_dup 2)))
16765    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16766    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16767    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16768    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16769    (parallel [(set (match_operand:XF 0 "register_operand" "")
16770                    (unspec:XF [(match_dup 8) (match_dup 4)]
16771                               UNSPEC_FSCALE_FRACT))
16772               (set (match_dup 9)
16773                    (unspec:XF [(match_dup 8) (match_dup 4)]
16774                               UNSPEC_FSCALE_EXP))])]
16775   "TARGET_USE_FANCY_MATH_387
16776    && flag_unsafe_math_optimizations && !optimize_size"
16778   rtx temp;
16779   int i;
16781   for (i=2; i<10; i++)
16782     operands[i] = gen_reg_rtx (XFmode);
16783   temp = standard_80387_constant_rtx (5); /* fldl2e */
16784   emit_move_insn (operands[2], temp);
16785   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16788 (define_expand "exp10sf2"
16789   [(set (match_dup 2)
16790         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16791    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16792    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16793    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16794    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16795    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16796    (parallel [(set (match_dup 10)
16797                    (unspec:XF [(match_dup 9) (match_dup 5)]
16798                               UNSPEC_FSCALE_FRACT))
16799               (set (match_dup 11)
16800                    (unspec:XF [(match_dup 9) (match_dup 5)]
16801                               UNSPEC_FSCALE_EXP))])
16802    (set (match_operand:SF 0 "register_operand" "")
16803         (float_truncate:SF (match_dup 10)))]
16804   "TARGET_USE_FANCY_MATH_387
16805    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16806    && flag_unsafe_math_optimizations && !optimize_size"
16808   rtx temp;
16809   int i;
16811   for (i=2; i<12; i++)
16812     operands[i] = gen_reg_rtx (XFmode);
16813   temp = standard_80387_constant_rtx (6); /* fldl2t */
16814   emit_move_insn (operands[3], temp);
16815   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16818 (define_expand "exp10df2"
16819   [(set (match_dup 2)
16820         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16821    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16822    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16823    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16824    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16825    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16826    (parallel [(set (match_dup 10)
16827                    (unspec:XF [(match_dup 9) (match_dup 5)]
16828                               UNSPEC_FSCALE_FRACT))
16829               (set (match_dup 11)
16830                    (unspec:XF [(match_dup 9) (match_dup 5)]
16831                               UNSPEC_FSCALE_EXP))])
16832    (set (match_operand:DF 0 "register_operand" "")
16833         (float_truncate:DF (match_dup 10)))]
16834   "TARGET_USE_FANCY_MATH_387
16835    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16836    && flag_unsafe_math_optimizations && !optimize_size"
16838   rtx temp;
16839   int i;
16841   for (i=2; i<12; i++)
16842     operands[i] = gen_reg_rtx (XFmode);
16843   temp = standard_80387_constant_rtx (6); /* fldl2t */
16844   emit_move_insn (operands[3], temp);
16845   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16848 (define_expand "exp10xf2"
16849   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16850                                (match_dup 2)))
16851    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16852    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16853    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16854    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16855    (parallel [(set (match_operand:XF 0 "register_operand" "")
16856                    (unspec:XF [(match_dup 8) (match_dup 4)]
16857                               UNSPEC_FSCALE_FRACT))
16858               (set (match_dup 9)
16859                    (unspec:XF [(match_dup 8) (match_dup 4)]
16860                               UNSPEC_FSCALE_EXP))])]
16861   "TARGET_USE_FANCY_MATH_387
16862    && flag_unsafe_math_optimizations && !optimize_size"
16864   rtx temp;
16865   int i;
16867   for (i=2; i<10; i++)
16868     operands[i] = gen_reg_rtx (XFmode);
16869   temp = standard_80387_constant_rtx (6); /* fldl2t */
16870   emit_move_insn (operands[2], temp);
16871   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16874 (define_expand "exp2sf2"
16875   [(set (match_dup 2)
16876         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16877    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16878    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16879    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16880    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16881    (parallel [(set (match_dup 8)
16882                    (unspec:XF [(match_dup 7) (match_dup 3)]
16883                               UNSPEC_FSCALE_FRACT))
16884               (set (match_dup 9)
16885                    (unspec:XF [(match_dup 7) (match_dup 3)]
16886                               UNSPEC_FSCALE_EXP))])
16887    (set (match_operand:SF 0 "register_operand" "")
16888         (float_truncate:SF (match_dup 8)))]
16889   "TARGET_USE_FANCY_MATH_387
16890    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16891    && flag_unsafe_math_optimizations && !optimize_size"
16893   int i;
16895   for (i=2; i<10; i++)
16896     operands[i] = gen_reg_rtx (XFmode);
16897   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16900 (define_expand "exp2df2"
16901   [(set (match_dup 2)
16902         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16903    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16904    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16905    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16906    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16907    (parallel [(set (match_dup 8)
16908                    (unspec:XF [(match_dup 7) (match_dup 3)]
16909                               UNSPEC_FSCALE_FRACT))
16910               (set (match_dup 9)
16911                    (unspec:XF [(match_dup 7) (match_dup 3)]
16912                               UNSPEC_FSCALE_EXP))])
16913    (set (match_operand:DF 0 "register_operand" "")
16914         (float_truncate:DF (match_dup 8)))]
16915   "TARGET_USE_FANCY_MATH_387
16916    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16917    && flag_unsafe_math_optimizations && !optimize_size"
16919   int i;
16921   for (i=2; i<10; i++)
16922     operands[i] = gen_reg_rtx (XFmode);
16923   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16926 (define_expand "exp2xf2"
16927   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16928    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16929    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16930    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16931    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16932    (parallel [(set (match_operand:XF 0 "register_operand" "")
16933                    (unspec:XF [(match_dup 7) (match_dup 3)]
16934                               UNSPEC_FSCALE_FRACT))
16935               (set (match_dup 8)
16936                    (unspec:XF [(match_dup 7) (match_dup 3)]
16937                               UNSPEC_FSCALE_EXP))])]
16938   "TARGET_USE_FANCY_MATH_387
16939    && flag_unsafe_math_optimizations && !optimize_size"
16941   int i;
16943   for (i=2; i<9; i++)
16944     operands[i] = gen_reg_rtx (XFmode);
16945   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16948 (define_expand "expm1df2"
16949   [(set (match_dup 2)
16950         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16951    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16952    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16953    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16954    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16955    (parallel [(set (match_dup 8)
16956                    (unspec:XF [(match_dup 7) (match_dup 5)]
16957                               UNSPEC_FSCALE_FRACT))
16958                    (set (match_dup 9)
16959                    (unspec:XF [(match_dup 7) (match_dup 5)]
16960                               UNSPEC_FSCALE_EXP))])
16961    (parallel [(set (match_dup 11)
16962                    (unspec:XF [(match_dup 10) (match_dup 9)]
16963                               UNSPEC_FSCALE_FRACT))
16964               (set (match_dup 12)
16965                    (unspec:XF [(match_dup 10) (match_dup 9)]
16966                               UNSPEC_FSCALE_EXP))])
16967    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16968    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16969    (set (match_operand:DF 0 "register_operand" "")
16970         (float_truncate:DF (match_dup 14)))]
16971   "TARGET_USE_FANCY_MATH_387
16972    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16973    && flag_unsafe_math_optimizations && !optimize_size"
16975   rtx temp;
16976   int i;
16978   for (i=2; i<15; i++)
16979     operands[i] = gen_reg_rtx (XFmode);
16980   temp = standard_80387_constant_rtx (5); /* fldl2e */
16981   emit_move_insn (operands[3], temp);
16982   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16985 (define_expand "expm1sf2"
16986   [(set (match_dup 2)
16987         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16988    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16989    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16990    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16991    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16992    (parallel [(set (match_dup 8)
16993                    (unspec:XF [(match_dup 7) (match_dup 5)]
16994                               UNSPEC_FSCALE_FRACT))
16995                    (set (match_dup 9)
16996                    (unspec:XF [(match_dup 7) (match_dup 5)]
16997                               UNSPEC_FSCALE_EXP))])
16998    (parallel [(set (match_dup 11)
16999                    (unspec:XF [(match_dup 10) (match_dup 9)]
17000                               UNSPEC_FSCALE_FRACT))
17001               (set (match_dup 12)
17002                    (unspec:XF [(match_dup 10) (match_dup 9)]
17003                               UNSPEC_FSCALE_EXP))])
17004    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17005    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17006    (set (match_operand:SF 0 "register_operand" "")
17007         (float_truncate:SF (match_dup 14)))]
17008   "TARGET_USE_FANCY_MATH_387
17009    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17010    && flag_unsafe_math_optimizations && !optimize_size"
17012   rtx temp;
17013   int i;
17015   for (i=2; i<15; i++)
17016     operands[i] = gen_reg_rtx (XFmode);
17017   temp = standard_80387_constant_rtx (5); /* fldl2e */
17018   emit_move_insn (operands[3], temp);
17019   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17022 (define_expand "expm1xf2"
17023   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17024                                (match_dup 2)))
17025    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17026    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17027    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17028    (parallel [(set (match_dup 7)
17029                    (unspec:XF [(match_dup 6) (match_dup 4)]
17030                               UNSPEC_FSCALE_FRACT))
17031                    (set (match_dup 8)
17032                    (unspec:XF [(match_dup 6) (match_dup 4)]
17033                               UNSPEC_FSCALE_EXP))])
17034    (parallel [(set (match_dup 10)
17035                    (unspec:XF [(match_dup 9) (match_dup 8)]
17036                               UNSPEC_FSCALE_FRACT))
17037               (set (match_dup 11)
17038                    (unspec:XF [(match_dup 9) (match_dup 8)]
17039                               UNSPEC_FSCALE_EXP))])
17040    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17041    (set (match_operand:XF 0 "register_operand" "")
17042         (plus:XF (match_dup 12) (match_dup 7)))]
17043   "TARGET_USE_FANCY_MATH_387
17044    && flag_unsafe_math_optimizations && !optimize_size"
17046   rtx temp;
17047   int i;
17049   for (i=2; i<13; i++)
17050     operands[i] = gen_reg_rtx (XFmode);
17051   temp = standard_80387_constant_rtx (5); /* fldl2e */
17052   emit_move_insn (operands[2], temp);
17053   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17056 (define_expand "ldexpdf3"
17057   [(set (match_dup 3)
17058         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17059    (set (match_dup 4)
17060         (float:XF (match_operand:SI 2 "register_operand" "")))
17061    (parallel [(set (match_dup 5)
17062                    (unspec:XF [(match_dup 3) (match_dup 4)]
17063                               UNSPEC_FSCALE_FRACT))
17064               (set (match_dup 6)
17065                    (unspec:XF [(match_dup 3) (match_dup 4)]
17066                               UNSPEC_FSCALE_EXP))])
17067    (set (match_operand:DF 0 "register_operand" "")
17068         (float_truncate:DF (match_dup 5)))]
17069   "TARGET_USE_FANCY_MATH_387
17070    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17071    && flag_unsafe_math_optimizations && !optimize_size"
17073   int i;
17075   for (i=3; i<7; i++)
17076     operands[i] = gen_reg_rtx (XFmode);
17079 (define_expand "ldexpsf3"
17080   [(set (match_dup 3)
17081         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17082    (set (match_dup 4)
17083         (float:XF (match_operand:SI 2 "register_operand" "")))
17084    (parallel [(set (match_dup 5)
17085                    (unspec:XF [(match_dup 3) (match_dup 4)]
17086                               UNSPEC_FSCALE_FRACT))
17087               (set (match_dup 6)
17088                    (unspec:XF [(match_dup 3) (match_dup 4)]
17089                               UNSPEC_FSCALE_EXP))])
17090    (set (match_operand:SF 0 "register_operand" "")
17091         (float_truncate:SF (match_dup 5)))]
17092   "TARGET_USE_FANCY_MATH_387
17093    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17094    && flag_unsafe_math_optimizations && !optimize_size"
17096   int i;
17098   for (i=3; i<7; i++)
17099     operands[i] = gen_reg_rtx (XFmode);
17102 (define_expand "ldexpxf3"
17103   [(set (match_dup 3)
17104         (float:XF (match_operand:SI 2 "register_operand" "")))
17105    (parallel [(set (match_operand:XF 0 " register_operand" "")
17106                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17107                                (match_dup 3)]
17108                               UNSPEC_FSCALE_FRACT))
17109               (set (match_dup 4)
17110                    (unspec:XF [(match_dup 1) (match_dup 3)]
17111                               UNSPEC_FSCALE_EXP))])]
17112   "TARGET_USE_FANCY_MATH_387
17113    && flag_unsafe_math_optimizations && !optimize_size"
17115   int i;
17117   for (i=3; i<5; i++)
17118     operands[i] = gen_reg_rtx (XFmode);
17122 (define_insn "frndintxf2"
17123   [(set (match_operand:XF 0 "register_operand" "=f")
17124         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17125          UNSPEC_FRNDINT))]
17126   "TARGET_USE_FANCY_MATH_387
17127    && flag_unsafe_math_optimizations"
17128   "frndint"
17129   [(set_attr "type" "fpspc")
17130    (set_attr "mode" "XF")])
17132 (define_expand "rintdf2"
17133   [(use (match_operand:DF 0 "register_operand" ""))
17134    (use (match_operand:DF 1 "register_operand" ""))]
17135   "(TARGET_USE_FANCY_MATH_387
17136     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17137     && flag_unsafe_math_optimizations)
17138    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17139        && !flag_trapping_math
17140        && !optimize_size)"
17142   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17143       && !flag_trapping_math
17144       && !optimize_size)
17145     ix86_expand_rint (operand0, operand1);
17146   else
17147     {
17148       rtx op0 = gen_reg_rtx (XFmode);
17149       rtx op1 = gen_reg_rtx (XFmode);
17151       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17152       emit_insn (gen_frndintxf2 (op0, op1));
17154       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17155     }
17156   DONE;
17159 (define_expand "rintsf2"
17160   [(use (match_operand:SF 0 "register_operand" ""))
17161    (use (match_operand:SF 1 "register_operand" ""))]
17162   "(TARGET_USE_FANCY_MATH_387
17163     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17164     && flag_unsafe_math_optimizations)
17165    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17166        && !flag_trapping_math
17167        && !optimize_size)"
17169   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17170       && !flag_trapping_math
17171       && !optimize_size)
17172     ix86_expand_rint (operand0, operand1);
17173   else
17174     {
17175       rtx op0 = gen_reg_rtx (XFmode);
17176       rtx op1 = gen_reg_rtx (XFmode);
17178       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17179       emit_insn (gen_frndintxf2 (op0, op1));
17181       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17182     }
17183   DONE;
17186 (define_expand "rintxf2"
17187   [(use (match_operand:XF 0 "register_operand" ""))
17188    (use (match_operand:XF 1 "register_operand" ""))]
17189   "TARGET_USE_FANCY_MATH_387
17190    && flag_unsafe_math_optimizations && !optimize_size"
17192   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17193   DONE;
17196 (define_expand "roundsf2"
17197   [(match_operand:SF 0 "register_operand" "")
17198    (match_operand:SF 1 "nonimmediate_operand" "")]
17199   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17200    && !flag_trapping_math && !flag_rounding_math
17201    && !optimize_size"
17203   ix86_expand_round (operand0, operand1);
17204   DONE;
17207 (define_expand "rounddf2"
17208   [(match_operand:DF 0 "register_operand" "")
17209    (match_operand:DF 1 "nonimmediate_operand" "")]
17210   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17211    && !flag_trapping_math && !flag_rounding_math
17212    && !optimize_size"
17214   if (TARGET_64BIT)
17215     ix86_expand_round (operand0, operand1);
17216   else
17217     ix86_expand_rounddf_32 (operand0, operand1);
17218   DONE;
17221 (define_insn_and_split "*fistdi2_1"
17222   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17223         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17224          UNSPEC_FIST))]
17225   "TARGET_USE_FANCY_MATH_387
17226    && !(reload_completed || reload_in_progress)"
17227   "#"
17228   "&& 1"
17229   [(const_int 0)]
17231   if (memory_operand (operands[0], VOIDmode))
17232     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17233   else
17234     {
17235       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17236       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17237                                          operands[2]));
17238     }
17239   DONE;
17241   [(set_attr "type" "fpspc")
17242    (set_attr "mode" "DI")])
17244 (define_insn "fistdi2"
17245   [(set (match_operand:DI 0 "memory_operand" "=m")
17246         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17247          UNSPEC_FIST))
17248    (clobber (match_scratch:XF 2 "=&1f"))]
17249   "TARGET_USE_FANCY_MATH_387"
17250   "* return output_fix_trunc (insn, operands, 0);"
17251   [(set_attr "type" "fpspc")
17252    (set_attr "mode" "DI")])
17254 (define_insn "fistdi2_with_temp"
17255   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17256         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17257          UNSPEC_FIST))
17258    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17259    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17260   "TARGET_USE_FANCY_MATH_387"
17261   "#"
17262   [(set_attr "type" "fpspc")
17263    (set_attr "mode" "DI")])
17265 (define_split
17266   [(set (match_operand:DI 0 "register_operand" "")
17267         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17268          UNSPEC_FIST))
17269    (clobber (match_operand:DI 2 "memory_operand" ""))
17270    (clobber (match_scratch 3 ""))]
17271   "reload_completed"
17272   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17273               (clobber (match_dup 3))])
17274    (set (match_dup 0) (match_dup 2))]
17275   "")
17277 (define_split
17278   [(set (match_operand:DI 0 "memory_operand" "")
17279         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17280          UNSPEC_FIST))
17281    (clobber (match_operand:DI 2 "memory_operand" ""))
17282    (clobber (match_scratch 3 ""))]
17283   "reload_completed"
17284   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17285               (clobber (match_dup 3))])]
17286   "")
17288 (define_insn_and_split "*fist<mode>2_1"
17289   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17290         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17291          UNSPEC_FIST))]
17292   "TARGET_USE_FANCY_MATH_387
17293    && !(reload_completed || reload_in_progress)"
17294   "#"
17295   "&& 1"
17296   [(const_int 0)]
17298   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17299   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17300                                         operands[2]));
17301   DONE;
17303   [(set_attr "type" "fpspc")
17304    (set_attr "mode" "<MODE>")])
17306 (define_insn "fist<mode>2"
17307   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17308         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17309          UNSPEC_FIST))]
17310   "TARGET_USE_FANCY_MATH_387"
17311   "* return output_fix_trunc (insn, operands, 0);"
17312   [(set_attr "type" "fpspc")
17313    (set_attr "mode" "<MODE>")])
17315 (define_insn "fist<mode>2_with_temp"
17316   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17317         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17318          UNSPEC_FIST))
17319    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17320   "TARGET_USE_FANCY_MATH_387"
17321   "#"
17322   [(set_attr "type" "fpspc")
17323    (set_attr "mode" "<MODE>")])
17325 (define_split
17326   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17327         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17328          UNSPEC_FIST))
17329    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17330   "reload_completed"
17331   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17332                        UNSPEC_FIST))
17333    (set (match_dup 0) (match_dup 2))]
17334   "")
17336 (define_split
17337   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17338         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17339          UNSPEC_FIST))
17340    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17341   "reload_completed"
17342   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17343                        UNSPEC_FIST))]
17344   "")
17346 (define_expand "lrintxf<mode>2"
17347   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17348      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17349       UNSPEC_FIST))]
17350   "TARGET_USE_FANCY_MATH_387"
17351   "")
17353 (define_expand "lrint<mode>di2"
17354   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17355      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17356       UNSPEC_FIX_NOTRUNC))]
17357   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17358   "")
17360 (define_expand "lrint<mode>si2"
17361   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17362      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17363       UNSPEC_FIX_NOTRUNC))]
17364   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17365   "")
17367 (define_expand "lround<mode>di2"
17368   [(match_operand:DI 0 "nonimmediate_operand" "")
17369    (match_operand:SSEMODEF 1 "register_operand" "")]
17370   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17371    && !flag_trapping_math && !flag_rounding_math
17372    && !optimize_size"
17374   ix86_expand_lround (operand0, operand1);
17375   DONE;
17378 (define_expand "lround<mode>si2"
17379   [(match_operand:SI 0 "nonimmediate_operand" "")
17380    (match_operand:SSEMODEF 1 "register_operand" "")]
17381   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17382    && !flag_trapping_math && !flag_rounding_math
17383    && !optimize_size"
17385   ix86_expand_lround (operand0, operand1);
17386   DONE;
17389 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17390 (define_insn_and_split "frndintxf2_floor"
17391   [(set (match_operand:XF 0 "register_operand" "=f")
17392         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17393          UNSPEC_FRNDINT_FLOOR))
17394    (clobber (reg:CC FLAGS_REG))]
17395   "TARGET_USE_FANCY_MATH_387
17396    && flag_unsafe_math_optimizations
17397    && !(reload_completed || reload_in_progress)"
17398   "#"
17399   "&& 1"
17400   [(const_int 0)]
17402   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17404   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17405   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17407   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17408                                         operands[2], operands[3]));
17409   DONE;
17411   [(set_attr "type" "frndint")
17412    (set_attr "i387_cw" "floor")
17413    (set_attr "mode" "XF")])
17415 (define_insn "frndintxf2_floor_i387"
17416   [(set (match_operand:XF 0 "register_operand" "=f")
17417         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17418          UNSPEC_FRNDINT_FLOOR))
17419    (use (match_operand:HI 2 "memory_operand" "m"))
17420    (use (match_operand:HI 3 "memory_operand" "m"))]
17421   "TARGET_USE_FANCY_MATH_387
17422    && flag_unsafe_math_optimizations"
17423   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17424   [(set_attr "type" "frndint")
17425    (set_attr "i387_cw" "floor")
17426    (set_attr "mode" "XF")])
17428 (define_expand "floorxf2"
17429   [(use (match_operand:XF 0 "register_operand" ""))
17430    (use (match_operand:XF 1 "register_operand" ""))]
17431   "TARGET_USE_FANCY_MATH_387
17432    && flag_unsafe_math_optimizations && !optimize_size"
17434   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17435   DONE;
17438 (define_expand "floordf2"
17439   [(use (match_operand:DF 0 "register_operand" ""))
17440    (use (match_operand:DF 1 "register_operand" ""))]
17441   "((TARGET_USE_FANCY_MATH_387
17442      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17443      && flag_unsafe_math_optimizations)
17444     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17445         && !flag_trapping_math))
17446    && !optimize_size"
17448   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17449       && !flag_trapping_math)
17450     {
17451       if (TARGET_64BIT)
17452         ix86_expand_floorceil (operand0, operand1, true);
17453       else
17454         ix86_expand_floorceildf_32 (operand0, operand1, true);
17455     }
17456   else
17457     {
17458       rtx op0 = gen_reg_rtx (XFmode);
17459       rtx op1 = gen_reg_rtx (XFmode);
17461       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17462       emit_insn (gen_frndintxf2_floor (op0, op1));
17464       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17465     }
17466   DONE;
17469 (define_expand "floorsf2"
17470   [(use (match_operand:SF 0 "register_operand" ""))
17471    (use (match_operand:SF 1 "register_operand" ""))]
17472   "((TARGET_USE_FANCY_MATH_387
17473      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17474      && flag_unsafe_math_optimizations)
17475     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17476         && !flag_trapping_math))
17477    && !optimize_size"
17479   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17480       && !flag_trapping_math)
17481     ix86_expand_floorceil (operand0, operand1, true);
17482   else
17483     {
17484       rtx op0 = gen_reg_rtx (XFmode);
17485       rtx op1 = gen_reg_rtx (XFmode);
17487       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17488       emit_insn (gen_frndintxf2_floor (op0, op1));
17490       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17491     }
17492   DONE;
17495 (define_insn_and_split "*fist<mode>2_floor_1"
17496   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17497         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17498          UNSPEC_FIST_FLOOR))
17499    (clobber (reg:CC FLAGS_REG))]
17500   "TARGET_USE_FANCY_MATH_387
17501    && flag_unsafe_math_optimizations
17502    && !(reload_completed || reload_in_progress)"
17503   "#"
17504   "&& 1"
17505   [(const_int 0)]
17507   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17509   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17510   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17511   if (memory_operand (operands[0], VOIDmode))
17512     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17513                                       operands[2], operands[3]));
17514   else
17515     {
17516       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17517       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17518                                                   operands[2], operands[3],
17519                                                   operands[4]));
17520     }
17521   DONE;
17523   [(set_attr "type" "fistp")
17524    (set_attr "i387_cw" "floor")
17525    (set_attr "mode" "<MODE>")])
17527 (define_insn "fistdi2_floor"
17528   [(set (match_operand:DI 0 "memory_operand" "=m")
17529         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17530          UNSPEC_FIST_FLOOR))
17531    (use (match_operand:HI 2 "memory_operand" "m"))
17532    (use (match_operand:HI 3 "memory_operand" "m"))
17533    (clobber (match_scratch:XF 4 "=&1f"))]
17534   "TARGET_USE_FANCY_MATH_387
17535    && flag_unsafe_math_optimizations"
17536   "* return output_fix_trunc (insn, operands, 0);"
17537   [(set_attr "type" "fistp")
17538    (set_attr "i387_cw" "floor")
17539    (set_attr "mode" "DI")])
17541 (define_insn "fistdi2_floor_with_temp"
17542   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17543         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17544          UNSPEC_FIST_FLOOR))
17545    (use (match_operand:HI 2 "memory_operand" "m,m"))
17546    (use (match_operand:HI 3 "memory_operand" "m,m"))
17547    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17548    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17549   "TARGET_USE_FANCY_MATH_387
17550    && flag_unsafe_math_optimizations"
17551   "#"
17552   [(set_attr "type" "fistp")
17553    (set_attr "i387_cw" "floor")
17554    (set_attr "mode" "DI")])
17556 (define_split
17557   [(set (match_operand:DI 0 "register_operand" "")
17558         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17559          UNSPEC_FIST_FLOOR))
17560    (use (match_operand:HI 2 "memory_operand" ""))
17561    (use (match_operand:HI 3 "memory_operand" ""))
17562    (clobber (match_operand:DI 4 "memory_operand" ""))
17563    (clobber (match_scratch 5 ""))]
17564   "reload_completed"
17565   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17566               (use (match_dup 2))
17567               (use (match_dup 3))
17568               (clobber (match_dup 5))])
17569    (set (match_dup 0) (match_dup 4))]
17570   "")
17572 (define_split
17573   [(set (match_operand:DI 0 "memory_operand" "")
17574         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17575          UNSPEC_FIST_FLOOR))
17576    (use (match_operand:HI 2 "memory_operand" ""))
17577    (use (match_operand:HI 3 "memory_operand" ""))
17578    (clobber (match_operand:DI 4 "memory_operand" ""))
17579    (clobber (match_scratch 5 ""))]
17580   "reload_completed"
17581   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17582               (use (match_dup 2))
17583               (use (match_dup 3))
17584               (clobber (match_dup 5))])]
17585   "")
17587 (define_insn "fist<mode>2_floor"
17588   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17589         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17590          UNSPEC_FIST_FLOOR))
17591    (use (match_operand:HI 2 "memory_operand" "m"))
17592    (use (match_operand:HI 3 "memory_operand" "m"))]
17593   "TARGET_USE_FANCY_MATH_387
17594    && flag_unsafe_math_optimizations"
17595   "* return output_fix_trunc (insn, operands, 0);"
17596   [(set_attr "type" "fistp")
17597    (set_attr "i387_cw" "floor")
17598    (set_attr "mode" "<MODE>")])
17600 (define_insn "fist<mode>2_floor_with_temp"
17601   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17602         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17603          UNSPEC_FIST_FLOOR))
17604    (use (match_operand:HI 2 "memory_operand" "m,m"))
17605    (use (match_operand:HI 3 "memory_operand" "m,m"))
17606    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17607   "TARGET_USE_FANCY_MATH_387
17608    && flag_unsafe_math_optimizations"
17609   "#"
17610   [(set_attr "type" "fistp")
17611    (set_attr "i387_cw" "floor")
17612    (set_attr "mode" "<MODE>")])
17614 (define_split
17615   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17616         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17617          UNSPEC_FIST_FLOOR))
17618    (use (match_operand:HI 2 "memory_operand" ""))
17619    (use (match_operand:HI 3 "memory_operand" ""))
17620    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17621   "reload_completed"
17622   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17623                                   UNSPEC_FIST_FLOOR))
17624               (use (match_dup 2))
17625               (use (match_dup 3))])
17626    (set (match_dup 0) (match_dup 4))]
17627   "")
17629 (define_split
17630   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17631         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17632          UNSPEC_FIST_FLOOR))
17633    (use (match_operand:HI 2 "memory_operand" ""))
17634    (use (match_operand:HI 3 "memory_operand" ""))
17635    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17636   "reload_completed"
17637   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17638                                   UNSPEC_FIST_FLOOR))
17639               (use (match_dup 2))
17640               (use (match_dup 3))])]
17641   "")
17643 (define_expand "lfloorxf<mode>2"
17644   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17645                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17646                     UNSPEC_FIST_FLOOR))
17647               (clobber (reg:CC FLAGS_REG))])]
17648   "TARGET_USE_FANCY_MATH_387
17649    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17650    && flag_unsafe_math_optimizations"
17651   "")
17653 (define_expand "lfloor<mode>di2"
17654   [(match_operand:DI 0 "nonimmediate_operand" "")
17655    (match_operand:SSEMODEF 1 "register_operand" "")]
17656   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17657    && !flag_trapping_math
17658    && !optimize_size"
17660   ix86_expand_lfloorceil (operand0, operand1, true);
17661   DONE;
17664 (define_expand "lfloor<mode>si2"
17665   [(match_operand:SI 0 "nonimmediate_operand" "")
17666    (match_operand:SSEMODEF 1 "register_operand" "")]
17667   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17668    && !flag_trapping_math
17669    && (!optimize_size || !TARGET_64BIT)"
17671   ix86_expand_lfloorceil (operand0, operand1, true);
17672   DONE;
17675 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17676 (define_insn_and_split "frndintxf2_ceil"
17677   [(set (match_operand:XF 0 "register_operand" "=f")
17678         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17679          UNSPEC_FRNDINT_CEIL))
17680    (clobber (reg:CC FLAGS_REG))]
17681   "TARGET_USE_FANCY_MATH_387
17682    && flag_unsafe_math_optimizations
17683    && !(reload_completed || reload_in_progress)"
17684   "#"
17685   "&& 1"
17686   [(const_int 0)]
17688   ix86_optimize_mode_switching[I387_CEIL] = 1;
17690   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17691   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17693   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17694                                        operands[2], operands[3]));
17695   DONE;
17697   [(set_attr "type" "frndint")
17698    (set_attr "i387_cw" "ceil")
17699    (set_attr "mode" "XF")])
17701 (define_insn "frndintxf2_ceil_i387"
17702   [(set (match_operand:XF 0 "register_operand" "=f")
17703         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17704          UNSPEC_FRNDINT_CEIL))
17705    (use (match_operand:HI 2 "memory_operand" "m"))
17706    (use (match_operand:HI 3 "memory_operand" "m"))]
17707   "TARGET_USE_FANCY_MATH_387
17708    && flag_unsafe_math_optimizations"
17709   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17710   [(set_attr "type" "frndint")
17711    (set_attr "i387_cw" "ceil")
17712    (set_attr "mode" "XF")])
17714 (define_expand "ceilxf2"
17715   [(use (match_operand:XF 0 "register_operand" ""))
17716    (use (match_operand:XF 1 "register_operand" ""))]
17717   "TARGET_USE_FANCY_MATH_387
17718    && flag_unsafe_math_optimizations && !optimize_size"
17720   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17721   DONE;
17724 (define_expand "ceildf2"
17725   [(use (match_operand:DF 0 "register_operand" ""))
17726    (use (match_operand:DF 1 "register_operand" ""))]
17727   "((TARGET_USE_FANCY_MATH_387
17728      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17729      && flag_unsafe_math_optimizations)
17730     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17731         && !flag_trapping_math))
17732    && !optimize_size"
17734   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17735       && !flag_trapping_math)
17736     {
17737       if (TARGET_64BIT)
17738         ix86_expand_floorceil (operand0, operand1, false);
17739       else
17740         ix86_expand_floorceildf_32 (operand0, operand1, false);
17741     }
17742   else
17743     {
17744       rtx op0 = gen_reg_rtx (XFmode);
17745       rtx op1 = gen_reg_rtx (XFmode);
17747       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17748       emit_insn (gen_frndintxf2_ceil (op0, op1));
17750       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17751     }
17752   DONE;
17755 (define_expand "ceilsf2"
17756   [(use (match_operand:SF 0 "register_operand" ""))
17757    (use (match_operand:SF 1 "register_operand" ""))]
17758   "((TARGET_USE_FANCY_MATH_387
17759      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17760      && flag_unsafe_math_optimizations)
17761     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17762         && !flag_trapping_math))
17763    && !optimize_size"
17765   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17766       && !flag_trapping_math)
17767     ix86_expand_floorceil (operand0, operand1, false);
17768   else
17769     {
17770       rtx op0 = gen_reg_rtx (XFmode);
17771       rtx op1 = gen_reg_rtx (XFmode);
17773       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17774       emit_insn (gen_frndintxf2_ceil (op0, op1));
17776       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17777     }
17778   DONE;
17781 (define_insn_and_split "*fist<mode>2_ceil_1"
17782   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17783         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17784          UNSPEC_FIST_CEIL))
17785    (clobber (reg:CC FLAGS_REG))]
17786   "TARGET_USE_FANCY_MATH_387
17787    && flag_unsafe_math_optimizations
17788    && !(reload_completed || reload_in_progress)"
17789   "#"
17790   "&& 1"
17791   [(const_int 0)]
17793   ix86_optimize_mode_switching[I387_CEIL] = 1;
17795   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17796   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17797   if (memory_operand (operands[0], VOIDmode))
17798     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17799                                      operands[2], operands[3]));
17800   else
17801     {
17802       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17803       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17804                                                  operands[2], operands[3],
17805                                                  operands[4]));
17806     }
17807   DONE;
17809   [(set_attr "type" "fistp")
17810    (set_attr "i387_cw" "ceil")
17811    (set_attr "mode" "<MODE>")])
17813 (define_insn "fistdi2_ceil"
17814   [(set (match_operand:DI 0 "memory_operand" "=m")
17815         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17816          UNSPEC_FIST_CEIL))
17817    (use (match_operand:HI 2 "memory_operand" "m"))
17818    (use (match_operand:HI 3 "memory_operand" "m"))
17819    (clobber (match_scratch:XF 4 "=&1f"))]
17820   "TARGET_USE_FANCY_MATH_387
17821    && flag_unsafe_math_optimizations"
17822   "* return output_fix_trunc (insn, operands, 0);"
17823   [(set_attr "type" "fistp")
17824    (set_attr "i387_cw" "ceil")
17825    (set_attr "mode" "DI")])
17827 (define_insn "fistdi2_ceil_with_temp"
17828   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17829         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17830          UNSPEC_FIST_CEIL))
17831    (use (match_operand:HI 2 "memory_operand" "m,m"))
17832    (use (match_operand:HI 3 "memory_operand" "m,m"))
17833    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17834    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17835   "TARGET_USE_FANCY_MATH_387
17836    && flag_unsafe_math_optimizations"
17837   "#"
17838   [(set_attr "type" "fistp")
17839    (set_attr "i387_cw" "ceil")
17840    (set_attr "mode" "DI")])
17842 (define_split
17843   [(set (match_operand:DI 0 "register_operand" "")
17844         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17845          UNSPEC_FIST_CEIL))
17846    (use (match_operand:HI 2 "memory_operand" ""))
17847    (use (match_operand:HI 3 "memory_operand" ""))
17848    (clobber (match_operand:DI 4 "memory_operand" ""))
17849    (clobber (match_scratch 5 ""))]
17850   "reload_completed"
17851   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17852               (use (match_dup 2))
17853               (use (match_dup 3))
17854               (clobber (match_dup 5))])
17855    (set (match_dup 0) (match_dup 4))]
17856   "")
17858 (define_split
17859   [(set (match_operand:DI 0 "memory_operand" "")
17860         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17861          UNSPEC_FIST_CEIL))
17862    (use (match_operand:HI 2 "memory_operand" ""))
17863    (use (match_operand:HI 3 "memory_operand" ""))
17864    (clobber (match_operand:DI 4 "memory_operand" ""))
17865    (clobber (match_scratch 5 ""))]
17866   "reload_completed"
17867   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17868               (use (match_dup 2))
17869               (use (match_dup 3))
17870               (clobber (match_dup 5))])]
17871   "")
17873 (define_insn "fist<mode>2_ceil"
17874   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17875         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17876          UNSPEC_FIST_CEIL))
17877    (use (match_operand:HI 2 "memory_operand" "m"))
17878    (use (match_operand:HI 3 "memory_operand" "m"))]
17879   "TARGET_USE_FANCY_MATH_387
17880    && flag_unsafe_math_optimizations"
17881   "* return output_fix_trunc (insn, operands, 0);"
17882   [(set_attr "type" "fistp")
17883    (set_attr "i387_cw" "ceil")
17884    (set_attr "mode" "<MODE>")])
17886 (define_insn "fist<mode>2_ceil_with_temp"
17887   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17888         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17889          UNSPEC_FIST_CEIL))
17890    (use (match_operand:HI 2 "memory_operand" "m,m"))
17891    (use (match_operand:HI 3 "memory_operand" "m,m"))
17892    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17893   "TARGET_USE_FANCY_MATH_387
17894    && flag_unsafe_math_optimizations"
17895   "#"
17896   [(set_attr "type" "fistp")
17897    (set_attr "i387_cw" "ceil")
17898    (set_attr "mode" "<MODE>")])
17900 (define_split
17901   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17902         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17903          UNSPEC_FIST_CEIL))
17904    (use (match_operand:HI 2 "memory_operand" ""))
17905    (use (match_operand:HI 3 "memory_operand" ""))
17906    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17907   "reload_completed"
17908   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17909                                   UNSPEC_FIST_CEIL))
17910               (use (match_dup 2))
17911               (use (match_dup 3))])
17912    (set (match_dup 0) (match_dup 4))]
17913   "")
17915 (define_split
17916   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17917         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17918          UNSPEC_FIST_CEIL))
17919    (use (match_operand:HI 2 "memory_operand" ""))
17920    (use (match_operand:HI 3 "memory_operand" ""))
17921    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17922   "reload_completed"
17923   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17924                                   UNSPEC_FIST_CEIL))
17925               (use (match_dup 2))
17926               (use (match_dup 3))])]
17927   "")
17929 (define_expand "lceilxf<mode>2"
17930   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17931                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17932                     UNSPEC_FIST_CEIL))
17933               (clobber (reg:CC FLAGS_REG))])]
17934   "TARGET_USE_FANCY_MATH_387
17935    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17936    && flag_unsafe_math_optimizations"
17937   "")
17939 (define_expand "lceil<mode>di2"
17940   [(match_operand:DI 0 "nonimmediate_operand" "")
17941    (match_operand:SSEMODEF 1 "register_operand" "")]
17942   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17943    && !flag_trapping_math"
17945   ix86_expand_lfloorceil (operand0, operand1, false);
17946   DONE;
17949 (define_expand "lceil<mode>si2"
17950   [(match_operand:SI 0 "nonimmediate_operand" "")
17951    (match_operand:SSEMODEF 1 "register_operand" "")]
17952   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17953    && !flag_trapping_math"
17955   ix86_expand_lfloorceil (operand0, operand1, false);
17956   DONE;
17959 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17960 (define_insn_and_split "frndintxf2_trunc"
17961   [(set (match_operand:XF 0 "register_operand" "=f")
17962         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17963          UNSPEC_FRNDINT_TRUNC))
17964    (clobber (reg:CC FLAGS_REG))]
17965   "TARGET_USE_FANCY_MATH_387
17966    && flag_unsafe_math_optimizations
17967    && !(reload_completed || reload_in_progress)"
17968   "#"
17969   "&& 1"
17970   [(const_int 0)]
17972   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17974   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17975   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17977   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17978                                         operands[2], operands[3]));
17979   DONE;
17981   [(set_attr "type" "frndint")
17982    (set_attr "i387_cw" "trunc")
17983    (set_attr "mode" "XF")])
17985 (define_insn "frndintxf2_trunc_i387"
17986   [(set (match_operand:XF 0 "register_operand" "=f")
17987         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17988          UNSPEC_FRNDINT_TRUNC))
17989    (use (match_operand:HI 2 "memory_operand" "m"))
17990    (use (match_operand:HI 3 "memory_operand" "m"))]
17991   "TARGET_USE_FANCY_MATH_387
17992    && flag_unsafe_math_optimizations"
17993   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17994   [(set_attr "type" "frndint")
17995    (set_attr "i387_cw" "trunc")
17996    (set_attr "mode" "XF")])
17998 (define_expand "btruncxf2"
17999   [(use (match_operand:XF 0 "register_operand" ""))
18000    (use (match_operand:XF 1 "register_operand" ""))]
18001   "TARGET_USE_FANCY_MATH_387
18002    && flag_unsafe_math_optimizations && !optimize_size"
18004   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18005   DONE;
18008 (define_expand "btruncdf2"
18009   [(use (match_operand:DF 0 "register_operand" ""))
18010    (use (match_operand:DF 1 "register_operand" ""))]
18011   "((TARGET_USE_FANCY_MATH_387
18012      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18013      && flag_unsafe_math_optimizations)
18014     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18015         && !flag_trapping_math))
18016    && !optimize_size"
18018   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18019       && !flag_trapping_math)
18020     {
18021       if (TARGET_64BIT)
18022         ix86_expand_trunc (operand0, operand1);
18023       else
18024         ix86_expand_truncdf_32 (operand0, operand1);
18025     }
18026   else
18027     {
18028       rtx op0 = gen_reg_rtx (XFmode);
18029       rtx op1 = gen_reg_rtx (XFmode);
18031       emit_insn (gen_extenddfxf2 (op1, operands[1]));
18032       emit_insn (gen_frndintxf2_trunc (op0, op1));
18034       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18035     }
18036   DONE;
18039 (define_expand "btruncsf2"
18040   [(use (match_operand:SF 0 "register_operand" ""))
18041    (use (match_operand:SF 1 "register_operand" ""))]
18042   "((TARGET_USE_FANCY_MATH_387
18043      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18044      && flag_unsafe_math_optimizations)
18045     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18046         && !flag_trapping_math))
18047    && !optimize_size"
18049   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18050       && !flag_trapping_math)
18051     ix86_expand_trunc (operand0, operand1);
18052   else
18053     {
18054       rtx op0 = gen_reg_rtx (XFmode);
18055       rtx op1 = gen_reg_rtx (XFmode);
18057       emit_insn (gen_extendsfxf2 (op1, operands[1]));
18058       emit_insn (gen_frndintxf2_trunc (op0, op1));
18060       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18061     }
18062   DONE;
18065 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18066 (define_insn_and_split "frndintxf2_mask_pm"
18067   [(set (match_operand:XF 0 "register_operand" "=f")
18068         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18069          UNSPEC_FRNDINT_MASK_PM))
18070    (clobber (reg:CC FLAGS_REG))]
18071   "TARGET_USE_FANCY_MATH_387
18072    && flag_unsafe_math_optimizations
18073    && !(reload_completed || reload_in_progress)"
18074   "#"
18075   "&& 1"
18076   [(const_int 0)]
18078   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18080   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18081   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18083   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18084                                           operands[2], operands[3]));
18085   DONE;
18087   [(set_attr "type" "frndint")
18088    (set_attr "i387_cw" "mask_pm")
18089    (set_attr "mode" "XF")])
18091 (define_insn "frndintxf2_mask_pm_i387"
18092   [(set (match_operand:XF 0 "register_operand" "=f")
18093         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18094          UNSPEC_FRNDINT_MASK_PM))
18095    (use (match_operand:HI 2 "memory_operand" "m"))
18096    (use (match_operand:HI 3 "memory_operand" "m"))]
18097   "TARGET_USE_FANCY_MATH_387
18098    && flag_unsafe_math_optimizations"
18099   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18100   [(set_attr "type" "frndint")
18101    (set_attr "i387_cw" "mask_pm")
18102    (set_attr "mode" "XF")])
18104 (define_expand "nearbyintxf2"
18105   [(use (match_operand:XF 0 "register_operand" ""))
18106    (use (match_operand:XF 1 "register_operand" ""))]
18107   "TARGET_USE_FANCY_MATH_387
18108    && flag_unsafe_math_optimizations"
18110   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18112   DONE;
18115 (define_expand "nearbyintdf2"
18116   [(use (match_operand:DF 0 "register_operand" ""))
18117    (use (match_operand:DF 1 "register_operand" ""))]
18118   "TARGET_USE_FANCY_MATH_387
18119    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18120    && flag_unsafe_math_optimizations"
18122   rtx op0 = gen_reg_rtx (XFmode);
18123   rtx op1 = gen_reg_rtx (XFmode);
18125   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18126   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18128   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18129   DONE;
18132 (define_expand "nearbyintsf2"
18133   [(use (match_operand:SF 0 "register_operand" ""))
18134    (use (match_operand:SF 1 "register_operand" ""))]
18135   "TARGET_USE_FANCY_MATH_387
18136    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18137    && flag_unsafe_math_optimizations"
18139   rtx op0 = gen_reg_rtx (XFmode);
18140   rtx op1 = gen_reg_rtx (XFmode);
18142   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18143   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18145   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18146   DONE;
18150 ;; Block operation instructions
18152 (define_insn "cld"
18153  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18154  ""
18155  "cld"
18156   [(set_attr "type" "cld")])
18158 (define_expand "movmemsi"
18159   [(use (match_operand:BLK 0 "memory_operand" ""))
18160    (use (match_operand:BLK 1 "memory_operand" ""))
18161    (use (match_operand:SI 2 "nonmemory_operand" ""))
18162    (use (match_operand:SI 3 "const_int_operand" ""))]
18163   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18165  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18166    DONE;
18167  else
18168    FAIL;
18171 (define_expand "movmemdi"
18172   [(use (match_operand:BLK 0 "memory_operand" ""))
18173    (use (match_operand:BLK 1 "memory_operand" ""))
18174    (use (match_operand:DI 2 "nonmemory_operand" ""))
18175    (use (match_operand:DI 3 "const_int_operand" ""))]
18176   "TARGET_64BIT"
18178  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18179    DONE;
18180  else
18181    FAIL;
18184 ;; Most CPUs don't like single string operations
18185 ;; Handle this case here to simplify previous expander.
18187 (define_expand "strmov"
18188   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18189    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18190    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18191               (clobber (reg:CC FLAGS_REG))])
18192    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18193               (clobber (reg:CC FLAGS_REG))])]
18194   ""
18196   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18198   /* If .md ever supports :P for Pmode, these can be directly
18199      in the pattern above.  */
18200   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18201   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18203   if (TARGET_SINGLE_STRINGOP || optimize_size)
18204     {
18205       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18206                                       operands[2], operands[3],
18207                                       operands[5], operands[6]));
18208       DONE;
18209     }
18211   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18214 (define_expand "strmov_singleop"
18215   [(parallel [(set (match_operand 1 "memory_operand" "")
18216                    (match_operand 3 "memory_operand" ""))
18217               (set (match_operand 0 "register_operand" "")
18218                    (match_operand 4 "" ""))
18219               (set (match_operand 2 "register_operand" "")
18220                    (match_operand 5 "" ""))
18221               (use (reg:SI DIRFLAG_REG))])]
18222   "TARGET_SINGLE_STRINGOP || optimize_size"
18223   "")
18225 (define_insn "*strmovdi_rex_1"
18226   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18227         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18228    (set (match_operand:DI 0 "register_operand" "=D")
18229         (plus:DI (match_dup 2)
18230                  (const_int 8)))
18231    (set (match_operand:DI 1 "register_operand" "=S")
18232         (plus:DI (match_dup 3)
18233                  (const_int 8)))
18234    (use (reg:SI DIRFLAG_REG))]
18235   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18236   "movsq"
18237   [(set_attr "type" "str")
18238    (set_attr "mode" "DI")
18239    (set_attr "memory" "both")])
18241 (define_insn "*strmovsi_1"
18242   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18243         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18244    (set (match_operand:SI 0 "register_operand" "=D")
18245         (plus:SI (match_dup 2)
18246                  (const_int 4)))
18247    (set (match_operand:SI 1 "register_operand" "=S")
18248         (plus:SI (match_dup 3)
18249                  (const_int 4)))
18250    (use (reg:SI DIRFLAG_REG))]
18251   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18252   "{movsl|movsd}"
18253   [(set_attr "type" "str")
18254    (set_attr "mode" "SI")
18255    (set_attr "memory" "both")])
18257 (define_insn "*strmovsi_rex_1"
18258   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18259         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18260    (set (match_operand:DI 0 "register_operand" "=D")
18261         (plus:DI (match_dup 2)
18262                  (const_int 4)))
18263    (set (match_operand:DI 1 "register_operand" "=S")
18264         (plus:DI (match_dup 3)
18265                  (const_int 4)))
18266    (use (reg:SI DIRFLAG_REG))]
18267   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18268   "{movsl|movsd}"
18269   [(set_attr "type" "str")
18270    (set_attr "mode" "SI")
18271    (set_attr "memory" "both")])
18273 (define_insn "*strmovhi_1"
18274   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18275         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18276    (set (match_operand:SI 0 "register_operand" "=D")
18277         (plus:SI (match_dup 2)
18278                  (const_int 2)))
18279    (set (match_operand:SI 1 "register_operand" "=S")
18280         (plus:SI (match_dup 3)
18281                  (const_int 2)))
18282    (use (reg:SI DIRFLAG_REG))]
18283   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18284   "movsw"
18285   [(set_attr "type" "str")
18286    (set_attr "memory" "both")
18287    (set_attr "mode" "HI")])
18289 (define_insn "*strmovhi_rex_1"
18290   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18291         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18292    (set (match_operand:DI 0 "register_operand" "=D")
18293         (plus:DI (match_dup 2)
18294                  (const_int 2)))
18295    (set (match_operand:DI 1 "register_operand" "=S")
18296         (plus:DI (match_dup 3)
18297                  (const_int 2)))
18298    (use (reg:SI DIRFLAG_REG))]
18299   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18300   "movsw"
18301   [(set_attr "type" "str")
18302    (set_attr "memory" "both")
18303    (set_attr "mode" "HI")])
18305 (define_insn "*strmovqi_1"
18306   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18307         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18308    (set (match_operand:SI 0 "register_operand" "=D")
18309         (plus:SI (match_dup 2)
18310                  (const_int 1)))
18311    (set (match_operand:SI 1 "register_operand" "=S")
18312         (plus:SI (match_dup 3)
18313                  (const_int 1)))
18314    (use (reg:SI DIRFLAG_REG))]
18315   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18316   "movsb"
18317   [(set_attr "type" "str")
18318    (set_attr "memory" "both")
18319    (set_attr "mode" "QI")])
18321 (define_insn "*strmovqi_rex_1"
18322   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18323         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18324    (set (match_operand:DI 0 "register_operand" "=D")
18325         (plus:DI (match_dup 2)
18326                  (const_int 1)))
18327    (set (match_operand:DI 1 "register_operand" "=S")
18328         (plus:DI (match_dup 3)
18329                  (const_int 1)))
18330    (use (reg:SI DIRFLAG_REG))]
18331   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18332   "movsb"
18333   [(set_attr "type" "str")
18334    (set_attr "memory" "both")
18335    (set_attr "mode" "QI")])
18337 (define_expand "rep_mov"
18338   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18339               (set (match_operand 0 "register_operand" "")
18340                    (match_operand 5 "" ""))
18341               (set (match_operand 2 "register_operand" "")
18342                    (match_operand 6 "" ""))
18343               (set (match_operand 1 "memory_operand" "")
18344                    (match_operand 3 "memory_operand" ""))
18345               (use (match_dup 4))
18346               (use (reg:SI DIRFLAG_REG))])]
18347   ""
18348   "")
18350 (define_insn "*rep_movdi_rex64"
18351   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18352    (set (match_operand:DI 0 "register_operand" "=D")
18353         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18354                             (const_int 3))
18355                  (match_operand:DI 3 "register_operand" "0")))
18356    (set (match_operand:DI 1 "register_operand" "=S")
18357         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18358                  (match_operand:DI 4 "register_operand" "1")))
18359    (set (mem:BLK (match_dup 3))
18360         (mem:BLK (match_dup 4)))
18361    (use (match_dup 5))
18362    (use (reg:SI DIRFLAG_REG))]
18363   "TARGET_64BIT"
18364   "{rep\;movsq|rep movsq}"
18365   [(set_attr "type" "str")
18366    (set_attr "prefix_rep" "1")
18367    (set_attr "memory" "both")
18368    (set_attr "mode" "DI")])
18370 (define_insn "*rep_movsi"
18371   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18372    (set (match_operand:SI 0 "register_operand" "=D")
18373         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18374                             (const_int 2))
18375                  (match_operand:SI 3 "register_operand" "0")))
18376    (set (match_operand:SI 1 "register_operand" "=S")
18377         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18378                  (match_operand:SI 4 "register_operand" "1")))
18379    (set (mem:BLK (match_dup 3))
18380         (mem:BLK (match_dup 4)))
18381    (use (match_dup 5))
18382    (use (reg:SI DIRFLAG_REG))]
18383   "!TARGET_64BIT"
18384   "{rep\;movsl|rep movsd}"
18385   [(set_attr "type" "str")
18386    (set_attr "prefix_rep" "1")
18387    (set_attr "memory" "both")
18388    (set_attr "mode" "SI")])
18390 (define_insn "*rep_movsi_rex64"
18391   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18392    (set (match_operand:DI 0 "register_operand" "=D")
18393         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18394                             (const_int 2))
18395                  (match_operand:DI 3 "register_operand" "0")))
18396    (set (match_operand:DI 1 "register_operand" "=S")
18397         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18398                  (match_operand:DI 4 "register_operand" "1")))
18399    (set (mem:BLK (match_dup 3))
18400         (mem:BLK (match_dup 4)))
18401    (use (match_dup 5))
18402    (use (reg:SI DIRFLAG_REG))]
18403   "TARGET_64BIT"
18404   "{rep\;movsl|rep movsd}"
18405   [(set_attr "type" "str")
18406    (set_attr "prefix_rep" "1")
18407    (set_attr "memory" "both")
18408    (set_attr "mode" "SI")])
18410 (define_insn "*rep_movqi"
18411   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18412    (set (match_operand:SI 0 "register_operand" "=D")
18413         (plus:SI (match_operand:SI 3 "register_operand" "0")
18414                  (match_operand:SI 5 "register_operand" "2")))
18415    (set (match_operand:SI 1 "register_operand" "=S")
18416         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18417    (set (mem:BLK (match_dup 3))
18418         (mem:BLK (match_dup 4)))
18419    (use (match_dup 5))
18420    (use (reg:SI DIRFLAG_REG))]
18421   "!TARGET_64BIT"
18422   "{rep\;movsb|rep movsb}"
18423   [(set_attr "type" "str")
18424    (set_attr "prefix_rep" "1")
18425    (set_attr "memory" "both")
18426    (set_attr "mode" "SI")])
18428 (define_insn "*rep_movqi_rex64"
18429   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18430    (set (match_operand:DI 0 "register_operand" "=D")
18431         (plus:DI (match_operand:DI 3 "register_operand" "0")
18432                  (match_operand:DI 5 "register_operand" "2")))
18433    (set (match_operand:DI 1 "register_operand" "=S")
18434         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18435    (set (mem:BLK (match_dup 3))
18436         (mem:BLK (match_dup 4)))
18437    (use (match_dup 5))
18438    (use (reg:SI DIRFLAG_REG))]
18439   "TARGET_64BIT"
18440   "{rep\;movsb|rep movsb}"
18441   [(set_attr "type" "str")
18442    (set_attr "prefix_rep" "1")
18443    (set_attr "memory" "both")
18444    (set_attr "mode" "SI")])
18446 (define_expand "setmemsi"
18447    [(use (match_operand:BLK 0 "memory_operand" ""))
18448     (use (match_operand:SI 1 "nonmemory_operand" ""))
18449     (use (match_operand 2 "const_int_operand" ""))
18450     (use (match_operand 3 "const_int_operand" ""))]
18451   ""
18453  /* If value to set is not zero, use the library routine.  */
18454  if (operands[2] != const0_rtx)
18455    FAIL;
18457  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18458    DONE;
18459  else
18460    FAIL;
18463 (define_expand "setmemdi"
18464    [(use (match_operand:BLK 0 "memory_operand" ""))
18465     (use (match_operand:DI 1 "nonmemory_operand" ""))
18466     (use (match_operand 2 "const_int_operand" ""))
18467     (use (match_operand 3 "const_int_operand" ""))]
18468   "TARGET_64BIT"
18470  /* If value to set is not zero, use the library routine.  */
18471  if (operands[2] != const0_rtx)
18472    FAIL;
18474  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18475    DONE;
18476  else
18477    FAIL;
18480 ;; Most CPUs don't like single string operations
18481 ;; Handle this case here to simplify previous expander.
18483 (define_expand "strset"
18484   [(set (match_operand 1 "memory_operand" "")
18485         (match_operand 2 "register_operand" ""))
18486    (parallel [(set (match_operand 0 "register_operand" "")
18487                    (match_dup 3))
18488               (clobber (reg:CC FLAGS_REG))])]
18489   ""
18491   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18492     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18494   /* If .md ever supports :P for Pmode, this can be directly
18495      in the pattern above.  */
18496   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18497                               GEN_INT (GET_MODE_SIZE (GET_MODE
18498                                                       (operands[2]))));
18499   if (TARGET_SINGLE_STRINGOP || optimize_size)
18500     {
18501       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18502                                       operands[3]));
18503       DONE;
18504     }
18507 (define_expand "strset_singleop"
18508   [(parallel [(set (match_operand 1 "memory_operand" "")
18509                    (match_operand 2 "register_operand" ""))
18510               (set (match_operand 0 "register_operand" "")
18511                    (match_operand 3 "" ""))
18512               (use (reg:SI DIRFLAG_REG))])]
18513   "TARGET_SINGLE_STRINGOP || optimize_size"
18514   "")
18516 (define_insn "*strsetdi_rex_1"
18517   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18518         (match_operand:DI 2 "register_operand" "a"))
18519    (set (match_operand:DI 0 "register_operand" "=D")
18520         (plus:DI (match_dup 1)
18521                  (const_int 8)))
18522    (use (reg:SI DIRFLAG_REG))]
18523   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18524   "stosq"
18525   [(set_attr "type" "str")
18526    (set_attr "memory" "store")
18527    (set_attr "mode" "DI")])
18529 (define_insn "*strsetsi_1"
18530   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18531         (match_operand:SI 2 "register_operand" "a"))
18532    (set (match_operand:SI 0 "register_operand" "=D")
18533         (plus:SI (match_dup 1)
18534                  (const_int 4)))
18535    (use (reg:SI DIRFLAG_REG))]
18536   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18537   "{stosl|stosd}"
18538   [(set_attr "type" "str")
18539    (set_attr "memory" "store")
18540    (set_attr "mode" "SI")])
18542 (define_insn "*strsetsi_rex_1"
18543   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18544         (match_operand:SI 2 "register_operand" "a"))
18545    (set (match_operand:DI 0 "register_operand" "=D")
18546         (plus:DI (match_dup 1)
18547                  (const_int 4)))
18548    (use (reg:SI DIRFLAG_REG))]
18549   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18550   "{stosl|stosd}"
18551   [(set_attr "type" "str")
18552    (set_attr "memory" "store")
18553    (set_attr "mode" "SI")])
18555 (define_insn "*strsethi_1"
18556   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18557         (match_operand:HI 2 "register_operand" "a"))
18558    (set (match_operand:SI 0 "register_operand" "=D")
18559         (plus:SI (match_dup 1)
18560                  (const_int 2)))
18561    (use (reg:SI DIRFLAG_REG))]
18562   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18563   "stosw"
18564   [(set_attr "type" "str")
18565    (set_attr "memory" "store")
18566    (set_attr "mode" "HI")])
18568 (define_insn "*strsethi_rex_1"
18569   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18570         (match_operand:HI 2 "register_operand" "a"))
18571    (set (match_operand:DI 0 "register_operand" "=D")
18572         (plus:DI (match_dup 1)
18573                  (const_int 2)))
18574    (use (reg:SI DIRFLAG_REG))]
18575   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18576   "stosw"
18577   [(set_attr "type" "str")
18578    (set_attr "memory" "store")
18579    (set_attr "mode" "HI")])
18581 (define_insn "*strsetqi_1"
18582   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18583         (match_operand:QI 2 "register_operand" "a"))
18584    (set (match_operand:SI 0 "register_operand" "=D")
18585         (plus:SI (match_dup 1)
18586                  (const_int 1)))
18587    (use (reg:SI DIRFLAG_REG))]
18588   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18589   "stosb"
18590   [(set_attr "type" "str")
18591    (set_attr "memory" "store")
18592    (set_attr "mode" "QI")])
18594 (define_insn "*strsetqi_rex_1"
18595   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18596         (match_operand:QI 2 "register_operand" "a"))
18597    (set (match_operand:DI 0 "register_operand" "=D")
18598         (plus:DI (match_dup 1)
18599                  (const_int 1)))
18600    (use (reg:SI DIRFLAG_REG))]
18601   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18602   "stosb"
18603   [(set_attr "type" "str")
18604    (set_attr "memory" "store")
18605    (set_attr "mode" "QI")])
18607 (define_expand "rep_stos"
18608   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18609               (set (match_operand 0 "register_operand" "")
18610                    (match_operand 4 "" ""))
18611               (set (match_operand 2 "memory_operand" "") (const_int 0))
18612               (use (match_operand 3 "register_operand" ""))
18613               (use (match_dup 1))
18614               (use (reg:SI DIRFLAG_REG))])]
18615   ""
18616   "")
18618 (define_insn "*rep_stosdi_rex64"
18619   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18620    (set (match_operand:DI 0 "register_operand" "=D")
18621         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18622                             (const_int 3))
18623                  (match_operand:DI 3 "register_operand" "0")))
18624    (set (mem:BLK (match_dup 3))
18625         (const_int 0))
18626    (use (match_operand:DI 2 "register_operand" "a"))
18627    (use (match_dup 4))
18628    (use (reg:SI DIRFLAG_REG))]
18629   "TARGET_64BIT"
18630   "{rep\;stosq|rep stosq}"
18631   [(set_attr "type" "str")
18632    (set_attr "prefix_rep" "1")
18633    (set_attr "memory" "store")
18634    (set_attr "mode" "DI")])
18636 (define_insn "*rep_stossi"
18637   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18638    (set (match_operand:SI 0 "register_operand" "=D")
18639         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18640                             (const_int 2))
18641                  (match_operand:SI 3 "register_operand" "0")))
18642    (set (mem:BLK (match_dup 3))
18643         (const_int 0))
18644    (use (match_operand:SI 2 "register_operand" "a"))
18645    (use (match_dup 4))
18646    (use (reg:SI DIRFLAG_REG))]
18647   "!TARGET_64BIT"
18648   "{rep\;stosl|rep stosd}"
18649   [(set_attr "type" "str")
18650    (set_attr "prefix_rep" "1")
18651    (set_attr "memory" "store")
18652    (set_attr "mode" "SI")])
18654 (define_insn "*rep_stossi_rex64"
18655   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18656    (set (match_operand:DI 0 "register_operand" "=D")
18657         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18658                             (const_int 2))
18659                  (match_operand:DI 3 "register_operand" "0")))
18660    (set (mem:BLK (match_dup 3))
18661         (const_int 0))
18662    (use (match_operand:SI 2 "register_operand" "a"))
18663    (use (match_dup 4))
18664    (use (reg:SI DIRFLAG_REG))]
18665   "TARGET_64BIT"
18666   "{rep\;stosl|rep stosd}"
18667   [(set_attr "type" "str")
18668    (set_attr "prefix_rep" "1")
18669    (set_attr "memory" "store")
18670    (set_attr "mode" "SI")])
18672 (define_insn "*rep_stosqi"
18673   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18674    (set (match_operand:SI 0 "register_operand" "=D")
18675         (plus:SI (match_operand:SI 3 "register_operand" "0")
18676                  (match_operand:SI 4 "register_operand" "1")))
18677    (set (mem:BLK (match_dup 3))
18678         (const_int 0))
18679    (use (match_operand:QI 2 "register_operand" "a"))
18680    (use (match_dup 4))
18681    (use (reg:SI DIRFLAG_REG))]
18682   "!TARGET_64BIT"
18683   "{rep\;stosb|rep stosb}"
18684   [(set_attr "type" "str")
18685    (set_attr "prefix_rep" "1")
18686    (set_attr "memory" "store")
18687    (set_attr "mode" "QI")])
18689 (define_insn "*rep_stosqi_rex64"
18690   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18691    (set (match_operand:DI 0 "register_operand" "=D")
18692         (plus:DI (match_operand:DI 3 "register_operand" "0")
18693                  (match_operand:DI 4 "register_operand" "1")))
18694    (set (mem:BLK (match_dup 3))
18695         (const_int 0))
18696    (use (match_operand:QI 2 "register_operand" "a"))
18697    (use (match_dup 4))
18698    (use (reg:SI DIRFLAG_REG))]
18699   "TARGET_64BIT"
18700   "{rep\;stosb|rep stosb}"
18701   [(set_attr "type" "str")
18702    (set_attr "prefix_rep" "1")
18703    (set_attr "memory" "store")
18704    (set_attr "mode" "QI")])
18706 (define_expand "cmpstrnsi"
18707   [(set (match_operand:SI 0 "register_operand" "")
18708         (compare:SI (match_operand:BLK 1 "general_operand" "")
18709                     (match_operand:BLK 2 "general_operand" "")))
18710    (use (match_operand 3 "general_operand" ""))
18711    (use (match_operand 4 "immediate_operand" ""))]
18712   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18714   rtx addr1, addr2, out, outlow, count, countreg, align;
18716   /* Can't use this if the user has appropriated esi or edi.  */
18717   if (global_regs[4] || global_regs[5])
18718     FAIL;
18720   out = operands[0];
18721   if (GET_CODE (out) != REG)
18722     out = gen_reg_rtx (SImode);
18724   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18725   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18726   if (addr1 != XEXP (operands[1], 0))
18727     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18728   if (addr2 != XEXP (operands[2], 0))
18729     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18731   count = operands[3];
18732   countreg = ix86_zero_extend_to_Pmode (count);
18734   /* %%% Iff we are testing strict equality, we can use known alignment
18735      to good advantage.  This may be possible with combine, particularly
18736      once cc0 is dead.  */
18737   align = operands[4];
18739   emit_insn (gen_cld ());
18740   if (GET_CODE (count) == CONST_INT)
18741     {
18742       if (INTVAL (count) == 0)
18743         {
18744           emit_move_insn (operands[0], const0_rtx);
18745           DONE;
18746         }
18747       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18748                                      operands[1], operands[2]));
18749     }
18750   else
18751     {
18752       if (TARGET_64BIT)
18753         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18754       else
18755         emit_insn (gen_cmpsi_1 (countreg, countreg));
18756       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18757                                   operands[1], operands[2]));
18758     }
18760   outlow = gen_lowpart (QImode, out);
18761   emit_insn (gen_cmpintqi (outlow));
18762   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18764   if (operands[0] != out)
18765     emit_move_insn (operands[0], out);
18767   DONE;
18770 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18772 (define_expand "cmpintqi"
18773   [(set (match_dup 1)
18774         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18775    (set (match_dup 2)
18776         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18777    (parallel [(set (match_operand:QI 0 "register_operand" "")
18778                    (minus:QI (match_dup 1)
18779                              (match_dup 2)))
18780               (clobber (reg:CC FLAGS_REG))])]
18781   ""
18782   "operands[1] = gen_reg_rtx (QImode);
18783    operands[2] = gen_reg_rtx (QImode);")
18785 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18786 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18788 (define_expand "cmpstrnqi_nz_1"
18789   [(parallel [(set (reg:CC FLAGS_REG)
18790                    (compare:CC (match_operand 4 "memory_operand" "")
18791                                (match_operand 5 "memory_operand" "")))
18792               (use (match_operand 2 "register_operand" ""))
18793               (use (match_operand:SI 3 "immediate_operand" ""))
18794               (use (reg:SI DIRFLAG_REG))
18795               (clobber (match_operand 0 "register_operand" ""))
18796               (clobber (match_operand 1 "register_operand" ""))
18797               (clobber (match_dup 2))])]
18798   ""
18799   "")
18801 (define_insn "*cmpstrnqi_nz_1"
18802   [(set (reg:CC FLAGS_REG)
18803         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18804                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18805    (use (match_operand:SI 6 "register_operand" "2"))
18806    (use (match_operand:SI 3 "immediate_operand" "i"))
18807    (use (reg:SI DIRFLAG_REG))
18808    (clobber (match_operand:SI 0 "register_operand" "=S"))
18809    (clobber (match_operand:SI 1 "register_operand" "=D"))
18810    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18811   "!TARGET_64BIT"
18812   "repz{\;| }cmpsb"
18813   [(set_attr "type" "str")
18814    (set_attr "mode" "QI")
18815    (set_attr "prefix_rep" "1")])
18817 (define_insn "*cmpstrnqi_nz_rex_1"
18818   [(set (reg:CC FLAGS_REG)
18819         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18820                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18821    (use (match_operand:DI 6 "register_operand" "2"))
18822    (use (match_operand:SI 3 "immediate_operand" "i"))
18823    (use (reg:SI DIRFLAG_REG))
18824    (clobber (match_operand:DI 0 "register_operand" "=S"))
18825    (clobber (match_operand:DI 1 "register_operand" "=D"))
18826    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18827   "TARGET_64BIT"
18828   "repz{\;| }cmpsb"
18829   [(set_attr "type" "str")
18830    (set_attr "mode" "QI")
18831    (set_attr "prefix_rep" "1")])
18833 ;; The same, but the count is not known to not be zero.
18835 (define_expand "cmpstrnqi_1"
18836   [(parallel [(set (reg:CC FLAGS_REG)
18837                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18838                                      (const_int 0))
18839                   (compare:CC (match_operand 4 "memory_operand" "")
18840                               (match_operand 5 "memory_operand" ""))
18841                   (const_int 0)))
18842               (use (match_operand:SI 3 "immediate_operand" ""))
18843               (use (reg:CC FLAGS_REG))
18844               (use (reg:SI DIRFLAG_REG))
18845               (clobber (match_operand 0 "register_operand" ""))
18846               (clobber (match_operand 1 "register_operand" ""))
18847               (clobber (match_dup 2))])]
18848   ""
18849   "")
18851 (define_insn "*cmpstrnqi_1"
18852   [(set (reg:CC FLAGS_REG)
18853         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18854                              (const_int 0))
18855           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18856                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18857           (const_int 0)))
18858    (use (match_operand:SI 3 "immediate_operand" "i"))
18859    (use (reg:CC FLAGS_REG))
18860    (use (reg:SI DIRFLAG_REG))
18861    (clobber (match_operand:SI 0 "register_operand" "=S"))
18862    (clobber (match_operand:SI 1 "register_operand" "=D"))
18863    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18864   "!TARGET_64BIT"
18865   "repz{\;| }cmpsb"
18866   [(set_attr "type" "str")
18867    (set_attr "mode" "QI")
18868    (set_attr "prefix_rep" "1")])
18870 (define_insn "*cmpstrnqi_rex_1"
18871   [(set (reg:CC FLAGS_REG)
18872         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18873                              (const_int 0))
18874           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18875                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18876           (const_int 0)))
18877    (use (match_operand:SI 3 "immediate_operand" "i"))
18878    (use (reg:CC FLAGS_REG))
18879    (use (reg:SI DIRFLAG_REG))
18880    (clobber (match_operand:DI 0 "register_operand" "=S"))
18881    (clobber (match_operand:DI 1 "register_operand" "=D"))
18882    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18883   "TARGET_64BIT"
18884   "repz{\;| }cmpsb"
18885   [(set_attr "type" "str")
18886    (set_attr "mode" "QI")
18887    (set_attr "prefix_rep" "1")])
18889 (define_expand "strlensi"
18890   [(set (match_operand:SI 0 "register_operand" "")
18891         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18892                     (match_operand:QI 2 "immediate_operand" "")
18893                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18894   ""
18896  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18897    DONE;
18898  else
18899    FAIL;
18902 (define_expand "strlendi"
18903   [(set (match_operand:DI 0 "register_operand" "")
18904         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18905                     (match_operand:QI 2 "immediate_operand" "")
18906                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18907   ""
18909  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18910    DONE;
18911  else
18912    FAIL;
18915 (define_expand "strlenqi_1"
18916   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18917               (use (reg:SI DIRFLAG_REG))
18918               (clobber (match_operand 1 "register_operand" ""))
18919               (clobber (reg:CC FLAGS_REG))])]
18920   ""
18921   "")
18923 (define_insn "*strlenqi_1"
18924   [(set (match_operand:SI 0 "register_operand" "=&c")
18925         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18926                     (match_operand:QI 2 "register_operand" "a")
18927                     (match_operand:SI 3 "immediate_operand" "i")
18928                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18929    (use (reg:SI DIRFLAG_REG))
18930    (clobber (match_operand:SI 1 "register_operand" "=D"))
18931    (clobber (reg:CC FLAGS_REG))]
18932   "!TARGET_64BIT"
18933   "repnz{\;| }scasb"
18934   [(set_attr "type" "str")
18935    (set_attr "mode" "QI")
18936    (set_attr "prefix_rep" "1")])
18938 (define_insn "*strlenqi_rex_1"
18939   [(set (match_operand:DI 0 "register_operand" "=&c")
18940         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18941                     (match_operand:QI 2 "register_operand" "a")
18942                     (match_operand:DI 3 "immediate_operand" "i")
18943                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18944    (use (reg:SI DIRFLAG_REG))
18945    (clobber (match_operand:DI 1 "register_operand" "=D"))
18946    (clobber (reg:CC FLAGS_REG))]
18947   "TARGET_64BIT"
18948   "repnz{\;| }scasb"
18949   [(set_attr "type" "str")
18950    (set_attr "mode" "QI")
18951    (set_attr "prefix_rep" "1")])
18953 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18954 ;; handled in combine, but it is not currently up to the task.
18955 ;; When used for their truth value, the cmpstrn* expanders generate
18956 ;; code like this:
18958 ;;   repz cmpsb
18959 ;;   seta       %al
18960 ;;   setb       %dl
18961 ;;   cmpb       %al, %dl
18962 ;;   jcc        label
18964 ;; The intermediate three instructions are unnecessary.
18966 ;; This one handles cmpstrn*_nz_1...
18967 (define_peephole2
18968   [(parallel[
18969      (set (reg:CC FLAGS_REG)
18970           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18971                       (mem:BLK (match_operand 5 "register_operand" ""))))
18972      (use (match_operand 6 "register_operand" ""))
18973      (use (match_operand:SI 3 "immediate_operand" ""))
18974      (use (reg:SI DIRFLAG_REG))
18975      (clobber (match_operand 0 "register_operand" ""))
18976      (clobber (match_operand 1 "register_operand" ""))
18977      (clobber (match_operand 2 "register_operand" ""))])
18978    (set (match_operand:QI 7 "register_operand" "")
18979         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18980    (set (match_operand:QI 8 "register_operand" "")
18981         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18982    (set (reg FLAGS_REG)
18983         (compare (match_dup 7) (match_dup 8)))
18984   ]
18985   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18986   [(parallel[
18987      (set (reg:CC FLAGS_REG)
18988           (compare:CC (mem:BLK (match_dup 4))
18989                       (mem:BLK (match_dup 5))))
18990      (use (match_dup 6))
18991      (use (match_dup 3))
18992      (use (reg:SI DIRFLAG_REG))
18993      (clobber (match_dup 0))
18994      (clobber (match_dup 1))
18995      (clobber (match_dup 2))])]
18996   "")
18998 ;; ...and this one handles cmpstrn*_1.
18999 (define_peephole2
19000   [(parallel[
19001      (set (reg:CC FLAGS_REG)
19002           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19003                                (const_int 0))
19004             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19005                         (mem:BLK (match_operand 5 "register_operand" "")))
19006             (const_int 0)))
19007      (use (match_operand:SI 3 "immediate_operand" ""))
19008      (use (reg:CC FLAGS_REG))
19009      (use (reg:SI DIRFLAG_REG))
19010      (clobber (match_operand 0 "register_operand" ""))
19011      (clobber (match_operand 1 "register_operand" ""))
19012      (clobber (match_operand 2 "register_operand" ""))])
19013    (set (match_operand:QI 7 "register_operand" "")
19014         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19015    (set (match_operand:QI 8 "register_operand" "")
19016         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19017    (set (reg FLAGS_REG)
19018         (compare (match_dup 7) (match_dup 8)))
19019   ]
19020   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19021   [(parallel[
19022      (set (reg:CC FLAGS_REG)
19023           (if_then_else:CC (ne (match_dup 6)
19024                                (const_int 0))
19025             (compare:CC (mem:BLK (match_dup 4))
19026                         (mem:BLK (match_dup 5)))
19027             (const_int 0)))
19028      (use (match_dup 3))
19029      (use (reg:CC FLAGS_REG))
19030      (use (reg:SI DIRFLAG_REG))
19031      (clobber (match_dup 0))
19032      (clobber (match_dup 1))
19033      (clobber (match_dup 2))])]
19034   "")
19038 ;; Conditional move instructions.
19040 (define_expand "movdicc"
19041   [(set (match_operand:DI 0 "register_operand" "")
19042         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19043                          (match_operand:DI 2 "general_operand" "")
19044                          (match_operand:DI 3 "general_operand" "")))]
19045   "TARGET_64BIT"
19046   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19048 (define_insn "x86_movdicc_0_m1_rex64"
19049   [(set (match_operand:DI 0 "register_operand" "=r")
19050         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19051           (const_int -1)
19052           (const_int 0)))
19053    (clobber (reg:CC FLAGS_REG))]
19054   "TARGET_64BIT"
19055   "sbb{q}\t%0, %0"
19056   ; Since we don't have the proper number of operands for an alu insn,
19057   ; fill in all the blanks.
19058   [(set_attr "type" "alu")
19059    (set_attr "pent_pair" "pu")
19060    (set_attr "memory" "none")
19061    (set_attr "imm_disp" "false")
19062    (set_attr "mode" "DI")
19063    (set_attr "length_immediate" "0")])
19065 (define_insn "*movdicc_c_rex64"
19066   [(set (match_operand:DI 0 "register_operand" "=r,r")
19067         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19068                                 [(reg FLAGS_REG) (const_int 0)])
19069                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19070                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19071   "TARGET_64BIT && TARGET_CMOVE
19072    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19073   "@
19074    cmov%O2%C1\t{%2, %0|%0, %2}
19075    cmov%O2%c1\t{%3, %0|%0, %3}"
19076   [(set_attr "type" "icmov")
19077    (set_attr "mode" "DI")])
19079 (define_expand "movsicc"
19080   [(set (match_operand:SI 0 "register_operand" "")
19081         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19082                          (match_operand:SI 2 "general_operand" "")
19083                          (match_operand:SI 3 "general_operand" "")))]
19084   ""
19085   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19087 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19088 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19089 ;; So just document what we're doing explicitly.
19091 (define_insn "x86_movsicc_0_m1"
19092   [(set (match_operand:SI 0 "register_operand" "=r")
19093         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19094           (const_int -1)
19095           (const_int 0)))
19096    (clobber (reg:CC FLAGS_REG))]
19097   ""
19098   "sbb{l}\t%0, %0"
19099   ; Since we don't have the proper number of operands for an alu insn,
19100   ; fill in all the blanks.
19101   [(set_attr "type" "alu")
19102    (set_attr "pent_pair" "pu")
19103    (set_attr "memory" "none")
19104    (set_attr "imm_disp" "false")
19105    (set_attr "mode" "SI")
19106    (set_attr "length_immediate" "0")])
19108 (define_insn "*movsicc_noc"
19109   [(set (match_operand:SI 0 "register_operand" "=r,r")
19110         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19111                                 [(reg FLAGS_REG) (const_int 0)])
19112                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19113                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19114   "TARGET_CMOVE
19115    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19116   "@
19117    cmov%O2%C1\t{%2, %0|%0, %2}
19118    cmov%O2%c1\t{%3, %0|%0, %3}"
19119   [(set_attr "type" "icmov")
19120    (set_attr "mode" "SI")])
19122 (define_expand "movhicc"
19123   [(set (match_operand:HI 0 "register_operand" "")
19124         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19125                          (match_operand:HI 2 "general_operand" "")
19126                          (match_operand:HI 3 "general_operand" "")))]
19127   "TARGET_HIMODE_MATH"
19128   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19130 (define_insn "*movhicc_noc"
19131   [(set (match_operand:HI 0 "register_operand" "=r,r")
19132         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19133                                 [(reg FLAGS_REG) (const_int 0)])
19134                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19135                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19136   "TARGET_CMOVE
19137    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19138   "@
19139    cmov%O2%C1\t{%2, %0|%0, %2}
19140    cmov%O2%c1\t{%3, %0|%0, %3}"
19141   [(set_attr "type" "icmov")
19142    (set_attr "mode" "HI")])
19144 (define_expand "movqicc"
19145   [(set (match_operand:QI 0 "register_operand" "")
19146         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19147                          (match_operand:QI 2 "general_operand" "")
19148                          (match_operand:QI 3 "general_operand" "")))]
19149   "TARGET_QIMODE_MATH"
19150   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19152 (define_insn_and_split "*movqicc_noc"
19153   [(set (match_operand:QI 0 "register_operand" "=r,r")
19154         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19155                                 [(match_operand 4 "flags_reg_operand" "")
19156                                  (const_int 0)])
19157                       (match_operand:QI 2 "register_operand" "r,0")
19158                       (match_operand:QI 3 "register_operand" "0,r")))]
19159   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19160   "#"
19161   "&& reload_completed"
19162   [(set (match_dup 0)
19163         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19164                       (match_dup 2)
19165                       (match_dup 3)))]
19166   "operands[0] = gen_lowpart (SImode, operands[0]);
19167    operands[2] = gen_lowpart (SImode, operands[2]);
19168    operands[3] = gen_lowpart (SImode, operands[3]);"
19169   [(set_attr "type" "icmov")
19170    (set_attr "mode" "SI")])
19172 (define_expand "movsfcc"
19173   [(set (match_operand:SF 0 "register_operand" "")
19174         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19175                          (match_operand:SF 2 "register_operand" "")
19176                          (match_operand:SF 3 "register_operand" "")))]
19177   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19178   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19180 (define_insn "*movsfcc_1_387"
19181   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19182         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19183                                 [(reg FLAGS_REG) (const_int 0)])
19184                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19185                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19186   "TARGET_80387 && TARGET_CMOVE
19187    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19188   "@
19189    fcmov%F1\t{%2, %0|%0, %2}
19190    fcmov%f1\t{%3, %0|%0, %3}
19191    cmov%O2%C1\t{%2, %0|%0, %2}
19192    cmov%O2%c1\t{%3, %0|%0, %3}"
19193   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19194    (set_attr "mode" "SF,SF,SI,SI")])
19196 (define_expand "movdfcc"
19197   [(set (match_operand:DF 0 "register_operand" "")
19198         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19199                          (match_operand:DF 2 "register_operand" "")
19200                          (match_operand:DF 3 "register_operand" "")))]
19201   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19202   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19204 (define_insn "*movdfcc_1"
19205   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19206         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19207                                 [(reg FLAGS_REG) (const_int 0)])
19208                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19209                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19210   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19211    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19212   "@
19213    fcmov%F1\t{%2, %0|%0, %2}
19214    fcmov%f1\t{%3, %0|%0, %3}
19215    #
19216    #"
19217   [(set_attr "type" "fcmov,fcmov,multi,multi")
19218    (set_attr "mode" "DF")])
19220 (define_insn "*movdfcc_1_rex64"
19221   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19222         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19223                                 [(reg FLAGS_REG) (const_int 0)])
19224                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19225                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19226   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19227    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19228   "@
19229    fcmov%F1\t{%2, %0|%0, %2}
19230    fcmov%f1\t{%3, %0|%0, %3}
19231    cmov%O2%C1\t{%2, %0|%0, %2}
19232    cmov%O2%c1\t{%3, %0|%0, %3}"
19233   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19234    (set_attr "mode" "DF")])
19236 (define_split
19237   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19238         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19239                                 [(match_operand 4 "flags_reg_operand" "")
19240                                  (const_int 0)])
19241                       (match_operand:DF 2 "nonimmediate_operand" "")
19242                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19243   "!TARGET_64BIT && reload_completed"
19244   [(set (match_dup 2)
19245         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19246                       (match_dup 5)
19247                       (match_dup 7)))
19248    (set (match_dup 3)
19249         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19250                       (match_dup 6)
19251                       (match_dup 8)))]
19252   "split_di (operands+2, 1, operands+5, operands+6);
19253    split_di (operands+3, 1, operands+7, operands+8);
19254    split_di (operands, 1, operands+2, operands+3);")
19256 (define_expand "movxfcc"
19257   [(set (match_operand:XF 0 "register_operand" "")
19258         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19259                          (match_operand:XF 2 "register_operand" "")
19260                          (match_operand:XF 3 "register_operand" "")))]
19261   "TARGET_80387 && TARGET_CMOVE"
19262   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19264 (define_insn "*movxfcc_1"
19265   [(set (match_operand:XF 0 "register_operand" "=f,f")
19266         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19267                                 [(reg FLAGS_REG) (const_int 0)])
19268                       (match_operand:XF 2 "register_operand" "f,0")
19269                       (match_operand:XF 3 "register_operand" "0,f")))]
19270   "TARGET_80387 && TARGET_CMOVE"
19271   "@
19272    fcmov%F1\t{%2, %0|%0, %2}
19273    fcmov%f1\t{%3, %0|%0, %3}"
19274   [(set_attr "type" "fcmov")
19275    (set_attr "mode" "XF")])
19277 ;; These versions of the min/max patterns are intentionally ignorant of
19278 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19279 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19280 ;; are undefined in this condition, we're certain this is correct.
19282 (define_insn "sminsf3"
19283   [(set (match_operand:SF 0 "register_operand" "=x")
19284         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19285                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19286   "TARGET_SSE_MATH"
19287   "minss\t{%2, %0|%0, %2}"
19288   [(set_attr "type" "sseadd")
19289    (set_attr "mode" "SF")])
19291 (define_insn "smaxsf3"
19292   [(set (match_operand:SF 0 "register_operand" "=x")
19293         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19294                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19295   "TARGET_SSE_MATH"
19296   "maxss\t{%2, %0|%0, %2}"
19297   [(set_attr "type" "sseadd")
19298    (set_attr "mode" "SF")])
19300 (define_insn "smindf3"
19301   [(set (match_operand:DF 0 "register_operand" "=x")
19302         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19303                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19304   "TARGET_SSE2 && TARGET_SSE_MATH"
19305   "minsd\t{%2, %0|%0, %2}"
19306   [(set_attr "type" "sseadd")
19307    (set_attr "mode" "DF")])
19309 (define_insn "smaxdf3"
19310   [(set (match_operand:DF 0 "register_operand" "=x")
19311         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19312                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19313   "TARGET_SSE2 && TARGET_SSE_MATH"
19314   "maxsd\t{%2, %0|%0, %2}"
19315   [(set_attr "type" "sseadd")
19316    (set_attr "mode" "DF")])
19318 ;; These versions of the min/max patterns implement exactly the operations
19319 ;;   min = (op1 < op2 ? op1 : op2)
19320 ;;   max = (!(op1 < op2) ? op1 : op2)
19321 ;; Their operands are not commutative, and thus they may be used in the
19322 ;; presence of -0.0 and NaN.
19324 (define_insn "*ieee_sminsf3"
19325   [(set (match_operand:SF 0 "register_operand" "=x")
19326         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19327                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19328                    UNSPEC_IEEE_MIN))]
19329   "TARGET_SSE_MATH"
19330   "minss\t{%2, %0|%0, %2}"
19331   [(set_attr "type" "sseadd")
19332    (set_attr "mode" "SF")])
19334 (define_insn "*ieee_smaxsf3"
19335   [(set (match_operand:SF 0 "register_operand" "=x")
19336         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19337                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19338                    UNSPEC_IEEE_MAX))]
19339   "TARGET_SSE_MATH"
19340   "maxss\t{%2, %0|%0, %2}"
19341   [(set_attr "type" "sseadd")
19342    (set_attr "mode" "SF")])
19344 (define_insn "*ieee_smindf3"
19345   [(set (match_operand:DF 0 "register_operand" "=x")
19346         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19347                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19348                    UNSPEC_IEEE_MIN))]
19349   "TARGET_SSE2 && TARGET_SSE_MATH"
19350   "minsd\t{%2, %0|%0, %2}"
19351   [(set_attr "type" "sseadd")
19352    (set_attr "mode" "DF")])
19354 (define_insn "*ieee_smaxdf3"
19355   [(set (match_operand:DF 0 "register_operand" "=x")
19356         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19357                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19358                    UNSPEC_IEEE_MAX))]
19359   "TARGET_SSE2 && TARGET_SSE_MATH"
19360   "maxsd\t{%2, %0|%0, %2}"
19361   [(set_attr "type" "sseadd")
19362    (set_attr "mode" "DF")])
19364 ;; Make two stack loads independent:
19365 ;;   fld aa              fld aa
19366 ;;   fld %st(0)     ->   fld bb
19367 ;;   fmul bb             fmul %st(1), %st
19369 ;; Actually we only match the last two instructions for simplicity.
19370 (define_peephole2
19371   [(set (match_operand 0 "fp_register_operand" "")
19372         (match_operand 1 "fp_register_operand" ""))
19373    (set (match_dup 0)
19374         (match_operator 2 "binary_fp_operator"
19375            [(match_dup 0)
19376             (match_operand 3 "memory_operand" "")]))]
19377   "REGNO (operands[0]) != REGNO (operands[1])"
19378   [(set (match_dup 0) (match_dup 3))
19379    (set (match_dup 0) (match_dup 4))]
19381   ;; The % modifier is not operational anymore in peephole2's, so we have to
19382   ;; swap the operands manually in the case of addition and multiplication.
19383   "if (COMMUTATIVE_ARITH_P (operands[2]))
19384      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19385                                  operands[0], operands[1]);
19386    else
19387      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19388                                  operands[1], operands[0]);")
19390 ;; Conditional addition patterns
19391 (define_expand "addqicc"
19392   [(match_operand:QI 0 "register_operand" "")
19393    (match_operand 1 "comparison_operator" "")
19394    (match_operand:QI 2 "register_operand" "")
19395    (match_operand:QI 3 "const_int_operand" "")]
19396   ""
19397   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19399 (define_expand "addhicc"
19400   [(match_operand:HI 0 "register_operand" "")
19401    (match_operand 1 "comparison_operator" "")
19402    (match_operand:HI 2 "register_operand" "")
19403    (match_operand:HI 3 "const_int_operand" "")]
19404   ""
19405   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19407 (define_expand "addsicc"
19408   [(match_operand:SI 0 "register_operand" "")
19409    (match_operand 1 "comparison_operator" "")
19410    (match_operand:SI 2 "register_operand" "")
19411    (match_operand:SI 3 "const_int_operand" "")]
19412   ""
19413   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19415 (define_expand "adddicc"
19416   [(match_operand:DI 0 "register_operand" "")
19417    (match_operand 1 "comparison_operator" "")
19418    (match_operand:DI 2 "register_operand" "")
19419    (match_operand:DI 3 "const_int_operand" "")]
19420   "TARGET_64BIT"
19421   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19424 ;; Misc patterns (?)
19426 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19427 ;; Otherwise there will be nothing to keep
19429 ;; [(set (reg ebp) (reg esp))]
19430 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19431 ;;  (clobber (eflags)]
19432 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19434 ;; in proper program order.
19435 (define_insn "pro_epilogue_adjust_stack_1"
19436   [(set (match_operand:SI 0 "register_operand" "=r,r")
19437         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19438                  (match_operand:SI 2 "immediate_operand" "i,i")))
19439    (clobber (reg:CC FLAGS_REG))
19440    (clobber (mem:BLK (scratch)))]
19441   "!TARGET_64BIT"
19443   switch (get_attr_type (insn))
19444     {
19445     case TYPE_IMOV:
19446       return "mov{l}\t{%1, %0|%0, %1}";
19448     case TYPE_ALU:
19449       if (GET_CODE (operands[2]) == CONST_INT
19450           && (INTVAL (operands[2]) == 128
19451               || (INTVAL (operands[2]) < 0
19452                   && INTVAL (operands[2]) != -128)))
19453         {
19454           operands[2] = GEN_INT (-INTVAL (operands[2]));
19455           return "sub{l}\t{%2, %0|%0, %2}";
19456         }
19457       return "add{l}\t{%2, %0|%0, %2}";
19459     case TYPE_LEA:
19460       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19461       return "lea{l}\t{%a2, %0|%0, %a2}";
19463     default:
19464       gcc_unreachable ();
19465     }
19467   [(set (attr "type")
19468         (cond [(eq_attr "alternative" "0")
19469                  (const_string "alu")
19470                (match_operand:SI 2 "const0_operand" "")
19471                  (const_string "imov")
19472               ]
19473               (const_string "lea")))
19474    (set_attr "mode" "SI")])
19476 (define_insn "pro_epilogue_adjust_stack_rex64"
19477   [(set (match_operand:DI 0 "register_operand" "=r,r")
19478         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19479                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19480    (clobber (reg:CC FLAGS_REG))
19481    (clobber (mem:BLK (scratch)))]
19482   "TARGET_64BIT"
19484   switch (get_attr_type (insn))
19485     {
19486     case TYPE_IMOV:
19487       return "mov{q}\t{%1, %0|%0, %1}";
19489     case TYPE_ALU:
19490       if (GET_CODE (operands[2]) == CONST_INT
19491           /* Avoid overflows.  */
19492           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19493           && (INTVAL (operands[2]) == 128
19494               || (INTVAL (operands[2]) < 0
19495                   && INTVAL (operands[2]) != -128)))
19496         {
19497           operands[2] = GEN_INT (-INTVAL (operands[2]));
19498           return "sub{q}\t{%2, %0|%0, %2}";
19499         }
19500       return "add{q}\t{%2, %0|%0, %2}";
19502     case TYPE_LEA:
19503       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19504       return "lea{q}\t{%a2, %0|%0, %a2}";
19506     default:
19507       gcc_unreachable ();
19508     }
19510   [(set (attr "type")
19511         (cond [(eq_attr "alternative" "0")
19512                  (const_string "alu")
19513                (match_operand:DI 2 "const0_operand" "")
19514                  (const_string "imov")
19515               ]
19516               (const_string "lea")))
19517    (set_attr "mode" "DI")])
19519 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19520   [(set (match_operand:DI 0 "register_operand" "=r,r")
19521         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19522                  (match_operand:DI 3 "immediate_operand" "i,i")))
19523    (use (match_operand:DI 2 "register_operand" "r,r"))
19524    (clobber (reg:CC FLAGS_REG))
19525    (clobber (mem:BLK (scratch)))]
19526   "TARGET_64BIT"
19528   switch (get_attr_type (insn))
19529     {
19530     case TYPE_ALU:
19531       return "add{q}\t{%2, %0|%0, %2}";
19533     case TYPE_LEA:
19534       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19535       return "lea{q}\t{%a2, %0|%0, %a2}";
19537     default:
19538       gcc_unreachable ();
19539     }
19541   [(set_attr "type" "alu,lea")
19542    (set_attr "mode" "DI")])
19544 (define_expand "allocate_stack_worker"
19545   [(match_operand:SI 0 "register_operand" "")]
19546   "TARGET_STACK_PROBE"
19548   if (reload_completed)
19549     {
19550       if (TARGET_64BIT)
19551         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19552       else
19553         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19554     }
19555   else
19556     {
19557       if (TARGET_64BIT)
19558         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19559       else
19560         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19561     }
19562   DONE;
19565 (define_insn "allocate_stack_worker_1"
19566   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19567     UNSPECV_STACK_PROBE)
19568    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19569    (clobber (match_scratch:SI 1 "=0"))
19570    (clobber (reg:CC FLAGS_REG))]
19571   "!TARGET_64BIT && TARGET_STACK_PROBE"
19572   "call\t__alloca"
19573   [(set_attr "type" "multi")
19574    (set_attr "length" "5")])
19576 (define_expand "allocate_stack_worker_postreload"
19577   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19578                                     UNSPECV_STACK_PROBE)
19579               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19580               (clobber (match_dup 0))
19581               (clobber (reg:CC FLAGS_REG))])]
19582   ""
19583   "")
19585 (define_insn "allocate_stack_worker_rex64"
19586   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19587     UNSPECV_STACK_PROBE)
19588    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19589    (clobber (match_scratch:DI 1 "=0"))
19590    (clobber (reg:CC FLAGS_REG))]
19591   "TARGET_64BIT && TARGET_STACK_PROBE"
19592   "call\t__alloca"
19593   [(set_attr "type" "multi")
19594    (set_attr "length" "5")])
19596 (define_expand "allocate_stack_worker_rex64_postreload"
19597   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19598                                     UNSPECV_STACK_PROBE)
19599               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19600               (clobber (match_dup 0))
19601               (clobber (reg:CC FLAGS_REG))])]
19602   ""
19603   "")
19605 (define_expand "allocate_stack"
19606   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19607                    (minus:SI (reg:SI SP_REG)
19608                              (match_operand:SI 1 "general_operand" "")))
19609               (clobber (reg:CC FLAGS_REG))])
19610    (parallel [(set (reg:SI SP_REG)
19611                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19612               (clobber (reg:CC FLAGS_REG))])]
19613   "TARGET_STACK_PROBE"
19615 #ifdef CHECK_STACK_LIMIT
19616   if (GET_CODE (operands[1]) == CONST_INT
19617       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19618     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19619                            operands[1]));
19620   else
19621 #endif
19622     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19623                                                             operands[1])));
19625   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19626   DONE;
19629 (define_expand "builtin_setjmp_receiver"
19630   [(label_ref (match_operand 0 "" ""))]
19631   "!TARGET_64BIT && flag_pic"
19633   if (TARGET_MACHO)
19634     {
19635       rtx xops[3];
19636       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19637       rtx label_rtx = gen_label_rtx ();
19638       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19639       xops[0] = xops[1] = picreg;
19640       xops[2] = gen_rtx_CONST (SImode,
19641                   gen_rtx_MINUS (SImode,
19642                     gen_rtx_LABEL_REF (SImode, label_rtx),
19643                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19644       ix86_expand_binary_operator (MINUS, SImode, xops);
19645     }
19646   else
19647     emit_insn (gen_set_got (pic_offset_table_rtx));
19648   DONE;
19651 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19653 (define_split
19654   [(set (match_operand 0 "register_operand" "")
19655         (match_operator 3 "promotable_binary_operator"
19656            [(match_operand 1 "register_operand" "")
19657             (match_operand 2 "aligned_operand" "")]))
19658    (clobber (reg:CC FLAGS_REG))]
19659   "! TARGET_PARTIAL_REG_STALL && reload_completed
19660    && ((GET_MODE (operands[0]) == HImode
19661         && ((!optimize_size && !TARGET_FAST_PREFIX)
19662             /* ??? next two lines just !satisfies_constraint_K (...) */
19663             || GET_CODE (operands[2]) != CONST_INT
19664             || satisfies_constraint_K (operands[2])))
19665        || (GET_MODE (operands[0]) == QImode
19666            && (TARGET_PROMOTE_QImode || optimize_size)))"
19667   [(parallel [(set (match_dup 0)
19668                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19669               (clobber (reg:CC FLAGS_REG))])]
19670   "operands[0] = gen_lowpart (SImode, operands[0]);
19671    operands[1] = gen_lowpart (SImode, operands[1]);
19672    if (GET_CODE (operands[3]) != ASHIFT)
19673      operands[2] = gen_lowpart (SImode, operands[2]);
19674    PUT_MODE (operands[3], SImode);")
19676 ; Promote the QImode tests, as i386 has encoding of the AND
19677 ; instruction with 32-bit sign-extended immediate and thus the
19678 ; instruction size is unchanged, except in the %eax case for
19679 ; which it is increased by one byte, hence the ! optimize_size.
19680 (define_split
19681   [(set (match_operand 0 "flags_reg_operand" "")
19682         (match_operator 2 "compare_operator"
19683           [(and (match_operand 3 "aligned_operand" "")
19684                 (match_operand 4 "const_int_operand" ""))
19685            (const_int 0)]))
19686    (set (match_operand 1 "register_operand" "")
19687         (and (match_dup 3) (match_dup 4)))]
19688   "! TARGET_PARTIAL_REG_STALL && reload_completed
19689    /* Ensure that the operand will remain sign-extended immediate.  */
19690    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19691    && ! optimize_size
19692    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19693        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19694   [(parallel [(set (match_dup 0)
19695                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19696                                     (const_int 0)]))
19697               (set (match_dup 1)
19698                    (and:SI (match_dup 3) (match_dup 4)))])]
19700   operands[4]
19701     = gen_int_mode (INTVAL (operands[4])
19702                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19703   operands[1] = gen_lowpart (SImode, operands[1]);
19704   operands[3] = gen_lowpart (SImode, operands[3]);
19707 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19708 ; the TEST instruction with 32-bit sign-extended immediate and thus
19709 ; the instruction size would at least double, which is not what we
19710 ; want even with ! optimize_size.
19711 (define_split
19712   [(set (match_operand 0 "flags_reg_operand" "")
19713         (match_operator 1 "compare_operator"
19714           [(and (match_operand:HI 2 "aligned_operand" "")
19715                 (match_operand:HI 3 "const_int_operand" ""))
19716            (const_int 0)]))]
19717   "! TARGET_PARTIAL_REG_STALL && reload_completed
19718    /* Ensure that the operand will remain sign-extended immediate.  */
19719    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19720    && ! TARGET_FAST_PREFIX
19721    && ! optimize_size"
19722   [(set (match_dup 0)
19723         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19724                          (const_int 0)]))]
19726   operands[3]
19727     = gen_int_mode (INTVAL (operands[3])
19728                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19729   operands[2] = gen_lowpart (SImode, operands[2]);
19732 (define_split
19733   [(set (match_operand 0 "register_operand" "")
19734         (neg (match_operand 1 "register_operand" "")))
19735    (clobber (reg:CC FLAGS_REG))]
19736   "! TARGET_PARTIAL_REG_STALL && reload_completed
19737    && (GET_MODE (operands[0]) == HImode
19738        || (GET_MODE (operands[0]) == QImode
19739            && (TARGET_PROMOTE_QImode || optimize_size)))"
19740   [(parallel [(set (match_dup 0)
19741                    (neg:SI (match_dup 1)))
19742               (clobber (reg:CC FLAGS_REG))])]
19743   "operands[0] = gen_lowpart (SImode, operands[0]);
19744    operands[1] = gen_lowpart (SImode, operands[1]);")
19746 (define_split
19747   [(set (match_operand 0 "register_operand" "")
19748         (not (match_operand 1 "register_operand" "")))]
19749   "! TARGET_PARTIAL_REG_STALL && reload_completed
19750    && (GET_MODE (operands[0]) == HImode
19751        || (GET_MODE (operands[0]) == QImode
19752            && (TARGET_PROMOTE_QImode || optimize_size)))"
19753   [(set (match_dup 0)
19754         (not:SI (match_dup 1)))]
19755   "operands[0] = gen_lowpart (SImode, operands[0]);
19756    operands[1] = gen_lowpart (SImode, operands[1]);")
19758 (define_split
19759   [(set (match_operand 0 "register_operand" "")
19760         (if_then_else (match_operator 1 "comparison_operator"
19761                                 [(reg FLAGS_REG) (const_int 0)])
19762                       (match_operand 2 "register_operand" "")
19763                       (match_operand 3 "register_operand" "")))]
19764   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19765    && (GET_MODE (operands[0]) == HImode
19766        || (GET_MODE (operands[0]) == QImode
19767            && (TARGET_PROMOTE_QImode || optimize_size)))"
19768   [(set (match_dup 0)
19769         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19770   "operands[0] = gen_lowpart (SImode, operands[0]);
19771    operands[2] = gen_lowpart (SImode, operands[2]);
19772    operands[3] = gen_lowpart (SImode, operands[3]);")
19775 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19776 ;; transform a complex memory operation into two memory to register operations.
19778 ;; Don't push memory operands
19779 (define_peephole2
19780   [(set (match_operand:SI 0 "push_operand" "")
19781         (match_operand:SI 1 "memory_operand" ""))
19782    (match_scratch:SI 2 "r")]
19783   "!optimize_size && !TARGET_PUSH_MEMORY
19784    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19785   [(set (match_dup 2) (match_dup 1))
19786    (set (match_dup 0) (match_dup 2))]
19787   "")
19789 (define_peephole2
19790   [(set (match_operand:DI 0 "push_operand" "")
19791         (match_operand:DI 1 "memory_operand" ""))
19792    (match_scratch:DI 2 "r")]
19793   "!optimize_size && !TARGET_PUSH_MEMORY
19794    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19795   [(set (match_dup 2) (match_dup 1))
19796    (set (match_dup 0) (match_dup 2))]
19797   "")
19799 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19800 ;; SImode pushes.
19801 (define_peephole2
19802   [(set (match_operand:SF 0 "push_operand" "")
19803         (match_operand:SF 1 "memory_operand" ""))
19804    (match_scratch:SF 2 "r")]
19805   "!optimize_size && !TARGET_PUSH_MEMORY
19806    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19807   [(set (match_dup 2) (match_dup 1))
19808    (set (match_dup 0) (match_dup 2))]
19809   "")
19811 (define_peephole2
19812   [(set (match_operand:HI 0 "push_operand" "")
19813         (match_operand:HI 1 "memory_operand" ""))
19814    (match_scratch:HI 2 "r")]
19815   "!optimize_size && !TARGET_PUSH_MEMORY
19816    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19817   [(set (match_dup 2) (match_dup 1))
19818    (set (match_dup 0) (match_dup 2))]
19819   "")
19821 (define_peephole2
19822   [(set (match_operand:QI 0 "push_operand" "")
19823         (match_operand:QI 1 "memory_operand" ""))
19824    (match_scratch:QI 2 "q")]
19825   "!optimize_size && !TARGET_PUSH_MEMORY
19826    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19827   [(set (match_dup 2) (match_dup 1))
19828    (set (match_dup 0) (match_dup 2))]
19829   "")
19831 ;; Don't move an immediate directly to memory when the instruction
19832 ;; gets too big.
19833 (define_peephole2
19834   [(match_scratch:SI 1 "r")
19835    (set (match_operand:SI 0 "memory_operand" "")
19836         (const_int 0))]
19837   "! optimize_size
19838    && ! TARGET_USE_MOV0
19839    && TARGET_SPLIT_LONG_MOVES
19840    && get_attr_length (insn) >= ix86_cost->large_insn
19841    && peep2_regno_dead_p (0, FLAGS_REG)"
19842   [(parallel [(set (match_dup 1) (const_int 0))
19843               (clobber (reg:CC FLAGS_REG))])
19844    (set (match_dup 0) (match_dup 1))]
19845   "")
19847 (define_peephole2
19848   [(match_scratch:HI 1 "r")
19849    (set (match_operand:HI 0 "memory_operand" "")
19850         (const_int 0))]
19851   "! optimize_size
19852    && ! TARGET_USE_MOV0
19853    && TARGET_SPLIT_LONG_MOVES
19854    && get_attr_length (insn) >= ix86_cost->large_insn
19855    && peep2_regno_dead_p (0, FLAGS_REG)"
19856   [(parallel [(set (match_dup 2) (const_int 0))
19857               (clobber (reg:CC FLAGS_REG))])
19858    (set (match_dup 0) (match_dup 1))]
19859   "operands[2] = gen_lowpart (SImode, operands[1]);")
19861 (define_peephole2
19862   [(match_scratch:QI 1 "q")
19863    (set (match_operand:QI 0 "memory_operand" "")
19864         (const_int 0))]
19865   "! optimize_size
19866    && ! TARGET_USE_MOV0
19867    && TARGET_SPLIT_LONG_MOVES
19868    && get_attr_length (insn) >= ix86_cost->large_insn
19869    && peep2_regno_dead_p (0, FLAGS_REG)"
19870   [(parallel [(set (match_dup 2) (const_int 0))
19871               (clobber (reg:CC FLAGS_REG))])
19872    (set (match_dup 0) (match_dup 1))]
19873   "operands[2] = gen_lowpart (SImode, operands[1]);")
19875 (define_peephole2
19876   [(match_scratch:SI 2 "r")
19877    (set (match_operand:SI 0 "memory_operand" "")
19878         (match_operand:SI 1 "immediate_operand" ""))]
19879   "! optimize_size
19880    && get_attr_length (insn) >= ix86_cost->large_insn
19881    && TARGET_SPLIT_LONG_MOVES"
19882   [(set (match_dup 2) (match_dup 1))
19883    (set (match_dup 0) (match_dup 2))]
19884   "")
19886 (define_peephole2
19887   [(match_scratch:HI 2 "r")
19888    (set (match_operand:HI 0 "memory_operand" "")
19889         (match_operand:HI 1 "immediate_operand" ""))]
19890   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19891   && TARGET_SPLIT_LONG_MOVES"
19892   [(set (match_dup 2) (match_dup 1))
19893    (set (match_dup 0) (match_dup 2))]
19894   "")
19896 (define_peephole2
19897   [(match_scratch:QI 2 "q")
19898    (set (match_operand:QI 0 "memory_operand" "")
19899         (match_operand:QI 1 "immediate_operand" ""))]
19900   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19901   && TARGET_SPLIT_LONG_MOVES"
19902   [(set (match_dup 2) (match_dup 1))
19903    (set (match_dup 0) (match_dup 2))]
19904   "")
19906 ;; Don't compare memory with zero, load and use a test instead.
19907 (define_peephole2
19908   [(set (match_operand 0 "flags_reg_operand" "")
19909         (match_operator 1 "compare_operator"
19910           [(match_operand:SI 2 "memory_operand" "")
19911            (const_int 0)]))
19912    (match_scratch:SI 3 "r")]
19913   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19914   [(set (match_dup 3) (match_dup 2))
19915    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19916   "")
19918 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19919 ;; Don't split NOTs with a displacement operand, because resulting XOR
19920 ;; will not be pairable anyway.
19922 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19923 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19924 ;; so this split helps here as well.
19926 ;; Note: Can't do this as a regular split because we can't get proper
19927 ;; lifetime information then.
19929 (define_peephole2
19930   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19931         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19932   "!optimize_size
19933    && peep2_regno_dead_p (0, FLAGS_REG)
19934    && ((TARGET_PENTIUM
19935         && (GET_CODE (operands[0]) != MEM
19936             || !memory_displacement_operand (operands[0], SImode)))
19937        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19938   [(parallel [(set (match_dup 0)
19939                    (xor:SI (match_dup 1) (const_int -1)))
19940               (clobber (reg:CC FLAGS_REG))])]
19941   "")
19943 (define_peephole2
19944   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19945         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19946   "!optimize_size
19947    && peep2_regno_dead_p (0, FLAGS_REG)
19948    && ((TARGET_PENTIUM
19949         && (GET_CODE (operands[0]) != MEM
19950             || !memory_displacement_operand (operands[0], HImode)))
19951        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19952   [(parallel [(set (match_dup 0)
19953                    (xor:HI (match_dup 1) (const_int -1)))
19954               (clobber (reg:CC FLAGS_REG))])]
19955   "")
19957 (define_peephole2
19958   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19959         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19960   "!optimize_size
19961    && peep2_regno_dead_p (0, FLAGS_REG)
19962    && ((TARGET_PENTIUM
19963         && (GET_CODE (operands[0]) != MEM
19964             || !memory_displacement_operand (operands[0], QImode)))
19965        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19966   [(parallel [(set (match_dup 0)
19967                    (xor:QI (match_dup 1) (const_int -1)))
19968               (clobber (reg:CC FLAGS_REG))])]
19969   "")
19971 ;; Non pairable "test imm, reg" instructions can be translated to
19972 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19973 ;; byte opcode instead of two, have a short form for byte operands),
19974 ;; so do it for other CPUs as well.  Given that the value was dead,
19975 ;; this should not create any new dependencies.  Pass on the sub-word
19976 ;; versions if we're concerned about partial register stalls.
19978 (define_peephole2
19979   [(set (match_operand 0 "flags_reg_operand" "")
19980         (match_operator 1 "compare_operator"
19981           [(and:SI (match_operand:SI 2 "register_operand" "")
19982                    (match_operand:SI 3 "immediate_operand" ""))
19983            (const_int 0)]))]
19984   "ix86_match_ccmode (insn, CCNOmode)
19985    && (true_regnum (operands[2]) != 0
19986        || satisfies_constraint_K (operands[3]))
19987    && peep2_reg_dead_p (1, operands[2])"
19988   [(parallel
19989      [(set (match_dup 0)
19990            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19991                             (const_int 0)]))
19992       (set (match_dup 2)
19993            (and:SI (match_dup 2) (match_dup 3)))])]
19994   "")
19996 ;; We don't need to handle HImode case, because it will be promoted to SImode
19997 ;; on ! TARGET_PARTIAL_REG_STALL
19999 (define_peephole2
20000   [(set (match_operand 0 "flags_reg_operand" "")
20001         (match_operator 1 "compare_operator"
20002           [(and:QI (match_operand:QI 2 "register_operand" "")
20003                    (match_operand:QI 3 "immediate_operand" ""))
20004            (const_int 0)]))]
20005   "! TARGET_PARTIAL_REG_STALL
20006    && ix86_match_ccmode (insn, CCNOmode)
20007    && true_regnum (operands[2]) != 0
20008    && peep2_reg_dead_p (1, operands[2])"
20009   [(parallel
20010      [(set (match_dup 0)
20011            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20012                             (const_int 0)]))
20013       (set (match_dup 2)
20014            (and:QI (match_dup 2) (match_dup 3)))])]
20015   "")
20017 (define_peephole2
20018   [(set (match_operand 0 "flags_reg_operand" "")
20019         (match_operator 1 "compare_operator"
20020           [(and:SI
20021              (zero_extract:SI
20022                (match_operand 2 "ext_register_operand" "")
20023                (const_int 8)
20024                (const_int 8))
20025              (match_operand 3 "const_int_operand" ""))
20026            (const_int 0)]))]
20027   "! TARGET_PARTIAL_REG_STALL
20028    && ix86_match_ccmode (insn, CCNOmode)
20029    && true_regnum (operands[2]) != 0
20030    && peep2_reg_dead_p (1, operands[2])"
20031   [(parallel [(set (match_dup 0)
20032                    (match_op_dup 1
20033                      [(and:SI
20034                         (zero_extract:SI
20035                           (match_dup 2)
20036                           (const_int 8)
20037                           (const_int 8))
20038                         (match_dup 3))
20039                       (const_int 0)]))
20040               (set (zero_extract:SI (match_dup 2)
20041                                     (const_int 8)
20042                                     (const_int 8))
20043                    (and:SI
20044                      (zero_extract:SI
20045                        (match_dup 2)
20046                        (const_int 8)
20047                        (const_int 8))
20048                      (match_dup 3)))])]
20049   "")
20051 ;; Don't do logical operations with memory inputs.
20052 (define_peephole2
20053   [(match_scratch:SI 2 "r")
20054    (parallel [(set (match_operand:SI 0 "register_operand" "")
20055                    (match_operator:SI 3 "arith_or_logical_operator"
20056                      [(match_dup 0)
20057                       (match_operand:SI 1 "memory_operand" "")]))
20058               (clobber (reg:CC FLAGS_REG))])]
20059   "! optimize_size && ! TARGET_READ_MODIFY"
20060   [(set (match_dup 2) (match_dup 1))
20061    (parallel [(set (match_dup 0)
20062                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20063               (clobber (reg:CC FLAGS_REG))])]
20064   "")
20066 (define_peephole2
20067   [(match_scratch:SI 2 "r")
20068    (parallel [(set (match_operand:SI 0 "register_operand" "")
20069                    (match_operator:SI 3 "arith_or_logical_operator"
20070                      [(match_operand:SI 1 "memory_operand" "")
20071                       (match_dup 0)]))
20072               (clobber (reg:CC FLAGS_REG))])]
20073   "! optimize_size && ! TARGET_READ_MODIFY"
20074   [(set (match_dup 2) (match_dup 1))
20075    (parallel [(set (match_dup 0)
20076                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20077               (clobber (reg:CC FLAGS_REG))])]
20078   "")
20080 ; Don't do logical operations with memory outputs
20082 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20083 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20084 ; the same decoder scheduling characteristics as the original.
20086 (define_peephole2
20087   [(match_scratch:SI 2 "r")
20088    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20089                    (match_operator:SI 3 "arith_or_logical_operator"
20090                      [(match_dup 0)
20091                       (match_operand:SI 1 "nonmemory_operand" "")]))
20092               (clobber (reg:CC FLAGS_REG))])]
20093   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20094   [(set (match_dup 2) (match_dup 0))
20095    (parallel [(set (match_dup 2)
20096                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20097               (clobber (reg:CC FLAGS_REG))])
20098    (set (match_dup 0) (match_dup 2))]
20099   "")
20101 (define_peephole2
20102   [(match_scratch:SI 2 "r")
20103    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20104                    (match_operator:SI 3 "arith_or_logical_operator"
20105                      [(match_operand:SI 1 "nonmemory_operand" "")
20106                       (match_dup 0)]))
20107               (clobber (reg:CC FLAGS_REG))])]
20108   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20109   [(set (match_dup 2) (match_dup 0))
20110    (parallel [(set (match_dup 2)
20111                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20112               (clobber (reg:CC FLAGS_REG))])
20113    (set (match_dup 0) (match_dup 2))]
20114   "")
20116 ;; Attempt to always use XOR for zeroing registers.
20117 (define_peephole2
20118   [(set (match_operand 0 "register_operand" "")
20119         (match_operand 1 "const0_operand" ""))]
20120   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20121    && (! TARGET_USE_MOV0 || optimize_size)
20122    && GENERAL_REG_P (operands[0])
20123    && peep2_regno_dead_p (0, FLAGS_REG)"
20124   [(parallel [(set (match_dup 0) (const_int 0))
20125               (clobber (reg:CC FLAGS_REG))])]
20127   operands[0] = gen_lowpart (word_mode, operands[0]);
20130 (define_peephole2
20131   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20132         (const_int 0))]
20133   "(GET_MODE (operands[0]) == QImode
20134     || GET_MODE (operands[0]) == HImode)
20135    && (! TARGET_USE_MOV0 || optimize_size)
20136    && peep2_regno_dead_p (0, FLAGS_REG)"
20137   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20138               (clobber (reg:CC FLAGS_REG))])])
20140 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20141 (define_peephole2
20142   [(set (match_operand 0 "register_operand" "")
20143         (const_int -1))]
20144   "(GET_MODE (operands[0]) == HImode
20145     || GET_MODE (operands[0]) == SImode
20146     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20147    && (optimize_size || TARGET_PENTIUM)
20148    && peep2_regno_dead_p (0, FLAGS_REG)"
20149   [(parallel [(set (match_dup 0) (const_int -1))
20150               (clobber (reg:CC FLAGS_REG))])]
20151   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20152                               operands[0]);")
20154 ;; Attempt to convert simple leas to adds. These can be created by
20155 ;; move expanders.
20156 (define_peephole2
20157   [(set (match_operand:SI 0 "register_operand" "")
20158         (plus:SI (match_dup 0)
20159                  (match_operand:SI 1 "nonmemory_operand" "")))]
20160   "peep2_regno_dead_p (0, FLAGS_REG)"
20161   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20162               (clobber (reg:CC FLAGS_REG))])]
20163   "")
20165 (define_peephole2
20166   [(set (match_operand:SI 0 "register_operand" "")
20167         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20168                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20169   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20170   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20171               (clobber (reg:CC FLAGS_REG))])]
20172   "operands[2] = gen_lowpart (SImode, operands[2]);")
20174 (define_peephole2
20175   [(set (match_operand:DI 0 "register_operand" "")
20176         (plus:DI (match_dup 0)
20177                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20178   "peep2_regno_dead_p (0, FLAGS_REG)"
20179   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20180               (clobber (reg:CC FLAGS_REG))])]
20181   "")
20183 (define_peephole2
20184   [(set (match_operand:SI 0 "register_operand" "")
20185         (mult:SI (match_dup 0)
20186                  (match_operand:SI 1 "const_int_operand" "")))]
20187   "exact_log2 (INTVAL (operands[1])) >= 0
20188    && peep2_regno_dead_p (0, FLAGS_REG)"
20189   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20190               (clobber (reg:CC FLAGS_REG))])]
20191   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20193 (define_peephole2
20194   [(set (match_operand:DI 0 "register_operand" "")
20195         (mult:DI (match_dup 0)
20196                  (match_operand:DI 1 "const_int_operand" "")))]
20197   "exact_log2 (INTVAL (operands[1])) >= 0
20198    && peep2_regno_dead_p (0, FLAGS_REG)"
20199   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20200               (clobber (reg:CC FLAGS_REG))])]
20201   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20203 (define_peephole2
20204   [(set (match_operand:SI 0 "register_operand" "")
20205         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20206                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20207   "exact_log2 (INTVAL (operands[2])) >= 0
20208    && REGNO (operands[0]) == REGNO (operands[1])
20209    && peep2_regno_dead_p (0, FLAGS_REG)"
20210   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20211               (clobber (reg:CC FLAGS_REG))])]
20212   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20214 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20215 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20216 ;; many CPUs it is also faster, since special hardware to avoid esp
20217 ;; dependencies is present.
20219 ;; While some of these conversions may be done using splitters, we use peepholes
20220 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20222 ;; Convert prologue esp subtractions to push.
20223 ;; We need register to push.  In order to keep verify_flow_info happy we have
20224 ;; two choices
20225 ;; - use scratch and clobber it in order to avoid dependencies
20226 ;; - use already live register
20227 ;; We can't use the second way right now, since there is no reliable way how to
20228 ;; verify that given register is live.  First choice will also most likely in
20229 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20230 ;; call clobbered registers are dead.  We may want to use base pointer as an
20231 ;; alternative when no register is available later.
20233 (define_peephole2
20234   [(match_scratch:SI 0 "r")
20235    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20236               (clobber (reg:CC FLAGS_REG))
20237               (clobber (mem:BLK (scratch)))])]
20238   "optimize_size || !TARGET_SUB_ESP_4"
20239   [(clobber (match_dup 0))
20240    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20241               (clobber (mem:BLK (scratch)))])])
20243 (define_peephole2
20244   [(match_scratch:SI 0 "r")
20245    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20246               (clobber (reg:CC FLAGS_REG))
20247               (clobber (mem:BLK (scratch)))])]
20248   "optimize_size || !TARGET_SUB_ESP_8"
20249   [(clobber (match_dup 0))
20250    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20251    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20252               (clobber (mem:BLK (scratch)))])])
20254 ;; Convert esp subtractions to push.
20255 (define_peephole2
20256   [(match_scratch:SI 0 "r")
20257    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20258               (clobber (reg:CC FLAGS_REG))])]
20259   "optimize_size || !TARGET_SUB_ESP_4"
20260   [(clobber (match_dup 0))
20261    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20263 (define_peephole2
20264   [(match_scratch:SI 0 "r")
20265    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20266               (clobber (reg:CC FLAGS_REG))])]
20267   "optimize_size || !TARGET_SUB_ESP_8"
20268   [(clobber (match_dup 0))
20269    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20270    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20272 ;; Convert epilogue deallocator to pop.
20273 (define_peephole2
20274   [(match_scratch:SI 0 "r")
20275    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20276               (clobber (reg:CC FLAGS_REG))
20277               (clobber (mem:BLK (scratch)))])]
20278   "optimize_size || !TARGET_ADD_ESP_4"
20279   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20280               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20281               (clobber (mem:BLK (scratch)))])]
20282   "")
20284 ;; Two pops case is tricky, since pop causes dependency on destination register.
20285 ;; We use two registers if available.
20286 (define_peephole2
20287   [(match_scratch:SI 0 "r")
20288    (match_scratch:SI 1 "r")
20289    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20290               (clobber (reg:CC FLAGS_REG))
20291               (clobber (mem:BLK (scratch)))])]
20292   "optimize_size || !TARGET_ADD_ESP_8"
20293   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20294               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20295               (clobber (mem:BLK (scratch)))])
20296    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20297               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20298   "")
20300 (define_peephole2
20301   [(match_scratch:SI 0 "r")
20302    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20303               (clobber (reg:CC FLAGS_REG))
20304               (clobber (mem:BLK (scratch)))])]
20305   "optimize_size"
20306   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20307               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20308               (clobber (mem:BLK (scratch)))])
20309    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20310               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20311   "")
20313 ;; Convert esp additions to pop.
20314 (define_peephole2
20315   [(match_scratch:SI 0 "r")
20316    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20317               (clobber (reg:CC FLAGS_REG))])]
20318   ""
20319   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20320               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20321   "")
20323 ;; Two pops case is tricky, since pop causes dependency on destination register.
20324 ;; We use two registers if available.
20325 (define_peephole2
20326   [(match_scratch:SI 0 "r")
20327    (match_scratch:SI 1 "r")
20328    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20329               (clobber (reg:CC FLAGS_REG))])]
20330   ""
20331   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20332               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20333    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20334               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20335   "")
20337 (define_peephole2
20338   [(match_scratch:SI 0 "r")
20339    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20340               (clobber (reg:CC FLAGS_REG))])]
20341   "optimize_size"
20342   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20343               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20344    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20345               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20346   "")
20348 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20349 ;; required and register dies.  Similarly for 128 to plus -128.
20350 (define_peephole2
20351   [(set (match_operand 0 "flags_reg_operand" "")
20352         (match_operator 1 "compare_operator"
20353           [(match_operand 2 "register_operand" "")
20354            (match_operand 3 "const_int_operand" "")]))]
20355   "(INTVAL (operands[3]) == -1
20356     || INTVAL (operands[3]) == 1
20357     || INTVAL (operands[3]) == 128)
20358    && ix86_match_ccmode (insn, CCGCmode)
20359    && peep2_reg_dead_p (1, operands[2])"
20360   [(parallel [(set (match_dup 0)
20361                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20362               (clobber (match_dup 2))])]
20363   "")
20365 (define_peephole2
20366   [(match_scratch:DI 0 "r")
20367    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20368               (clobber (reg:CC FLAGS_REG))
20369               (clobber (mem:BLK (scratch)))])]
20370   "optimize_size || !TARGET_SUB_ESP_4"
20371   [(clobber (match_dup 0))
20372    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20373               (clobber (mem:BLK (scratch)))])])
20375 (define_peephole2
20376   [(match_scratch:DI 0 "r")
20377    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20378               (clobber (reg:CC FLAGS_REG))
20379               (clobber (mem:BLK (scratch)))])]
20380   "optimize_size || !TARGET_SUB_ESP_8"
20381   [(clobber (match_dup 0))
20382    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20383    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20384               (clobber (mem:BLK (scratch)))])])
20386 ;; Convert esp subtractions to push.
20387 (define_peephole2
20388   [(match_scratch:DI 0 "r")
20389    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20390               (clobber (reg:CC FLAGS_REG))])]
20391   "optimize_size || !TARGET_SUB_ESP_4"
20392   [(clobber (match_dup 0))
20393    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20395 (define_peephole2
20396   [(match_scratch:DI 0 "r")
20397    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20398               (clobber (reg:CC FLAGS_REG))])]
20399   "optimize_size || !TARGET_SUB_ESP_8"
20400   [(clobber (match_dup 0))
20401    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20402    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20404 ;; Convert epilogue deallocator to pop.
20405 (define_peephole2
20406   [(match_scratch:DI 0 "r")
20407    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20408               (clobber (reg:CC FLAGS_REG))
20409               (clobber (mem:BLK (scratch)))])]
20410   "optimize_size || !TARGET_ADD_ESP_4"
20411   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20412               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20413               (clobber (mem:BLK (scratch)))])]
20414   "")
20416 ;; Two pops case is tricky, since pop causes dependency on destination register.
20417 ;; We use two registers if available.
20418 (define_peephole2
20419   [(match_scratch:DI 0 "r")
20420    (match_scratch:DI 1 "r")
20421    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20422               (clobber (reg:CC FLAGS_REG))
20423               (clobber (mem:BLK (scratch)))])]
20424   "optimize_size || !TARGET_ADD_ESP_8"
20425   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20426               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20427               (clobber (mem:BLK (scratch)))])
20428    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20429               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20430   "")
20432 (define_peephole2
20433   [(match_scratch:DI 0 "r")
20434    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20435               (clobber (reg:CC FLAGS_REG))
20436               (clobber (mem:BLK (scratch)))])]
20437   "optimize_size"
20438   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20439               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20440               (clobber (mem:BLK (scratch)))])
20441    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20442               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20443   "")
20445 ;; Convert esp additions to pop.
20446 (define_peephole2
20447   [(match_scratch:DI 0 "r")
20448    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20449               (clobber (reg:CC FLAGS_REG))])]
20450   ""
20451   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20452               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20453   "")
20455 ;; Two pops case is tricky, since pop causes dependency on destination register.
20456 ;; We use two registers if available.
20457 (define_peephole2
20458   [(match_scratch:DI 0 "r")
20459    (match_scratch:DI 1 "r")
20460    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20461               (clobber (reg:CC FLAGS_REG))])]
20462   ""
20463   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20464               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20465    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20466               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20467   "")
20469 (define_peephole2
20470   [(match_scratch:DI 0 "r")
20471    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20472               (clobber (reg:CC FLAGS_REG))])]
20473   "optimize_size"
20474   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20475               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20476    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20477               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20478   "")
20480 ;; Convert imul by three, five and nine into lea
20481 (define_peephole2
20482   [(parallel
20483     [(set (match_operand:SI 0 "register_operand" "")
20484           (mult:SI (match_operand:SI 1 "register_operand" "")
20485                    (match_operand:SI 2 "const_int_operand" "")))
20486      (clobber (reg:CC FLAGS_REG))])]
20487   "INTVAL (operands[2]) == 3
20488    || INTVAL (operands[2]) == 5
20489    || INTVAL (operands[2]) == 9"
20490   [(set (match_dup 0)
20491         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20492                  (match_dup 1)))]
20493   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20495 (define_peephole2
20496   [(parallel
20497     [(set (match_operand:SI 0 "register_operand" "")
20498           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20499                    (match_operand:SI 2 "const_int_operand" "")))
20500      (clobber (reg:CC FLAGS_REG))])]
20501   "!optimize_size
20502    && (INTVAL (operands[2]) == 3
20503        || INTVAL (operands[2]) == 5
20504        || INTVAL (operands[2]) == 9)"
20505   [(set (match_dup 0) (match_dup 1))
20506    (set (match_dup 0)
20507         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20508                  (match_dup 0)))]
20509   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20511 (define_peephole2
20512   [(parallel
20513     [(set (match_operand:DI 0 "register_operand" "")
20514           (mult:DI (match_operand:DI 1 "register_operand" "")
20515                    (match_operand:DI 2 "const_int_operand" "")))
20516      (clobber (reg:CC FLAGS_REG))])]
20517   "TARGET_64BIT
20518    && (INTVAL (operands[2]) == 3
20519        || INTVAL (operands[2]) == 5
20520        || INTVAL (operands[2]) == 9)"
20521   [(set (match_dup 0)
20522         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20523                  (match_dup 1)))]
20524   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20526 (define_peephole2
20527   [(parallel
20528     [(set (match_operand:DI 0 "register_operand" "")
20529           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20530                    (match_operand:DI 2 "const_int_operand" "")))
20531      (clobber (reg:CC FLAGS_REG))])]
20532   "TARGET_64BIT
20533    && !optimize_size
20534    && (INTVAL (operands[2]) == 3
20535        || INTVAL (operands[2]) == 5
20536        || INTVAL (operands[2]) == 9)"
20537   [(set (match_dup 0) (match_dup 1))
20538    (set (match_dup 0)
20539         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20540                  (match_dup 0)))]
20541   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20543 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20544 ;; imul $32bit_imm, reg, reg is direct decoded.
20545 (define_peephole2
20546   [(match_scratch:DI 3 "r")
20547    (parallel [(set (match_operand:DI 0 "register_operand" "")
20548                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20549                             (match_operand:DI 2 "immediate_operand" "")))
20550               (clobber (reg:CC FLAGS_REG))])]
20551   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20552    && !satisfies_constraint_K (operands[2])"
20553   [(set (match_dup 3) (match_dup 1))
20554    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20555               (clobber (reg:CC FLAGS_REG))])]
20558 (define_peephole2
20559   [(match_scratch:SI 3 "r")
20560    (parallel [(set (match_operand:SI 0 "register_operand" "")
20561                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20562                             (match_operand:SI 2 "immediate_operand" "")))
20563               (clobber (reg:CC FLAGS_REG))])]
20564   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20565    && !satisfies_constraint_K (operands[2])"
20566   [(set (match_dup 3) (match_dup 1))
20567    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20568               (clobber (reg:CC FLAGS_REG))])]
20571 (define_peephole2
20572   [(match_scratch:SI 3 "r")
20573    (parallel [(set (match_operand:DI 0 "register_operand" "")
20574                    (zero_extend:DI
20575                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20576                               (match_operand:SI 2 "immediate_operand" ""))))
20577               (clobber (reg:CC FLAGS_REG))])]
20578   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20579    && !satisfies_constraint_K (operands[2])"
20580   [(set (match_dup 3) (match_dup 1))
20581    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20582               (clobber (reg:CC FLAGS_REG))])]
20585 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20586 ;; Convert it into imul reg, reg
20587 ;; It would be better to force assembler to encode instruction using long
20588 ;; immediate, but there is apparently no way to do so.
20589 (define_peephole2
20590   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20591                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20592                             (match_operand:DI 2 "const_int_operand" "")))
20593               (clobber (reg:CC FLAGS_REG))])
20594    (match_scratch:DI 3 "r")]
20595   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20596    && satisfies_constraint_K (operands[2])"
20597   [(set (match_dup 3) (match_dup 2))
20598    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20599               (clobber (reg:CC FLAGS_REG))])]
20601   if (!rtx_equal_p (operands[0], operands[1]))
20602     emit_move_insn (operands[0], operands[1]);
20605 (define_peephole2
20606   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20607                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20608                             (match_operand:SI 2 "const_int_operand" "")))
20609               (clobber (reg:CC FLAGS_REG))])
20610    (match_scratch:SI 3 "r")]
20611   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20612    && satisfies_constraint_K (operands[2])"
20613   [(set (match_dup 3) (match_dup 2))
20614    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20615               (clobber (reg:CC FLAGS_REG))])]
20617   if (!rtx_equal_p (operands[0], operands[1]))
20618     emit_move_insn (operands[0], operands[1]);
20621 (define_peephole2
20622   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20623                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20624                             (match_operand:HI 2 "immediate_operand" "")))
20625               (clobber (reg:CC FLAGS_REG))])
20626    (match_scratch:HI 3 "r")]
20627   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20628   [(set (match_dup 3) (match_dup 2))
20629    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20630               (clobber (reg:CC FLAGS_REG))])]
20632   if (!rtx_equal_p (operands[0], operands[1]))
20633     emit_move_insn (operands[0], operands[1]);
20636 ;; After splitting up read-modify operations, array accesses with memory
20637 ;; operands might end up in form:
20638 ;;  sall    $2, %eax
20639 ;;  movl    4(%esp), %edx
20640 ;;  addl    %edx, %eax
20641 ;; instead of pre-splitting:
20642 ;;  sall    $2, %eax
20643 ;;  addl    4(%esp), %eax
20644 ;; Turn it into:
20645 ;;  movl    4(%esp), %edx
20646 ;;  leal    (%edx,%eax,4), %eax
20648 (define_peephole2
20649   [(parallel [(set (match_operand 0 "register_operand" "")
20650                    (ashift (match_operand 1 "register_operand" "")
20651                            (match_operand 2 "const_int_operand" "")))
20652                (clobber (reg:CC FLAGS_REG))])
20653    (set (match_operand 3 "register_operand")
20654         (match_operand 4 "x86_64_general_operand" ""))
20655    (parallel [(set (match_operand 5 "register_operand" "")
20656                    (plus (match_operand 6 "register_operand" "")
20657                          (match_operand 7 "register_operand" "")))
20658                    (clobber (reg:CC FLAGS_REG))])]
20659   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20660    /* Validate MODE for lea.  */
20661    && ((!TARGET_PARTIAL_REG_STALL
20662         && (GET_MODE (operands[0]) == QImode
20663             || GET_MODE (operands[0]) == HImode))
20664        || GET_MODE (operands[0]) == SImode
20665        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20666    /* We reorder load and the shift.  */
20667    && !rtx_equal_p (operands[1], operands[3])
20668    && !reg_overlap_mentioned_p (operands[0], operands[4])
20669    /* Last PLUS must consist of operand 0 and 3.  */
20670    && !rtx_equal_p (operands[0], operands[3])
20671    && (rtx_equal_p (operands[3], operands[6])
20672        || rtx_equal_p (operands[3], operands[7]))
20673    && (rtx_equal_p (operands[0], operands[6])
20674        || rtx_equal_p (operands[0], operands[7]))
20675    /* The intermediate operand 0 must die or be same as output.  */
20676    && (rtx_equal_p (operands[0], operands[5])
20677        || peep2_reg_dead_p (3, operands[0]))"
20678   [(set (match_dup 3) (match_dup 4))
20679    (set (match_dup 0) (match_dup 1))]
20681   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20682   int scale = 1 << INTVAL (operands[2]);
20683   rtx index = gen_lowpart (Pmode, operands[1]);
20684   rtx base = gen_lowpart (Pmode, operands[3]);
20685   rtx dest = gen_lowpart (mode, operands[5]);
20687   operands[1] = gen_rtx_PLUS (Pmode, base,
20688                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20689   if (mode != Pmode)
20690     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20691   operands[0] = dest;
20694 ;; Call-value patterns last so that the wildcard operand does not
20695 ;; disrupt insn-recog's switch tables.
20697 (define_insn "*call_value_pop_0"
20698   [(set (match_operand 0 "" "")
20699         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20700               (match_operand:SI 2 "" "")))
20701    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20702                             (match_operand:SI 3 "immediate_operand" "")))]
20703   "!TARGET_64BIT"
20705   if (SIBLING_CALL_P (insn))
20706     return "jmp\t%P1";
20707   else
20708     return "call\t%P1";
20710   [(set_attr "type" "callv")])
20712 (define_insn "*call_value_pop_1"
20713   [(set (match_operand 0 "" "")
20714         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20715               (match_operand:SI 2 "" "")))
20716    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20717                             (match_operand:SI 3 "immediate_operand" "i")))]
20718   "!TARGET_64BIT"
20720   if (constant_call_address_operand (operands[1], Pmode))
20721     {
20722       if (SIBLING_CALL_P (insn))
20723         return "jmp\t%P1";
20724       else
20725         return "call\t%P1";
20726     }
20727   if (SIBLING_CALL_P (insn))
20728     return "jmp\t%A1";
20729   else
20730     return "call\t%A1";
20732   [(set_attr "type" "callv")])
20734 (define_insn "*call_value_0"
20735   [(set (match_operand 0 "" "")
20736         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20737               (match_operand:SI 2 "" "")))]
20738   "!TARGET_64BIT"
20740   if (SIBLING_CALL_P (insn))
20741     return "jmp\t%P1";
20742   else
20743     return "call\t%P1";
20745   [(set_attr "type" "callv")])
20747 (define_insn "*call_value_0_rex64"
20748   [(set (match_operand 0 "" "")
20749         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20750               (match_operand:DI 2 "const_int_operand" "")))]
20751   "TARGET_64BIT"
20753   if (SIBLING_CALL_P (insn))
20754     return "jmp\t%P1";
20755   else
20756     return "call\t%P1";
20758   [(set_attr "type" "callv")])
20760 (define_insn "*call_value_1"
20761   [(set (match_operand 0 "" "")
20762         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20763               (match_operand:SI 2 "" "")))]
20764   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20766   if (constant_call_address_operand (operands[1], Pmode))
20767     return "call\t%P1";
20768   return "call\t%A1";
20770   [(set_attr "type" "callv")])
20772 (define_insn "*sibcall_value_1"
20773   [(set (match_operand 0 "" "")
20774         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20775               (match_operand:SI 2 "" "")))]
20776   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20778   if (constant_call_address_operand (operands[1], Pmode))
20779     return "jmp\t%P1";
20780   return "jmp\t%A1";
20782   [(set_attr "type" "callv")])
20784 (define_insn "*call_value_1_rex64"
20785   [(set (match_operand 0 "" "")
20786         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20787               (match_operand:DI 2 "" "")))]
20788   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20790   if (constant_call_address_operand (operands[1], Pmode))
20791     return "call\t%P1";
20792   return "call\t%A1";
20794   [(set_attr "type" "callv")])
20796 (define_insn "*sibcall_value_1_rex64"
20797   [(set (match_operand 0 "" "")
20798         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20799               (match_operand:DI 2 "" "")))]
20800   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20801   "jmp\t%P1"
20802   [(set_attr "type" "callv")])
20804 (define_insn "*sibcall_value_1_rex64_v"
20805   [(set (match_operand 0 "" "")
20806         (call (mem:QI (reg:DI R11_REG))
20807               (match_operand:DI 1 "" "")))]
20808   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20809   "jmp\t*%%r11"
20810   [(set_attr "type" "callv")])
20812 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20813 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20814 ;; caught for use by garbage collectors and the like.  Using an insn that
20815 ;; maps to SIGILL makes it more likely the program will rightfully die.
20816 ;; Keeping with tradition, "6" is in honor of #UD.
20817 (define_insn "trap"
20818   [(trap_if (const_int 1) (const_int 6))]
20819   ""
20820   { return ASM_SHORT "0x0b0f"; }
20821   [(set_attr "length" "2")])
20823 (define_expand "sse_prologue_save"
20824   [(parallel [(set (match_operand:BLK 0 "" "")
20825                    (unspec:BLK [(reg:DI 22)
20826                                 (reg:DI 23)
20827                                 (reg:DI 24)
20828                                 (reg:DI 25)
20829                                 (reg:DI 26)
20830                                 (reg:DI 27)
20831                                 (reg:DI 28)
20832                                 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20833               (use (match_operand:DI 1 "register_operand" ""))
20834               (use (match_operand:DI 2 "immediate_operand" ""))
20835               (use (label_ref:DI (match_operand 3 "" "")))])]
20836   "TARGET_64BIT"
20837   "")
20839 (define_insn "*sse_prologue_save_insn"
20840   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20841                           (match_operand:DI 4 "const_int_operand" "n")))
20842         (unspec:BLK [(reg:DI 22)
20843                      (reg:DI 23)
20844                      (reg:DI 24)
20845                      (reg:DI 25)
20846                      (reg:DI 26)
20847                      (reg:DI 27)
20848                      (reg:DI 28)
20849                      (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20850    (use (match_operand:DI 1 "register_operand" "r"))
20851    (use (match_operand:DI 2 "const_int_operand" "i"))
20852    (use (label_ref:DI (match_operand 3 "" "X")))]
20853   "TARGET_64BIT
20854    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20855    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20856   "*
20858   int i;
20859   operands[0] = gen_rtx_MEM (Pmode,
20860                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20861   output_asm_insn (\"jmp\\t%A1\", operands);
20862   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20863     {
20864       operands[4] = adjust_address (operands[0], DImode, i*16);
20865       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20866       PUT_MODE (operands[4], TImode);
20867       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20868         output_asm_insn (\"rex\", operands);
20869       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20870     }
20871   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20872                              CODE_LABEL_NUMBER (operands[3]));
20873   RET;
20875   "
20876   [(set_attr "type" "other")
20877    (set_attr "length_immediate" "0")
20878    (set_attr "length_address" "0")
20879    (set_attr "length" "135")
20880    (set_attr "memory" "store")
20881    (set_attr "modrm" "0")
20882    (set_attr "mode" "DI")])
20884 (define_expand "prefetch"
20885   [(prefetch (match_operand 0 "address_operand" "")
20886              (match_operand:SI 1 "const_int_operand" "")
20887              (match_operand:SI 2 "const_int_operand" ""))]
20888   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20890   int rw = INTVAL (operands[1]);
20891   int locality = INTVAL (operands[2]);
20893   gcc_assert (rw == 0 || rw == 1);
20894   gcc_assert (locality >= 0 && locality <= 3);
20895   gcc_assert (GET_MODE (operands[0]) == Pmode
20896               || GET_MODE (operands[0]) == VOIDmode);
20898   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20899      supported by SSE counterpart or the SSE prefetch is not available
20900      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20901      of locality.  */
20902   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20903     operands[2] = GEN_INT (3);
20904   else
20905     operands[1] = const0_rtx;
20908 (define_insn "*prefetch_sse"
20909   [(prefetch (match_operand:SI 0 "address_operand" "p")
20910              (const_int 0)
20911              (match_operand:SI 1 "const_int_operand" ""))]
20912   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20914   static const char * const patterns[4] = {
20915    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20916   };
20918   int locality = INTVAL (operands[1]);
20919   gcc_assert (locality >= 0 && locality <= 3);
20921   return patterns[locality];
20923   [(set_attr "type" "sse")
20924    (set_attr "memory" "none")])
20926 (define_insn "*prefetch_sse_rex"
20927   [(prefetch (match_operand:DI 0 "address_operand" "p")
20928              (const_int 0)
20929              (match_operand:SI 1 "const_int_operand" ""))]
20930   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20932   static const char * const patterns[4] = {
20933    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20934   };
20936   int locality = INTVAL (operands[1]);
20937   gcc_assert (locality >= 0 && locality <= 3);
20939   return patterns[locality];
20941   [(set_attr "type" "sse")
20942    (set_attr "memory" "none")])
20944 (define_insn "*prefetch_3dnow"
20945   [(prefetch (match_operand:SI 0 "address_operand" "p")
20946              (match_operand:SI 1 "const_int_operand" "n")
20947              (const_int 3))]
20948   "TARGET_3DNOW && !TARGET_64BIT"
20950   if (INTVAL (operands[1]) == 0)
20951     return "prefetch\t%a0";
20952   else
20953     return "prefetchw\t%a0";
20955   [(set_attr "type" "mmx")
20956    (set_attr "memory" "none")])
20958 (define_insn "*prefetch_3dnow_rex"
20959   [(prefetch (match_operand:DI 0 "address_operand" "p")
20960              (match_operand:SI 1 "const_int_operand" "n")
20961              (const_int 3))]
20962   "TARGET_3DNOW && TARGET_64BIT"
20964   if (INTVAL (operands[1]) == 0)
20965     return "prefetch\t%a0";
20966   else
20967     return "prefetchw\t%a0";
20969   [(set_attr "type" "mmx")
20970    (set_attr "memory" "none")])
20972 (define_expand "stack_protect_set"
20973   [(match_operand 0 "memory_operand" "")
20974    (match_operand 1 "memory_operand" "")]
20975   ""
20977 #ifdef TARGET_THREAD_SSP_OFFSET
20978   if (TARGET_64BIT)
20979     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20980                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20981   else
20982     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20983                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20984 #else
20985   if (TARGET_64BIT)
20986     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20987   else
20988     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20989 #endif
20990   DONE;
20993 (define_insn "stack_protect_set_si"
20994   [(set (match_operand:SI 0 "memory_operand" "=m")
20995         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20996    (set (match_scratch:SI 2 "=&r") (const_int 0))
20997    (clobber (reg:CC FLAGS_REG))]
20998   ""
20999   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21000   [(set_attr "type" "multi")])
21002 (define_insn "stack_protect_set_di"
21003   [(set (match_operand:DI 0 "memory_operand" "=m")
21004         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21005    (set (match_scratch:DI 2 "=&r") (const_int 0))
21006    (clobber (reg:CC FLAGS_REG))]
21007   "TARGET_64BIT"
21008   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21009   [(set_attr "type" "multi")])
21011 (define_insn "stack_tls_protect_set_si"
21012   [(set (match_operand:SI 0 "memory_operand" "=m")
21013         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21014    (set (match_scratch:SI 2 "=&r") (const_int 0))
21015    (clobber (reg:CC FLAGS_REG))]
21016   ""
21017   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21018   [(set_attr "type" "multi")])
21020 (define_insn "stack_tls_protect_set_di"
21021   [(set (match_operand:DI 0 "memory_operand" "=m")
21022         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21023    (set (match_scratch:DI 2 "=&r") (const_int 0))
21024    (clobber (reg:CC FLAGS_REG))]
21025   "TARGET_64BIT"
21026   {
21027      /* The kernel uses a different segment register for performance reasons; a
21028         system call would not have to trash the userspace segment register,
21029         which would be expensive */
21030      if (ix86_cmodel != CM_KERNEL)
21031         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21032      else
21033         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21034   }
21035   [(set_attr "type" "multi")])
21037 (define_expand "stack_protect_test"
21038   [(match_operand 0 "memory_operand" "")
21039    (match_operand 1 "memory_operand" "")
21040    (match_operand 2 "" "")]
21041   ""
21043   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21044   ix86_compare_op0 = operands[0];
21045   ix86_compare_op1 = operands[1];
21046   ix86_compare_emitted = flags;
21048 #ifdef TARGET_THREAD_SSP_OFFSET
21049   if (TARGET_64BIT)
21050     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21051                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21052   else
21053     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21054                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21055 #else
21056   if (TARGET_64BIT)
21057     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21058   else
21059     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21060 #endif
21061   emit_jump_insn (gen_beq (operands[2]));
21062   DONE;
21065 (define_insn "stack_protect_test_si"
21066   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21067         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21068                      (match_operand:SI 2 "memory_operand" "m")]
21069                     UNSPEC_SP_TEST))
21070    (clobber (match_scratch:SI 3 "=&r"))]
21071   ""
21072   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21073   [(set_attr "type" "multi")])
21075 (define_insn "stack_protect_test_di"
21076   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21077         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21078                      (match_operand:DI 2 "memory_operand" "m")]
21079                     UNSPEC_SP_TEST))
21080    (clobber (match_scratch:DI 3 "=&r"))]
21081   "TARGET_64BIT"
21082   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21083   [(set_attr "type" "multi")])
21085 (define_insn "stack_tls_protect_test_si"
21086   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21087         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21088                      (match_operand:SI 2 "const_int_operand" "i")]
21089                     UNSPEC_SP_TLS_TEST))
21090    (clobber (match_scratch:SI 3 "=r"))]
21091   ""
21092   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21093   [(set_attr "type" "multi")])
21095 (define_insn "stack_tls_protect_test_di"
21096   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21097         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21098                      (match_operand:DI 2 "const_int_operand" "i")]
21099                     UNSPEC_SP_TLS_TEST))
21100    (clobber (match_scratch:DI 3 "=r"))]
21101   "TARGET_64BIT"
21102   {
21103      /* The kernel uses a different segment register for performance reasons; a
21104         system call would not have to trash the userspace segment register,
21105         which would be expensive */
21106      if (ix86_cmodel != CM_KERNEL)
21107         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21108      else
21109         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21110   }
21111   [(set_attr "type" "multi")])
21113 (include "mmx.md")
21114 (include "sse.md")
21115 (include "sync.md")