* config/i386/i386.md (R10_REG): New constant.
[official-gcc.git] / gcc / config / i386 / i386.md
bloba4be7e1ef2dce42752f0e66b20cb9a5af46d3756
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    (R10_REG                     40)
185    (R11_REG                     41)
186   ])
188 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
189 ;; from i386.c.
191 ;; In C guard expressions, put expressions which may be compile-time
192 ;; constants first.  This allows for better optimization.  For
193 ;; example, write "TARGET_64BIT && reload_completed", not
194 ;; "reload_completed && TARGET_64BIT".
197 ;; Processor type.  This attribute must exactly match the processor_type
198 ;; enumeration in i386.h.
199 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
200   (const (symbol_ref "ix86_tune")))
202 ;; A basic instruction type.  Refinements due to arguments to be
203 ;; provided in other attributes.
204 (define_attr "type"
205   "other,multi,
206    alu,alu1,negnot,imov,imovx,lea,
207    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
208    icmp,test,ibr,setcc,icmov,
209    push,pop,call,callv,leave,
210    str,cld,
211    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
212    sselog,sselog1,sseiadd,sseishft,sseimul,
213    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
214    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
215   (const_string "other"))
217 ;; Main data type used by the insn
218 (define_attr "mode"
219   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
220   (const_string "unknown"))
222 ;; The CPU unit operations uses.
223 (define_attr "unit" "integer,i387,sse,mmx,unknown"
224   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
225            (const_string "i387")
226          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
227                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
228            (const_string "sse")
229          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
230            (const_string "mmx")
231          (eq_attr "type" "other")
232            (const_string "unknown")]
233          (const_string "integer")))
235 ;; The (bounding maximum) length of an instruction immediate.
236 (define_attr "length_immediate" ""
237   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
238            (const_int 0)
239          (eq_attr "unit" "i387,sse,mmx")
240            (const_int 0)
241          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
242                           imul,icmp,push,pop")
243            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
244          (eq_attr "type" "imov,test")
245            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
246          (eq_attr "type" "call")
247            (if_then_else (match_operand 0 "constant_call_address_operand" "")
248              (const_int 4)
249              (const_int 0))
250          (eq_attr "type" "callv")
251            (if_then_else (match_operand 1 "constant_call_address_operand" "")
252              (const_int 4)
253              (const_int 0))
254          ;; We don't know the size before shorten_branches.  Expect
255          ;; the instruction to fit for better scheduling.
256          (eq_attr "type" "ibr")
257            (const_int 1)
258          ]
259          (symbol_ref "/* Update immediate_length and other attributes! */
260                       gcc_unreachable (),1")))
262 ;; The (bounding maximum) length of an instruction address.
263 (define_attr "length_address" ""
264   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
265            (const_int 0)
266          (and (eq_attr "type" "call")
267               (match_operand 0 "constant_call_address_operand" ""))
268              (const_int 0)
269          (and (eq_attr "type" "callv")
270               (match_operand 1 "constant_call_address_operand" ""))
271              (const_int 0)
272          ]
273          (symbol_ref "ix86_attr_length_address_default (insn)")))
275 ;; Set when length prefix is used.
276 (define_attr "prefix_data16" ""
277   (if_then_else (ior (eq_attr "mode" "HI")
278                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
279     (const_int 1)
280     (const_int 0)))
282 ;; Set when string REP prefix is used.
283 (define_attr "prefix_rep" ""
284   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
285     (const_int 1)
286     (const_int 0)))
288 ;; Set when 0f opcode prefix is used.
289 (define_attr "prefix_0f" ""
290   (if_then_else
291     (ior (eq_attr "type" "imovx,setcc,icmov")
292          (eq_attr "unit" "sse,mmx"))
293     (const_int 1)
294     (const_int 0)))
296 ;; Set when REX opcode prefix is used.
297 (define_attr "prefix_rex" ""
298   (cond [(and (eq_attr "mode" "DI")
299               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
300            (const_int 1)
301          (and (eq_attr "mode" "QI")
302               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
303                   (const_int 0)))
304            (const_int 1)
305          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
306              (const_int 0))
307            (const_int 1)
308         ]
309         (const_int 0)))
311 ;; Set when modrm byte is used.
312 (define_attr "modrm" ""
313   (cond [(eq_attr "type" "str,cld,leave")
314            (const_int 0)
315          (eq_attr "unit" "i387")
316            (const_int 0)
317          (and (eq_attr "type" "incdec")
318               (ior (match_operand:SI 1 "register_operand" "")
319                    (match_operand:HI 1 "register_operand" "")))
320            (const_int 0)
321          (and (eq_attr "type" "push")
322               (not (match_operand 1 "memory_operand" "")))
323            (const_int 0)
324          (and (eq_attr "type" "pop")
325               (not (match_operand 0 "memory_operand" "")))
326            (const_int 0)
327          (and (eq_attr "type" "imov")
328               (ior (and (match_operand 0 "register_operand" "")
329                         (match_operand 1 "immediate_operand" ""))
330                    (ior (and (match_operand 0 "ax_reg_operand" "")
331                              (match_operand 1 "memory_displacement_only_operand" ""))
332                         (and (match_operand 0 "memory_displacement_only_operand" "")
333                              (match_operand 1 "ax_reg_operand" "")))))
334            (const_int 0)
335          (and (eq_attr "type" "call")
336               (match_operand 0 "constant_call_address_operand" ""))
337              (const_int 0)
338          (and (eq_attr "type" "callv")
339               (match_operand 1 "constant_call_address_operand" ""))
340              (const_int 0)
341          ]
342          (const_int 1)))
344 ;; The (bounding maximum) length of an instruction in bytes.
345 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
346 ;; Later we may want to split them and compute proper length as for
347 ;; other insns.
348 (define_attr "length" ""
349   (cond [(eq_attr "type" "other,multi,fistp,frndint")
350            (const_int 16)
351          (eq_attr "type" "fcmp")
352            (const_int 4)
353          (eq_attr "unit" "i387")
354            (plus (const_int 2)
355                  (plus (attr "prefix_data16")
356                        (attr "length_address")))]
357          (plus (plus (attr "modrm")
358                      (plus (attr "prefix_0f")
359                            (plus (attr "prefix_rex")
360                                  (const_int 1))))
361                (plus (attr "prefix_rep")
362                      (plus (attr "prefix_data16")
363                            (plus (attr "length_immediate")
364                                  (attr "length_address")))))))
366 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
367 ;; `store' if there is a simple memory reference therein, or `unknown'
368 ;; if the instruction is complex.
370 (define_attr "memory" "none,load,store,both,unknown"
371   (cond [(eq_attr "type" "other,multi,str")
372            (const_string "unknown")
373          (eq_attr "type" "lea,fcmov,fpspc,cld")
374            (const_string "none")
375          (eq_attr "type" "fistp,leave")
376            (const_string "both")
377          (eq_attr "type" "frndint")
378            (const_string "load")
379          (eq_attr "type" "push")
380            (if_then_else (match_operand 1 "memory_operand" "")
381              (const_string "both")
382              (const_string "store"))
383          (eq_attr "type" "pop")
384            (if_then_else (match_operand 0 "memory_operand" "")
385              (const_string "both")
386              (const_string "load"))
387          (eq_attr "type" "setcc")
388            (if_then_else (match_operand 0 "memory_operand" "")
389              (const_string "store")
390              (const_string "none"))
391          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
392            (if_then_else (ior (match_operand 0 "memory_operand" "")
393                               (match_operand 1 "memory_operand" ""))
394              (const_string "load")
395              (const_string "none"))
396          (eq_attr "type" "ibr")
397            (if_then_else (match_operand 0 "memory_operand" "")
398              (const_string "load")
399              (const_string "none"))
400          (eq_attr "type" "call")
401            (if_then_else (match_operand 0 "constant_call_address_operand" "")
402              (const_string "none")
403              (const_string "load"))
404          (eq_attr "type" "callv")
405            (if_then_else (match_operand 1 "constant_call_address_operand" "")
406              (const_string "none")
407              (const_string "load"))
408          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
409               (match_operand 1 "memory_operand" ""))
410            (const_string "both")
411          (and (match_operand 0 "memory_operand" "")
412               (match_operand 1 "memory_operand" ""))
413            (const_string "both")
414          (match_operand 0 "memory_operand" "")
415            (const_string "store")
416          (match_operand 1 "memory_operand" "")
417            (const_string "load")
418          (and (eq_attr "type"
419                  "!alu1,negnot,ishift1,
420                    imov,imovx,icmp,test,
421                    fmov,fcmp,fsgn,
422                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
423                    mmx,mmxmov,mmxcmp,mmxcvt")
424               (match_operand 2 "memory_operand" ""))
425            (const_string "load")
426          (and (eq_attr "type" "icmov")
427               (match_operand 3 "memory_operand" ""))
428            (const_string "load")
429         ]
430         (const_string "none")))
432 ;; Indicates if an instruction has both an immediate and a displacement.
434 (define_attr "imm_disp" "false,true,unknown"
435   (cond [(eq_attr "type" "other,multi")
436            (const_string "unknown")
437          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
438               (and (match_operand 0 "memory_displacement_operand" "")
439                    (match_operand 1 "immediate_operand" "")))
440            (const_string "true")
441          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
442               (and (match_operand 0 "memory_displacement_operand" "")
443                    (match_operand 2 "immediate_operand" "")))
444            (const_string "true")
445         ]
446         (const_string "false")))
448 ;; Indicates if an FP operation has an integer source.
450 (define_attr "fp_int_src" "false,true"
451   (const_string "false"))
453 ;; Defines rounding mode of an FP operation.
455 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
456   (const_string "any"))
458 ;; Describe a user's asm statement.
459 (define_asm_attributes
460   [(set_attr "length" "128")
461    (set_attr "type" "multi")])
463 ;; All x87 floating point modes
464 (define_mode_macro X87MODEF [SF DF XF])
466 ;; x87 SFmode and DFMode floating point modes
467 (define_mode_macro X87MODEF12 [SF DF])
469 ;; All integer modes handled by x87 fisttp operator.
470 (define_mode_macro X87MODEI [HI SI DI])
472 ;; All integer modes handled by integer x87 operators.
473 (define_mode_macro X87MODEI12 [HI SI])
475 ;; All SSE floating point modes
476 (define_mode_macro SSEMODEF [SF DF])
478 ;; All integer modes handled by SSE cvtts?2si* operators.
479 (define_mode_macro SSEMODEI24 [SI DI])
481 ;; SSE asm suffix for floating point modes
482 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
485 ;; Scheduling descriptions
487 (include "pentium.md")
488 (include "ppro.md")
489 (include "k6.md")
490 (include "athlon.md")
491 (include "geode.md")
494 ;; Operand and operator predicates and constraints
496 (include "predicates.md")
497 (include "constraints.md")
500 ;; Compare instructions.
502 ;; All compare insns have expanders that save the operands away without
503 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
504 ;; after the cmp) will actually emit the cmpM.
506 (define_expand "cmpti"
507   [(set (reg:CC FLAGS_REG)
508         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
509                     (match_operand:TI 1 "x86_64_general_operand" "")))]
510   "TARGET_64BIT"
512   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
513     operands[0] = force_reg (TImode, operands[0]);
514   ix86_compare_op0 = operands[0];
515   ix86_compare_op1 = operands[1];
516   DONE;
519 (define_expand "cmpdi"
520   [(set (reg:CC FLAGS_REG)
521         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
522                     (match_operand:DI 1 "x86_64_general_operand" "")))]
523   ""
525   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
526     operands[0] = force_reg (DImode, operands[0]);
527   ix86_compare_op0 = operands[0];
528   ix86_compare_op1 = operands[1];
529   DONE;
532 (define_expand "cmpsi"
533   [(set (reg:CC FLAGS_REG)
534         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
535                     (match_operand:SI 1 "general_operand" "")))]
536   ""
538   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
539     operands[0] = force_reg (SImode, operands[0]);
540   ix86_compare_op0 = operands[0];
541   ix86_compare_op1 = operands[1];
542   DONE;
545 (define_expand "cmphi"
546   [(set (reg:CC FLAGS_REG)
547         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
548                     (match_operand:HI 1 "general_operand" "")))]
549   ""
551   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
552     operands[0] = force_reg (HImode, operands[0]);
553   ix86_compare_op0 = operands[0];
554   ix86_compare_op1 = operands[1];
555   DONE;
558 (define_expand "cmpqi"
559   [(set (reg:CC FLAGS_REG)
560         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
561                     (match_operand:QI 1 "general_operand" "")))]
562   "TARGET_QIMODE_MATH"
564   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
565     operands[0] = force_reg (QImode, operands[0]);
566   ix86_compare_op0 = operands[0];
567   ix86_compare_op1 = operands[1];
568   DONE;
571 (define_insn "cmpdi_ccno_1_rex64"
572   [(set (reg FLAGS_REG)
573         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
574                  (match_operand:DI 1 "const0_operand" "n,n")))]
575   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
576   "@
577    test{q}\t{%0, %0|%0, %0}
578    cmp{q}\t{%1, %0|%0, %1}"
579   [(set_attr "type" "test,icmp")
580    (set_attr "length_immediate" "0,1")
581    (set_attr "mode" "DI")])
583 (define_insn "*cmpdi_minus_1_rex64"
584   [(set (reg FLAGS_REG)
585         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
586                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
587                  (const_int 0)))]
588   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
589   "cmp{q}\t{%1, %0|%0, %1}"
590   [(set_attr "type" "icmp")
591    (set_attr "mode" "DI")])
593 (define_expand "cmpdi_1_rex64"
594   [(set (reg:CC FLAGS_REG)
595         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
596                     (match_operand:DI 1 "general_operand" "")))]
597   "TARGET_64BIT"
598   "")
600 (define_insn "cmpdi_1_insn_rex64"
601   [(set (reg FLAGS_REG)
602         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
603                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
604   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
605   "cmp{q}\t{%1, %0|%0, %1}"
606   [(set_attr "type" "icmp")
607    (set_attr "mode" "DI")])
610 (define_insn "*cmpsi_ccno_1"
611   [(set (reg FLAGS_REG)
612         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
613                  (match_operand:SI 1 "const0_operand" "n,n")))]
614   "ix86_match_ccmode (insn, CCNOmode)"
615   "@
616    test{l}\t{%0, %0|%0, %0}
617    cmp{l}\t{%1, %0|%0, %1}"
618   [(set_attr "type" "test,icmp")
619    (set_attr "length_immediate" "0,1")
620    (set_attr "mode" "SI")])
622 (define_insn "*cmpsi_minus_1"
623   [(set (reg FLAGS_REG)
624         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625                            (match_operand:SI 1 "general_operand" "ri,mr"))
626                  (const_int 0)))]
627   "ix86_match_ccmode (insn, CCGOCmode)"
628   "cmp{l}\t{%1, %0|%0, %1}"
629   [(set_attr "type" "icmp")
630    (set_attr "mode" "SI")])
632 (define_expand "cmpsi_1"
633   [(set (reg:CC FLAGS_REG)
634         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
635                     (match_operand:SI 1 "general_operand" "ri,mr")))]
636   ""
637   "")
639 (define_insn "*cmpsi_1_insn"
640   [(set (reg FLAGS_REG)
641         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642                  (match_operand:SI 1 "general_operand" "ri,mr")))]
643   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
644     && ix86_match_ccmode (insn, CCmode)"
645   "cmp{l}\t{%1, %0|%0, %1}"
646   [(set_attr "type" "icmp")
647    (set_attr "mode" "SI")])
649 (define_insn "*cmphi_ccno_1"
650   [(set (reg FLAGS_REG)
651         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
652                  (match_operand:HI 1 "const0_operand" "n,n")))]
653   "ix86_match_ccmode (insn, CCNOmode)"
654   "@
655    test{w}\t{%0, %0|%0, %0}
656    cmp{w}\t{%1, %0|%0, %1}"
657   [(set_attr "type" "test,icmp")
658    (set_attr "length_immediate" "0,1")
659    (set_attr "mode" "HI")])
661 (define_insn "*cmphi_minus_1"
662   [(set (reg FLAGS_REG)
663         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
664                            (match_operand:HI 1 "general_operand" "ri,mr"))
665                  (const_int 0)))]
666   "ix86_match_ccmode (insn, CCGOCmode)"
667   "cmp{w}\t{%1, %0|%0, %1}"
668   [(set_attr "type" "icmp")
669    (set_attr "mode" "HI")])
671 (define_insn "*cmphi_1"
672   [(set (reg FLAGS_REG)
673         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
674                  (match_operand:HI 1 "general_operand" "ri,mr")))]
675   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
676    && ix86_match_ccmode (insn, CCmode)"
677   "cmp{w}\t{%1, %0|%0, %1}"
678   [(set_attr "type" "icmp")
679    (set_attr "mode" "HI")])
681 (define_insn "*cmpqi_ccno_1"
682   [(set (reg FLAGS_REG)
683         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
684                  (match_operand:QI 1 "const0_operand" "n,n")))]
685   "ix86_match_ccmode (insn, CCNOmode)"
686   "@
687    test{b}\t{%0, %0|%0, %0}
688    cmp{b}\t{$0, %0|%0, 0}"
689   [(set_attr "type" "test,icmp")
690    (set_attr "length_immediate" "0,1")
691    (set_attr "mode" "QI")])
693 (define_insn "*cmpqi_1"
694   [(set (reg FLAGS_REG)
695         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
696                  (match_operand:QI 1 "general_operand" "qi,mq")))]
697   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
698     && ix86_match_ccmode (insn, CCmode)"
699   "cmp{b}\t{%1, %0|%0, %1}"
700   [(set_attr "type" "icmp")
701    (set_attr "mode" "QI")])
703 (define_insn "*cmpqi_minus_1"
704   [(set (reg FLAGS_REG)
705         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
706                            (match_operand:QI 1 "general_operand" "qi,mq"))
707                  (const_int 0)))]
708   "ix86_match_ccmode (insn, CCGOCmode)"
709   "cmp{b}\t{%1, %0|%0, %1}"
710   [(set_attr "type" "icmp")
711    (set_attr "mode" "QI")])
713 (define_insn "*cmpqi_ext_1"
714   [(set (reg FLAGS_REG)
715         (compare
716           (match_operand:QI 0 "general_operand" "Qm")
717           (subreg:QI
718             (zero_extract:SI
719               (match_operand 1 "ext_register_operand" "Q")
720               (const_int 8)
721               (const_int 8)) 0)))]
722   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
723   "cmp{b}\t{%h1, %0|%0, %h1}"
724   [(set_attr "type" "icmp")
725    (set_attr "mode" "QI")])
727 (define_insn "*cmpqi_ext_1_rex64"
728   [(set (reg FLAGS_REG)
729         (compare
730           (match_operand:QI 0 "register_operand" "Q")
731           (subreg:QI
732             (zero_extract:SI
733               (match_operand 1 "ext_register_operand" "Q")
734               (const_int 8)
735               (const_int 8)) 0)))]
736   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
737   "cmp{b}\t{%h1, %0|%0, %h1}"
738   [(set_attr "type" "icmp")
739    (set_attr "mode" "QI")])
741 (define_insn "*cmpqi_ext_2"
742   [(set (reg FLAGS_REG)
743         (compare
744           (subreg:QI
745             (zero_extract:SI
746               (match_operand 0 "ext_register_operand" "Q")
747               (const_int 8)
748               (const_int 8)) 0)
749           (match_operand:QI 1 "const0_operand" "n")))]
750   "ix86_match_ccmode (insn, CCNOmode)"
751   "test{b}\t%h0, %h0"
752   [(set_attr "type" "test")
753    (set_attr "length_immediate" "0")
754    (set_attr "mode" "QI")])
756 (define_expand "cmpqi_ext_3"
757   [(set (reg:CC FLAGS_REG)
758         (compare:CC
759           (subreg:QI
760             (zero_extract:SI
761               (match_operand 0 "ext_register_operand" "")
762               (const_int 8)
763               (const_int 8)) 0)
764           (match_operand:QI 1 "general_operand" "")))]
765   ""
766   "")
768 (define_insn "cmpqi_ext_3_insn"
769   [(set (reg FLAGS_REG)
770         (compare
771           (subreg:QI
772             (zero_extract:SI
773               (match_operand 0 "ext_register_operand" "Q")
774               (const_int 8)
775               (const_int 8)) 0)
776           (match_operand:QI 1 "general_operand" "Qmn")))]
777   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
778   "cmp{b}\t{%1, %h0|%h0, %1}"
779   [(set_attr "type" "icmp")
780    (set_attr "mode" "QI")])
782 (define_insn "cmpqi_ext_3_insn_rex64"
783   [(set (reg FLAGS_REG)
784         (compare
785           (subreg:QI
786             (zero_extract:SI
787               (match_operand 0 "ext_register_operand" "Q")
788               (const_int 8)
789               (const_int 8)) 0)
790           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
791   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
792   "cmp{b}\t{%1, %h0|%h0, %1}"
793   [(set_attr "type" "icmp")
794    (set_attr "mode" "QI")])
796 (define_insn "*cmpqi_ext_4"
797   [(set (reg FLAGS_REG)
798         (compare
799           (subreg:QI
800             (zero_extract:SI
801               (match_operand 0 "ext_register_operand" "Q")
802               (const_int 8)
803               (const_int 8)) 0)
804           (subreg:QI
805             (zero_extract:SI
806               (match_operand 1 "ext_register_operand" "Q")
807               (const_int 8)
808               (const_int 8)) 0)))]
809   "ix86_match_ccmode (insn, CCmode)"
810   "cmp{b}\t{%h1, %h0|%h0, %h1}"
811   [(set_attr "type" "icmp")
812    (set_attr "mode" "QI")])
814 ;; These implement float point compares.
815 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
816 ;; which would allow mix and match FP modes on the compares.  Which is what
817 ;; the old patterns did, but with many more of them.
819 (define_expand "cmpxf"
820   [(set (reg:CC FLAGS_REG)
821         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
822                     (match_operand:XF 1 "nonmemory_operand" "")))]
823   "TARGET_80387"
825   ix86_compare_op0 = operands[0];
826   ix86_compare_op1 = operands[1];
827   DONE;
830 (define_expand "cmpdf"
831   [(set (reg:CC FLAGS_REG)
832         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
833                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
834   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
836   ix86_compare_op0 = operands[0];
837   ix86_compare_op1 = operands[1];
838   DONE;
841 (define_expand "cmpsf"
842   [(set (reg:CC FLAGS_REG)
843         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
844                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
845   "TARGET_80387 || TARGET_SSE_MATH"
847   ix86_compare_op0 = operands[0];
848   ix86_compare_op1 = operands[1];
849   DONE;
852 ;; FP compares, step 1:
853 ;; Set the FP condition codes.
855 ;; CCFPmode     compare with exceptions
856 ;; CCFPUmode    compare with no exceptions
858 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
859 ;; used to manage the reg stack popping would not be preserved.
861 (define_insn "*cmpfp_0"
862   [(set (match_operand:HI 0 "register_operand" "=a")
863         (unspec:HI
864           [(compare:CCFP
865              (match_operand 1 "register_operand" "f")
866              (match_operand 2 "const0_operand" "X"))]
867         UNSPEC_FNSTSW))]
868   "TARGET_80387
869    && FLOAT_MODE_P (GET_MODE (operands[1]))
870    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "unit" "i387")
874    (set (attr "mode")
875      (cond [(match_operand:SF 1 "" "")
876               (const_string "SF")
877             (match_operand:DF 1 "" "")
878               (const_string "DF")
879            ]
880            (const_string "XF")))])
882 (define_insn "*cmpfp_sf"
883   [(set (match_operand:HI 0 "register_operand" "=a")
884         (unspec:HI
885           [(compare:CCFP
886              (match_operand:SF 1 "register_operand" "f")
887              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
888           UNSPEC_FNSTSW))]
889   "TARGET_80387"
890   "* return output_fp_compare (insn, operands, 0, 0);"
891   [(set_attr "type" "multi")
892    (set_attr "unit" "i387")
893    (set_attr "mode" "SF")])
895 (define_insn "*cmpfp_df"
896   [(set (match_operand:HI 0 "register_operand" "=a")
897         (unspec:HI
898           [(compare:CCFP
899              (match_operand:DF 1 "register_operand" "f")
900              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
901           UNSPEC_FNSTSW))]
902   "TARGET_80387"
903   "* return output_fp_compare (insn, operands, 0, 0);"
904   [(set_attr "type" "multi")
905    (set_attr "unit" "i387")
906    (set_attr "mode" "DF")])
908 (define_insn "*cmpfp_xf"
909   [(set (match_operand:HI 0 "register_operand" "=a")
910         (unspec:HI
911           [(compare:CCFP
912              (match_operand:XF 1 "register_operand" "f")
913              (match_operand:XF 2 "register_operand" "f"))]
914           UNSPEC_FNSTSW))]
915   "TARGET_80387"
916   "* return output_fp_compare (insn, operands, 0, 0);"
917   [(set_attr "type" "multi")
918    (set_attr "unit" "i387")
919    (set_attr "mode" "XF")])
921 (define_insn "*cmpfp_u"
922   [(set (match_operand:HI 0 "register_operand" "=a")
923         (unspec:HI
924           [(compare:CCFPU
925              (match_operand 1 "register_operand" "f")
926              (match_operand 2 "register_operand" "f"))]
927           UNSPEC_FNSTSW))]
928   "TARGET_80387
929    && FLOAT_MODE_P (GET_MODE (operands[1]))
930    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
931   "* return output_fp_compare (insn, operands, 0, 1);"
932   [(set_attr "type" "multi")
933    (set_attr "unit" "i387")
934    (set (attr "mode")
935      (cond [(match_operand:SF 1 "" "")
936               (const_string "SF")
937             (match_operand:DF 1 "" "")
938               (const_string "DF")
939            ]
940            (const_string "XF")))])
942 (define_insn "*cmpfp_<mode>"
943   [(set (match_operand:HI 0 "register_operand" "=a")
944         (unspec:HI
945           [(compare:CCFP
946              (match_operand 1 "register_operand" "f")
947              (match_operator 3 "float_operator"
948                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
949           UNSPEC_FNSTSW))]
950   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
951    && FLOAT_MODE_P (GET_MODE (operands[1]))
952    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
953   "* return output_fp_compare (insn, operands, 0, 0);"
954   [(set_attr "type" "multi")
955    (set_attr "unit" "i387")
956    (set_attr "fp_int_src" "true")
957    (set_attr "mode" "<MODE>")])
959 ;; FP compares, step 2
960 ;; Move the fpsw to ax.
962 (define_insn "x86_fnstsw_1"
963   [(set (match_operand:HI 0 "register_operand" "=a")
964         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
965   "TARGET_80387"
966   "fnstsw\t%0"
967   [(set_attr "length" "2")
968    (set_attr "mode" "SI")
969    (set_attr "unit" "i387")])
971 ;; FP compares, step 3
972 ;; Get ax into flags, general case.
974 (define_insn "x86_sahf_1"
975   [(set (reg:CC FLAGS_REG)
976         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
977   "!TARGET_64BIT"
978   "sahf"
979   [(set_attr "length" "1")
980    (set_attr "athlon_decode" "vector")
981    (set_attr "mode" "SI")])
983 ;; Pentium Pro can do steps 1 through 3 in one go.
985 (define_insn "*cmpfp_i_mixed"
986   [(set (reg:CCFP FLAGS_REG)
987         (compare:CCFP (match_operand 0 "register_operand" "f,x")
988                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
989   "TARGET_MIX_SSE_I387
990    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
992   "* return output_fp_compare (insn, operands, 1, 0);"
993   [(set_attr "type" "fcmp,ssecomi")
994    (set (attr "mode")
995      (if_then_else (match_operand:SF 1 "" "")
996         (const_string "SF")
997         (const_string "DF")))
998    (set_attr "athlon_decode" "vector")])
1000 (define_insn "*cmpfp_i_sse"
1001   [(set (reg:CCFP FLAGS_REG)
1002         (compare:CCFP (match_operand 0 "register_operand" "x")
1003                       (match_operand 1 "nonimmediate_operand" "xm")))]
1004   "TARGET_SSE_MATH
1005    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1006    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007   "* return output_fp_compare (insn, operands, 1, 0);"
1008   [(set_attr "type" "ssecomi")
1009    (set (attr "mode")
1010      (if_then_else (match_operand:SF 1 "" "")
1011         (const_string "SF")
1012         (const_string "DF")))
1013    (set_attr "athlon_decode" "vector")])
1015 (define_insn "*cmpfp_i_i387"
1016   [(set (reg:CCFP FLAGS_REG)
1017         (compare:CCFP (match_operand 0 "register_operand" "f")
1018                       (match_operand 1 "register_operand" "f")))]
1019   "TARGET_80387 && TARGET_CMOVE
1020    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1021    && FLOAT_MODE_P (GET_MODE (operands[0]))
1022    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1023   "* return output_fp_compare (insn, operands, 1, 0);"
1024   [(set_attr "type" "fcmp")
1025    (set (attr "mode")
1026      (cond [(match_operand:SF 1 "" "")
1027               (const_string "SF")
1028             (match_operand:DF 1 "" "")
1029               (const_string "DF")
1030            ]
1031            (const_string "XF")))
1032    (set_attr "athlon_decode" "vector")])
1034 (define_insn "*cmpfp_iu_mixed"
1035   [(set (reg:CCFPU FLAGS_REG)
1036         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1037                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1038   "TARGET_MIX_SSE_I387
1039    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1040    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1041   "* return output_fp_compare (insn, operands, 1, 1);"
1042   [(set_attr "type" "fcmp,ssecomi")
1043    (set (attr "mode")
1044      (if_then_else (match_operand:SF 1 "" "")
1045         (const_string "SF")
1046         (const_string "DF")))
1047    (set_attr "athlon_decode" "vector")])
1049 (define_insn "*cmpfp_iu_sse"
1050   [(set (reg:CCFPU FLAGS_REG)
1051         (compare:CCFPU (match_operand 0 "register_operand" "x")
1052                        (match_operand 1 "nonimmediate_operand" "xm")))]
1053   "TARGET_SSE_MATH
1054    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1055    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1056   "* return output_fp_compare (insn, operands, 1, 1);"
1057   [(set_attr "type" "ssecomi")
1058    (set (attr "mode")
1059      (if_then_else (match_operand:SF 1 "" "")
1060         (const_string "SF")
1061         (const_string "DF")))
1062    (set_attr "athlon_decode" "vector")])
1064 (define_insn "*cmpfp_iu_387"
1065   [(set (reg:CCFPU FLAGS_REG)
1066         (compare:CCFPU (match_operand 0 "register_operand" "f")
1067                        (match_operand 1 "register_operand" "f")))]
1068   "TARGET_80387 && TARGET_CMOVE
1069    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1070    && FLOAT_MODE_P (GET_MODE (operands[0]))
1071    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1072   "* return output_fp_compare (insn, operands, 1, 1);"
1073   [(set_attr "type" "fcmp")
1074    (set (attr "mode")
1075      (cond [(match_operand:SF 1 "" "")
1076               (const_string "SF")
1077             (match_operand:DF 1 "" "")
1078               (const_string "DF")
1079            ]
1080            (const_string "XF")))
1081    (set_attr "athlon_decode" "vector")])
1083 ;; Move instructions.
1085 ;; General case of fullword move.
1087 (define_expand "movsi"
1088   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1089         (match_operand:SI 1 "general_operand" ""))]
1090   ""
1091   "ix86_expand_move (SImode, operands); DONE;")
1093 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1094 ;; general_operand.
1096 ;; %%% We don't use a post-inc memory reference because x86 is not a
1097 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1098 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1099 ;; targets without our curiosities, and it is just as easy to represent
1100 ;; this differently.
1102 (define_insn "*pushsi2"
1103   [(set (match_operand:SI 0 "push_operand" "=<")
1104         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1105   "!TARGET_64BIT"
1106   "push{l}\t%1"
1107   [(set_attr "type" "push")
1108    (set_attr "mode" "SI")])
1110 ;; For 64BIT abi we always round up to 8 bytes.
1111 (define_insn "*pushsi2_rex64"
1112   [(set (match_operand:SI 0 "push_operand" "=X")
1113         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1114   "TARGET_64BIT"
1115   "push{q}\t%q1"
1116   [(set_attr "type" "push")
1117    (set_attr "mode" "SI")])
1119 (define_insn "*pushsi2_prologue"
1120   [(set (match_operand:SI 0 "push_operand" "=<")
1121         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1122    (clobber (mem:BLK (scratch)))]
1123   "!TARGET_64BIT"
1124   "push{l}\t%1"
1125   [(set_attr "type" "push")
1126    (set_attr "mode" "SI")])
1128 (define_insn "*popsi1_epilogue"
1129   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1130         (mem:SI (reg:SI SP_REG)))
1131    (set (reg:SI SP_REG)
1132         (plus:SI (reg:SI SP_REG) (const_int 4)))
1133    (clobber (mem:BLK (scratch)))]
1134   "!TARGET_64BIT"
1135   "pop{l}\t%0"
1136   [(set_attr "type" "pop")
1137    (set_attr "mode" "SI")])
1139 (define_insn "popsi1"
1140   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1141         (mem:SI (reg:SI SP_REG)))
1142    (set (reg:SI SP_REG)
1143         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1144   "!TARGET_64BIT"
1145   "pop{l}\t%0"
1146   [(set_attr "type" "pop")
1147    (set_attr "mode" "SI")])
1149 (define_insn "*movsi_xor"
1150   [(set (match_operand:SI 0 "register_operand" "=r")
1151         (match_operand:SI 1 "const0_operand" "i"))
1152    (clobber (reg:CC FLAGS_REG))]
1153   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1154   "xor{l}\t{%0, %0|%0, %0}"
1155   [(set_attr "type" "alu1")
1156    (set_attr "mode" "SI")
1157    (set_attr "length_immediate" "0")])
1159 (define_insn "*movsi_or"
1160   [(set (match_operand:SI 0 "register_operand" "=r")
1161         (match_operand:SI 1 "immediate_operand" "i"))
1162    (clobber (reg:CC FLAGS_REG))]
1163   "reload_completed
1164    && operands[1] == constm1_rtx
1165    && (TARGET_PENTIUM || optimize_size)"
1167   operands[1] = constm1_rtx;
1168   return "or{l}\t{%1, %0|%0, %1}";
1170   [(set_attr "type" "alu1")
1171    (set_attr "mode" "SI")
1172    (set_attr "length_immediate" "1")])
1174 (define_insn "*movsi_1"
1175   [(set (match_operand:SI 0 "nonimmediate_operand"
1176                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1177         (match_operand:SI 1 "general_operand"
1178                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1179   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1181   switch (get_attr_type (insn))
1182     {
1183     case TYPE_SSELOG1:
1184       if (get_attr_mode (insn) == MODE_TI)
1185         return "pxor\t%0, %0";
1186       return "xorps\t%0, %0";
1188     case TYPE_SSEMOV:
1189       switch (get_attr_mode (insn))
1190         {
1191         case MODE_TI:
1192           return "movdqa\t{%1, %0|%0, %1}";
1193         case MODE_V4SF:
1194           return "movaps\t{%1, %0|%0, %1}";
1195         case MODE_SI:
1196           return "movd\t{%1, %0|%0, %1}";
1197         case MODE_SF:
1198           return "movss\t{%1, %0|%0, %1}";
1199         default:
1200           gcc_unreachable ();
1201         }
1203     case TYPE_MMXADD:
1204       return "pxor\t%0, %0";
1206     case TYPE_MMXMOV:
1207       if (get_attr_mode (insn) == MODE_DI)
1208         return "movq\t{%1, %0|%0, %1}";
1209       return "movd\t{%1, %0|%0, %1}";
1211     case TYPE_LEA:
1212       return "lea{l}\t{%1, %0|%0, %1}";
1214     default:
1215       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1216       return "mov{l}\t{%1, %0|%0, %1}";
1217     }
1219   [(set (attr "type")
1220      (cond [(eq_attr "alternative" "2")
1221               (const_string "mmxadd")
1222             (eq_attr "alternative" "3,4,5")
1223               (const_string "mmxmov")
1224             (eq_attr "alternative" "6")
1225               (const_string "sselog1")
1226             (eq_attr "alternative" "7,8,9,10,11")
1227               (const_string "ssemov")
1228             (match_operand:DI 1 "pic_32bit_operand" "")
1229               (const_string "lea")
1230            ]
1231            (const_string "imov")))
1232    (set (attr "mode")
1233      (cond [(eq_attr "alternative" "2,3")
1234               (const_string "DI")
1235             (eq_attr "alternative" "6,7")
1236               (if_then_else
1237                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1238                 (const_string "V4SF")
1239                 (const_string "TI"))
1240             (and (eq_attr "alternative" "8,9,10,11")
1241                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1242               (const_string "SF")
1243            ]
1244            (const_string "SI")))])
1246 ;; Stores and loads of ax to arbitrary constant address.
1247 ;; We fake an second form of instruction to force reload to load address
1248 ;; into register when rax is not available
1249 (define_insn "*movabssi_1_rex64"
1250   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1251         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1252   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1253   "@
1254    movabs{l}\t{%1, %P0|%P0, %1}
1255    mov{l}\t{%1, %a0|%a0, %1}"
1256   [(set_attr "type" "imov")
1257    (set_attr "modrm" "0,*")
1258    (set_attr "length_address" "8,0")
1259    (set_attr "length_immediate" "0,*")
1260    (set_attr "memory" "store")
1261    (set_attr "mode" "SI")])
1263 (define_insn "*movabssi_2_rex64"
1264   [(set (match_operand:SI 0 "register_operand" "=a,r")
1265         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1266   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1267   "@
1268    movabs{l}\t{%P1, %0|%0, %P1}
1269    mov{l}\t{%a1, %0|%0, %a1}"
1270   [(set_attr "type" "imov")
1271    (set_attr "modrm" "0,*")
1272    (set_attr "length_address" "8,0")
1273    (set_attr "length_immediate" "0")
1274    (set_attr "memory" "load")
1275    (set_attr "mode" "SI")])
1277 (define_insn "*swapsi"
1278   [(set (match_operand:SI 0 "register_operand" "+r")
1279         (match_operand:SI 1 "register_operand" "+r"))
1280    (set (match_dup 1)
1281         (match_dup 0))]
1282   ""
1283   "xchg{l}\t%1, %0"
1284   [(set_attr "type" "imov")
1285    (set_attr "mode" "SI")
1286    (set_attr "pent_pair" "np")
1287    (set_attr "athlon_decode" "vector")])
1289 (define_expand "movhi"
1290   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1291         (match_operand:HI 1 "general_operand" ""))]
1292   ""
1293   "ix86_expand_move (HImode, operands); DONE;")
1295 (define_insn "*pushhi2"
1296   [(set (match_operand:HI 0 "push_operand" "=X")
1297         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1298   "!TARGET_64BIT"
1299   "push{l}\t%k1"
1300   [(set_attr "type" "push")
1301    (set_attr "mode" "SI")])
1303 ;; For 64BIT abi we always round up to 8 bytes.
1304 (define_insn "*pushhi2_rex64"
1305   [(set (match_operand:HI 0 "push_operand" "=X")
1306         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1307   "TARGET_64BIT"
1308   "push{q}\t%q1"
1309   [(set_attr "type" "push")
1310    (set_attr "mode" "DI")])
1312 (define_insn "*movhi_1"
1313   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1314         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1315   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1317   switch (get_attr_type (insn))
1318     {
1319     case TYPE_IMOVX:
1320       /* movzwl is faster than movw on p2 due to partial word stalls,
1321          though not as fast as an aligned movl.  */
1322       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1323     default:
1324       if (get_attr_mode (insn) == MODE_SI)
1325         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1326       else
1327         return "mov{w}\t{%1, %0|%0, %1}";
1328     }
1330   [(set (attr "type")
1331      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1332               (const_string "imov")
1333             (and (eq_attr "alternative" "0")
1334                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1335                           (const_int 0))
1336                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1337                           (const_int 0))))
1338               (const_string "imov")
1339             (and (eq_attr "alternative" "1,2")
1340                  (match_operand:HI 1 "aligned_operand" ""))
1341               (const_string "imov")
1342             (and (ne (symbol_ref "TARGET_MOVX")
1343                      (const_int 0))
1344                  (eq_attr "alternative" "0,2"))
1345               (const_string "imovx")
1346            ]
1347            (const_string "imov")))
1348     (set (attr "mode")
1349       (cond [(eq_attr "type" "imovx")
1350                (const_string "SI")
1351              (and (eq_attr "alternative" "1,2")
1352                   (match_operand:HI 1 "aligned_operand" ""))
1353                (const_string "SI")
1354              (and (eq_attr "alternative" "0")
1355                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1356                            (const_int 0))
1357                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1358                            (const_int 0))))
1359                (const_string "SI")
1360             ]
1361             (const_string "HI")))])
1363 ;; Stores and loads of ax to arbitrary constant address.
1364 ;; We fake an second form of instruction to force reload to load address
1365 ;; into register when rax is not available
1366 (define_insn "*movabshi_1_rex64"
1367   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1368         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1369   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1370   "@
1371    movabs{w}\t{%1, %P0|%P0, %1}
1372    mov{w}\t{%1, %a0|%a0, %1}"
1373   [(set_attr "type" "imov")
1374    (set_attr "modrm" "0,*")
1375    (set_attr "length_address" "8,0")
1376    (set_attr "length_immediate" "0,*")
1377    (set_attr "memory" "store")
1378    (set_attr "mode" "HI")])
1380 (define_insn "*movabshi_2_rex64"
1381   [(set (match_operand:HI 0 "register_operand" "=a,r")
1382         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1383   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1384   "@
1385    movabs{w}\t{%P1, %0|%0, %P1}
1386    mov{w}\t{%a1, %0|%0, %a1}"
1387   [(set_attr "type" "imov")
1388    (set_attr "modrm" "0,*")
1389    (set_attr "length_address" "8,0")
1390    (set_attr "length_immediate" "0")
1391    (set_attr "memory" "load")
1392    (set_attr "mode" "HI")])
1394 (define_insn "*swaphi_1"
1395   [(set (match_operand:HI 0 "register_operand" "+r")
1396         (match_operand:HI 1 "register_operand" "+r"))
1397    (set (match_dup 1)
1398         (match_dup 0))]
1399   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1400   "xchg{l}\t%k1, %k0"
1401   [(set_attr "type" "imov")
1402    (set_attr "mode" "SI")
1403    (set_attr "pent_pair" "np")
1404    (set_attr "athlon_decode" "vector")])
1406 (define_insn "*swaphi_2"
1407   [(set (match_operand:HI 0 "register_operand" "+r")
1408         (match_operand:HI 1 "register_operand" "+r"))
1409    (set (match_dup 1)
1410         (match_dup 0))]
1411   "TARGET_PARTIAL_REG_STALL"
1412   "xchg{w}\t%1, %0"
1413   [(set_attr "type" "imov")
1414    (set_attr "mode" "HI")
1415    (set_attr "pent_pair" "np")
1416    (set_attr "athlon_decode" "vector")])
1418 (define_expand "movstricthi"
1419   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1420         (match_operand:HI 1 "general_operand" ""))]
1421   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1423   /* Don't generate memory->memory moves, go through a register */
1424   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1425     operands[1] = force_reg (HImode, operands[1]);
1428 (define_insn "*movstricthi_1"
1429   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1430         (match_operand:HI 1 "general_operand" "rn,m"))]
1431   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1432    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1433   "mov{w}\t{%1, %0|%0, %1}"
1434   [(set_attr "type" "imov")
1435    (set_attr "mode" "HI")])
1437 (define_insn "*movstricthi_xor"
1438   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1439         (match_operand:HI 1 "const0_operand" "i"))
1440    (clobber (reg:CC FLAGS_REG))]
1441   "reload_completed
1442    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1443   "xor{w}\t{%0, %0|%0, %0}"
1444   [(set_attr "type" "alu1")
1445    (set_attr "mode" "HI")
1446    (set_attr "length_immediate" "0")])
1448 (define_expand "movqi"
1449   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1450         (match_operand:QI 1 "general_operand" ""))]
1451   ""
1452   "ix86_expand_move (QImode, operands); DONE;")
1454 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1455 ;; "push a byte".  But actually we use pushl, which has the effect
1456 ;; of rounding the amount pushed up to a word.
1458 (define_insn "*pushqi2"
1459   [(set (match_operand:QI 0 "push_operand" "=X")
1460         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1461   "!TARGET_64BIT"
1462   "push{l}\t%k1"
1463   [(set_attr "type" "push")
1464    (set_attr "mode" "SI")])
1466 ;; For 64BIT abi we always round up to 8 bytes.
1467 (define_insn "*pushqi2_rex64"
1468   [(set (match_operand:QI 0 "push_operand" "=X")
1469         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1470   "TARGET_64BIT"
1471   "push{q}\t%q1"
1472   [(set_attr "type" "push")
1473    (set_attr "mode" "DI")])
1475 ;; Situation is quite tricky about when to choose full sized (SImode) move
1476 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1477 ;; partial register dependency machines (such as AMD Athlon), where QImode
1478 ;; moves issue extra dependency and for partial register stalls machines
1479 ;; that don't use QImode patterns (and QImode move cause stall on the next
1480 ;; instruction).
1482 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1483 ;; register stall machines with, where we use QImode instructions, since
1484 ;; partial register stall can be caused there.  Then we use movzx.
1485 (define_insn "*movqi_1"
1486   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1487         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1488   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1490   switch (get_attr_type (insn))
1491     {
1492     case TYPE_IMOVX:
1493       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1494       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1495     default:
1496       if (get_attr_mode (insn) == MODE_SI)
1497         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1498       else
1499         return "mov{b}\t{%1, %0|%0, %1}";
1500     }
1502   [(set (attr "type")
1503      (cond [(and (eq_attr "alternative" "5")
1504                  (not (match_operand:QI 1 "aligned_operand" "")))
1505               (const_string "imovx")
1506             (ne (symbol_ref "optimize_size") (const_int 0))
1507               (const_string "imov")
1508             (and (eq_attr "alternative" "3")
1509                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1510                           (const_int 0))
1511                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1512                           (const_int 0))))
1513               (const_string "imov")
1514             (eq_attr "alternative" "3,5")
1515               (const_string "imovx")
1516             (and (ne (symbol_ref "TARGET_MOVX")
1517                      (const_int 0))
1518                  (eq_attr "alternative" "2"))
1519               (const_string "imovx")
1520            ]
1521            (const_string "imov")))
1522    (set (attr "mode")
1523       (cond [(eq_attr "alternative" "3,4,5")
1524                (const_string "SI")
1525              (eq_attr "alternative" "6")
1526                (const_string "QI")
1527              (eq_attr "type" "imovx")
1528                (const_string "SI")
1529              (and (eq_attr "type" "imov")
1530                   (and (eq_attr "alternative" "0,1")
1531                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1532                                 (const_int 0))
1533                             (and (eq (symbol_ref "optimize_size")
1534                                      (const_int 0))
1535                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1536                                      (const_int 0))))))
1537                (const_string "SI")
1538              ;; Avoid partial register stalls when not using QImode arithmetic
1539              (and (eq_attr "type" "imov")
1540                   (and (eq_attr "alternative" "0,1")
1541                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1542                                 (const_int 0))
1543                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1544                                 (const_int 0)))))
1545                (const_string "SI")
1546            ]
1547            (const_string "QI")))])
1549 (define_expand "reload_outqi"
1550   [(parallel [(match_operand:QI 0 "" "=m")
1551               (match_operand:QI 1 "register_operand" "r")
1552               (match_operand:QI 2 "register_operand" "=&q")])]
1553   ""
1555   rtx op0, op1, op2;
1556   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1558   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1559   if (! q_regs_operand (op1, QImode))
1560     {
1561       emit_insn (gen_movqi (op2, op1));
1562       op1 = op2;
1563     }
1564   emit_insn (gen_movqi (op0, op1));
1565   DONE;
1568 (define_insn "*swapqi_1"
1569   [(set (match_operand:QI 0 "register_operand" "+r")
1570         (match_operand:QI 1 "register_operand" "+r"))
1571    (set (match_dup 1)
1572         (match_dup 0))]
1573   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1574   "xchg{l}\t%k1, %k0"
1575   [(set_attr "type" "imov")
1576    (set_attr "mode" "SI")
1577    (set_attr "pent_pair" "np")
1578    (set_attr "athlon_decode" "vector")])
1580 (define_insn "*swapqi_2"
1581   [(set (match_operand:QI 0 "register_operand" "+q")
1582         (match_operand:QI 1 "register_operand" "+q"))
1583    (set (match_dup 1)
1584         (match_dup 0))]
1585   "TARGET_PARTIAL_REG_STALL"
1586   "xchg{b}\t%1, %0"
1587   [(set_attr "type" "imov")
1588    (set_attr "mode" "QI")
1589    (set_attr "pent_pair" "np")
1590    (set_attr "athlon_decode" "vector")])
1592 (define_expand "movstrictqi"
1593   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1594         (match_operand:QI 1 "general_operand" ""))]
1595   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1597   /* Don't generate memory->memory moves, go through a register.  */
1598   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1599     operands[1] = force_reg (QImode, operands[1]);
1602 (define_insn "*movstrictqi_1"
1603   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1604         (match_operand:QI 1 "general_operand" "*qn,m"))]
1605   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1606    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1607   "mov{b}\t{%1, %0|%0, %1}"
1608   [(set_attr "type" "imov")
1609    (set_attr "mode" "QI")])
1611 (define_insn "*movstrictqi_xor"
1612   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1613         (match_operand:QI 1 "const0_operand" "i"))
1614    (clobber (reg:CC FLAGS_REG))]
1615   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1616   "xor{b}\t{%0, %0|%0, %0}"
1617   [(set_attr "type" "alu1")
1618    (set_attr "mode" "QI")
1619    (set_attr "length_immediate" "0")])
1621 (define_insn "*movsi_extv_1"
1622   [(set (match_operand:SI 0 "register_operand" "=R")
1623         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1624                          (const_int 8)
1625                          (const_int 8)))]
1626   ""
1627   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1628   [(set_attr "type" "imovx")
1629    (set_attr "mode" "SI")])
1631 (define_insn "*movhi_extv_1"
1632   [(set (match_operand:HI 0 "register_operand" "=R")
1633         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1634                          (const_int 8)
1635                          (const_int 8)))]
1636   ""
1637   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1638   [(set_attr "type" "imovx")
1639    (set_attr "mode" "SI")])
1641 (define_insn "*movqi_extv_1"
1642   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1643         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1644                          (const_int 8)
1645                          (const_int 8)))]
1646   "!TARGET_64BIT"
1648   switch (get_attr_type (insn))
1649     {
1650     case TYPE_IMOVX:
1651       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1652     default:
1653       return "mov{b}\t{%h1, %0|%0, %h1}";
1654     }
1656   [(set (attr "type")
1657      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1658                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1659                              (ne (symbol_ref "TARGET_MOVX")
1660                                  (const_int 0))))
1661         (const_string "imovx")
1662         (const_string "imov")))
1663    (set (attr "mode")
1664      (if_then_else (eq_attr "type" "imovx")
1665         (const_string "SI")
1666         (const_string "QI")))])
1668 (define_insn "*movqi_extv_1_rex64"
1669   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1670         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1671                          (const_int 8)
1672                          (const_int 8)))]
1673   "TARGET_64BIT"
1675   switch (get_attr_type (insn))
1676     {
1677     case TYPE_IMOVX:
1678       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1679     default:
1680       return "mov{b}\t{%h1, %0|%0, %h1}";
1681     }
1683   [(set (attr "type")
1684      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1685                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1686                              (ne (symbol_ref "TARGET_MOVX")
1687                                  (const_int 0))))
1688         (const_string "imovx")
1689         (const_string "imov")))
1690    (set (attr "mode")
1691      (if_then_else (eq_attr "type" "imovx")
1692         (const_string "SI")
1693         (const_string "QI")))])
1695 ;; Stores and loads of ax to arbitrary constant address.
1696 ;; We fake an second form of instruction to force reload to load address
1697 ;; into register when rax is not available
1698 (define_insn "*movabsqi_1_rex64"
1699   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1700         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1701   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1702   "@
1703    movabs{b}\t{%1, %P0|%P0, %1}
1704    mov{b}\t{%1, %a0|%a0, %1}"
1705   [(set_attr "type" "imov")
1706    (set_attr "modrm" "0,*")
1707    (set_attr "length_address" "8,0")
1708    (set_attr "length_immediate" "0,*")
1709    (set_attr "memory" "store")
1710    (set_attr "mode" "QI")])
1712 (define_insn "*movabsqi_2_rex64"
1713   [(set (match_operand:QI 0 "register_operand" "=a,r")
1714         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1715   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1716   "@
1717    movabs{b}\t{%P1, %0|%0, %P1}
1718    mov{b}\t{%a1, %0|%0, %a1}"
1719   [(set_attr "type" "imov")
1720    (set_attr "modrm" "0,*")
1721    (set_attr "length_address" "8,0")
1722    (set_attr "length_immediate" "0")
1723    (set_attr "memory" "load")
1724    (set_attr "mode" "QI")])
1726 (define_insn "*movdi_extzv_1"
1727   [(set (match_operand:DI 0 "register_operand" "=R")
1728         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1729                          (const_int 8)
1730                          (const_int 8)))]
1731   "TARGET_64BIT"
1732   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1733   [(set_attr "type" "imovx")
1734    (set_attr "mode" "DI")])
1736 (define_insn "*movsi_extzv_1"
1737   [(set (match_operand:SI 0 "register_operand" "=R")
1738         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1739                          (const_int 8)
1740                          (const_int 8)))]
1741   ""
1742   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1743   [(set_attr "type" "imovx")
1744    (set_attr "mode" "SI")])
1746 (define_insn "*movqi_extzv_2"
1747   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1748         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1749                                     (const_int 8)
1750                                     (const_int 8)) 0))]
1751   "!TARGET_64BIT"
1753   switch (get_attr_type (insn))
1754     {
1755     case TYPE_IMOVX:
1756       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1757     default:
1758       return "mov{b}\t{%h1, %0|%0, %h1}";
1759     }
1761   [(set (attr "type")
1762      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1763                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1764                              (ne (symbol_ref "TARGET_MOVX")
1765                                  (const_int 0))))
1766         (const_string "imovx")
1767         (const_string "imov")))
1768    (set (attr "mode")
1769      (if_then_else (eq_attr "type" "imovx")
1770         (const_string "SI")
1771         (const_string "QI")))])
1773 (define_insn "*movqi_extzv_2_rex64"
1774   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1775         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1776                                     (const_int 8)
1777                                     (const_int 8)) 0))]
1778   "TARGET_64BIT"
1780   switch (get_attr_type (insn))
1781     {
1782     case TYPE_IMOVX:
1783       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1784     default:
1785       return "mov{b}\t{%h1, %0|%0, %h1}";
1786     }
1788   [(set (attr "type")
1789      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1790                         (ne (symbol_ref "TARGET_MOVX")
1791                             (const_int 0)))
1792         (const_string "imovx")
1793         (const_string "imov")))
1794    (set (attr "mode")
1795      (if_then_else (eq_attr "type" "imovx")
1796         (const_string "SI")
1797         (const_string "QI")))])
1799 (define_insn "movsi_insv_1"
1800   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1801                          (const_int 8)
1802                          (const_int 8))
1803         (match_operand:SI 1 "general_operand" "Qmn"))]
1804   "!TARGET_64BIT"
1805   "mov{b}\t{%b1, %h0|%h0, %b1}"
1806   [(set_attr "type" "imov")
1807    (set_attr "mode" "QI")])
1809 (define_insn "*movsi_insv_1_rex64"
1810   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1811                          (const_int 8)
1812                          (const_int 8))
1813         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1814   "TARGET_64BIT"
1815   "mov{b}\t{%b1, %h0|%h0, %b1}"
1816   [(set_attr "type" "imov")
1817    (set_attr "mode" "QI")])
1819 (define_insn "movdi_insv_1_rex64"
1820   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1821                          (const_int 8)
1822                          (const_int 8))
1823         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1824   "TARGET_64BIT"
1825   "mov{b}\t{%b1, %h0|%h0, %b1}"
1826   [(set_attr "type" "imov")
1827    (set_attr "mode" "QI")])
1829 (define_insn "*movqi_insv_2"
1830   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1831                          (const_int 8)
1832                          (const_int 8))
1833         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1834                      (const_int 8)))]
1835   ""
1836   "mov{b}\t{%h1, %h0|%h0, %h1}"
1837   [(set_attr "type" "imov")
1838    (set_attr "mode" "QI")])
1840 (define_expand "movdi"
1841   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1842         (match_operand:DI 1 "general_operand" ""))]
1843   ""
1844   "ix86_expand_move (DImode, operands); DONE;")
1846 (define_insn "*pushdi"
1847   [(set (match_operand:DI 0 "push_operand" "=<")
1848         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1849   "!TARGET_64BIT"
1850   "#")
1852 (define_insn "*pushdi2_rex64"
1853   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1854         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1855   "TARGET_64BIT"
1856   "@
1857    push{q}\t%1
1858    #"
1859   [(set_attr "type" "push,multi")
1860    (set_attr "mode" "DI")])
1862 ;; Convert impossible pushes of immediate to existing instructions.
1863 ;; First try to get scratch register and go through it.  In case this
1864 ;; fails, push sign extended lower part first and then overwrite
1865 ;; upper part by 32bit move.
1866 (define_peephole2
1867   [(match_scratch:DI 2 "r")
1868    (set (match_operand:DI 0 "push_operand" "")
1869         (match_operand:DI 1 "immediate_operand" ""))]
1870   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1871    && !x86_64_immediate_operand (operands[1], DImode)"
1872   [(set (match_dup 2) (match_dup 1))
1873    (set (match_dup 0) (match_dup 2))]
1874   "")
1876 ;; We need to define this as both peepholer and splitter for case
1877 ;; peephole2 pass is not run.
1878 ;; "&& 1" is needed to keep it from matching the previous pattern.
1879 (define_peephole2
1880   [(set (match_operand:DI 0 "push_operand" "")
1881         (match_operand:DI 1 "immediate_operand" ""))]
1882   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1883    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1884   [(set (match_dup 0) (match_dup 1))
1885    (set (match_dup 2) (match_dup 3))]
1886   "split_di (operands + 1, 1, operands + 2, operands + 3);
1887    operands[1] = gen_lowpart (DImode, operands[2]);
1888    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1889                                                     GEN_INT (4)));
1890   ")
1892 (define_split
1893   [(set (match_operand:DI 0 "push_operand" "")
1894         (match_operand:DI 1 "immediate_operand" ""))]
1895   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1896                     ? flow2_completed : reload_completed)
1897    && !symbolic_operand (operands[1], DImode)
1898    && !x86_64_immediate_operand (operands[1], DImode)"
1899   [(set (match_dup 0) (match_dup 1))
1900    (set (match_dup 2) (match_dup 3))]
1901   "split_di (operands + 1, 1, operands + 2, operands + 3);
1902    operands[1] = gen_lowpart (DImode, operands[2]);
1903    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1904                                                     GEN_INT (4)));
1905   ")
1907 (define_insn "*pushdi2_prologue_rex64"
1908   [(set (match_operand:DI 0 "push_operand" "=<")
1909         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1910    (clobber (mem:BLK (scratch)))]
1911   "TARGET_64BIT"
1912   "push{q}\t%1"
1913   [(set_attr "type" "push")
1914    (set_attr "mode" "DI")])
1916 (define_insn "*popdi1_epilogue_rex64"
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    (clobber (mem:BLK (scratch)))]
1922   "TARGET_64BIT"
1923   "pop{q}\t%0"
1924   [(set_attr "type" "pop")
1925    (set_attr "mode" "DI")])
1927 (define_insn "popdi1"
1928   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1929         (mem:DI (reg:DI SP_REG)))
1930    (set (reg:DI SP_REG)
1931         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1932   "TARGET_64BIT"
1933   "pop{q}\t%0"
1934   [(set_attr "type" "pop")
1935    (set_attr "mode" "DI")])
1937 (define_insn "*movdi_xor_rex64"
1938   [(set (match_operand:DI 0 "register_operand" "=r")
1939         (match_operand:DI 1 "const0_operand" "i"))
1940    (clobber (reg:CC FLAGS_REG))]
1941   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1942    && reload_completed"
1943   "xor{l}\t{%k0, %k0|%k0, %k0}"
1944   [(set_attr "type" "alu1")
1945    (set_attr "mode" "SI")
1946    (set_attr "length_immediate" "0")])
1948 (define_insn "*movdi_or_rex64"
1949   [(set (match_operand:DI 0 "register_operand" "=r")
1950         (match_operand:DI 1 "const_int_operand" "i"))
1951    (clobber (reg:CC FLAGS_REG))]
1952   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1953    && reload_completed
1954    && operands[1] == constm1_rtx"
1956   operands[1] = constm1_rtx;
1957   return "or{q}\t{%1, %0|%0, %1}";
1959   [(set_attr "type" "alu1")
1960    (set_attr "mode" "DI")
1961    (set_attr "length_immediate" "1")])
1963 (define_insn "*movdi_2"
1964   [(set (match_operand:DI 0 "nonimmediate_operand"
1965                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1966         (match_operand:DI 1 "general_operand"
1967                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1968   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1969   "@
1970    #
1971    #
1972    pxor\t%0, %0
1973    movq\t{%1, %0|%0, %1}
1974    movq\t{%1, %0|%0, %1}
1975    pxor\t%0, %0
1976    movq\t{%1, %0|%0, %1}
1977    movdqa\t{%1, %0|%0, %1}
1978    movq\t{%1, %0|%0, %1}
1979    xorps\t%0, %0
1980    movlps\t{%1, %0|%0, %1}
1981    movaps\t{%1, %0|%0, %1}
1982    movlps\t{%1, %0|%0, %1}"
1983   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1984    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1986 (define_split
1987   [(set (match_operand:DI 0 "push_operand" "")
1988         (match_operand:DI 1 "general_operand" ""))]
1989   "!TARGET_64BIT && reload_completed
1990    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1991   [(const_int 0)]
1992   "ix86_split_long_move (operands); DONE;")
1994 ;; %%% This multiword shite has got to go.
1995 (define_split
1996   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1997         (match_operand:DI 1 "general_operand" ""))]
1998   "!TARGET_64BIT && reload_completed
1999    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2000    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2001   [(const_int 0)]
2002   "ix86_split_long_move (operands); DONE;")
2004 (define_insn "*movdi_1_rex64"
2005   [(set (match_operand:DI 0 "nonimmediate_operand"
2006                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2007         (match_operand:DI 1 "general_operand"
2008                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2009   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2011   switch (get_attr_type (insn))
2012     {
2013     case TYPE_SSECVT:
2014       if (which_alternative == 13)
2015         return "movq2dq\t{%1, %0|%0, %1}";
2016       else
2017         return "movdq2q\t{%1, %0|%0, %1}";
2018     case TYPE_SSEMOV:
2019       if (get_attr_mode (insn) == MODE_TI)
2020           return "movdqa\t{%1, %0|%0, %1}";
2021       /* FALLTHRU */
2022     case TYPE_MMXMOV:
2023       /* Moves from and into integer register is done using movd opcode with
2024          REX prefix.  */
2025       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2026           return "movd\t{%1, %0|%0, %1}";
2027       return "movq\t{%1, %0|%0, %1}";
2028     case TYPE_SSELOG1:
2029     case TYPE_MMXADD:
2030       return "pxor\t%0, %0";
2031     case TYPE_MULTI:
2032       return "#";
2033     case TYPE_LEA:
2034       return "lea{q}\t{%a1, %0|%0, %a1}";
2035     default:
2036       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2037       if (get_attr_mode (insn) == MODE_SI)
2038         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2039       else if (which_alternative == 2)
2040         return "movabs{q}\t{%1, %0|%0, %1}";
2041       else
2042         return "mov{q}\t{%1, %0|%0, %1}";
2043     }
2045   [(set (attr "type")
2046      (cond [(eq_attr "alternative" "5")
2047               (const_string "mmxadd")
2048             (eq_attr "alternative" "6,7,8")
2049               (const_string "mmxmov")
2050             (eq_attr "alternative" "9")
2051               (const_string "sselog1")
2052             (eq_attr "alternative" "10,11,12")
2053               (const_string "ssemov")
2054             (eq_attr "alternative" "13,14")
2055               (const_string "ssecvt")
2056             (eq_attr "alternative" "4")
2057               (const_string "multi")
2058             (match_operand:DI 1 "pic_32bit_operand" "")
2059               (const_string "lea")
2060            ]
2061            (const_string "imov")))
2062    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2063    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2064    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2066 ;; Stores and loads of ax to arbitrary constant address.
2067 ;; We fake an second form of instruction to force reload to load address
2068 ;; into register when rax is not available
2069 (define_insn "*movabsdi_1_rex64"
2070   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2071         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2072   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2073   "@
2074    movabs{q}\t{%1, %P0|%P0, %1}
2075    mov{q}\t{%1, %a0|%a0, %1}"
2076   [(set_attr "type" "imov")
2077    (set_attr "modrm" "0,*")
2078    (set_attr "length_address" "8,0")
2079    (set_attr "length_immediate" "0,*")
2080    (set_attr "memory" "store")
2081    (set_attr "mode" "DI")])
2083 (define_insn "*movabsdi_2_rex64"
2084   [(set (match_operand:DI 0 "register_operand" "=a,r")
2085         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2086   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2087   "@
2088    movabs{q}\t{%P1, %0|%0, %P1}
2089    mov{q}\t{%a1, %0|%0, %a1}"
2090   [(set_attr "type" "imov")
2091    (set_attr "modrm" "0,*")
2092    (set_attr "length_address" "8,0")
2093    (set_attr "length_immediate" "0")
2094    (set_attr "memory" "load")
2095    (set_attr "mode" "DI")])
2097 ;; Convert impossible stores of immediate to existing instructions.
2098 ;; First try to get scratch register and go through it.  In case this
2099 ;; fails, move by 32bit parts.
2100 (define_peephole2
2101   [(match_scratch:DI 2 "r")
2102    (set (match_operand:DI 0 "memory_operand" "")
2103         (match_operand:DI 1 "immediate_operand" ""))]
2104   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2105    && !x86_64_immediate_operand (operands[1], DImode)"
2106   [(set (match_dup 2) (match_dup 1))
2107    (set (match_dup 0) (match_dup 2))]
2108   "")
2110 ;; We need to define this as both peepholer and splitter for case
2111 ;; peephole2 pass is not run.
2112 ;; "&& 1" is needed to keep it from matching the previous pattern.
2113 (define_peephole2
2114   [(set (match_operand:DI 0 "memory_operand" "")
2115         (match_operand:DI 1 "immediate_operand" ""))]
2116   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2117    && !x86_64_immediate_operand (operands[1], DImode) && 1"
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_split
2123   [(set (match_operand:DI 0 "memory_operand" "")
2124         (match_operand:DI 1 "immediate_operand" ""))]
2125   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2126                     ? flow2_completed : reload_completed)
2127    && !symbolic_operand (operands[1], DImode)
2128    && !x86_64_immediate_operand (operands[1], DImode)"
2129   [(set (match_dup 2) (match_dup 3))
2130    (set (match_dup 4) (match_dup 5))]
2131   "split_di (operands, 2, operands + 2, operands + 4);")
2133 (define_insn "*swapdi_rex64"
2134   [(set (match_operand:DI 0 "register_operand" "+r")
2135         (match_operand:DI 1 "register_operand" "+r"))
2136    (set (match_dup 1)
2137         (match_dup 0))]
2138   "TARGET_64BIT"
2139   "xchg{q}\t%1, %0"
2140   [(set_attr "type" "imov")
2141    (set_attr "mode" "DI")
2142    (set_attr "pent_pair" "np")
2143    (set_attr "athlon_decode" "vector")])
2145 (define_expand "movti"
2146   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2147         (match_operand:TI 1 "nonimmediate_operand" ""))]
2148   "TARGET_SSE || TARGET_64BIT"
2150   if (TARGET_64BIT)
2151     ix86_expand_move (TImode, operands);
2152   else
2153     ix86_expand_vector_move (TImode, operands);
2154   DONE;
2157 (define_insn "*movti_internal"
2158   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2159         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2160   "TARGET_SSE && !TARGET_64BIT
2161    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2163   switch (which_alternative)
2164     {
2165     case 0:
2166       if (get_attr_mode (insn) == MODE_V4SF)
2167         return "xorps\t%0, %0";
2168       else
2169         return "pxor\t%0, %0";
2170     case 1:
2171     case 2:
2172       if (get_attr_mode (insn) == MODE_V4SF)
2173         return "movaps\t{%1, %0|%0, %1}";
2174       else
2175         return "movdqa\t{%1, %0|%0, %1}";
2176     default:
2177       gcc_unreachable ();
2178     }
2180   [(set_attr "type" "sselog1,ssemov,ssemov")
2181    (set (attr "mode")
2182         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2183                     (ne (symbol_ref "optimize_size") (const_int 0)))
2184                  (const_string "V4SF")
2185                (and (eq_attr "alternative" "2")
2186                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2187                         (const_int 0)))
2188                  (const_string "V4SF")]
2189               (const_string "TI")))])
2191 (define_insn "*movti_rex64"
2192   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2193         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2194   "TARGET_64BIT
2195    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2197   switch (which_alternative)
2198     {
2199     case 0:
2200     case 1:
2201       return "#";
2202     case 2:
2203       if (get_attr_mode (insn) == MODE_V4SF)
2204         return "xorps\t%0, %0";
2205       else
2206         return "pxor\t%0, %0";
2207     case 3:
2208     case 4:
2209       if (get_attr_mode (insn) == MODE_V4SF)
2210         return "movaps\t{%1, %0|%0, %1}";
2211       else
2212         return "movdqa\t{%1, %0|%0, %1}";
2213     default:
2214       gcc_unreachable ();
2215     }
2217   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2218    (set (attr "mode")
2219         (cond [(eq_attr "alternative" "2,3")
2220                  (if_then_else
2221                    (ne (symbol_ref "optimize_size")
2222                        (const_int 0))
2223                    (const_string "V4SF")
2224                    (const_string "TI"))
2225                (eq_attr "alternative" "4")
2226                  (if_then_else
2227                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2228                             (const_int 0))
2229                         (ne (symbol_ref "optimize_size")
2230                             (const_int 0)))
2231                    (const_string "V4SF")
2232                    (const_string "TI"))]
2233                (const_string "DI")))])
2235 (define_split
2236   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2237         (match_operand:TI 1 "general_operand" ""))]
2238   "reload_completed && !SSE_REG_P (operands[0])
2239    && !SSE_REG_P (operands[1])"
2240   [(const_int 0)]
2241   "ix86_split_long_move (operands); DONE;")
2243 (define_expand "movsf"
2244   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2245         (match_operand:SF 1 "general_operand" ""))]
2246   ""
2247   "ix86_expand_move (SFmode, operands); DONE;")
2249 (define_insn "*pushsf"
2250   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2251         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2252   "!TARGET_64BIT"
2254   /* Anything else should be already split before reg-stack.  */
2255   gcc_assert (which_alternative == 1);
2256   return "push{l}\t%1";
2258   [(set_attr "type" "multi,push,multi")
2259    (set_attr "unit" "i387,*,*")
2260    (set_attr "mode" "SF,SI,SF")])
2262 (define_insn "*pushsf_rex64"
2263   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2264         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2265   "TARGET_64BIT"
2267   /* Anything else should be already split before reg-stack.  */
2268   gcc_assert (which_alternative == 1);
2269   return "push{q}\t%q1";
2271   [(set_attr "type" "multi,push,multi")
2272    (set_attr "unit" "i387,*,*")
2273    (set_attr "mode" "SF,DI,SF")])
2275 (define_split
2276   [(set (match_operand:SF 0 "push_operand" "")
2277         (match_operand:SF 1 "memory_operand" ""))]
2278   "reload_completed
2279    && GET_CODE (operands[1]) == MEM
2280    && constant_pool_reference_p (operands[1])"
2281   [(set (match_dup 0)
2282         (match_dup 1))]
2283   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2286 ;; %%% Kill this when call knows how to work this out.
2287 (define_split
2288   [(set (match_operand:SF 0 "push_operand" "")
2289         (match_operand:SF 1 "any_fp_register_operand" ""))]
2290   "!TARGET_64BIT"
2291   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2292    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2294 (define_split
2295   [(set (match_operand:SF 0 "push_operand" "")
2296         (match_operand:SF 1 "any_fp_register_operand" ""))]
2297   "TARGET_64BIT"
2298   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2299    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2301 (define_insn "*movsf_1"
2302   [(set (match_operand:SF 0 "nonimmediate_operand"
2303           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2304         (match_operand:SF 1 "general_operand"
2305           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2306   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2307    && (reload_in_progress || reload_completed
2308        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2309        || (!TARGET_SSE_MATH && optimize_size
2310            && standard_80387_constant_p (operands[1]))
2311        || GET_CODE (operands[1]) != CONST_DOUBLE
2312        || memory_operand (operands[0], SFmode))"
2314   switch (which_alternative)
2315     {
2316     case 0:
2317       return output_387_reg_move (insn, operands);
2319     case 1:
2320       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2321         return "fstp%z0\t%y0";
2322       else
2323         return "fst%z0\t%y0";
2325     case 2:
2326       return standard_80387_constant_opcode (operands[1]);
2328     case 3:
2329     case 4:
2330       return "mov{l}\t{%1, %0|%0, %1}";
2331     case 5:
2332       if (get_attr_mode (insn) == MODE_TI)
2333         return "pxor\t%0, %0";
2334       else
2335         return "xorps\t%0, %0";
2336     case 6:
2337       if (get_attr_mode (insn) == MODE_V4SF)
2338         return "movaps\t{%1, %0|%0, %1}";
2339       else
2340         return "movss\t{%1, %0|%0, %1}";
2341     case 7:
2342     case 8:
2343       return "movss\t{%1, %0|%0, %1}";
2345     case 9:
2346     case 10:
2347       return "movd\t{%1, %0|%0, %1}";
2349     case 11:
2350       return "movq\t{%1, %0|%0, %1}";
2352     default:
2353       gcc_unreachable ();
2354     }
2356   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2357    (set (attr "mode")
2358         (cond [(eq_attr "alternative" "3,4,9,10")
2359                  (const_string "SI")
2360                (eq_attr "alternative" "5")
2361                  (if_then_else
2362                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2363                                  (const_int 0))
2364                              (ne (symbol_ref "TARGET_SSE2")
2365                                  (const_int 0)))
2366                         (eq (symbol_ref "optimize_size")
2367                             (const_int 0)))
2368                    (const_string "TI")
2369                    (const_string "V4SF"))
2370                /* For architectures resolving dependencies on
2371                   whole SSE registers use APS move to break dependency
2372                   chains, otherwise use short move to avoid extra work.
2374                   Do the same for architectures resolving dependencies on
2375                   the parts.  While in DF mode it is better to always handle
2376                   just register parts, the SF mode is different due to lack
2377                   of instructions to load just part of the register.  It is
2378                   better to maintain the whole registers in single format
2379                   to avoid problems on using packed logical operations.  */
2380                (eq_attr "alternative" "6")
2381                  (if_then_else
2382                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2383                             (const_int 0))
2384                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2385                             (const_int 0)))
2386                    (const_string "V4SF")
2387                    (const_string "SF"))
2388                (eq_attr "alternative" "11")
2389                  (const_string "DI")]
2390                (const_string "SF")))])
2392 (define_insn "*swapsf"
2393   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2394         (match_operand:SF 1 "fp_register_operand" "+f"))
2395    (set (match_dup 1)
2396         (match_dup 0))]
2397   "reload_completed || TARGET_80387"
2399   if (STACK_TOP_P (operands[0]))
2400     return "fxch\t%1";
2401   else
2402     return "fxch\t%0";
2404   [(set_attr "type" "fxch")
2405    (set_attr "mode" "SF")])
2407 (define_expand "movdf"
2408   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2409         (match_operand:DF 1 "general_operand" ""))]
2410   ""
2411   "ix86_expand_move (DFmode, operands); DONE;")
2413 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2414 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2415 ;; On the average, pushdf using integers can be still shorter.  Allow this
2416 ;; pattern for optimize_size too.
2418 (define_insn "*pushdf_nointeger"
2419   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2420         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2421   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2423   /* This insn should be already split before reg-stack.  */
2424   gcc_unreachable ();
2426   [(set_attr "type" "multi")
2427    (set_attr "unit" "i387,*,*,*")
2428    (set_attr "mode" "DF,SI,SI,DF")])
2430 (define_insn "*pushdf_integer"
2431   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2432         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2433   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2435   /* This insn should be already split before reg-stack.  */
2436   gcc_unreachable ();
2438   [(set_attr "type" "multi")
2439    (set_attr "unit" "i387,*,*")
2440    (set_attr "mode" "DF,SI,DF")])
2442 ;; %%% Kill this when call knows how to work this out.
2443 (define_split
2444   [(set (match_operand:DF 0 "push_operand" "")
2445         (match_operand:DF 1 "any_fp_register_operand" ""))]
2446   "!TARGET_64BIT && reload_completed"
2447   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2448    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2449   "")
2451 (define_split
2452   [(set (match_operand:DF 0 "push_operand" "")
2453         (match_operand:DF 1 "any_fp_register_operand" ""))]
2454   "TARGET_64BIT && reload_completed"
2455   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2456    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2457   "")
2459 (define_split
2460   [(set (match_operand:DF 0 "push_operand" "")
2461         (match_operand:DF 1 "general_operand" ""))]
2462   "reload_completed"
2463   [(const_int 0)]
2464   "ix86_split_long_move (operands); DONE;")
2466 ;; Moving is usually shorter when only FP registers are used. This separate
2467 ;; movdf pattern avoids the use of integer registers for FP operations
2468 ;; when optimizing for size.
2470 (define_insn "*movdf_nointeger"
2471   [(set (match_operand:DF 0 "nonimmediate_operand"
2472                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2473         (match_operand:DF 1 "general_operand"
2474                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2475   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2476    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2477    && (reload_in_progress || reload_completed
2478        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2479        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2480            && standard_80387_constant_p (operands[1]))
2481        || GET_CODE (operands[1]) != CONST_DOUBLE
2482        || memory_operand (operands[0], DFmode))"
2484   switch (which_alternative)
2485     {
2486     case 0:
2487       return output_387_reg_move (insn, operands);
2489     case 1:
2490       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2491         return "fstp%z0\t%y0";
2492       else
2493         return "fst%z0\t%y0";
2495     case 2:
2496       return standard_80387_constant_opcode (operands[1]);
2498     case 3:
2499     case 4:
2500       return "#";
2501     case 5:
2502       switch (get_attr_mode (insn))
2503         {
2504         case MODE_V4SF:
2505           return "xorps\t%0, %0";
2506         case MODE_V2DF:
2507           return "xorpd\t%0, %0";
2508         case MODE_TI:
2509           return "pxor\t%0, %0";
2510         default:
2511           gcc_unreachable ();
2512         }
2513     case 6:
2514     case 7:
2515     case 8:
2516       switch (get_attr_mode (insn))
2517         {
2518         case MODE_V4SF:
2519           return "movaps\t{%1, %0|%0, %1}";
2520         case MODE_V2DF:
2521           return "movapd\t{%1, %0|%0, %1}";
2522         case MODE_TI:
2523           return "movdqa\t{%1, %0|%0, %1}";
2524         case MODE_DI:
2525           return "movq\t{%1, %0|%0, %1}";
2526         case MODE_DF:
2527           return "movsd\t{%1, %0|%0, %1}";
2528         case MODE_V1DF:
2529           return "movlpd\t{%1, %0|%0, %1}";
2530         case MODE_V2SF:
2531           return "movlps\t{%1, %0|%0, %1}";
2532         default:
2533           gcc_unreachable ();
2534         }
2536     default:
2537       gcc_unreachable ();
2538     }
2540   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2541    (set (attr "mode")
2542         (cond [(eq_attr "alternative" "0,1,2")
2543                  (const_string "DF")
2544                (eq_attr "alternative" "3,4")
2545                  (const_string "SI")
2547                /* For SSE1, we have many fewer alternatives.  */
2548                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2549                  (cond [(eq_attr "alternative" "5,6")
2550                           (const_string "V4SF")
2551                        ]
2552                    (const_string "V2SF"))
2554                /* xorps is one byte shorter.  */
2555                (eq_attr "alternative" "5")
2556                  (cond [(ne (symbol_ref "optimize_size")
2557                             (const_int 0))
2558                           (const_string "V4SF")
2559                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2560                             (const_int 0))
2561                           (const_string "TI")
2562                        ]
2563                        (const_string "V2DF"))
2565                /* For architectures resolving dependencies on
2566                   whole SSE registers use APD move to break dependency
2567                   chains, otherwise use short move to avoid extra work.
2569                   movaps encodes one byte shorter.  */
2570                (eq_attr "alternative" "6")
2571                  (cond
2572                    [(ne (symbol_ref "optimize_size")
2573                         (const_int 0))
2574                       (const_string "V4SF")
2575                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2576                         (const_int 0))
2577                       (const_string "V2DF")
2578                    ]
2579                    (const_string "DF"))
2580                /* For architectures resolving dependencies on register
2581                   parts we may avoid extra work to zero out upper part
2582                   of register.  */
2583                (eq_attr "alternative" "7")
2584                  (if_then_else
2585                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2586                        (const_int 0))
2587                    (const_string "V1DF")
2588                    (const_string "DF"))
2589               ]
2590               (const_string "DF")))])
2592 (define_insn "*movdf_integer"
2593   [(set (match_operand:DF 0 "nonimmediate_operand"
2594                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2595         (match_operand:DF 1 "general_operand"
2596                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2597   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2598    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2599    && (reload_in_progress || reload_completed
2600        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2601        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2602            && standard_80387_constant_p (operands[1]))
2603        || GET_CODE (operands[1]) != CONST_DOUBLE
2604        || memory_operand (operands[0], DFmode))"
2606   switch (which_alternative)
2607     {
2608     case 0:
2609       return output_387_reg_move (insn, operands);
2611     case 1:
2612       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2613         return "fstp%z0\t%y0";
2614       else
2615         return "fst%z0\t%y0";
2617     case 2:
2618       return standard_80387_constant_opcode (operands[1]);
2620     case 3:
2621     case 4:
2622       return "#";
2624     case 5:
2625       switch (get_attr_mode (insn))
2626         {
2627         case MODE_V4SF:
2628           return "xorps\t%0, %0";
2629         case MODE_V2DF:
2630           return "xorpd\t%0, %0";
2631         case MODE_TI:
2632           return "pxor\t%0, %0";
2633         default:
2634           gcc_unreachable ();
2635         }
2636     case 6:
2637     case 7:
2638     case 8:
2639       switch (get_attr_mode (insn))
2640         {
2641         case MODE_V4SF:
2642           return "movaps\t{%1, %0|%0, %1}";
2643         case MODE_V2DF:
2644           return "movapd\t{%1, %0|%0, %1}";
2645         case MODE_TI:
2646           return "movdqa\t{%1, %0|%0, %1}";
2647         case MODE_DI:
2648           return "movq\t{%1, %0|%0, %1}";
2649         case MODE_DF:
2650           return "movsd\t{%1, %0|%0, %1}";
2651         case MODE_V1DF:
2652           return "movlpd\t{%1, %0|%0, %1}";
2653         case MODE_V2SF:
2654           return "movlps\t{%1, %0|%0, %1}";
2655         default:
2656           gcc_unreachable ();
2657         }
2659     default:
2660       gcc_unreachable();
2661     }
2663   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2664    (set (attr "mode")
2665         (cond [(eq_attr "alternative" "0,1,2")
2666                  (const_string "DF")
2667                (eq_attr "alternative" "3,4")
2668                  (const_string "SI")
2670                /* For SSE1, we have many fewer alternatives.  */
2671                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2672                  (cond [(eq_attr "alternative" "5,6")
2673                           (const_string "V4SF")
2674                        ]
2675                    (const_string "V2SF"))
2677                /* xorps is one byte shorter.  */
2678                (eq_attr "alternative" "5")
2679                  (cond [(ne (symbol_ref "optimize_size")
2680                             (const_int 0))
2681                           (const_string "V4SF")
2682                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2683                             (const_int 0))
2684                           (const_string "TI")
2685                        ]
2686                        (const_string "V2DF"))
2688                /* For architectures resolving dependencies on
2689                   whole SSE registers use APD move to break dependency
2690                   chains, otherwise use short move to avoid extra work.
2692                   movaps encodes one byte shorter.  */
2693                (eq_attr "alternative" "6")
2694                  (cond
2695                    [(ne (symbol_ref "optimize_size")
2696                         (const_int 0))
2697                       (const_string "V4SF")
2698                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2699                         (const_int 0))
2700                       (const_string "V2DF")
2701                    ]
2702                    (const_string "DF"))
2703                /* For architectures resolving dependencies on register
2704                   parts we may avoid extra work to zero out upper part
2705                   of register.  */
2706                (eq_attr "alternative" "7")
2707                  (if_then_else
2708                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2709                        (const_int 0))
2710                    (const_string "V1DF")
2711                    (const_string "DF"))
2712               ]
2713               (const_string "DF")))])
2715 (define_split
2716   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2717         (match_operand:DF 1 "general_operand" ""))]
2718   "reload_completed
2719    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2720    && ! (ANY_FP_REG_P (operands[0]) ||
2721          (GET_CODE (operands[0]) == SUBREG
2722           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2723    && ! (ANY_FP_REG_P (operands[1]) ||
2724          (GET_CODE (operands[1]) == SUBREG
2725           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2726   [(const_int 0)]
2727   "ix86_split_long_move (operands); DONE;")
2729 (define_insn "*swapdf"
2730   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2731         (match_operand:DF 1 "fp_register_operand" "+f"))
2732    (set (match_dup 1)
2733         (match_dup 0))]
2734   "reload_completed || TARGET_80387"
2736   if (STACK_TOP_P (operands[0]))
2737     return "fxch\t%1";
2738   else
2739     return "fxch\t%0";
2741   [(set_attr "type" "fxch")
2742    (set_attr "mode" "DF")])
2744 (define_expand "movxf"
2745   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2746         (match_operand:XF 1 "general_operand" ""))]
2747   ""
2748   "ix86_expand_move (XFmode, operands); DONE;")
2750 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2751 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2752 ;; Pushing using integer instructions is longer except for constants
2753 ;; and direct memory references.
2754 ;; (assuming that any given constant is pushed only once, but this ought to be
2755 ;;  handled elsewhere).
2757 (define_insn "*pushxf_nointeger"
2758   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2759         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2760   "optimize_size"
2762   /* This insn should be already split before reg-stack.  */
2763   gcc_unreachable ();
2765   [(set_attr "type" "multi")
2766    (set_attr "unit" "i387,*,*")
2767    (set_attr "mode" "XF,SI,SI")])
2769 (define_insn "*pushxf_integer"
2770   [(set (match_operand:XF 0 "push_operand" "=<,<")
2771         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2772   "!optimize_size"
2774   /* This insn should be already split before reg-stack.  */
2775   gcc_unreachable ();
2777   [(set_attr "type" "multi")
2778    (set_attr "unit" "i387,*")
2779    (set_attr "mode" "XF,SI")])
2781 (define_split
2782   [(set (match_operand 0 "push_operand" "")
2783         (match_operand 1 "general_operand" ""))]
2784   "reload_completed
2785    && (GET_MODE (operands[0]) == XFmode
2786        || GET_MODE (operands[0]) == DFmode)
2787    && !ANY_FP_REG_P (operands[1])"
2788   [(const_int 0)]
2789   "ix86_split_long_move (operands); DONE;")
2791 (define_split
2792   [(set (match_operand:XF 0 "push_operand" "")
2793         (match_operand:XF 1 "any_fp_register_operand" ""))]
2794   "!TARGET_64BIT"
2795   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2796    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2797   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2799 (define_split
2800   [(set (match_operand:XF 0 "push_operand" "")
2801         (match_operand:XF 1 "any_fp_register_operand" ""))]
2802   "TARGET_64BIT"
2803   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2804    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2805   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2807 ;; Do not use integer registers when optimizing for size
2808 (define_insn "*movxf_nointeger"
2809   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2810         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2811   "optimize_size
2812    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2813    && (reload_in_progress || reload_completed
2814        || (optimize_size && standard_80387_constant_p (operands[1]))
2815        || GET_CODE (operands[1]) != CONST_DOUBLE
2816        || memory_operand (operands[0], XFmode))"
2818   switch (which_alternative)
2819     {
2820     case 0:
2821       return output_387_reg_move (insn, operands);
2823     case 1:
2824       /* There is no non-popping store to memory for XFmode.  So if
2825          we need one, follow the store with a load.  */
2826       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827         return "fstp%z0\t%y0\;fld%z0\t%y0";
2828       else
2829         return "fstp%z0\t%y0";
2831     case 2:
2832       return standard_80387_constant_opcode (operands[1]);
2834     case 3: case 4:
2835       return "#";
2836     default:
2837       gcc_unreachable ();
2838     }
2840   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2841    (set_attr "mode" "XF,XF,XF,SI,SI")])
2843 (define_insn "*movxf_integer"
2844   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2845         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2846   "!optimize_size
2847    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2848    && (reload_in_progress || reload_completed
2849        || (optimize_size && standard_80387_constant_p (operands[1]))
2850        || GET_CODE (operands[1]) != CONST_DOUBLE
2851        || memory_operand (operands[0], XFmode))"
2853   switch (which_alternative)
2854     {
2855     case 0:
2856       return output_387_reg_move (insn, operands);
2858     case 1:
2859       /* There is no non-popping store to memory for XFmode.  So if
2860          we need one, follow the store with a load.  */
2861       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2862         return "fstp%z0\t%y0\;fld%z0\t%y0";
2863       else
2864         return "fstp%z0\t%y0";
2866     case 2:
2867       return standard_80387_constant_opcode (operands[1]);
2869     case 3: case 4:
2870       return "#";
2872     default:
2873       gcc_unreachable ();
2874     }
2876   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2877    (set_attr "mode" "XF,XF,XF,SI,SI")])
2879 (define_split
2880   [(set (match_operand 0 "nonimmediate_operand" "")
2881         (match_operand 1 "general_operand" ""))]
2882   "reload_completed
2883    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2884    && GET_MODE (operands[0]) == XFmode
2885    && ! (ANY_FP_REG_P (operands[0]) ||
2886          (GET_CODE (operands[0]) == SUBREG
2887           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2888    && ! (ANY_FP_REG_P (operands[1]) ||
2889          (GET_CODE (operands[1]) == SUBREG
2890           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2891   [(const_int 0)]
2892   "ix86_split_long_move (operands); DONE;")
2894 (define_split
2895   [(set (match_operand 0 "register_operand" "")
2896         (match_operand 1 "memory_operand" ""))]
2897   "reload_completed
2898    && GET_CODE (operands[1]) == MEM
2899    && (GET_MODE (operands[0]) == XFmode
2900        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2901    && constant_pool_reference_p (operands[1])"
2902   [(set (match_dup 0) (match_dup 1))]
2904   rtx c = avoid_constant_pool_reference (operands[1]);
2905   rtx r = operands[0];
2907   if (GET_CODE (r) == SUBREG)
2908     r = SUBREG_REG (r);
2910   if (SSE_REG_P (r))
2911     {
2912       if (!standard_sse_constant_p (c))
2913         FAIL;
2914     }
2915   else if (FP_REG_P (r))
2916     {
2917       if (!standard_80387_constant_p (c))
2918         FAIL;
2919     }
2920   else if (MMX_REG_P (r))
2921     FAIL;
2923   operands[1] = c;
2926 (define_split
2927   [(set (match_operand 0 "register_operand" "")
2928         (float_extend (match_operand 1 "memory_operand" "")))]
2929   "reload_completed
2930    && GET_CODE (operands[1]) == MEM
2931    && (GET_MODE (operands[0]) == XFmode
2932        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2933    && constant_pool_reference_p (operands[1])"
2934   [(set (match_dup 0) (match_dup 1))]
2936   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2937   rtx r = operands[0];
2939   if (GET_CODE (r) == SUBREG)
2940     r = SUBREG_REG (r);
2942   if (SSE_REG_P (r))
2943     {
2944       if (!standard_sse_constant_p (c))
2945         FAIL;
2946     }
2947   else if (FP_REG_P (r))
2948     {
2949       if (!standard_80387_constant_p (c))
2950         FAIL;
2951     }
2952   else if (MMX_REG_P (r))
2953     FAIL;
2955   operands[1] = c;
2958 (define_insn "swapxf"
2959   [(set (match_operand:XF 0 "register_operand" "+f")
2960         (match_operand:XF 1 "register_operand" "+f"))
2961    (set (match_dup 1)
2962         (match_dup 0))]
2963   "TARGET_80387"
2965   if (STACK_TOP_P (operands[0]))
2966     return "fxch\t%1";
2967   else
2968     return "fxch\t%0";
2970   [(set_attr "type" "fxch")
2971    (set_attr "mode" "XF")])
2973 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2974 (define_split
2975   [(set (match_operand:X87MODEF 0 "register_operand" "")
2976         (match_operand:X87MODEF 1 "immediate_operand" ""))]
2977   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2978    && (standard_80387_constant_p (operands[1]) == 8
2979        || standard_80387_constant_p (operands[1]) == 9)"
2980   [(set (match_dup 0)(match_dup 1))
2981    (set (match_dup 0)
2982         (neg:X87MODEF (match_dup 0)))]
2984   REAL_VALUE_TYPE r;
2986   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2987   if (real_isnegzero (&r))
2988     operands[1] = CONST0_RTX (<MODE>mode);
2989   else
2990     operands[1] = CONST1_RTX (<MODE>mode);
2993 (define_expand "movtf"
2994   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2995         (match_operand:TF 1 "nonimmediate_operand" ""))]
2996   "TARGET_64BIT"
2998   ix86_expand_move (TFmode, operands);
2999   DONE;
3002 (define_insn "*movtf_internal"
3003   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3004         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3005   "TARGET_64BIT
3006    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3008   switch (which_alternative)
3009     {
3010     case 0:
3011     case 1:
3012       return "#";
3013     case 2:
3014       if (get_attr_mode (insn) == MODE_V4SF)
3015         return "xorps\t%0, %0";
3016       else
3017         return "pxor\t%0, %0";
3018     case 3:
3019     case 4:
3020       if (get_attr_mode (insn) == MODE_V4SF)
3021         return "movaps\t{%1, %0|%0, %1}";
3022       else
3023         return "movdqa\t{%1, %0|%0, %1}";
3024     default:
3025       gcc_unreachable ();
3026     }
3028   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3029    (set (attr "mode")
3030         (cond [(eq_attr "alternative" "2,3")
3031                  (if_then_else
3032                    (ne (symbol_ref "optimize_size")
3033                        (const_int 0))
3034                    (const_string "V4SF")
3035                    (const_string "TI"))
3036                (eq_attr "alternative" "4")
3037                  (if_then_else
3038                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3039                             (const_int 0))
3040                         (ne (symbol_ref "optimize_size")
3041                             (const_int 0)))
3042                    (const_string "V4SF")
3043                    (const_string "TI"))]
3044                (const_string "DI")))])
3046 (define_split
3047   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3048         (match_operand:TF 1 "general_operand" ""))]
3049   "reload_completed && !SSE_REG_P (operands[0])
3050    && !SSE_REG_P (operands[1])"
3051   [(const_int 0)]
3052   "ix86_split_long_move (operands); DONE;")
3054 ;; Zero extension instructions
3056 (define_expand "zero_extendhisi2"
3057   [(set (match_operand:SI 0 "register_operand" "")
3058      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3059   ""
3061   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3062     {
3063       operands[1] = force_reg (HImode, operands[1]);
3064       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3065       DONE;
3066     }
3069 (define_insn "zero_extendhisi2_and"
3070   [(set (match_operand:SI 0 "register_operand" "=r")
3071      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3072    (clobber (reg:CC FLAGS_REG))]
3073   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3074   "#"
3075   [(set_attr "type" "alu1")
3076    (set_attr "mode" "SI")])
3078 (define_split
3079   [(set (match_operand:SI 0 "register_operand" "")
3080         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3081    (clobber (reg:CC FLAGS_REG))]
3082   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3083   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3084               (clobber (reg:CC FLAGS_REG))])]
3085   "")
3087 (define_insn "*zero_extendhisi2_movzwl"
3088   [(set (match_operand:SI 0 "register_operand" "=r")
3089      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3090   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3091   "movz{wl|x}\t{%1, %0|%0, %1}"
3092   [(set_attr "type" "imovx")
3093    (set_attr "mode" "SI")])
3095 (define_expand "zero_extendqihi2"
3096   [(parallel
3097     [(set (match_operand:HI 0 "register_operand" "")
3098        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3099      (clobber (reg:CC FLAGS_REG))])]
3100   ""
3101   "")
3103 (define_insn "*zero_extendqihi2_and"
3104   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3105      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3106    (clobber (reg:CC FLAGS_REG))]
3107   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3108   "#"
3109   [(set_attr "type" "alu1")
3110    (set_attr "mode" "HI")])
3112 (define_insn "*zero_extendqihi2_movzbw_and"
3113   [(set (match_operand:HI 0 "register_operand" "=r,r")
3114      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3115    (clobber (reg:CC FLAGS_REG))]
3116   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3117   "#"
3118   [(set_attr "type" "imovx,alu1")
3119    (set_attr "mode" "HI")])
3121 ; zero extend to SImode here to avoid partial register stalls
3122 (define_insn "*zero_extendqihi2_movzbl"
3123   [(set (match_operand:HI 0 "register_operand" "=r")
3124      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3125   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3126   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3127   [(set_attr "type" "imovx")
3128    (set_attr "mode" "SI")])
3130 ;; For the movzbw case strip only the clobber
3131 (define_split
3132   [(set (match_operand:HI 0 "register_operand" "")
3133         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3134    (clobber (reg:CC FLAGS_REG))]
3135   "reload_completed
3136    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3137    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3138   [(set (match_operand:HI 0 "register_operand" "")
3139         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3141 ;; When source and destination does not overlap, clear destination
3142 ;; first and then do the movb
3143 (define_split
3144   [(set (match_operand:HI 0 "register_operand" "")
3145         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3146    (clobber (reg:CC FLAGS_REG))]
3147   "reload_completed
3148    && ANY_QI_REG_P (operands[0])
3149    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3150    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3151   [(set (match_dup 0) (const_int 0))
3152    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3153   "operands[2] = gen_lowpart (QImode, operands[0]);")
3155 ;; Rest is handled by single and.
3156 (define_split
3157   [(set (match_operand:HI 0 "register_operand" "")
3158         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3159    (clobber (reg:CC FLAGS_REG))]
3160   "reload_completed
3161    && true_regnum (operands[0]) == true_regnum (operands[1])"
3162   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3163               (clobber (reg:CC FLAGS_REG))])]
3164   "")
3166 (define_expand "zero_extendqisi2"
3167   [(parallel
3168     [(set (match_operand:SI 0 "register_operand" "")
3169        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3170      (clobber (reg:CC FLAGS_REG))])]
3171   ""
3172   "")
3174 (define_insn "*zero_extendqisi2_and"
3175   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3176      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3177    (clobber (reg:CC FLAGS_REG))]
3178   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3179   "#"
3180   [(set_attr "type" "alu1")
3181    (set_attr "mode" "SI")])
3183 (define_insn "*zero_extendqisi2_movzbw_and"
3184   [(set (match_operand:SI 0 "register_operand" "=r,r")
3185      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3186    (clobber (reg:CC FLAGS_REG))]
3187   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3188   "#"
3189   [(set_attr "type" "imovx,alu1")
3190    (set_attr "mode" "SI")])
3192 (define_insn "*zero_extendqisi2_movzbw"
3193   [(set (match_operand:SI 0 "register_operand" "=r")
3194      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3195   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3196   "movz{bl|x}\t{%1, %0|%0, %1}"
3197   [(set_attr "type" "imovx")
3198    (set_attr "mode" "SI")])
3200 ;; For the movzbl case strip only the clobber
3201 (define_split
3202   [(set (match_operand:SI 0 "register_operand" "")
3203         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3204    (clobber (reg:CC FLAGS_REG))]
3205   "reload_completed
3206    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3207    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3208   [(set (match_dup 0)
3209         (zero_extend:SI (match_dup 1)))])
3211 ;; When source and destination does not overlap, clear destination
3212 ;; first and then do the movb
3213 (define_split
3214   [(set (match_operand:SI 0 "register_operand" "")
3215         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3216    (clobber (reg:CC FLAGS_REG))]
3217   "reload_completed
3218    && ANY_QI_REG_P (operands[0])
3219    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3220    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3221    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3222   [(set (match_dup 0) (const_int 0))
3223    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3224   "operands[2] = gen_lowpart (QImode, operands[0]);")
3226 ;; Rest is handled by single and.
3227 (define_split
3228   [(set (match_operand:SI 0 "register_operand" "")
3229         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3230    (clobber (reg:CC FLAGS_REG))]
3231   "reload_completed
3232    && true_regnum (operands[0]) == true_regnum (operands[1])"
3233   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3234               (clobber (reg:CC FLAGS_REG))])]
3235   "")
3237 ;; %%% Kill me once multi-word ops are sane.
3238 (define_expand "zero_extendsidi2"
3239   [(set (match_operand:DI 0 "register_operand" "=r")
3240      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3241   ""
3242   "if (!TARGET_64BIT)
3243      {
3244        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3245        DONE;
3246      }
3247   ")
3249 (define_insn "zero_extendsidi2_32"
3250   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3251         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3252    (clobber (reg:CC FLAGS_REG))]
3253   "!TARGET_64BIT"
3254   "@
3255    #
3256    #
3257    #
3258    movd\t{%1, %0|%0, %1}
3259    movd\t{%1, %0|%0, %1}"
3260   [(set_attr "mode" "SI,SI,SI,DI,TI")
3261    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3263 (define_insn "zero_extendsidi2_rex64"
3264   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3265      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3266   "TARGET_64BIT"
3267   "@
3268    mov\t{%k1, %k0|%k0, %k1}
3269    #
3270    movd\t{%1, %0|%0, %1}
3271    movd\t{%1, %0|%0, %1}"
3272   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3273    (set_attr "mode" "SI,DI,SI,SI")])
3275 (define_split
3276   [(set (match_operand:DI 0 "memory_operand" "")
3277      (zero_extend:DI (match_dup 0)))]
3278   "TARGET_64BIT"
3279   [(set (match_dup 4) (const_int 0))]
3280   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3282 (define_split
3283   [(set (match_operand:DI 0 "register_operand" "")
3284         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3285    (clobber (reg:CC FLAGS_REG))]
3286   "!TARGET_64BIT && reload_completed
3287    && true_regnum (operands[0]) == true_regnum (operands[1])"
3288   [(set (match_dup 4) (const_int 0))]
3289   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3291 (define_split
3292   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3293         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3294    (clobber (reg:CC FLAGS_REG))]
3295   "!TARGET_64BIT && reload_completed
3296    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3297   [(set (match_dup 3) (match_dup 1))
3298    (set (match_dup 4) (const_int 0))]
3299   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3301 (define_insn "zero_extendhidi2"
3302   [(set (match_operand:DI 0 "register_operand" "=r")
3303      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3304   "TARGET_64BIT"
3305   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3306   [(set_attr "type" "imovx")
3307    (set_attr "mode" "DI")])
3309 (define_insn "zero_extendqidi2"
3310   [(set (match_operand:DI 0 "register_operand" "=r")
3311      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3312   "TARGET_64BIT"
3313   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3314   [(set_attr "type" "imovx")
3315    (set_attr "mode" "DI")])
3317 ;; Sign extension instructions
3319 (define_expand "extendsidi2"
3320   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3321                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3322               (clobber (reg:CC FLAGS_REG))
3323               (clobber (match_scratch:SI 2 ""))])]
3324   ""
3326   if (TARGET_64BIT)
3327     {
3328       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3329       DONE;
3330     }
3333 (define_insn "*extendsidi2_1"
3334   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3335         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3336    (clobber (reg:CC FLAGS_REG))
3337    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3338   "!TARGET_64BIT"
3339   "#")
3341 (define_insn "extendsidi2_rex64"
3342   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3343         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3344   "TARGET_64BIT"
3345   "@
3346    {cltq|cdqe}
3347    movs{lq|x}\t{%1,%0|%0, %1}"
3348   [(set_attr "type" "imovx")
3349    (set_attr "mode" "DI")
3350    (set_attr "prefix_0f" "0")
3351    (set_attr "modrm" "0,1")])
3353 (define_insn "extendhidi2"
3354   [(set (match_operand:DI 0 "register_operand" "=r")
3355         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3356   "TARGET_64BIT"
3357   "movs{wq|x}\t{%1,%0|%0, %1}"
3358   [(set_attr "type" "imovx")
3359    (set_attr "mode" "DI")])
3361 (define_insn "extendqidi2"
3362   [(set (match_operand:DI 0 "register_operand" "=r")
3363         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3364   "TARGET_64BIT"
3365   "movs{bq|x}\t{%1,%0|%0, %1}"
3366    [(set_attr "type" "imovx")
3367     (set_attr "mode" "DI")])
3369 ;; Extend to memory case when source register does die.
3370 (define_split
3371   [(set (match_operand:DI 0 "memory_operand" "")
3372         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3373    (clobber (reg:CC FLAGS_REG))
3374    (clobber (match_operand:SI 2 "register_operand" ""))]
3375   "(reload_completed
3376     && dead_or_set_p (insn, operands[1])
3377     && !reg_mentioned_p (operands[1], operands[0]))"
3378   [(set (match_dup 3) (match_dup 1))
3379    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3380               (clobber (reg:CC FLAGS_REG))])
3381    (set (match_dup 4) (match_dup 1))]
3382   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3384 ;; Extend to memory case when source register does not die.
3385 (define_split
3386   [(set (match_operand:DI 0 "memory_operand" "")
3387         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3388    (clobber (reg:CC FLAGS_REG))
3389    (clobber (match_operand:SI 2 "register_operand" ""))]
3390   "reload_completed"
3391   [(const_int 0)]
3393   split_di (&operands[0], 1, &operands[3], &operands[4]);
3395   emit_move_insn (operands[3], operands[1]);
3397   /* Generate a cltd if possible and doing so it profitable.  */
3398   if (true_regnum (operands[1]) == 0
3399       && true_regnum (operands[2]) == 1
3400       && (optimize_size || TARGET_USE_CLTD))
3401     {
3402       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3403     }
3404   else
3405     {
3406       emit_move_insn (operands[2], operands[1]);
3407       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3408     }
3409   emit_move_insn (operands[4], operands[2]);
3410   DONE;
3413 ;; Extend to register case.  Optimize case where source and destination
3414 ;; registers match and cases where we can use cltd.
3415 (define_split
3416   [(set (match_operand:DI 0 "register_operand" "")
3417         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3418    (clobber (reg:CC FLAGS_REG))
3419    (clobber (match_scratch:SI 2 ""))]
3420   "reload_completed"
3421   [(const_int 0)]
3423   split_di (&operands[0], 1, &operands[3], &operands[4]);
3425   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3426     emit_move_insn (operands[3], operands[1]);
3428   /* Generate a cltd if possible and doing so it profitable.  */
3429   if (true_regnum (operands[3]) == 0
3430       && (optimize_size || TARGET_USE_CLTD))
3431     {
3432       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3433       DONE;
3434     }
3436   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3437     emit_move_insn (operands[4], operands[1]);
3439   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3440   DONE;
3443 (define_insn "extendhisi2"
3444   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3445         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3446   ""
3448   switch (get_attr_prefix_0f (insn))
3449     {
3450     case 0:
3451       return "{cwtl|cwde}";
3452     default:
3453       return "movs{wl|x}\t{%1,%0|%0, %1}";
3454     }
3456   [(set_attr "type" "imovx")
3457    (set_attr "mode" "SI")
3458    (set (attr "prefix_0f")
3459      ;; movsx is short decodable while cwtl is vector decoded.
3460      (if_then_else (and (eq_attr "cpu" "!k6")
3461                         (eq_attr "alternative" "0"))
3462         (const_string "0")
3463         (const_string "1")))
3464    (set (attr "modrm")
3465      (if_then_else (eq_attr "prefix_0f" "0")
3466         (const_string "0")
3467         (const_string "1")))])
3469 (define_insn "*extendhisi2_zext"
3470   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3471         (zero_extend:DI
3472           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3473   "TARGET_64BIT"
3475   switch (get_attr_prefix_0f (insn))
3476     {
3477     case 0:
3478       return "{cwtl|cwde}";
3479     default:
3480       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3481     }
3483   [(set_attr "type" "imovx")
3484    (set_attr "mode" "SI")
3485    (set (attr "prefix_0f")
3486      ;; movsx is short decodable while cwtl is vector decoded.
3487      (if_then_else (and (eq_attr "cpu" "!k6")
3488                         (eq_attr "alternative" "0"))
3489         (const_string "0")
3490         (const_string "1")))
3491    (set (attr "modrm")
3492      (if_then_else (eq_attr "prefix_0f" "0")
3493         (const_string "0")
3494         (const_string "1")))])
3496 (define_insn "extendqihi2"
3497   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3498         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3499   ""
3501   switch (get_attr_prefix_0f (insn))
3502     {
3503     case 0:
3504       return "{cbtw|cbw}";
3505     default:
3506       return "movs{bw|x}\t{%1,%0|%0, %1}";
3507     }
3509   [(set_attr "type" "imovx")
3510    (set_attr "mode" "HI")
3511    (set (attr "prefix_0f")
3512      ;; movsx is short decodable while cwtl is vector decoded.
3513      (if_then_else (and (eq_attr "cpu" "!k6")
3514                         (eq_attr "alternative" "0"))
3515         (const_string "0")
3516         (const_string "1")))
3517    (set (attr "modrm")
3518      (if_then_else (eq_attr "prefix_0f" "0")
3519         (const_string "0")
3520         (const_string "1")))])
3522 (define_insn "extendqisi2"
3523   [(set (match_operand:SI 0 "register_operand" "=r")
3524         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3525   ""
3526   "movs{bl|x}\t{%1,%0|%0, %1}"
3527    [(set_attr "type" "imovx")
3528     (set_attr "mode" "SI")])
3530 (define_insn "*extendqisi2_zext"
3531   [(set (match_operand:DI 0 "register_operand" "=r")
3532         (zero_extend:DI
3533           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3534   "TARGET_64BIT"
3535   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3536    [(set_attr "type" "imovx")
3537     (set_attr "mode" "SI")])
3539 ;; Conversions between float and double.
3541 ;; These are all no-ops in the model used for the 80387.  So just
3542 ;; emit moves.
3544 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3545 (define_insn "*dummy_extendsfdf2"
3546   [(set (match_operand:DF 0 "push_operand" "=<")
3547         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3548   "0"
3549   "#")
3551 (define_split
3552   [(set (match_operand:DF 0 "push_operand" "")
3553         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3554   "!TARGET_64BIT"
3555   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3556    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3558 (define_split
3559   [(set (match_operand:DF 0 "push_operand" "")
3560         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3561   "TARGET_64BIT"
3562   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3563    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3565 (define_insn "*dummy_extendsfxf2"
3566   [(set (match_operand:XF 0 "push_operand" "=<")
3567         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3568   "0"
3569   "#")
3571 (define_split
3572   [(set (match_operand:XF 0 "push_operand" "")
3573         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3574   ""
3575   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3576    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3577   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3579 (define_split
3580   [(set (match_operand:XF 0 "push_operand" "")
3581         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3582   "TARGET_64BIT"
3583   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3584    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3585   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3587 (define_split
3588   [(set (match_operand:XF 0 "push_operand" "")
3589         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3590   ""
3591   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3592    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3593   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3595 (define_split
3596   [(set (match_operand:XF 0 "push_operand" "")
3597         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3598   "TARGET_64BIT"
3599   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3600    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3601   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3603 (define_expand "extendsfdf2"
3604   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3605         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3606   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3608   /* ??? Needed for compress_float_constant since all fp constants
3609      are LEGITIMATE_CONSTANT_P.  */
3610   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3611     {
3612       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3613           && standard_80387_constant_p (operands[1]) > 0)
3614         {
3615           operands[1] = simplify_const_unary_operation
3616             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3617           emit_move_insn_1 (operands[0], operands[1]);
3618           DONE;
3619         }
3620       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3621     }
3624 (define_insn "*extendsfdf2_mixed"
3625   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3626         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3627   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3629   switch (which_alternative)
3630     {
3631     case 0:
3632       return output_387_reg_move (insn, operands);
3634     case 1:
3635       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3636         return "fstp%z0\t%y0";
3637       else
3638         return "fst%z0\t%y0";
3640     case 2:
3641       return "cvtss2sd\t{%1, %0|%0, %1}";
3643     default:
3644       gcc_unreachable ();
3645     }
3647   [(set_attr "type" "fmov,fmov,ssecvt")
3648    (set_attr "mode" "SF,XF,DF")])
3650 (define_insn "*extendsfdf2_sse"
3651   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3652         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3653   "TARGET_SSE2 && TARGET_SSE_MATH"
3654   "cvtss2sd\t{%1, %0|%0, %1}"
3655   [(set_attr "type" "ssecvt")
3656    (set_attr "mode" "DF")])
3658 (define_insn "*extendsfdf2_i387"
3659   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3660         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3661   "TARGET_80387"
3663   switch (which_alternative)
3664     {
3665     case 0:
3666       return output_387_reg_move (insn, operands);
3668     case 1:
3669       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3670         return "fstp%z0\t%y0";
3671       else
3672         return "fst%z0\t%y0";
3674     default:
3675       gcc_unreachable ();
3676     }
3678   [(set_attr "type" "fmov")
3679    (set_attr "mode" "SF,XF")])
3681 (define_expand "extendsfxf2"
3682   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3683         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3684   "TARGET_80387"
3686   /* ??? Needed for compress_float_constant since all fp constants
3687      are LEGITIMATE_CONSTANT_P.  */
3688   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3689     {
3690       if (standard_80387_constant_p (operands[1]) > 0)
3691         {
3692           operands[1] = simplify_const_unary_operation
3693             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3694           emit_move_insn_1 (operands[0], operands[1]);
3695           DONE;
3696         }
3697       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3698     }
3701 (define_insn "*extendsfxf2_i387"
3702   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3703         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3704   "TARGET_80387"
3706   switch (which_alternative)
3707     {
3708     case 0:
3709       return output_387_reg_move (insn, operands);
3711     case 1:
3712       /* There is no non-popping store to memory for XFmode.  So if
3713          we need one, follow the store with a load.  */
3714       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3715         return "fstp%z0\t%y0";
3716       else
3717         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3719     default:
3720       gcc_unreachable ();
3721     }
3723   [(set_attr "type" "fmov")
3724    (set_attr "mode" "SF,XF")])
3726 (define_expand "extenddfxf2"
3727   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3728         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3729   "TARGET_80387"
3731   /* ??? Needed for compress_float_constant since all fp constants
3732      are LEGITIMATE_CONSTANT_P.  */
3733   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3734     {
3735       if (standard_80387_constant_p (operands[1]) > 0)
3736         {
3737           operands[1] = simplify_const_unary_operation
3738             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3739           emit_move_insn_1 (operands[0], operands[1]);
3740           DONE;
3741         }
3742       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3743     }
3746 (define_insn "*extenddfxf2_i387"
3747   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3748         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3749   "TARGET_80387"
3751   switch (which_alternative)
3752     {
3753     case 0:
3754       return output_387_reg_move (insn, operands);
3756     case 1:
3757       /* There is no non-popping store to memory for XFmode.  So if
3758          we need one, follow the store with a load.  */
3759       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3760         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3761       else
3762         return "fstp%z0\t%y0";
3764     default:
3765       gcc_unreachable ();
3766     }
3768   [(set_attr "type" "fmov")
3769    (set_attr "mode" "DF,XF")])
3771 ;; %%% This seems bad bad news.
3772 ;; This cannot output into an f-reg because there is no way to be sure
3773 ;; of truncating in that case.  Otherwise this is just like a simple move
3774 ;; insn.  So we pretend we can output to a reg in order to get better
3775 ;; register preferencing, but we really use a stack slot.
3777 ;; Conversion from DFmode to SFmode.
3779 (define_expand "truncdfsf2"
3780   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3781         (float_truncate:SF
3782           (match_operand:DF 1 "nonimmediate_operand" "")))]
3783   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3785   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3786     ;
3787   else if (flag_unsafe_math_optimizations)
3788     ;
3789   else
3790     {
3791       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3792       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3793       DONE;
3794     }
3797 (define_expand "truncdfsf2_with_temp"
3798   [(parallel [(set (match_operand:SF 0 "" "")
3799                    (float_truncate:SF (match_operand:DF 1 "" "")))
3800               (clobber (match_operand:SF 2 "" ""))])]
3801   "")
3803 (define_insn "*truncdfsf_fast_mixed"
3804   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3805         (float_truncate:SF
3806           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3807   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3809   switch (which_alternative)
3810     {
3811     case 0:
3812       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3813         return "fstp%z0\t%y0";
3814       else
3815         return "fst%z0\t%y0";
3816     case 1:
3817       return output_387_reg_move (insn, operands);
3818     case 2:
3819       return "cvtsd2ss\t{%1, %0|%0, %1}";
3820     default:
3821       gcc_unreachable ();
3822     }
3824   [(set_attr "type" "fmov,fmov,ssecvt")
3825    (set_attr "mode" "SF")])
3827 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3828 ;; because nothing we do here is unsafe.
3829 (define_insn "*truncdfsf_fast_sse"
3830   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3831         (float_truncate:SF
3832           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3833   "TARGET_SSE2 && TARGET_SSE_MATH"
3834   "cvtsd2ss\t{%1, %0|%0, %1}"
3835   [(set_attr "type" "ssecvt")
3836    (set_attr "mode" "SF")])
3838 (define_insn "*truncdfsf_fast_i387"
3839   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3840         (float_truncate:SF
3841           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3842   "TARGET_80387 && flag_unsafe_math_optimizations"
3843   "* return output_387_reg_move (insn, operands);"
3844   [(set_attr "type" "fmov")
3845    (set_attr "mode" "SF")])
3847 (define_insn "*truncdfsf_mixed"
3848   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3849         (float_truncate:SF
3850           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3851    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3852   "TARGET_MIX_SSE_I387"
3854   switch (which_alternative)
3855     {
3856     case 0:
3857       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3858         return "fstp%z0\t%y0";
3859       else
3860         return "fst%z0\t%y0";
3861     case 1:
3862       return "#";
3863     case 2:
3864       return "cvtsd2ss\t{%1, %0|%0, %1}";
3865     default:
3866       gcc_unreachable ();
3867     }
3869   [(set_attr "type" "fmov,multi,ssecvt")
3870    (set_attr "unit" "*,i387,*")
3871    (set_attr "mode" "SF")])
3873 (define_insn "*truncdfsf_i387"
3874   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3875         (float_truncate:SF
3876           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3877    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3878   "TARGET_80387"
3880   switch (which_alternative)
3881     {
3882     case 0:
3883       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3884         return "fstp%z0\t%y0";
3885       else
3886         return "fst%z0\t%y0";
3887     case 1:
3888       return "#";
3889     default:
3890       gcc_unreachable ();
3891     }
3893   [(set_attr "type" "fmov,multi")
3894    (set_attr "unit" "*,i387")
3895    (set_attr "mode" "SF")])
3897 (define_insn "*truncdfsf2_i387_1"
3898   [(set (match_operand:SF 0 "memory_operand" "=m")
3899         (float_truncate:SF
3900           (match_operand:DF 1 "register_operand" "f")))]
3901   "TARGET_80387
3902    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3903    && !TARGET_MIX_SSE_I387"
3905   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3906     return "fstp%z0\t%y0";
3907   else
3908     return "fst%z0\t%y0";
3910   [(set_attr "type" "fmov")
3911    (set_attr "mode" "SF")])
3913 (define_split
3914   [(set (match_operand:SF 0 "register_operand" "")
3915         (float_truncate:SF
3916          (match_operand:DF 1 "fp_register_operand" "")))
3917    (clobber (match_operand 2 "" ""))]
3918   "reload_completed"
3919   [(set (match_dup 2) (match_dup 1))
3920    (set (match_dup 0) (match_dup 2))]
3922   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3925 ;; Conversion from XFmode to SFmode.
3927 (define_expand "truncxfsf2"
3928   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3929                    (float_truncate:SF
3930                     (match_operand:XF 1 "register_operand" "")))
3931               (clobber (match_dup 2))])]
3932   "TARGET_80387"
3934   if (flag_unsafe_math_optimizations)
3935     {
3936       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3937       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3938       if (reg != operands[0])
3939         emit_move_insn (operands[0], reg);
3940       DONE;
3941     }
3942   else
3943     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3946 (define_insn "*truncxfsf2_mixed"
3947   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3948         (float_truncate:SF
3949          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3950    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3951   "TARGET_80387"
3953   gcc_assert (!which_alternative);
3954   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3955     return "fstp%z0\t%y0";
3956   else
3957     return "fst%z0\t%y0";
3959   [(set_attr "type" "fmov,multi,multi,multi")
3960    (set_attr "unit" "*,i387,i387,i387")
3961    (set_attr "mode" "SF")])
3963 (define_insn "truncxfsf2_i387_noop"
3964   [(set (match_operand:SF 0 "register_operand" "=f")
3965         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3966   "TARGET_80387 && flag_unsafe_math_optimizations"
3967   "* return output_387_reg_move (insn, operands);"
3968   [(set_attr "type" "fmov")
3969    (set_attr "mode" "SF")])
3971 (define_insn "*truncxfsf2_i387"
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_80387"
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 "memory_operand" "=m")
4052         (float_truncate:DF
4053           (match_operand:XF 1 "register_operand" "f")))]
4054   "TARGET_80387"
4056   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4057     return "fstp%z0\t%y0";
4058   else
4059     return "fst%z0\t%y0";
4061   [(set_attr "type" "fmov")
4062    (set_attr "mode" "DF")])
4064 (define_split
4065   [(set (match_operand:DF 0 "register_operand" "")
4066         (float_truncate:DF
4067          (match_operand:XF 1 "register_operand" "")))
4068    (clobber (match_operand:DF 2 "memory_operand" ""))]
4069   "TARGET_80387 && reload_completed"
4070   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4071    (set (match_dup 0) (match_dup 2))]
4072   "")
4074 (define_split
4075   [(set (match_operand:DF 0 "memory_operand" "")
4076         (float_truncate:DF
4077          (match_operand:XF 1 "register_operand" "")))
4078    (clobber (match_operand:DF 2 "memory_operand" ""))]
4079   "TARGET_80387"
4080   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4081   "")
4083 ;; Signed conversion to DImode.
4085 (define_expand "fix_truncxfdi2"
4086   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4087                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4088               (clobber (reg:CC FLAGS_REG))])]
4089   "TARGET_80387"
4091   if (TARGET_FISTTP)
4092    {
4093      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4094      DONE;
4095    }
4098 (define_expand "fix_trunc<mode>di2"
4099   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4100                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4101               (clobber (reg:CC FLAGS_REG))])]
4102   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4104   if (TARGET_FISTTP
4105       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4106    {
4107      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4108      DONE;
4109    }
4110   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4111    {
4112      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4113      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4114      if (out != operands[0])
4115         emit_move_insn (operands[0], out);
4116      DONE;
4117    }
4120 ;; Signed conversion to SImode.
4122 (define_expand "fix_truncxfsi2"
4123   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4124                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4125               (clobber (reg:CC FLAGS_REG))])]
4126   "TARGET_80387"
4128   if (TARGET_FISTTP)
4129    {
4130      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4131      DONE;
4132    }
4135 (define_expand "fix_trunc<mode>si2"
4136   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4137                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4138               (clobber (reg:CC FLAGS_REG))])]
4139   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4141   if (TARGET_FISTTP
4142       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4143    {
4144      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4145      DONE;
4146    }
4147   if (SSE_FLOAT_MODE_P (<MODE>mode))
4148    {
4149      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4150      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4151      if (out != operands[0])
4152         emit_move_insn (operands[0], out);
4153      DONE;
4154    }
4157 ;; Signed conversion to HImode.
4159 (define_expand "fix_trunc<mode>hi2"
4160   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4161                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4162               (clobber (reg:CC FLAGS_REG))])]
4163   "TARGET_80387
4164    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4166   if (TARGET_FISTTP)
4167    {
4168      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4169      DONE;
4170    }
4173 ;; When SSE is available, it is always faster to use it!
4174 (define_insn "fix_truncsfdi_sse"
4175   [(set (match_operand:DI 0 "register_operand" "=r,r")
4176         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4177   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4178   "cvttss2si{q}\t{%1, %0|%0, %1}"
4179   [(set_attr "type" "sseicvt")
4180    (set_attr "mode" "SF")
4181    (set_attr "athlon_decode" "double,vector")])
4183 (define_insn "fix_truncdfdi_sse"
4184   [(set (match_operand:DI 0 "register_operand" "=r,r")
4185         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4186   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4187   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4188   [(set_attr "type" "sseicvt")
4189    (set_attr "mode" "DF")
4190    (set_attr "athlon_decode" "double,vector")])
4192 (define_insn "fix_truncsfsi_sse"
4193   [(set (match_operand:SI 0 "register_operand" "=r,r")
4194         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4195   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4196   "cvttss2si\t{%1, %0|%0, %1}"
4197   [(set_attr "type" "sseicvt")
4198    (set_attr "mode" "DF")
4199    (set_attr "athlon_decode" "double,vector")])
4201 (define_insn "fix_truncdfsi_sse"
4202   [(set (match_operand:SI 0 "register_operand" "=r,r")
4203         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4204   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4205   "cvttsd2si\t{%1, %0|%0, %1}"
4206   [(set_attr "type" "sseicvt")
4207    (set_attr "mode" "DF")
4208    (set_attr "athlon_decode" "double,vector")])
4210 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4211 (define_peephole2
4212   [(set (match_operand:DF 0 "register_operand" "")
4213         (match_operand:DF 1 "memory_operand" ""))
4214    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4215         (fix:SSEMODEI24 (match_dup 0)))]
4216   "!TARGET_K8
4217    && peep2_reg_dead_p (2, operands[0])"
4218   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4219   "")
4221 (define_peephole2
4222   [(set (match_operand:SF 0 "register_operand" "")
4223         (match_operand:SF 1 "memory_operand" ""))
4224    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4225         (fix:SSEMODEI24 (match_dup 0)))]
4226   "!TARGET_K8
4227    && peep2_reg_dead_p (2, operands[0])"
4228   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4229   "")
4231 ;; Avoid vector decoded forms of the instruction.
4232 (define_peephole2
4233   [(match_scratch:DF 2 "Y")
4234    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4235         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4236   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4237   [(set (match_dup 2) (match_dup 1))
4238    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4239   "")
4241 (define_peephole2
4242   [(match_scratch:SF 2 "x")
4243    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4244         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4245   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4246   [(set (match_dup 2) (match_dup 1))
4247    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4248   "")
4250 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4251   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4252         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4253   "TARGET_FISTTP
4254    && FLOAT_MODE_P (GET_MODE (operands[1]))
4255    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4256          && (TARGET_64BIT || <MODE>mode != DImode))
4257         && TARGET_SSE_MATH)
4258    && !(reload_completed || reload_in_progress)"
4259   "#"
4260   "&& 1"
4261   [(const_int 0)]
4263   if (memory_operand (operands[0], VOIDmode))
4264     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4265   else
4266     {
4267       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4268       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4269                                                             operands[1],
4270                                                             operands[2]));
4271     }
4272   DONE;
4274   [(set_attr "type" "fisttp")
4275    (set_attr "mode" "<MODE>")])
4277 (define_insn "fix_trunc<mode>_i387_fisttp"
4278   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4279         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4280    (clobber (match_scratch:XF 2 "=&1f"))]
4281   "TARGET_FISTTP
4282    && FLOAT_MODE_P (GET_MODE (operands[1]))
4283    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4284          && (TARGET_64BIT || <MODE>mode != DImode))
4285         && TARGET_SSE_MATH)"
4286   "* return output_fix_trunc (insn, operands, 1);"
4287   [(set_attr "type" "fisttp")
4288    (set_attr "mode" "<MODE>")])
4290 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4291   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4292         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4293    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4294    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4295   "TARGET_FISTTP
4296    && FLOAT_MODE_P (GET_MODE (operands[1]))
4297    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4298         && (TARGET_64BIT || <MODE>mode != DImode))
4299         && TARGET_SSE_MATH)"
4300   "#"
4301   [(set_attr "type" "fisttp")
4302    (set_attr "mode" "<MODE>")])
4304 (define_split
4305   [(set (match_operand:X87MODEI 0 "register_operand" "")
4306         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4307    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4308    (clobber (match_scratch 3 ""))]
4309   "reload_completed"
4310   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4311               (clobber (match_dup 3))])
4312    (set (match_dup 0) (match_dup 2))]
4313   "")
4315 (define_split
4316   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4317         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4318    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4319    (clobber (match_scratch 3 ""))]
4320   "reload_completed"
4321   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4322               (clobber (match_dup 3))])]
4323   "")
4325 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4326 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4327 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4328 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4329 ;; function in i386.c.
4330 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4331   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4332         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4333    (clobber (reg:CC FLAGS_REG))]
4334   "TARGET_80387 && !TARGET_FISTTP
4335    && FLOAT_MODE_P (GET_MODE (operands[1]))
4336    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4337          && (TARGET_64BIT || <MODE>mode != DImode))
4338    && !(reload_completed || reload_in_progress)"
4339   "#"
4340   "&& 1"
4341   [(const_int 0)]
4343   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4345   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4346   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4347   if (memory_operand (operands[0], VOIDmode))
4348     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4349                                          operands[2], operands[3]));
4350   else
4351     {
4352       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4353       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4354                                                      operands[2], operands[3],
4355                                                      operands[4]));
4356     }
4357   DONE;
4359   [(set_attr "type" "fistp")
4360    (set_attr "i387_cw" "trunc")
4361    (set_attr "mode" "<MODE>")])
4363 (define_insn "fix_truncdi_i387"
4364   [(set (match_operand:DI 0 "memory_operand" "=m")
4365         (fix:DI (match_operand 1 "register_operand" "f")))
4366    (use (match_operand:HI 2 "memory_operand" "m"))
4367    (use (match_operand:HI 3 "memory_operand" "m"))
4368    (clobber (match_scratch:XF 4 "=&1f"))]
4369   "TARGET_80387 && !TARGET_FISTTP
4370    && FLOAT_MODE_P (GET_MODE (operands[1]))
4371    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4372   "* return output_fix_trunc (insn, operands, 0);"
4373   [(set_attr "type" "fistp")
4374    (set_attr "i387_cw" "trunc")
4375    (set_attr "mode" "DI")])
4377 (define_insn "fix_truncdi_i387_with_temp"
4378   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4379         (fix:DI (match_operand 1 "register_operand" "f,f")))
4380    (use (match_operand:HI 2 "memory_operand" "m,m"))
4381    (use (match_operand:HI 3 "memory_operand" "m,m"))
4382    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4383    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4384   "TARGET_80387 && !TARGET_FISTTP
4385    && FLOAT_MODE_P (GET_MODE (operands[1]))
4386    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4387   "#"
4388   [(set_attr "type" "fistp")
4389    (set_attr "i387_cw" "trunc")
4390    (set_attr "mode" "DI")])
4392 (define_split
4393   [(set (match_operand:DI 0 "register_operand" "")
4394         (fix:DI (match_operand 1 "register_operand" "")))
4395    (use (match_operand:HI 2 "memory_operand" ""))
4396    (use (match_operand:HI 3 "memory_operand" ""))
4397    (clobber (match_operand:DI 4 "memory_operand" ""))
4398    (clobber (match_scratch 5 ""))]
4399   "reload_completed"
4400   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4401               (use (match_dup 2))
4402               (use (match_dup 3))
4403               (clobber (match_dup 5))])
4404    (set (match_dup 0) (match_dup 4))]
4405   "")
4407 (define_split
4408   [(set (match_operand:DI 0 "memory_operand" "")
4409         (fix:DI (match_operand 1 "register_operand" "")))
4410    (use (match_operand:HI 2 "memory_operand" ""))
4411    (use (match_operand:HI 3 "memory_operand" ""))
4412    (clobber (match_operand:DI 4 "memory_operand" ""))
4413    (clobber (match_scratch 5 ""))]
4414   "reload_completed"
4415   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4416               (use (match_dup 2))
4417               (use (match_dup 3))
4418               (clobber (match_dup 5))])]
4419   "")
4421 (define_insn "fix_trunc<mode>_i387"
4422   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4423         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4424    (use (match_operand:HI 2 "memory_operand" "m"))
4425    (use (match_operand:HI 3 "memory_operand" "m"))]
4426   "TARGET_80387 && !TARGET_FISTTP
4427    && FLOAT_MODE_P (GET_MODE (operands[1]))
4428    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4429   "* return output_fix_trunc (insn, operands, 0);"
4430   [(set_attr "type" "fistp")
4431    (set_attr "i387_cw" "trunc")
4432    (set_attr "mode" "<MODE>")])
4434 (define_insn "fix_trunc<mode>_i387_with_temp"
4435   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4436         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4437    (use (match_operand:HI 2 "memory_operand" "m,m"))
4438    (use (match_operand:HI 3 "memory_operand" "m,m"))
4439    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4440   "TARGET_80387 && !TARGET_FISTTP
4441    && FLOAT_MODE_P (GET_MODE (operands[1]))
4442    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4443   "#"
4444   [(set_attr "type" "fistp")
4445    (set_attr "i387_cw" "trunc")
4446    (set_attr "mode" "<MODE>")])
4448 (define_split
4449   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4450         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4451    (use (match_operand:HI 2 "memory_operand" ""))
4452    (use (match_operand:HI 3 "memory_operand" ""))
4453    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4454   "reload_completed"
4455   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4456               (use (match_dup 2))
4457               (use (match_dup 3))])
4458    (set (match_dup 0) (match_dup 4))]
4459   "")
4461 (define_split
4462   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4463         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4464    (use (match_operand:HI 2 "memory_operand" ""))
4465    (use (match_operand:HI 3 "memory_operand" ""))
4466    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4467   "reload_completed"
4468   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4469               (use (match_dup 2))
4470               (use (match_dup 3))])]
4471   "")
4473 (define_insn "x86_fnstcw_1"
4474   [(set (match_operand:HI 0 "memory_operand" "=m")
4475         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4476   "TARGET_80387"
4477   "fnstcw\t%0"
4478   [(set_attr "length" "2")
4479    (set_attr "mode" "HI")
4480    (set_attr "unit" "i387")])
4482 (define_insn "x86_fldcw_1"
4483   [(set (reg:HI FPCR_REG)
4484         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4485   "TARGET_80387"
4486   "fldcw\t%0"
4487   [(set_attr "length" "2")
4488    (set_attr "mode" "HI")
4489    (set_attr "unit" "i387")
4490    (set_attr "athlon_decode" "vector")])
4492 ;; Conversion between fixed point and floating point.
4494 ;; Even though we only accept memory inputs, the backend _really_
4495 ;; wants to be able to do this between registers.
4497 (define_expand "floathisf2"
4498   [(set (match_operand:SF 0 "register_operand" "")
4499         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4500   "TARGET_80387 || TARGET_SSE_MATH"
4502   if (TARGET_SSE_MATH)
4503     {
4504       emit_insn (gen_floatsisf2 (operands[0],
4505                                  convert_to_mode (SImode, operands[1], 0)));
4506       DONE;
4507     }
4510 (define_insn "*floathisf2_i387"
4511   [(set (match_operand:SF 0 "register_operand" "=f,f")
4512         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4513   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4514   "@
4515    fild%z1\t%1
4516    #"
4517   [(set_attr "type" "fmov,multi")
4518    (set_attr "mode" "SF")
4519    (set_attr "unit" "*,i387")
4520    (set_attr "fp_int_src" "true")])
4522 (define_expand "floatsisf2"
4523   [(set (match_operand:SF 0 "register_operand" "")
4524         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4525   "TARGET_80387 || TARGET_SSE_MATH"
4526   "")
4528 (define_insn "*floatsisf2_mixed"
4529   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4530         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4531   "TARGET_MIX_SSE_I387"
4532   "@
4533    fild%z1\t%1
4534    #
4535    cvtsi2ss\t{%1, %0|%0, %1}
4536    cvtsi2ss\t{%1, %0|%0, %1}"
4537   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4538    (set_attr "mode" "SF")
4539    (set_attr "unit" "*,i387,*,*")
4540    (set_attr "athlon_decode" "*,*,vector,double")
4541    (set_attr "fp_int_src" "true")])
4543 (define_insn "*floatsisf2_sse"
4544   [(set (match_operand:SF 0 "register_operand" "=x,x")
4545         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4546   "TARGET_SSE_MATH"
4547   "cvtsi2ss\t{%1, %0|%0, %1}"
4548   [(set_attr "type" "sseicvt")
4549    (set_attr "mode" "SF")
4550    (set_attr "athlon_decode" "vector,double")
4551    (set_attr "fp_int_src" "true")])
4553 (define_insn "*floatsisf2_i387"
4554   [(set (match_operand:SF 0 "register_operand" "=f,f")
4555         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4556   "TARGET_80387"
4557   "@
4558    fild%z1\t%1
4559    #"
4560   [(set_attr "type" "fmov,multi")
4561    (set_attr "mode" "SF")
4562    (set_attr "unit" "*,i387")
4563    (set_attr "fp_int_src" "true")])
4565 (define_expand "floatdisf2"
4566   [(set (match_operand:SF 0 "register_operand" "")
4567         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4568   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4569   "")
4571 (define_insn "*floatdisf2_mixed"
4572   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4573         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4574   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4575   "@
4576    fild%z1\t%1
4577    #
4578    cvtsi2ss{q}\t{%1, %0|%0, %1}
4579    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4580   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4581    (set_attr "mode" "SF")
4582    (set_attr "unit" "*,i387,*,*")
4583    (set_attr "athlon_decode" "*,*,vector,double")
4584    (set_attr "fp_int_src" "true")])
4586 (define_insn "*floatdisf2_sse"
4587   [(set (match_operand:SF 0 "register_operand" "=x,x")
4588         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4589   "TARGET_64BIT && TARGET_SSE_MATH"
4590   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4591   [(set_attr "type" "sseicvt")
4592    (set_attr "mode" "SF")
4593    (set_attr "athlon_decode" "vector,double")
4594    (set_attr "fp_int_src" "true")])
4596 (define_insn "*floatdisf2_i387"
4597   [(set (match_operand:SF 0 "register_operand" "=f,f")
4598         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4599   "TARGET_80387"
4600   "@
4601    fild%z1\t%1
4602    #"
4603   [(set_attr "type" "fmov,multi")
4604    (set_attr "mode" "SF")
4605    (set_attr "unit" "*,i387")
4606    (set_attr "fp_int_src" "true")])
4608 (define_expand "floathidf2"
4609   [(set (match_operand:DF 0 "register_operand" "")
4610         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4611   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4613   if (TARGET_SSE2 && TARGET_SSE_MATH)
4614     {
4615       emit_insn (gen_floatsidf2 (operands[0],
4616                                  convert_to_mode (SImode, operands[1], 0)));
4617       DONE;
4618     }
4621 (define_insn "*floathidf2_i387"
4622   [(set (match_operand:DF 0 "register_operand" "=f,f")
4623         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4624   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4625   "@
4626    fild%z1\t%1
4627    #"
4628   [(set_attr "type" "fmov,multi")
4629    (set_attr "mode" "DF")
4630    (set_attr "unit" "*,i387")
4631    (set_attr "fp_int_src" "true")])
4633 (define_expand "floatsidf2"
4634   [(set (match_operand:DF 0 "register_operand" "")
4635         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4636   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4637   "")
4639 (define_insn "*floatsidf2_mixed"
4640   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4641         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4642   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4643   "@
4644    fild%z1\t%1
4645    #
4646    cvtsi2sd\t{%1, %0|%0, %1}
4647    cvtsi2sd\t{%1, %0|%0, %1}"
4648   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4649    (set_attr "mode" "DF")
4650    (set_attr "unit" "*,i387,*,*")
4651    (set_attr "athlon_decode" "*,*,double,direct")
4652    (set_attr "fp_int_src" "true")])
4654 (define_insn "*floatsidf2_sse"
4655   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4656         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4657   "TARGET_SSE2 && TARGET_SSE_MATH"
4658   "cvtsi2sd\t{%1, %0|%0, %1}"
4659   [(set_attr "type" "sseicvt")
4660    (set_attr "mode" "DF")
4661    (set_attr "athlon_decode" "double,direct")
4662    (set_attr "fp_int_src" "true")])
4664 (define_insn "*floatsidf2_i387"
4665   [(set (match_operand:DF 0 "register_operand" "=f,f")
4666         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4667   "TARGET_80387"
4668   "@
4669    fild%z1\t%1
4670    #"
4671   [(set_attr "type" "fmov,multi")
4672    (set_attr "mode" "DF")
4673    (set_attr "unit" "*,i387")
4674    (set_attr "fp_int_src" "true")])
4676 (define_expand "floatdidf2"
4677   [(set (match_operand:DF 0 "register_operand" "")
4678         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4679   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4680   "")
4682 (define_insn "*floatdidf2_mixed"
4683   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4684         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4685   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4686   "@
4687    fild%z1\t%1
4688    #
4689    cvtsi2sd{q}\t{%1, %0|%0, %1}
4690    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4691   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4692    (set_attr "mode" "DF")
4693    (set_attr "unit" "*,i387,*,*")
4694    (set_attr "athlon_decode" "*,*,double,direct")
4695    (set_attr "fp_int_src" "true")])
4697 (define_insn "*floatdidf2_sse"
4698   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4699         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4700   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4701   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4702   [(set_attr "type" "sseicvt")
4703    (set_attr "mode" "DF")
4704    (set_attr "athlon_decode" "double,direct")
4705    (set_attr "fp_int_src" "true")])
4707 (define_insn "*floatdidf2_i387"
4708   [(set (match_operand:DF 0 "register_operand" "=f,f")
4709         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4710   "TARGET_80387"
4711   "@
4712    fild%z1\t%1
4713    #"
4714   [(set_attr "type" "fmov,multi")
4715    (set_attr "mode" "DF")
4716    (set_attr "unit" "*,i387")
4717    (set_attr "fp_int_src" "true")])
4719 (define_insn "floathixf2"
4720   [(set (match_operand:XF 0 "register_operand" "=f,f")
4721         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4722   "TARGET_80387"
4723   "@
4724    fild%z1\t%1
4725    #"
4726   [(set_attr "type" "fmov,multi")
4727    (set_attr "mode" "XF")
4728    (set_attr "unit" "*,i387")
4729    (set_attr "fp_int_src" "true")])
4731 (define_insn "floatsixf2"
4732   [(set (match_operand:XF 0 "register_operand" "=f,f")
4733         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4734   "TARGET_80387"
4735   "@
4736    fild%z1\t%1
4737    #"
4738   [(set_attr "type" "fmov,multi")
4739    (set_attr "mode" "XF")
4740    (set_attr "unit" "*,i387")
4741    (set_attr "fp_int_src" "true")])
4743 (define_insn "floatdixf2"
4744   [(set (match_operand:XF 0 "register_operand" "=f,f")
4745         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4746   "TARGET_80387"
4747   "@
4748    fild%z1\t%1
4749    #"
4750   [(set_attr "type" "fmov,multi")
4751    (set_attr "mode" "XF")
4752    (set_attr "unit" "*,i387")
4753    (set_attr "fp_int_src" "true")])
4755 ;; %%% Kill these when reload knows how to do it.
4756 (define_split
4757   [(set (match_operand 0 "fp_register_operand" "")
4758         (float (match_operand 1 "register_operand" "")))]
4759   "reload_completed
4760    && TARGET_80387
4761    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4762   [(const_int 0)]
4764   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4765   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4766   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4767   ix86_free_from_memory (GET_MODE (operands[1]));
4768   DONE;
4771 (define_expand "floatunssisf2"
4772   [(use (match_operand:SF 0 "register_operand" ""))
4773    (use (match_operand:SI 1 "register_operand" ""))]
4774   "!TARGET_64BIT && TARGET_SSE_MATH"
4775   "x86_emit_floatuns (operands); DONE;")
4777 (define_expand "floatunsdisf2"
4778   [(use (match_operand:SF 0 "register_operand" ""))
4779    (use (match_operand:DI 1 "register_operand" ""))]
4780   "TARGET_64BIT && TARGET_SSE_MATH"
4781   "x86_emit_floatuns (operands); DONE;")
4783 (define_expand "floatunsdidf2"
4784   [(use (match_operand:DF 0 "register_operand" ""))
4785    (use (match_operand:DI 1 "register_operand" ""))]
4786   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4787   "x86_emit_floatuns (operands); DONE;")
4789 ;; SSE extract/set expanders
4792 ;; Add instructions
4794 ;; %%% splits for addditi3
4796 (define_expand "addti3"
4797   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4798         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4799                  (match_operand:TI 2 "x86_64_general_operand" "")))
4800    (clobber (reg:CC FLAGS_REG))]
4801   "TARGET_64BIT"
4802   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4804 (define_insn "*addti3_1"
4805   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4806         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4807                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4808    (clobber (reg:CC FLAGS_REG))]
4809   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4810   "#")
4812 (define_split
4813   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4814         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4815                  (match_operand:TI 2 "general_operand" "")))
4816    (clobber (reg:CC FLAGS_REG))]
4817   "TARGET_64BIT && reload_completed"
4818   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4819                                           UNSPEC_ADD_CARRY))
4820               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4821    (parallel [(set (match_dup 3)
4822                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4823                                      (match_dup 4))
4824                             (match_dup 5)))
4825               (clobber (reg:CC FLAGS_REG))])]
4826   "split_ti (operands+0, 1, operands+0, operands+3);
4827    split_ti (operands+1, 1, operands+1, operands+4);
4828    split_ti (operands+2, 1, operands+2, operands+5);")
4830 ;; %%% splits for addsidi3
4831 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4832 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4833 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4835 (define_expand "adddi3"
4836   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4837         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4838                  (match_operand:DI 2 "x86_64_general_operand" "")))
4839    (clobber (reg:CC FLAGS_REG))]
4840   ""
4841   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4843 (define_insn "*adddi3_1"
4844   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4845         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4846                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4847    (clobber (reg:CC FLAGS_REG))]
4848   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4849   "#")
4851 (define_split
4852   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4853         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4854                  (match_operand:DI 2 "general_operand" "")))
4855    (clobber (reg:CC FLAGS_REG))]
4856   "!TARGET_64BIT && reload_completed"
4857   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4858                                           UNSPEC_ADD_CARRY))
4859               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4860    (parallel [(set (match_dup 3)
4861                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4862                                      (match_dup 4))
4863                             (match_dup 5)))
4864               (clobber (reg:CC FLAGS_REG))])]
4865   "split_di (operands+0, 1, operands+0, operands+3);
4866    split_di (operands+1, 1, operands+1, operands+4);
4867    split_di (operands+2, 1, operands+2, operands+5);")
4869 (define_insn "adddi3_carry_rex64"
4870   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4871           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4872                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4873                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4874    (clobber (reg:CC FLAGS_REG))]
4875   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4876   "adc{q}\t{%2, %0|%0, %2}"
4877   [(set_attr "type" "alu")
4878    (set_attr "pent_pair" "pu")
4879    (set_attr "mode" "DI")])
4881 (define_insn "*adddi3_cc_rex64"
4882   [(set (reg:CC FLAGS_REG)
4883         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4884                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4885                    UNSPEC_ADD_CARRY))
4886    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4887         (plus:DI (match_dup 1) (match_dup 2)))]
4888   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4889   "add{q}\t{%2, %0|%0, %2}"
4890   [(set_attr "type" "alu")
4891    (set_attr "mode" "DI")])
4893 (define_insn "addqi3_carry"
4894   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4895           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4896                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4897                    (match_operand:QI 2 "general_operand" "qi,qm")))
4898    (clobber (reg:CC FLAGS_REG))]
4899   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4900   "adc{b}\t{%2, %0|%0, %2}"
4901   [(set_attr "type" "alu")
4902    (set_attr "pent_pair" "pu")
4903    (set_attr "mode" "QI")])
4905 (define_insn "addhi3_carry"
4906   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4907           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4908                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4909                    (match_operand:HI 2 "general_operand" "ri,rm")))
4910    (clobber (reg:CC FLAGS_REG))]
4911   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4912   "adc{w}\t{%2, %0|%0, %2}"
4913   [(set_attr "type" "alu")
4914    (set_attr "pent_pair" "pu")
4915    (set_attr "mode" "HI")])
4917 (define_insn "addsi3_carry"
4918   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4919           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4920                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4921                    (match_operand:SI 2 "general_operand" "ri,rm")))
4922    (clobber (reg:CC FLAGS_REG))]
4923   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4924   "adc{l}\t{%2, %0|%0, %2}"
4925   [(set_attr "type" "alu")
4926    (set_attr "pent_pair" "pu")
4927    (set_attr "mode" "SI")])
4929 (define_insn "*addsi3_carry_zext"
4930   [(set (match_operand:DI 0 "register_operand" "=r")
4931           (zero_extend:DI
4932             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4933                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4934                      (match_operand:SI 2 "general_operand" "rim"))))
4935    (clobber (reg:CC FLAGS_REG))]
4936   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4937   "adc{l}\t{%2, %k0|%k0, %2}"
4938   [(set_attr "type" "alu")
4939    (set_attr "pent_pair" "pu")
4940    (set_attr "mode" "SI")])
4942 (define_insn "*addsi3_cc"
4943   [(set (reg:CC FLAGS_REG)
4944         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4945                     (match_operand:SI 2 "general_operand" "ri,rm")]
4946                    UNSPEC_ADD_CARRY))
4947    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4948         (plus:SI (match_dup 1) (match_dup 2)))]
4949   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4950   "add{l}\t{%2, %0|%0, %2}"
4951   [(set_attr "type" "alu")
4952    (set_attr "mode" "SI")])
4954 (define_insn "addqi3_cc"
4955   [(set (reg:CC FLAGS_REG)
4956         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4957                     (match_operand:QI 2 "general_operand" "qi,qm")]
4958                    UNSPEC_ADD_CARRY))
4959    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4960         (plus:QI (match_dup 1) (match_dup 2)))]
4961   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4962   "add{b}\t{%2, %0|%0, %2}"
4963   [(set_attr "type" "alu")
4964    (set_attr "mode" "QI")])
4966 (define_expand "addsi3"
4967   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4968                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4969                             (match_operand:SI 2 "general_operand" "")))
4970               (clobber (reg:CC FLAGS_REG))])]
4971   ""
4972   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4974 (define_insn "*lea_1"
4975   [(set (match_operand:SI 0 "register_operand" "=r")
4976         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4977   "!TARGET_64BIT"
4978   "lea{l}\t{%a1, %0|%0, %a1}"
4979   [(set_attr "type" "lea")
4980    (set_attr "mode" "SI")])
4982 (define_insn "*lea_1_rex64"
4983   [(set (match_operand:SI 0 "register_operand" "=r")
4984         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4985   "TARGET_64BIT"
4986   "lea{l}\t{%a1, %0|%0, %a1}"
4987   [(set_attr "type" "lea")
4988    (set_attr "mode" "SI")])
4990 (define_insn "*lea_1_zext"
4991   [(set (match_operand:DI 0 "register_operand" "=r")
4992         (zero_extend:DI
4993          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4994   "TARGET_64BIT"
4995   "lea{l}\t{%a1, %k0|%k0, %a1}"
4996   [(set_attr "type" "lea")
4997    (set_attr "mode" "SI")])
4999 (define_insn "*lea_2_rex64"
5000   [(set (match_operand:DI 0 "register_operand" "=r")
5001         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5002   "TARGET_64BIT"
5003   "lea{q}\t{%a1, %0|%0, %a1}"
5004   [(set_attr "type" "lea")
5005    (set_attr "mode" "DI")])
5007 ;; The lea patterns for non-Pmodes needs to be matched by several
5008 ;; insns converted to real lea by splitters.
5010 (define_insn_and_split "*lea_general_1"
5011   [(set (match_operand 0 "register_operand" "=r")
5012         (plus (plus (match_operand 1 "index_register_operand" "l")
5013                     (match_operand 2 "register_operand" "r"))
5014               (match_operand 3 "immediate_operand" "i")))]
5015   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5016     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5017    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5018    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5019    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5020    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5021        || GET_MODE (operands[3]) == VOIDmode)"
5022   "#"
5023   "&& reload_completed"
5024   [(const_int 0)]
5026   rtx pat;
5027   operands[0] = gen_lowpart (SImode, operands[0]);
5028   operands[1] = gen_lowpart (Pmode, operands[1]);
5029   operands[2] = gen_lowpart (Pmode, operands[2]);
5030   operands[3] = gen_lowpart (Pmode, operands[3]);
5031   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5032                       operands[3]);
5033   if (Pmode != SImode)
5034     pat = gen_rtx_SUBREG (SImode, pat, 0);
5035   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5036   DONE;
5038   [(set_attr "type" "lea")
5039    (set_attr "mode" "SI")])
5041 (define_insn_and_split "*lea_general_1_zext"
5042   [(set (match_operand:DI 0 "register_operand" "=r")
5043         (zero_extend:DI
5044           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5045                             (match_operand:SI 2 "register_operand" "r"))
5046                    (match_operand:SI 3 "immediate_operand" "i"))))]
5047   "TARGET_64BIT"
5048   "#"
5049   "&& reload_completed"
5050   [(set (match_dup 0)
5051         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5052                                                      (match_dup 2))
5053                                             (match_dup 3)) 0)))]
5055   operands[1] = gen_lowpart (Pmode, operands[1]);
5056   operands[2] = gen_lowpart (Pmode, operands[2]);
5057   operands[3] = gen_lowpart (Pmode, operands[3]);
5059   [(set_attr "type" "lea")
5060    (set_attr "mode" "SI")])
5062 (define_insn_and_split "*lea_general_2"
5063   [(set (match_operand 0 "register_operand" "=r")
5064         (plus (mult (match_operand 1 "index_register_operand" "l")
5065                     (match_operand 2 "const248_operand" "i"))
5066               (match_operand 3 "nonmemory_operand" "ri")))]
5067   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5068     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5069    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5070    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5071    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5072        || GET_MODE (operands[3]) == VOIDmode)"
5073   "#"
5074   "&& reload_completed"
5075   [(const_int 0)]
5077   rtx pat;
5078   operands[0] = gen_lowpart (SImode, operands[0]);
5079   operands[1] = gen_lowpart (Pmode, operands[1]);
5080   operands[3] = gen_lowpart (Pmode, operands[3]);
5081   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5082                       operands[3]);
5083   if (Pmode != SImode)
5084     pat = gen_rtx_SUBREG (SImode, pat, 0);
5085   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5086   DONE;
5088   [(set_attr "type" "lea")
5089    (set_attr "mode" "SI")])
5091 (define_insn_and_split "*lea_general_2_zext"
5092   [(set (match_operand:DI 0 "register_operand" "=r")
5093         (zero_extend:DI
5094           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5095                             (match_operand:SI 2 "const248_operand" "n"))
5096                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5097   "TARGET_64BIT"
5098   "#"
5099   "&& reload_completed"
5100   [(set (match_dup 0)
5101         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5102                                                      (match_dup 2))
5103                                             (match_dup 3)) 0)))]
5105   operands[1] = gen_lowpart (Pmode, operands[1]);
5106   operands[3] = gen_lowpart (Pmode, operands[3]);
5108   [(set_attr "type" "lea")
5109    (set_attr "mode" "SI")])
5111 (define_insn_and_split "*lea_general_3"
5112   [(set (match_operand 0 "register_operand" "=r")
5113         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5114                           (match_operand 2 "const248_operand" "i"))
5115                     (match_operand 3 "register_operand" "r"))
5116               (match_operand 4 "immediate_operand" "i")))]
5117   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5118     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5119    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5120    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5121    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5122   "#"
5123   "&& reload_completed"
5124   [(const_int 0)]
5126   rtx pat;
5127   operands[0] = gen_lowpart (SImode, operands[0]);
5128   operands[1] = gen_lowpart (Pmode, operands[1]);
5129   operands[3] = gen_lowpart (Pmode, operands[3]);
5130   operands[4] = gen_lowpart (Pmode, operands[4]);
5131   pat = gen_rtx_PLUS (Pmode,
5132                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5133                                                          operands[2]),
5134                                     operands[3]),
5135                       operands[4]);
5136   if (Pmode != SImode)
5137     pat = gen_rtx_SUBREG (SImode, pat, 0);
5138   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5139   DONE;
5141   [(set_attr "type" "lea")
5142    (set_attr "mode" "SI")])
5144 (define_insn_and_split "*lea_general_3_zext"
5145   [(set (match_operand:DI 0 "register_operand" "=r")
5146         (zero_extend:DI
5147           (plus:SI (plus:SI (mult:SI
5148                               (match_operand:SI 1 "index_register_operand" "l")
5149                               (match_operand:SI 2 "const248_operand" "n"))
5150                             (match_operand:SI 3 "register_operand" "r"))
5151                    (match_operand:SI 4 "immediate_operand" "i"))))]
5152   "TARGET_64BIT"
5153   "#"
5154   "&& reload_completed"
5155   [(set (match_dup 0)
5156         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5157                                                               (match_dup 2))
5158                                                      (match_dup 3))
5159                                             (match_dup 4)) 0)))]
5161   operands[1] = gen_lowpart (Pmode, operands[1]);
5162   operands[3] = gen_lowpart (Pmode, operands[3]);
5163   operands[4] = gen_lowpart (Pmode, operands[4]);
5165   [(set_attr "type" "lea")
5166    (set_attr "mode" "SI")])
5168 (define_insn "*adddi_1_rex64"
5169   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5170         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5171                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5172    (clobber (reg:CC FLAGS_REG))]
5173   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5175   switch (get_attr_type (insn))
5176     {
5177     case TYPE_LEA:
5178       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5179       return "lea{q}\t{%a2, %0|%0, %a2}";
5181     case TYPE_INCDEC:
5182       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5183       if (operands[2] == const1_rtx)
5184         return "inc{q}\t%0";
5185       else
5186         {
5187           gcc_assert (operands[2] == constm1_rtx);
5188           return "dec{q}\t%0";
5189         }
5191     default:
5192       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5194       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5195          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5196       if (GET_CODE (operands[2]) == CONST_INT
5197           /* Avoid overflows.  */
5198           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5199           && (INTVAL (operands[2]) == 128
5200               || (INTVAL (operands[2]) < 0
5201                   && INTVAL (operands[2]) != -128)))
5202         {
5203           operands[2] = GEN_INT (-INTVAL (operands[2]));
5204           return "sub{q}\t{%2, %0|%0, %2}";
5205         }
5206       return "add{q}\t{%2, %0|%0, %2}";
5207     }
5209   [(set (attr "type")
5210      (cond [(eq_attr "alternative" "2")
5211               (const_string "lea")
5212             ; Current assemblers are broken and do not allow @GOTOFF in
5213             ; ought but a memory context.
5214             (match_operand:DI 2 "pic_symbolic_operand" "")
5215               (const_string "lea")
5216             (match_operand:DI 2 "incdec_operand" "")
5217               (const_string "incdec")
5218            ]
5219            (const_string "alu")))
5220    (set_attr "mode" "DI")])
5222 ;; Convert lea to the lea pattern to avoid flags dependency.
5223 (define_split
5224   [(set (match_operand:DI 0 "register_operand" "")
5225         (plus:DI (match_operand:DI 1 "register_operand" "")
5226                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5227    (clobber (reg:CC FLAGS_REG))]
5228   "TARGET_64BIT && reload_completed
5229    && true_regnum (operands[0]) != true_regnum (operands[1])"
5230   [(set (match_dup 0)
5231         (plus:DI (match_dup 1)
5232                  (match_dup 2)))]
5233   "")
5235 (define_insn "*adddi_2_rex64"
5236   [(set (reg FLAGS_REG)
5237         (compare
5238           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5239                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5240           (const_int 0)))
5241    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5242         (plus:DI (match_dup 1) (match_dup 2)))]
5243   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5244    && ix86_binary_operator_ok (PLUS, DImode, operands)
5245    /* Current assemblers are broken and do not allow @GOTOFF in
5246       ought but a memory context.  */
5247    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5249   switch (get_attr_type (insn))
5250     {
5251     case TYPE_INCDEC:
5252       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5253       if (operands[2] == const1_rtx)
5254         return "inc{q}\t%0";
5255       else
5256         {
5257           gcc_assert (operands[2] == constm1_rtx);
5258           return "dec{q}\t%0";
5259         }
5261     default:
5262       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5263       /* ???? We ought to handle there the 32bit case too
5264          - do we need new constraint?  */
5265       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5266          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5267       if (GET_CODE (operands[2]) == CONST_INT
5268           /* Avoid overflows.  */
5269           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5270           && (INTVAL (operands[2]) == 128
5271               || (INTVAL (operands[2]) < 0
5272                   && INTVAL (operands[2]) != -128)))
5273         {
5274           operands[2] = GEN_INT (-INTVAL (operands[2]));
5275           return "sub{q}\t{%2, %0|%0, %2}";
5276         }
5277       return "add{q}\t{%2, %0|%0, %2}";
5278     }
5280   [(set (attr "type")
5281      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5282         (const_string "incdec")
5283         (const_string "alu")))
5284    (set_attr "mode" "DI")])
5286 (define_insn "*adddi_3_rex64"
5287   [(set (reg FLAGS_REG)
5288         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5289                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5290    (clobber (match_scratch:DI 0 "=r"))]
5291   "TARGET_64BIT
5292    && ix86_match_ccmode (insn, CCZmode)
5293    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5294    /* Current assemblers are broken and do not allow @GOTOFF in
5295       ought but a memory context.  */
5296    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5298   switch (get_attr_type (insn))
5299     {
5300     case TYPE_INCDEC:
5301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5302       if (operands[2] == const1_rtx)
5303         return "inc{q}\t%0";
5304       else
5305         {
5306           gcc_assert (operands[2] == constm1_rtx);
5307           return "dec{q}\t%0";
5308         }
5310     default:
5311       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5312       /* ???? We ought to handle there the 32bit case too
5313          - do we need new constraint?  */
5314       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5315          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5316       if (GET_CODE (operands[2]) == CONST_INT
5317           /* Avoid overflows.  */
5318           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5319           && (INTVAL (operands[2]) == 128
5320               || (INTVAL (operands[2]) < 0
5321                   && INTVAL (operands[2]) != -128)))
5322         {
5323           operands[2] = GEN_INT (-INTVAL (operands[2]));
5324           return "sub{q}\t{%2, %0|%0, %2}";
5325         }
5326       return "add{q}\t{%2, %0|%0, %2}";
5327     }
5329   [(set (attr "type")
5330      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5331         (const_string "incdec")
5332         (const_string "alu")))
5333    (set_attr "mode" "DI")])
5335 ; For comparisons against 1, -1 and 128, we may generate better code
5336 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5337 ; is matched then.  We can't accept general immediate, because for
5338 ; case of overflows,  the result is messed up.
5339 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5340 ; when negated.
5341 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5342 ; only for comparisons not depending on it.
5343 (define_insn "*adddi_4_rex64"
5344   [(set (reg FLAGS_REG)
5345         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5346                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5347    (clobber (match_scratch:DI 0 "=rm"))]
5348   "TARGET_64BIT
5349    &&  ix86_match_ccmode (insn, CCGCmode)"
5351   switch (get_attr_type (insn))
5352     {
5353     case TYPE_INCDEC:
5354       if (operands[2] == constm1_rtx)
5355         return "inc{q}\t%0";
5356       else
5357         {
5358           gcc_assert (operands[2] == const1_rtx);
5359           return "dec{q}\t%0";
5360         }
5362     default:
5363       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5364       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5365          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5366       if ((INTVAL (operands[2]) == -128
5367            || (INTVAL (operands[2]) > 0
5368                && INTVAL (operands[2]) != 128))
5369           /* Avoid overflows.  */
5370           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5371         return "sub{q}\t{%2, %0|%0, %2}";
5372       operands[2] = GEN_INT (-INTVAL (operands[2]));
5373       return "add{q}\t{%2, %0|%0, %2}";
5374     }
5376   [(set (attr "type")
5377      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378         (const_string "incdec")
5379         (const_string "alu")))
5380    (set_attr "mode" "DI")])
5382 (define_insn "*adddi_5_rex64"
5383   [(set (reg FLAGS_REG)
5384         (compare
5385           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5386                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5387           (const_int 0)))
5388    (clobber (match_scratch:DI 0 "=r"))]
5389   "TARGET_64BIT
5390    && ix86_match_ccmode (insn, CCGOCmode)
5391    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5392    /* Current assemblers are broken and do not allow @GOTOFF in
5393       ought but a memory context.  */
5394    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5396   switch (get_attr_type (insn))
5397     {
5398     case TYPE_INCDEC:
5399       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5400       if (operands[2] == const1_rtx)
5401         return "inc{q}\t%0";
5402       else
5403         {
5404           gcc_assert (operands[2] == constm1_rtx);
5405           return "dec{q}\t%0";
5406         }
5408     default:
5409       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5410       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5411          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5412       if (GET_CODE (operands[2]) == CONST_INT
5413           /* Avoid overflows.  */
5414           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5415           && (INTVAL (operands[2]) == 128
5416               || (INTVAL (operands[2]) < 0
5417                   && INTVAL (operands[2]) != -128)))
5418         {
5419           operands[2] = GEN_INT (-INTVAL (operands[2]));
5420           return "sub{q}\t{%2, %0|%0, %2}";
5421         }
5422       return "add{q}\t{%2, %0|%0, %2}";
5423     }
5425   [(set (attr "type")
5426      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5427         (const_string "incdec")
5428         (const_string "alu")))
5429    (set_attr "mode" "DI")])
5432 (define_insn "*addsi_1"
5433   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5434         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5435                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5436    (clobber (reg:CC FLAGS_REG))]
5437   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5439   switch (get_attr_type (insn))
5440     {
5441     case TYPE_LEA:
5442       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5443       return "lea{l}\t{%a2, %0|%0, %a2}";
5445     case TYPE_INCDEC:
5446       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5447       if (operands[2] == const1_rtx)
5448         return "inc{l}\t%0";
5449       else
5450         {
5451           gcc_assert (operands[2] == constm1_rtx);
5452           return "dec{l}\t%0";
5453         }
5455     default:
5456       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5458       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5459          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5460       if (GET_CODE (operands[2]) == CONST_INT
5461           && (INTVAL (operands[2]) == 128
5462               || (INTVAL (operands[2]) < 0
5463                   && INTVAL (operands[2]) != -128)))
5464         {
5465           operands[2] = GEN_INT (-INTVAL (operands[2]));
5466           return "sub{l}\t{%2, %0|%0, %2}";
5467         }
5468       return "add{l}\t{%2, %0|%0, %2}";
5469     }
5471   [(set (attr "type")
5472      (cond [(eq_attr "alternative" "2")
5473               (const_string "lea")
5474             ; Current assemblers are broken and do not allow @GOTOFF in
5475             ; ought but a memory context.
5476             (match_operand:SI 2 "pic_symbolic_operand" "")
5477               (const_string "lea")
5478             (match_operand:SI 2 "incdec_operand" "")
5479               (const_string "incdec")
5480            ]
5481            (const_string "alu")))
5482    (set_attr "mode" "SI")])
5484 ;; Convert lea to the lea pattern to avoid flags dependency.
5485 (define_split
5486   [(set (match_operand 0 "register_operand" "")
5487         (plus (match_operand 1 "register_operand" "")
5488               (match_operand 2 "nonmemory_operand" "")))
5489    (clobber (reg:CC FLAGS_REG))]
5490   "reload_completed
5491    && true_regnum (operands[0]) != true_regnum (operands[1])"
5492   [(const_int 0)]
5494   rtx pat;
5495   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5496      may confuse gen_lowpart.  */
5497   if (GET_MODE (operands[0]) != Pmode)
5498     {
5499       operands[1] = gen_lowpart (Pmode, operands[1]);
5500       operands[2] = gen_lowpart (Pmode, operands[2]);
5501     }
5502   operands[0] = gen_lowpart (SImode, operands[0]);
5503   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5504   if (Pmode != SImode)
5505     pat = gen_rtx_SUBREG (SImode, pat, 0);
5506   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5507   DONE;
5510 ;; It may seem that nonimmediate operand is proper one for operand 1.
5511 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5512 ;; we take care in ix86_binary_operator_ok to not allow two memory
5513 ;; operands so proper swapping will be done in reload.  This allow
5514 ;; patterns constructed from addsi_1 to match.
5515 (define_insn "addsi_1_zext"
5516   [(set (match_operand:DI 0 "register_operand" "=r,r")
5517         (zero_extend:DI
5518           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5519                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5520    (clobber (reg:CC FLAGS_REG))]
5521   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5523   switch (get_attr_type (insn))
5524     {
5525     case TYPE_LEA:
5526       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5527       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5529     case TYPE_INCDEC:
5530       if (operands[2] == const1_rtx)
5531         return "inc{l}\t%k0";
5532       else
5533         {
5534           gcc_assert (operands[2] == constm1_rtx);
5535           return "dec{l}\t%k0";
5536         }
5538     default:
5539       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5540          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5541       if (GET_CODE (operands[2]) == CONST_INT
5542           && (INTVAL (operands[2]) == 128
5543               || (INTVAL (operands[2]) < 0
5544                   && INTVAL (operands[2]) != -128)))
5545         {
5546           operands[2] = GEN_INT (-INTVAL (operands[2]));
5547           return "sub{l}\t{%2, %k0|%k0, %2}";
5548         }
5549       return "add{l}\t{%2, %k0|%k0, %2}";
5550     }
5552   [(set (attr "type")
5553      (cond [(eq_attr "alternative" "1")
5554               (const_string "lea")
5555             ; Current assemblers are broken and do not allow @GOTOFF in
5556             ; ought but a memory context.
5557             (match_operand:SI 2 "pic_symbolic_operand" "")
5558               (const_string "lea")
5559             (match_operand:SI 2 "incdec_operand" "")
5560               (const_string "incdec")
5561            ]
5562            (const_string "alu")))
5563    (set_attr "mode" "SI")])
5565 ;; Convert lea to the lea pattern to avoid flags dependency.
5566 (define_split
5567   [(set (match_operand:DI 0 "register_operand" "")
5568         (zero_extend:DI
5569           (plus:SI (match_operand:SI 1 "register_operand" "")
5570                    (match_operand:SI 2 "nonmemory_operand" ""))))
5571    (clobber (reg:CC FLAGS_REG))]
5572   "TARGET_64BIT && reload_completed
5573    && true_regnum (operands[0]) != true_regnum (operands[1])"
5574   [(set (match_dup 0)
5575         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5577   operands[1] = gen_lowpart (Pmode, operands[1]);
5578   operands[2] = gen_lowpart (Pmode, operands[2]);
5581 (define_insn "*addsi_2"
5582   [(set (reg FLAGS_REG)
5583         (compare
5584           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5585                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5586           (const_int 0)))
5587    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5588         (plus:SI (match_dup 1) (match_dup 2)))]
5589   "ix86_match_ccmode (insn, CCGOCmode)
5590    && ix86_binary_operator_ok (PLUS, SImode, operands)
5591    /* Current assemblers are broken and do not allow @GOTOFF in
5592       ought but a memory context.  */
5593    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5595   switch (get_attr_type (insn))
5596     {
5597     case TYPE_INCDEC:
5598       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599       if (operands[2] == const1_rtx)
5600         return "inc{l}\t%0";
5601       else
5602         {
5603           gcc_assert (operands[2] == constm1_rtx);
5604           return "dec{l}\t%0";
5605         }
5607     default:
5608       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5610          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5611       if (GET_CODE (operands[2]) == CONST_INT
5612           && (INTVAL (operands[2]) == 128
5613               || (INTVAL (operands[2]) < 0
5614                   && INTVAL (operands[2]) != -128)))
5615         {
5616           operands[2] = GEN_INT (-INTVAL (operands[2]));
5617           return "sub{l}\t{%2, %0|%0, %2}";
5618         }
5619       return "add{l}\t{%2, %0|%0, %2}";
5620     }
5622   [(set (attr "type")
5623      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5624         (const_string "incdec")
5625         (const_string "alu")))
5626    (set_attr "mode" "SI")])
5628 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5629 (define_insn "*addsi_2_zext"
5630   [(set (reg FLAGS_REG)
5631         (compare
5632           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5633                    (match_operand:SI 2 "general_operand" "rmni"))
5634           (const_int 0)))
5635    (set (match_operand:DI 0 "register_operand" "=r")
5636         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5637   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5638    && ix86_binary_operator_ok (PLUS, SImode, operands)
5639    /* Current assemblers are broken and do not allow @GOTOFF in
5640       ought but a memory context.  */
5641    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5643   switch (get_attr_type (insn))
5644     {
5645     case TYPE_INCDEC:
5646       if (operands[2] == const1_rtx)
5647         return "inc{l}\t%k0";
5648       else
5649         {
5650           gcc_assert (operands[2] == constm1_rtx);
5651           return "dec{l}\t%k0";
5652         }
5654     default:
5655       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5657       if (GET_CODE (operands[2]) == CONST_INT
5658           && (INTVAL (operands[2]) == 128
5659               || (INTVAL (operands[2]) < 0
5660                   && INTVAL (operands[2]) != -128)))
5661         {
5662           operands[2] = GEN_INT (-INTVAL (operands[2]));
5663           return "sub{l}\t{%2, %k0|%k0, %2}";
5664         }
5665       return "add{l}\t{%2, %k0|%k0, %2}";
5666     }
5668   [(set (attr "type")
5669      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670         (const_string "incdec")
5671         (const_string "alu")))
5672    (set_attr "mode" "SI")])
5674 (define_insn "*addsi_3"
5675   [(set (reg FLAGS_REG)
5676         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5677                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5678    (clobber (match_scratch:SI 0 "=r"))]
5679   "ix86_match_ccmode (insn, CCZmode)
5680    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5681    /* Current assemblers are broken and do not allow @GOTOFF in
5682       ought but a memory context.  */
5683    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5685   switch (get_attr_type (insn))
5686     {
5687     case TYPE_INCDEC:
5688       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689       if (operands[2] == const1_rtx)
5690         return "inc{l}\t%0";
5691       else
5692         {
5693           gcc_assert (operands[2] == constm1_rtx);
5694           return "dec{l}\t%0";
5695         }
5697     default:
5698       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5700          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5701       if (GET_CODE (operands[2]) == CONST_INT
5702           && (INTVAL (operands[2]) == 128
5703               || (INTVAL (operands[2]) < 0
5704                   && INTVAL (operands[2]) != -128)))
5705         {
5706           operands[2] = GEN_INT (-INTVAL (operands[2]));
5707           return "sub{l}\t{%2, %0|%0, %2}";
5708         }
5709       return "add{l}\t{%2, %0|%0, %2}";
5710     }
5712   [(set (attr "type")
5713      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5714         (const_string "incdec")
5715         (const_string "alu")))
5716    (set_attr "mode" "SI")])
5718 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5719 (define_insn "*addsi_3_zext"
5720   [(set (reg FLAGS_REG)
5721         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5722                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5723    (set (match_operand:DI 0 "register_operand" "=r")
5724         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5725   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5726    && ix86_binary_operator_ok (PLUS, SImode, operands)
5727    /* Current assemblers are broken and do not allow @GOTOFF in
5728       ought but a memory context.  */
5729    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5731   switch (get_attr_type (insn))
5732     {
5733     case TYPE_INCDEC:
5734       if (operands[2] == const1_rtx)
5735         return "inc{l}\t%k0";
5736       else
5737         {
5738           gcc_assert (operands[2] == constm1_rtx);
5739           return "dec{l}\t%k0";
5740         }
5742     default:
5743       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5744          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5745       if (GET_CODE (operands[2]) == CONST_INT
5746           && (INTVAL (operands[2]) == 128
5747               || (INTVAL (operands[2]) < 0
5748                   && INTVAL (operands[2]) != -128)))
5749         {
5750           operands[2] = GEN_INT (-INTVAL (operands[2]));
5751           return "sub{l}\t{%2, %k0|%k0, %2}";
5752         }
5753       return "add{l}\t{%2, %k0|%k0, %2}";
5754     }
5756   [(set (attr "type")
5757      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5758         (const_string "incdec")
5759         (const_string "alu")))
5760    (set_attr "mode" "SI")])
5762 ; For comparisons against 1, -1 and 128, we may generate better code
5763 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5764 ; is matched then.  We can't accept general immediate, because for
5765 ; case of overflows,  the result is messed up.
5766 ; This pattern also don't hold of 0x80000000, since the value overflows
5767 ; when negated.
5768 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5769 ; only for comparisons not depending on it.
5770 (define_insn "*addsi_4"
5771   [(set (reg FLAGS_REG)
5772         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5773                  (match_operand:SI 2 "const_int_operand" "n")))
5774    (clobber (match_scratch:SI 0 "=rm"))]
5775   "ix86_match_ccmode (insn, CCGCmode)
5776    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5778   switch (get_attr_type (insn))
5779     {
5780     case TYPE_INCDEC:
5781       if (operands[2] == constm1_rtx)
5782         return "inc{l}\t%0";
5783       else
5784         {
5785           gcc_assert (operands[2] == const1_rtx);
5786           return "dec{l}\t%0";
5787         }
5789     default:
5790       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5791       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5792          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5793       if ((INTVAL (operands[2]) == -128
5794            || (INTVAL (operands[2]) > 0
5795                && INTVAL (operands[2]) != 128)))
5796         return "sub{l}\t{%2, %0|%0, %2}";
5797       operands[2] = GEN_INT (-INTVAL (operands[2]));
5798       return "add{l}\t{%2, %0|%0, %2}";
5799     }
5801   [(set (attr "type")
5802      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5803         (const_string "incdec")
5804         (const_string "alu")))
5805    (set_attr "mode" "SI")])
5807 (define_insn "*addsi_5"
5808   [(set (reg FLAGS_REG)
5809         (compare
5810           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5811                    (match_operand:SI 2 "general_operand" "rmni"))
5812           (const_int 0)))
5813    (clobber (match_scratch:SI 0 "=r"))]
5814   "ix86_match_ccmode (insn, CCGOCmode)
5815    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5816    /* Current assemblers are broken and do not allow @GOTOFF in
5817       ought but a memory context.  */
5818    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5820   switch (get_attr_type (insn))
5821     {
5822     case TYPE_INCDEC:
5823       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5824       if (operands[2] == const1_rtx)
5825         return "inc{l}\t%0";
5826       else
5827         {
5828           gcc_assert (operands[2] == constm1_rtx);
5829           return "dec{l}\t%0";
5830         }
5832     default:
5833       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5834       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5835          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5836       if (GET_CODE (operands[2]) == CONST_INT
5837           && (INTVAL (operands[2]) == 128
5838               || (INTVAL (operands[2]) < 0
5839                   && INTVAL (operands[2]) != -128)))
5840         {
5841           operands[2] = GEN_INT (-INTVAL (operands[2]));
5842           return "sub{l}\t{%2, %0|%0, %2}";
5843         }
5844       return "add{l}\t{%2, %0|%0, %2}";
5845     }
5847   [(set (attr "type")
5848      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5849         (const_string "incdec")
5850         (const_string "alu")))
5851    (set_attr "mode" "SI")])
5853 (define_expand "addhi3"
5854   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5855                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5856                             (match_operand:HI 2 "general_operand" "")))
5857               (clobber (reg:CC FLAGS_REG))])]
5858   "TARGET_HIMODE_MATH"
5859   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5861 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5862 ;; type optimizations enabled by define-splits.  This is not important
5863 ;; for PII, and in fact harmful because of partial register stalls.
5865 (define_insn "*addhi_1_lea"
5866   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5867         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5868                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5869    (clobber (reg:CC FLAGS_REG))]
5870   "!TARGET_PARTIAL_REG_STALL
5871    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5873   switch (get_attr_type (insn))
5874     {
5875     case TYPE_LEA:
5876       return "#";
5877     case TYPE_INCDEC:
5878       if (operands[2] == const1_rtx)
5879         return "inc{w}\t%0";
5880       else
5881         {
5882           gcc_assert (operands[2] == constm1_rtx);
5883           return "dec{w}\t%0";
5884         }
5886     default:
5887       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5888          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5889       if (GET_CODE (operands[2]) == CONST_INT
5890           && (INTVAL (operands[2]) == 128
5891               || (INTVAL (operands[2]) < 0
5892                   && INTVAL (operands[2]) != -128)))
5893         {
5894           operands[2] = GEN_INT (-INTVAL (operands[2]));
5895           return "sub{w}\t{%2, %0|%0, %2}";
5896         }
5897       return "add{w}\t{%2, %0|%0, %2}";
5898     }
5900   [(set (attr "type")
5901      (if_then_else (eq_attr "alternative" "2")
5902         (const_string "lea")
5903         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5904            (const_string "incdec")
5905            (const_string "alu"))))
5906    (set_attr "mode" "HI,HI,SI")])
5908 (define_insn "*addhi_1"
5909   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5910         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5911                  (match_operand:HI 2 "general_operand" "ri,rm")))
5912    (clobber (reg:CC FLAGS_REG))]
5913   "TARGET_PARTIAL_REG_STALL
5914    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5916   switch (get_attr_type (insn))
5917     {
5918     case TYPE_INCDEC:
5919       if (operands[2] == const1_rtx)
5920         return "inc{w}\t%0";
5921       else
5922         {
5923           gcc_assert (operands[2] == constm1_rtx);
5924           return "dec{w}\t%0";
5925         }
5927     default:
5928       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5929          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5930       if (GET_CODE (operands[2]) == CONST_INT
5931           && (INTVAL (operands[2]) == 128
5932               || (INTVAL (operands[2]) < 0
5933                   && INTVAL (operands[2]) != -128)))
5934         {
5935           operands[2] = GEN_INT (-INTVAL (operands[2]));
5936           return "sub{w}\t{%2, %0|%0, %2}";
5937         }
5938       return "add{w}\t{%2, %0|%0, %2}";
5939     }
5941   [(set (attr "type")
5942      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5943         (const_string "incdec")
5944         (const_string "alu")))
5945    (set_attr "mode" "HI")])
5947 (define_insn "*addhi_2"
5948   [(set (reg FLAGS_REG)
5949         (compare
5950           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5951                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5952           (const_int 0)))
5953    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5954         (plus:HI (match_dup 1) (match_dup 2)))]
5955   "ix86_match_ccmode (insn, CCGOCmode)
5956    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5958   switch (get_attr_type (insn))
5959     {
5960     case TYPE_INCDEC:
5961       if (operands[2] == const1_rtx)
5962         return "inc{w}\t%0";
5963       else
5964         {
5965           gcc_assert (operands[2] == constm1_rtx);
5966           return "dec{w}\t%0";
5967         }
5969     default:
5970       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5971          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5972       if (GET_CODE (operands[2]) == CONST_INT
5973           && (INTVAL (operands[2]) == 128
5974               || (INTVAL (operands[2]) < 0
5975                   && INTVAL (operands[2]) != -128)))
5976         {
5977           operands[2] = GEN_INT (-INTVAL (operands[2]));
5978           return "sub{w}\t{%2, %0|%0, %2}";
5979         }
5980       return "add{w}\t{%2, %0|%0, %2}";
5981     }
5983   [(set (attr "type")
5984      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5985         (const_string "incdec")
5986         (const_string "alu")))
5987    (set_attr "mode" "HI")])
5989 (define_insn "*addhi_3"
5990   [(set (reg FLAGS_REG)
5991         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5992                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5993    (clobber (match_scratch:HI 0 "=r"))]
5994   "ix86_match_ccmode (insn, CCZmode)
5995    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5997   switch (get_attr_type (insn))
5998     {
5999     case TYPE_INCDEC:
6000       if (operands[2] == const1_rtx)
6001         return "inc{w}\t%0";
6002       else
6003         {
6004           gcc_assert (operands[2] == constm1_rtx);
6005           return "dec{w}\t%0";
6006         }
6008     default:
6009       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6011       if (GET_CODE (operands[2]) == CONST_INT
6012           && (INTVAL (operands[2]) == 128
6013               || (INTVAL (operands[2]) < 0
6014                   && INTVAL (operands[2]) != -128)))
6015         {
6016           operands[2] = GEN_INT (-INTVAL (operands[2]));
6017           return "sub{w}\t{%2, %0|%0, %2}";
6018         }
6019       return "add{w}\t{%2, %0|%0, %2}";
6020     }
6022   [(set (attr "type")
6023      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6024         (const_string "incdec")
6025         (const_string "alu")))
6026    (set_attr "mode" "HI")])
6028 ; See comments above addsi_4 for details.
6029 (define_insn "*addhi_4"
6030   [(set (reg FLAGS_REG)
6031         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6032                  (match_operand:HI 2 "const_int_operand" "n")))
6033    (clobber (match_scratch:HI 0 "=rm"))]
6034   "ix86_match_ccmode (insn, CCGCmode)
6035    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6037   switch (get_attr_type (insn))
6038     {
6039     case TYPE_INCDEC:
6040       if (operands[2] == constm1_rtx)
6041         return "inc{w}\t%0";
6042       else
6043         {
6044           gcc_assert (operands[2] == const1_rtx);
6045           return "dec{w}\t%0";
6046         }
6048     default:
6049       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6050       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6051          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6052       if ((INTVAL (operands[2]) == -128
6053            || (INTVAL (operands[2]) > 0
6054                && INTVAL (operands[2]) != 128)))
6055         return "sub{w}\t{%2, %0|%0, %2}";
6056       operands[2] = GEN_INT (-INTVAL (operands[2]));
6057       return "add{w}\t{%2, %0|%0, %2}";
6058     }
6060   [(set (attr "type")
6061      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6062         (const_string "incdec")
6063         (const_string "alu")))
6064    (set_attr "mode" "SI")])
6067 (define_insn "*addhi_5"
6068   [(set (reg FLAGS_REG)
6069         (compare
6070           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6071                    (match_operand:HI 2 "general_operand" "rmni"))
6072           (const_int 0)))
6073    (clobber (match_scratch:HI 0 "=r"))]
6074   "ix86_match_ccmode (insn, CCGOCmode)
6075    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6077   switch (get_attr_type (insn))
6078     {
6079     case TYPE_INCDEC:
6080       if (operands[2] == const1_rtx)
6081         return "inc{w}\t%0";
6082       else
6083         {
6084           gcc_assert (operands[2] == constm1_rtx);
6085           return "dec{w}\t%0";
6086         }
6088     default:
6089       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6090          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6091       if (GET_CODE (operands[2]) == CONST_INT
6092           && (INTVAL (operands[2]) == 128
6093               || (INTVAL (operands[2]) < 0
6094                   && INTVAL (operands[2]) != -128)))
6095         {
6096           operands[2] = GEN_INT (-INTVAL (operands[2]));
6097           return "sub{w}\t{%2, %0|%0, %2}";
6098         }
6099       return "add{w}\t{%2, %0|%0, %2}";
6100     }
6102   [(set (attr "type")
6103      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6104         (const_string "incdec")
6105         (const_string "alu")))
6106    (set_attr "mode" "HI")])
6108 (define_expand "addqi3"
6109   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6110                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6111                             (match_operand:QI 2 "general_operand" "")))
6112               (clobber (reg:CC FLAGS_REG))])]
6113   "TARGET_QIMODE_MATH"
6114   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6116 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6117 (define_insn "*addqi_1_lea"
6118   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6119         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6120                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6121    (clobber (reg:CC FLAGS_REG))]
6122   "!TARGET_PARTIAL_REG_STALL
6123    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6125   int widen = (which_alternative == 2);
6126   switch (get_attr_type (insn))
6127     {
6128     case TYPE_LEA:
6129       return "#";
6130     case TYPE_INCDEC:
6131       if (operands[2] == const1_rtx)
6132         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6133       else
6134         {
6135           gcc_assert (operands[2] == constm1_rtx);
6136           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6137         }
6139     default:
6140       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6141          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6142       if (GET_CODE (operands[2]) == CONST_INT
6143           && (INTVAL (operands[2]) == 128
6144               || (INTVAL (operands[2]) < 0
6145                   && INTVAL (operands[2]) != -128)))
6146         {
6147           operands[2] = GEN_INT (-INTVAL (operands[2]));
6148           if (widen)
6149             return "sub{l}\t{%2, %k0|%k0, %2}";
6150           else
6151             return "sub{b}\t{%2, %0|%0, %2}";
6152         }
6153       if (widen)
6154         return "add{l}\t{%k2, %k0|%k0, %k2}";
6155       else
6156         return "add{b}\t{%2, %0|%0, %2}";
6157     }
6159   [(set (attr "type")
6160      (if_then_else (eq_attr "alternative" "3")
6161         (const_string "lea")
6162         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6163            (const_string "incdec")
6164            (const_string "alu"))))
6165    (set_attr "mode" "QI,QI,SI,SI")])
6167 (define_insn "*addqi_1"
6168   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6169         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6170                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6171    (clobber (reg:CC FLAGS_REG))]
6172   "TARGET_PARTIAL_REG_STALL
6173    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6175   int widen = (which_alternative == 2);
6176   switch (get_attr_type (insn))
6177     {
6178     case TYPE_INCDEC:
6179       if (operands[2] == const1_rtx)
6180         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6181       else
6182         {
6183           gcc_assert (operands[2] == constm1_rtx);
6184           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6185         }
6187     default:
6188       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6189          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6190       if (GET_CODE (operands[2]) == CONST_INT
6191           && (INTVAL (operands[2]) == 128
6192               || (INTVAL (operands[2]) < 0
6193                   && INTVAL (operands[2]) != -128)))
6194         {
6195           operands[2] = GEN_INT (-INTVAL (operands[2]));
6196           if (widen)
6197             return "sub{l}\t{%2, %k0|%k0, %2}";
6198           else
6199             return "sub{b}\t{%2, %0|%0, %2}";
6200         }
6201       if (widen)
6202         return "add{l}\t{%k2, %k0|%k0, %k2}";
6203       else
6204         return "add{b}\t{%2, %0|%0, %2}";
6205     }
6207   [(set (attr "type")
6208      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6209         (const_string "incdec")
6210         (const_string "alu")))
6211    (set_attr "mode" "QI,QI,SI")])
6213 (define_insn "*addqi_1_slp"
6214   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6215         (plus:QI (match_dup 0)
6216                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6217    (clobber (reg:CC FLAGS_REG))]
6218   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6219    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6221   switch (get_attr_type (insn))
6222     {
6223     case TYPE_INCDEC:
6224       if (operands[1] == const1_rtx)
6225         return "inc{b}\t%0";
6226       else
6227         {
6228           gcc_assert (operands[1] == constm1_rtx);
6229           return "dec{b}\t%0";
6230         }
6232     default:
6233       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6234       if (GET_CODE (operands[1]) == CONST_INT
6235           && INTVAL (operands[1]) < 0)
6236         {
6237           operands[1] = GEN_INT (-INTVAL (operands[1]));
6238           return "sub{b}\t{%1, %0|%0, %1}";
6239         }
6240       return "add{b}\t{%1, %0|%0, %1}";
6241     }
6243   [(set (attr "type")
6244      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6245         (const_string "incdec")
6246         (const_string "alu1")))
6247    (set (attr "memory")
6248      (if_then_else (match_operand 1 "memory_operand" "")
6249         (const_string "load")
6250         (const_string "none")))
6251    (set_attr "mode" "QI")])
6253 (define_insn "*addqi_2"
6254   [(set (reg FLAGS_REG)
6255         (compare
6256           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6257                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6258           (const_int 0)))
6259    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6260         (plus:QI (match_dup 1) (match_dup 2)))]
6261   "ix86_match_ccmode (insn, CCGOCmode)
6262    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6264   switch (get_attr_type (insn))
6265     {
6266     case TYPE_INCDEC:
6267       if (operands[2] == const1_rtx)
6268         return "inc{b}\t%0";
6269       else
6270         {
6271           gcc_assert (operands[2] == constm1_rtx
6272                       || (GET_CODE (operands[2]) == CONST_INT
6273                           && INTVAL (operands[2]) == 255));
6274           return "dec{b}\t%0";
6275         }
6277     default:
6278       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6279       if (GET_CODE (operands[2]) == CONST_INT
6280           && INTVAL (operands[2]) < 0)
6281         {
6282           operands[2] = GEN_INT (-INTVAL (operands[2]));
6283           return "sub{b}\t{%2, %0|%0, %2}";
6284         }
6285       return "add{b}\t{%2, %0|%0, %2}";
6286     }
6288   [(set (attr "type")
6289      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6290         (const_string "incdec")
6291         (const_string "alu")))
6292    (set_attr "mode" "QI")])
6294 (define_insn "*addqi_3"
6295   [(set (reg FLAGS_REG)
6296         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6297                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6298    (clobber (match_scratch:QI 0 "=q"))]
6299   "ix86_match_ccmode (insn, CCZmode)
6300    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6302   switch (get_attr_type (insn))
6303     {
6304     case TYPE_INCDEC:
6305       if (operands[2] == const1_rtx)
6306         return "inc{b}\t%0";
6307       else
6308         {
6309           gcc_assert (operands[2] == constm1_rtx
6310                       || (GET_CODE (operands[2]) == CONST_INT
6311                           && INTVAL (operands[2]) == 255));
6312           return "dec{b}\t%0";
6313         }
6315     default:
6316       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6317       if (GET_CODE (operands[2]) == CONST_INT
6318           && INTVAL (operands[2]) < 0)
6319         {
6320           operands[2] = GEN_INT (-INTVAL (operands[2]));
6321           return "sub{b}\t{%2, %0|%0, %2}";
6322         }
6323       return "add{b}\t{%2, %0|%0, %2}";
6324     }
6326   [(set (attr "type")
6327      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6328         (const_string "incdec")
6329         (const_string "alu")))
6330    (set_attr "mode" "QI")])
6332 ; See comments above addsi_4 for details.
6333 (define_insn "*addqi_4"
6334   [(set (reg FLAGS_REG)
6335         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6336                  (match_operand:QI 2 "const_int_operand" "n")))
6337    (clobber (match_scratch:QI 0 "=qm"))]
6338   "ix86_match_ccmode (insn, CCGCmode)
6339    && (INTVAL (operands[2]) & 0xff) != 0x80"
6341   switch (get_attr_type (insn))
6342     {
6343     case TYPE_INCDEC:
6344       if (operands[2] == constm1_rtx
6345           || (GET_CODE (operands[2]) == CONST_INT
6346               && INTVAL (operands[2]) == 255))
6347         return "inc{b}\t%0";
6348       else
6349         {
6350           gcc_assert (operands[2] == const1_rtx);
6351           return "dec{b}\t%0";
6352         }
6354     default:
6355       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6356       if (INTVAL (operands[2]) < 0)
6357         {
6358           operands[2] = GEN_INT (-INTVAL (operands[2]));
6359           return "add{b}\t{%2, %0|%0, %2}";
6360         }
6361       return "sub{b}\t{%2, %0|%0, %2}";
6362     }
6364   [(set (attr "type")
6365      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6366         (const_string "incdec")
6367         (const_string "alu")))
6368    (set_attr "mode" "QI")])
6371 (define_insn "*addqi_5"
6372   [(set (reg FLAGS_REG)
6373         (compare
6374           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6375                    (match_operand:QI 2 "general_operand" "qmni"))
6376           (const_int 0)))
6377    (clobber (match_scratch:QI 0 "=q"))]
6378   "ix86_match_ccmode (insn, CCGOCmode)
6379    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6381   switch (get_attr_type (insn))
6382     {
6383     case TYPE_INCDEC:
6384       if (operands[2] == const1_rtx)
6385         return "inc{b}\t%0";
6386       else
6387         {
6388           gcc_assert (operands[2] == constm1_rtx
6389                       || (GET_CODE (operands[2]) == CONST_INT
6390                           && INTVAL (operands[2]) == 255));
6391           return "dec{b}\t%0";
6392         }
6394     default:
6395       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6396       if (GET_CODE (operands[2]) == CONST_INT
6397           && INTVAL (operands[2]) < 0)
6398         {
6399           operands[2] = GEN_INT (-INTVAL (operands[2]));
6400           return "sub{b}\t{%2, %0|%0, %2}";
6401         }
6402       return "add{b}\t{%2, %0|%0, %2}";
6403     }
6405   [(set (attr "type")
6406      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407         (const_string "incdec")
6408         (const_string "alu")))
6409    (set_attr "mode" "QI")])
6412 (define_insn "addqi_ext_1"
6413   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6414                          (const_int 8)
6415                          (const_int 8))
6416         (plus:SI
6417           (zero_extract:SI
6418             (match_operand 1 "ext_register_operand" "0")
6419             (const_int 8)
6420             (const_int 8))
6421           (match_operand:QI 2 "general_operand" "Qmn")))
6422    (clobber (reg:CC FLAGS_REG))]
6423   "!TARGET_64BIT"
6425   switch (get_attr_type (insn))
6426     {
6427     case TYPE_INCDEC:
6428       if (operands[2] == const1_rtx)
6429         return "inc{b}\t%h0";
6430       else
6431         {
6432           gcc_assert (operands[2] == constm1_rtx
6433                       || (GET_CODE (operands[2]) == CONST_INT
6434                           && INTVAL (operands[2]) == 255));
6435           return "dec{b}\t%h0";
6436         }
6438     default:
6439       return "add{b}\t{%2, %h0|%h0, %2}";
6440     }
6442   [(set (attr "type")
6443      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6444         (const_string "incdec")
6445         (const_string "alu")))
6446    (set_attr "mode" "QI")])
6448 (define_insn "*addqi_ext_1_rex64"
6449   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6450                          (const_int 8)
6451                          (const_int 8))
6452         (plus:SI
6453           (zero_extract:SI
6454             (match_operand 1 "ext_register_operand" "0")
6455             (const_int 8)
6456             (const_int 8))
6457           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6458    (clobber (reg:CC FLAGS_REG))]
6459   "TARGET_64BIT"
6461   switch (get_attr_type (insn))
6462     {
6463     case TYPE_INCDEC:
6464       if (operands[2] == const1_rtx)
6465         return "inc{b}\t%h0";
6466       else
6467         {
6468           gcc_assert (operands[2] == constm1_rtx
6469                       || (GET_CODE (operands[2]) == CONST_INT
6470                           && INTVAL (operands[2]) == 255));
6471           return "dec{b}\t%h0";
6472         }
6474     default:
6475       return "add{b}\t{%2, %h0|%h0, %2}";
6476     }
6478   [(set (attr "type")
6479      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6480         (const_string "incdec")
6481         (const_string "alu")))
6482    (set_attr "mode" "QI")])
6484 (define_insn "*addqi_ext_2"
6485   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6486                          (const_int 8)
6487                          (const_int 8))
6488         (plus:SI
6489           (zero_extract:SI
6490             (match_operand 1 "ext_register_operand" "%0")
6491             (const_int 8)
6492             (const_int 8))
6493           (zero_extract:SI
6494             (match_operand 2 "ext_register_operand" "Q")
6495             (const_int 8)
6496             (const_int 8))))
6497    (clobber (reg:CC FLAGS_REG))]
6498   ""
6499   "add{b}\t{%h2, %h0|%h0, %h2}"
6500   [(set_attr "type" "alu")
6501    (set_attr "mode" "QI")])
6503 ;; The patterns that match these are at the end of this file.
6505 (define_expand "addxf3"
6506   [(set (match_operand:XF 0 "register_operand" "")
6507         (plus:XF (match_operand:XF 1 "register_operand" "")
6508                  (match_operand:XF 2 "register_operand" "")))]
6509   "TARGET_80387"
6510   "")
6512 (define_expand "adddf3"
6513   [(set (match_operand:DF 0 "register_operand" "")
6514         (plus:DF (match_operand:DF 1 "register_operand" "")
6515                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6516   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6517   "")
6519 (define_expand "addsf3"
6520   [(set (match_operand:SF 0 "register_operand" "")
6521         (plus:SF (match_operand:SF 1 "register_operand" "")
6522                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6523   "TARGET_80387 || TARGET_SSE_MATH"
6524   "")
6526 ;; Subtract instructions
6528 ;; %%% splits for subditi3
6530 (define_expand "subti3"
6531   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6532                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6533                              (match_operand:TI 2 "x86_64_general_operand" "")))
6534               (clobber (reg:CC FLAGS_REG))])]
6535   "TARGET_64BIT"
6536   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6538 (define_insn "*subti3_1"
6539   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6540         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6541                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6542    (clobber (reg:CC FLAGS_REG))]
6543   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6544   "#")
6546 (define_split
6547   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6548         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6549                   (match_operand:TI 2 "general_operand" "")))
6550    (clobber (reg:CC FLAGS_REG))]
6551   "TARGET_64BIT && reload_completed"
6552   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6553               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6554    (parallel [(set (match_dup 3)
6555                    (minus:DI (match_dup 4)
6556                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6557                                       (match_dup 5))))
6558               (clobber (reg:CC FLAGS_REG))])]
6559   "split_ti (operands+0, 1, operands+0, operands+3);
6560    split_ti (operands+1, 1, operands+1, operands+4);
6561    split_ti (operands+2, 1, operands+2, operands+5);")
6563 ;; %%% splits for subsidi3
6565 (define_expand "subdi3"
6566   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6567                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6568                              (match_operand:DI 2 "x86_64_general_operand" "")))
6569               (clobber (reg:CC FLAGS_REG))])]
6570   ""
6571   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6573 (define_insn "*subdi3_1"
6574   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6575         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6576                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6577    (clobber (reg:CC FLAGS_REG))]
6578   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6579   "#")
6581 (define_split
6582   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6583         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6584                   (match_operand:DI 2 "general_operand" "")))
6585    (clobber (reg:CC FLAGS_REG))]
6586   "!TARGET_64BIT && reload_completed"
6587   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6588               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6589    (parallel [(set (match_dup 3)
6590                    (minus:SI (match_dup 4)
6591                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6592                                       (match_dup 5))))
6593               (clobber (reg:CC FLAGS_REG))])]
6594   "split_di (operands+0, 1, operands+0, operands+3);
6595    split_di (operands+1, 1, operands+1, operands+4);
6596    split_di (operands+2, 1, operands+2, operands+5);")
6598 (define_insn "subdi3_carry_rex64"
6599   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6600           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6601             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6602                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6603    (clobber (reg:CC FLAGS_REG))]
6604   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6605   "sbb{q}\t{%2, %0|%0, %2}"
6606   [(set_attr "type" "alu")
6607    (set_attr "pent_pair" "pu")
6608    (set_attr "mode" "DI")])
6610 (define_insn "*subdi_1_rex64"
6611   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6612         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6613                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6614    (clobber (reg:CC FLAGS_REG))]
6615   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6616   "sub{q}\t{%2, %0|%0, %2}"
6617   [(set_attr "type" "alu")
6618    (set_attr "mode" "DI")])
6620 (define_insn "*subdi_2_rex64"
6621   [(set (reg FLAGS_REG)
6622         (compare
6623           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6624                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6625           (const_int 0)))
6626    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6627         (minus:DI (match_dup 1) (match_dup 2)))]
6628   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6629    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6630   "sub{q}\t{%2, %0|%0, %2}"
6631   [(set_attr "type" "alu")
6632    (set_attr "mode" "DI")])
6634 (define_insn "*subdi_3_rex63"
6635   [(set (reg FLAGS_REG)
6636         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6637                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6638    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6639         (minus:DI (match_dup 1) (match_dup 2)))]
6640   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6641    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6642   "sub{q}\t{%2, %0|%0, %2}"
6643   [(set_attr "type" "alu")
6644    (set_attr "mode" "DI")])
6646 (define_insn "subqi3_carry"
6647   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6648           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6649             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6650                (match_operand:QI 2 "general_operand" "qi,qm"))))
6651    (clobber (reg:CC FLAGS_REG))]
6652   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6653   "sbb{b}\t{%2, %0|%0, %2}"
6654   [(set_attr "type" "alu")
6655    (set_attr "pent_pair" "pu")
6656    (set_attr "mode" "QI")])
6658 (define_insn "subhi3_carry"
6659   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6660           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6661             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6662                (match_operand:HI 2 "general_operand" "ri,rm"))))
6663    (clobber (reg:CC FLAGS_REG))]
6664   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6665   "sbb{w}\t{%2, %0|%0, %2}"
6666   [(set_attr "type" "alu")
6667    (set_attr "pent_pair" "pu")
6668    (set_attr "mode" "HI")])
6670 (define_insn "subsi3_carry"
6671   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6672           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6674                (match_operand:SI 2 "general_operand" "ri,rm"))))
6675    (clobber (reg:CC FLAGS_REG))]
6676   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6677   "sbb{l}\t{%2, %0|%0, %2}"
6678   [(set_attr "type" "alu")
6679    (set_attr "pent_pair" "pu")
6680    (set_attr "mode" "SI")])
6682 (define_insn "subsi3_carry_zext"
6683   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6684           (zero_extend:DI
6685             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6686               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6687                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6688    (clobber (reg:CC FLAGS_REG))]
6689   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6690   "sbb{l}\t{%2, %k0|%k0, %2}"
6691   [(set_attr "type" "alu")
6692    (set_attr "pent_pair" "pu")
6693    (set_attr "mode" "SI")])
6695 (define_expand "subsi3"
6696   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6697                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6698                              (match_operand:SI 2 "general_operand" "")))
6699               (clobber (reg:CC FLAGS_REG))])]
6700   ""
6701   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6703 (define_insn "*subsi_1"
6704   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6705         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6706                   (match_operand:SI 2 "general_operand" "ri,rm")))
6707    (clobber (reg:CC FLAGS_REG))]
6708   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6709   "sub{l}\t{%2, %0|%0, %2}"
6710   [(set_attr "type" "alu")
6711    (set_attr "mode" "SI")])
6713 (define_insn "*subsi_1_zext"
6714   [(set (match_operand:DI 0 "register_operand" "=r")
6715         (zero_extend:DI
6716           (minus:SI (match_operand:SI 1 "register_operand" "0")
6717                     (match_operand:SI 2 "general_operand" "rim"))))
6718    (clobber (reg:CC FLAGS_REG))]
6719   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6720   "sub{l}\t{%2, %k0|%k0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "mode" "SI")])
6724 (define_insn "*subsi_2"
6725   [(set (reg FLAGS_REG)
6726         (compare
6727           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6728                     (match_operand:SI 2 "general_operand" "ri,rm"))
6729           (const_int 0)))
6730    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6731         (minus:SI (match_dup 1) (match_dup 2)))]
6732   "ix86_match_ccmode (insn, CCGOCmode)
6733    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6734   "sub{l}\t{%2, %0|%0, %2}"
6735   [(set_attr "type" "alu")
6736    (set_attr "mode" "SI")])
6738 (define_insn "*subsi_2_zext"
6739   [(set (reg FLAGS_REG)
6740         (compare
6741           (minus:SI (match_operand:SI 1 "register_operand" "0")
6742                     (match_operand:SI 2 "general_operand" "rim"))
6743           (const_int 0)))
6744    (set (match_operand:DI 0 "register_operand" "=r")
6745         (zero_extend:DI
6746           (minus:SI (match_dup 1)
6747                     (match_dup 2))))]
6748   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6749    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6750   "sub{l}\t{%2, %k0|%k0, %2}"
6751   [(set_attr "type" "alu")
6752    (set_attr "mode" "SI")])
6754 (define_insn "*subsi_3"
6755   [(set (reg FLAGS_REG)
6756         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6757                  (match_operand:SI 2 "general_operand" "ri,rm")))
6758    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6759         (minus:SI (match_dup 1) (match_dup 2)))]
6760   "ix86_match_ccmode (insn, CCmode)
6761    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6762   "sub{l}\t{%2, %0|%0, %2}"
6763   [(set_attr "type" "alu")
6764    (set_attr "mode" "SI")])
6766 (define_insn "*subsi_3_zext"
6767   [(set (reg FLAGS_REG)
6768         (compare (match_operand:SI 1 "register_operand" "0")
6769                  (match_operand:SI 2 "general_operand" "rim")))
6770    (set (match_operand:DI 0 "register_operand" "=r")
6771         (zero_extend:DI
6772           (minus:SI (match_dup 1)
6773                     (match_dup 2))))]
6774   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6775    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6776   "sub{l}\t{%2, %1|%1, %2}"
6777   [(set_attr "type" "alu")
6778    (set_attr "mode" "DI")])
6780 (define_expand "subhi3"
6781   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6782                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6783                              (match_operand:HI 2 "general_operand" "")))
6784               (clobber (reg:CC FLAGS_REG))])]
6785   "TARGET_HIMODE_MATH"
6786   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6788 (define_insn "*subhi_1"
6789   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6790         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6791                   (match_operand:HI 2 "general_operand" "ri,rm")))
6792    (clobber (reg:CC FLAGS_REG))]
6793   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6794   "sub{w}\t{%2, %0|%0, %2}"
6795   [(set_attr "type" "alu")
6796    (set_attr "mode" "HI")])
6798 (define_insn "*subhi_2"
6799   [(set (reg FLAGS_REG)
6800         (compare
6801           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6802                     (match_operand:HI 2 "general_operand" "ri,rm"))
6803           (const_int 0)))
6804    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6805         (minus:HI (match_dup 1) (match_dup 2)))]
6806   "ix86_match_ccmode (insn, CCGOCmode)
6807    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6808   "sub{w}\t{%2, %0|%0, %2}"
6809   [(set_attr "type" "alu")
6810    (set_attr "mode" "HI")])
6812 (define_insn "*subhi_3"
6813   [(set (reg FLAGS_REG)
6814         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6815                  (match_operand:HI 2 "general_operand" "ri,rm")))
6816    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6817         (minus:HI (match_dup 1) (match_dup 2)))]
6818   "ix86_match_ccmode (insn, CCmode)
6819    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6820   "sub{w}\t{%2, %0|%0, %2}"
6821   [(set_attr "type" "alu")
6822    (set_attr "mode" "HI")])
6824 (define_expand "subqi3"
6825   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6826                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6827                              (match_operand:QI 2 "general_operand" "")))
6828               (clobber (reg:CC FLAGS_REG))])]
6829   "TARGET_QIMODE_MATH"
6830   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6832 (define_insn "*subqi_1"
6833   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6834         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6835                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6836    (clobber (reg:CC FLAGS_REG))]
6837   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6838   "sub{b}\t{%2, %0|%0, %2}"
6839   [(set_attr "type" "alu")
6840    (set_attr "mode" "QI")])
6842 (define_insn "*subqi_1_slp"
6843   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6844         (minus:QI (match_dup 0)
6845                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6846    (clobber (reg:CC FLAGS_REG))]
6847   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6848    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6849   "sub{b}\t{%1, %0|%0, %1}"
6850   [(set_attr "type" "alu1")
6851    (set_attr "mode" "QI")])
6853 (define_insn "*subqi_2"
6854   [(set (reg FLAGS_REG)
6855         (compare
6856           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6857                     (match_operand:QI 2 "general_operand" "qi,qm"))
6858           (const_int 0)))
6859    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6860         (minus:HI (match_dup 1) (match_dup 2)))]
6861   "ix86_match_ccmode (insn, CCGOCmode)
6862    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6863   "sub{b}\t{%2, %0|%0, %2}"
6864   [(set_attr "type" "alu")
6865    (set_attr "mode" "QI")])
6867 (define_insn "*subqi_3"
6868   [(set (reg FLAGS_REG)
6869         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6870                  (match_operand:QI 2 "general_operand" "qi,qm")))
6871    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6872         (minus:HI (match_dup 1) (match_dup 2)))]
6873   "ix86_match_ccmode (insn, CCmode)
6874    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6875   "sub{b}\t{%2, %0|%0, %2}"
6876   [(set_attr "type" "alu")
6877    (set_attr "mode" "QI")])
6879 ;; The patterns that match these are at the end of this file.
6881 (define_expand "subxf3"
6882   [(set (match_operand:XF 0 "register_operand" "")
6883         (minus:XF (match_operand:XF 1 "register_operand" "")
6884                   (match_operand:XF 2 "register_operand" "")))]
6885   "TARGET_80387"
6886   "")
6888 (define_expand "subdf3"
6889   [(set (match_operand:DF 0 "register_operand" "")
6890         (minus:DF (match_operand:DF 1 "register_operand" "")
6891                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6892   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6893   "")
6895 (define_expand "subsf3"
6896   [(set (match_operand:SF 0 "register_operand" "")
6897         (minus:SF (match_operand:SF 1 "register_operand" "")
6898                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6899   "TARGET_80387 || TARGET_SSE_MATH"
6900   "")
6902 ;; Multiply instructions
6904 (define_expand "muldi3"
6905   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6906                    (mult:DI (match_operand:DI 1 "register_operand" "")
6907                             (match_operand:DI 2 "x86_64_general_operand" "")))
6908               (clobber (reg:CC FLAGS_REG))])]
6909   "TARGET_64BIT"
6910   "")
6912 (define_insn "*muldi3_1_rex64"
6913   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6914         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6915                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "TARGET_64BIT
6918    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6919   "@
6920    imul{q}\t{%2, %1, %0|%0, %1, %2}
6921    imul{q}\t{%2, %1, %0|%0, %1, %2}
6922    imul{q}\t{%2, %0|%0, %2}"
6923   [(set_attr "type" "imul")
6924    (set_attr "prefix_0f" "0,0,1")
6925    (set (attr "athlon_decode")
6926         (cond [(eq_attr "cpu" "athlon")
6927                   (const_string "vector")
6928                (eq_attr "alternative" "1")
6929                   (const_string "vector")
6930                (and (eq_attr "alternative" "2")
6931                     (match_operand 1 "memory_operand" ""))
6932                   (const_string "vector")]
6933               (const_string "direct")))
6934    (set_attr "mode" "DI")])
6936 (define_expand "mulsi3"
6937   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6938                    (mult:SI (match_operand:SI 1 "register_operand" "")
6939                             (match_operand:SI 2 "general_operand" "")))
6940               (clobber (reg:CC FLAGS_REG))])]
6941   ""
6942   "")
6944 (define_insn "*mulsi3_1"
6945   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6946         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6947                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6948    (clobber (reg:CC FLAGS_REG))]
6949   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6950   "@
6951    imul{l}\t{%2, %1, %0|%0, %1, %2}
6952    imul{l}\t{%2, %1, %0|%0, %1, %2}
6953    imul{l}\t{%2, %0|%0, %2}"
6954   [(set_attr "type" "imul")
6955    (set_attr "prefix_0f" "0,0,1")
6956    (set (attr "athlon_decode")
6957         (cond [(eq_attr "cpu" "athlon")
6958                   (const_string "vector")
6959                (eq_attr "alternative" "1")
6960                   (const_string "vector")
6961                (and (eq_attr "alternative" "2")
6962                     (match_operand 1 "memory_operand" ""))
6963                   (const_string "vector")]
6964               (const_string "direct")))
6965    (set_attr "mode" "SI")])
6967 (define_insn "*mulsi3_1_zext"
6968   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6969         (zero_extend:DI
6970           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6971                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6972    (clobber (reg:CC FLAGS_REG))]
6973   "TARGET_64BIT
6974    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6975   "@
6976    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6977    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6978    imul{l}\t{%2, %k0|%k0, %2}"
6979   [(set_attr "type" "imul")
6980    (set_attr "prefix_0f" "0,0,1")
6981    (set (attr "athlon_decode")
6982         (cond [(eq_attr "cpu" "athlon")
6983                   (const_string "vector")
6984                (eq_attr "alternative" "1")
6985                   (const_string "vector")
6986                (and (eq_attr "alternative" "2")
6987                     (match_operand 1 "memory_operand" ""))
6988                   (const_string "vector")]
6989               (const_string "direct")))
6990    (set_attr "mode" "SI")])
6992 (define_expand "mulhi3"
6993   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6994                    (mult:HI (match_operand:HI 1 "register_operand" "")
6995                             (match_operand:HI 2 "general_operand" "")))
6996               (clobber (reg:CC FLAGS_REG))])]
6997   "TARGET_HIMODE_MATH"
6998   "")
7000 (define_insn "*mulhi3_1"
7001   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7002         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7003                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7004    (clobber (reg:CC FLAGS_REG))]
7005   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7006   "@
7007    imul{w}\t{%2, %1, %0|%0, %1, %2}
7008    imul{w}\t{%2, %1, %0|%0, %1, %2}
7009    imul{w}\t{%2, %0|%0, %2}"
7010   [(set_attr "type" "imul")
7011    (set_attr "prefix_0f" "0,0,1")
7012    (set (attr "athlon_decode")
7013         (cond [(eq_attr "cpu" "athlon")
7014                   (const_string "vector")
7015                (eq_attr "alternative" "1,2")
7016                   (const_string "vector")]
7017               (const_string "direct")))
7018    (set_attr "mode" "HI")])
7020 (define_expand "mulqi3"
7021   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7022                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7023                             (match_operand:QI 2 "register_operand" "")))
7024               (clobber (reg:CC FLAGS_REG))])]
7025   "TARGET_QIMODE_MATH"
7026   "")
7028 (define_insn "*mulqi3_1"
7029   [(set (match_operand:QI 0 "register_operand" "=a")
7030         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7031                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7032    (clobber (reg:CC FLAGS_REG))]
7033   "TARGET_QIMODE_MATH
7034    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7035   "mul{b}\t%2"
7036   [(set_attr "type" "imul")
7037    (set_attr "length_immediate" "0")
7038    (set (attr "athlon_decode")
7039      (if_then_else (eq_attr "cpu" "athlon")
7040         (const_string "vector")
7041         (const_string "direct")))
7042    (set_attr "mode" "QI")])
7044 (define_expand "umulqihi3"
7045   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7046                    (mult:HI (zero_extend:HI
7047                               (match_operand:QI 1 "nonimmediate_operand" ""))
7048                             (zero_extend:HI
7049                               (match_operand:QI 2 "register_operand" ""))))
7050               (clobber (reg:CC FLAGS_REG))])]
7051   "TARGET_QIMODE_MATH"
7052   "")
7054 (define_insn "*umulqihi3_1"
7055   [(set (match_operand:HI 0 "register_operand" "=a")
7056         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7057                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7058    (clobber (reg:CC FLAGS_REG))]
7059   "TARGET_QIMODE_MATH
7060    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7061   "mul{b}\t%2"
7062   [(set_attr "type" "imul")
7063    (set_attr "length_immediate" "0")
7064    (set (attr "athlon_decode")
7065      (if_then_else (eq_attr "cpu" "athlon")
7066         (const_string "vector")
7067         (const_string "direct")))
7068    (set_attr "mode" "QI")])
7070 (define_expand "mulqihi3"
7071   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7072                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7073                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7074               (clobber (reg:CC FLAGS_REG))])]
7075   "TARGET_QIMODE_MATH"
7076   "")
7078 (define_insn "*mulqihi3_insn"
7079   [(set (match_operand:HI 0 "register_operand" "=a")
7080         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7081                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7082    (clobber (reg:CC FLAGS_REG))]
7083   "TARGET_QIMODE_MATH
7084    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7085   "imul{b}\t%2"
7086   [(set_attr "type" "imul")
7087    (set_attr "length_immediate" "0")
7088    (set (attr "athlon_decode")
7089      (if_then_else (eq_attr "cpu" "athlon")
7090         (const_string "vector")
7091         (const_string "direct")))
7092    (set_attr "mode" "QI")])
7094 (define_expand "umulditi3"
7095   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7096                    (mult:TI (zero_extend:TI
7097                               (match_operand:DI 1 "nonimmediate_operand" ""))
7098                             (zero_extend:TI
7099                               (match_operand:DI 2 "register_operand" ""))))
7100               (clobber (reg:CC FLAGS_REG))])]
7101   "TARGET_64BIT"
7102   "")
7104 (define_insn "*umulditi3_insn"
7105   [(set (match_operand:TI 0 "register_operand" "=A")
7106         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7107                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7108    (clobber (reg:CC FLAGS_REG))]
7109   "TARGET_64BIT
7110    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7111   "mul{q}\t%2"
7112   [(set_attr "type" "imul")
7113    (set_attr "length_immediate" "0")
7114    (set (attr "athlon_decode")
7115      (if_then_else (eq_attr "cpu" "athlon")
7116         (const_string "vector")
7117         (const_string "double")))
7118    (set_attr "mode" "DI")])
7120 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7121 (define_expand "umulsidi3"
7122   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7123                    (mult:DI (zero_extend:DI
7124                               (match_operand:SI 1 "nonimmediate_operand" ""))
7125                             (zero_extend:DI
7126                               (match_operand:SI 2 "register_operand" ""))))
7127               (clobber (reg:CC FLAGS_REG))])]
7128   "!TARGET_64BIT"
7129   "")
7131 (define_insn "*umulsidi3_insn"
7132   [(set (match_operand:DI 0 "register_operand" "=A")
7133         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7134                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7135    (clobber (reg:CC FLAGS_REG))]
7136   "!TARGET_64BIT
7137    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7138   "mul{l}\t%2"
7139   [(set_attr "type" "imul")
7140    (set_attr "length_immediate" "0")
7141    (set (attr "athlon_decode")
7142      (if_then_else (eq_attr "cpu" "athlon")
7143         (const_string "vector")
7144         (const_string "double")))
7145    (set_attr "mode" "SI")])
7147 (define_expand "mulditi3"
7148   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7149                    (mult:TI (sign_extend:TI
7150                               (match_operand:DI 1 "nonimmediate_operand" ""))
7151                             (sign_extend:TI
7152                               (match_operand:DI 2 "register_operand" ""))))
7153               (clobber (reg:CC FLAGS_REG))])]
7154   "TARGET_64BIT"
7155   "")
7157 (define_insn "*mulditi3_insn"
7158   [(set (match_operand:TI 0 "register_operand" "=A")
7159         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7160                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7161    (clobber (reg:CC FLAGS_REG))]
7162   "TARGET_64BIT
7163    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7164   "imul{q}\t%2"
7165   [(set_attr "type" "imul")
7166    (set_attr "length_immediate" "0")
7167    (set (attr "athlon_decode")
7168      (if_then_else (eq_attr "cpu" "athlon")
7169         (const_string "vector")
7170         (const_string "double")))
7171    (set_attr "mode" "DI")])
7173 (define_expand "mulsidi3"
7174   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7175                    (mult:DI (sign_extend:DI
7176                               (match_operand:SI 1 "nonimmediate_operand" ""))
7177                             (sign_extend:DI
7178                               (match_operand:SI 2 "register_operand" ""))))
7179               (clobber (reg:CC FLAGS_REG))])]
7180   "!TARGET_64BIT"
7181   "")
7183 (define_insn "*mulsidi3_insn"
7184   [(set (match_operand:DI 0 "register_operand" "=A")
7185         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7186                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7187    (clobber (reg:CC FLAGS_REG))]
7188   "!TARGET_64BIT
7189    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7190   "imul{l}\t%2"
7191   [(set_attr "type" "imul")
7192    (set_attr "length_immediate" "0")
7193    (set (attr "athlon_decode")
7194      (if_then_else (eq_attr "cpu" "athlon")
7195         (const_string "vector")
7196         (const_string "double")))
7197    (set_attr "mode" "SI")])
7199 (define_expand "umuldi3_highpart"
7200   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7201                    (truncate:DI
7202                      (lshiftrt:TI
7203                        (mult:TI (zero_extend:TI
7204                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7205                                 (zero_extend:TI
7206                                   (match_operand:DI 2 "register_operand" "")))
7207                        (const_int 64))))
7208               (clobber (match_scratch:DI 3 ""))
7209               (clobber (reg:CC FLAGS_REG))])]
7210   "TARGET_64BIT"
7211   "")
7213 (define_insn "*umuldi3_highpart_rex64"
7214   [(set (match_operand:DI 0 "register_operand" "=d")
7215         (truncate:DI
7216           (lshiftrt:TI
7217             (mult:TI (zero_extend:TI
7218                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7219                      (zero_extend:TI
7220                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7221             (const_int 64))))
7222    (clobber (match_scratch:DI 3 "=1"))
7223    (clobber (reg:CC FLAGS_REG))]
7224   "TARGET_64BIT
7225    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7226   "mul{q}\t%2"
7227   [(set_attr "type" "imul")
7228    (set_attr "length_immediate" "0")
7229    (set (attr "athlon_decode")
7230      (if_then_else (eq_attr "cpu" "athlon")
7231         (const_string "vector")
7232         (const_string "double")))
7233    (set_attr "mode" "DI")])
7235 (define_expand "umulsi3_highpart"
7236   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7237                    (truncate:SI
7238                      (lshiftrt:DI
7239                        (mult:DI (zero_extend:DI
7240                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7241                                 (zero_extend:DI
7242                                   (match_operand:SI 2 "register_operand" "")))
7243                        (const_int 32))))
7244               (clobber (match_scratch:SI 3 ""))
7245               (clobber (reg:CC FLAGS_REG))])]
7246   ""
7247   "")
7249 (define_insn "*umulsi3_highpart_insn"
7250   [(set (match_operand:SI 0 "register_operand" "=d")
7251         (truncate:SI
7252           (lshiftrt:DI
7253             (mult:DI (zero_extend:DI
7254                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7255                      (zero_extend:DI
7256                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7257             (const_int 32))))
7258    (clobber (match_scratch:SI 3 "=1"))
7259    (clobber (reg:CC FLAGS_REG))]
7260   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7261   "mul{l}\t%2"
7262   [(set_attr "type" "imul")
7263    (set_attr "length_immediate" "0")
7264    (set (attr "athlon_decode")
7265      (if_then_else (eq_attr "cpu" "athlon")
7266         (const_string "vector")
7267         (const_string "double")))
7268    (set_attr "mode" "SI")])
7270 (define_insn "*umulsi3_highpart_zext"
7271   [(set (match_operand:DI 0 "register_operand" "=d")
7272         (zero_extend:DI (truncate:SI
7273           (lshiftrt:DI
7274             (mult:DI (zero_extend:DI
7275                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7276                      (zero_extend:DI
7277                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7278             (const_int 32)))))
7279    (clobber (match_scratch:SI 3 "=1"))
7280    (clobber (reg:CC FLAGS_REG))]
7281   "TARGET_64BIT
7282    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7283   "mul{l}\t%2"
7284   [(set_attr "type" "imul")
7285    (set_attr "length_immediate" "0")
7286    (set (attr "athlon_decode")
7287      (if_then_else (eq_attr "cpu" "athlon")
7288         (const_string "vector")
7289         (const_string "double")))
7290    (set_attr "mode" "SI")])
7292 (define_expand "smuldi3_highpart"
7293   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7294                    (truncate:DI
7295                      (lshiftrt:TI
7296                        (mult:TI (sign_extend:TI
7297                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7298                                 (sign_extend:TI
7299                                   (match_operand:DI 2 "register_operand" "")))
7300                        (const_int 64))))
7301               (clobber (match_scratch:DI 3 ""))
7302               (clobber (reg:CC FLAGS_REG))])]
7303   "TARGET_64BIT"
7304   "")
7306 (define_insn "*smuldi3_highpart_rex64"
7307   [(set (match_operand:DI 0 "register_operand" "=d")
7308         (truncate:DI
7309           (lshiftrt:TI
7310             (mult:TI (sign_extend:TI
7311                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7312                      (sign_extend:TI
7313                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7314             (const_int 64))))
7315    (clobber (match_scratch:DI 3 "=1"))
7316    (clobber (reg:CC FLAGS_REG))]
7317   "TARGET_64BIT
7318    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7319   "imul{q}\t%2"
7320   [(set_attr "type" "imul")
7321    (set (attr "athlon_decode")
7322      (if_then_else (eq_attr "cpu" "athlon")
7323         (const_string "vector")
7324         (const_string "double")))
7325    (set_attr "mode" "DI")])
7327 (define_expand "smulsi3_highpart"
7328   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7329                    (truncate:SI
7330                      (lshiftrt:DI
7331                        (mult:DI (sign_extend:DI
7332                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7333                                 (sign_extend:DI
7334                                   (match_operand:SI 2 "register_operand" "")))
7335                        (const_int 32))))
7336               (clobber (match_scratch:SI 3 ""))
7337               (clobber (reg:CC FLAGS_REG))])]
7338   ""
7339   "")
7341 (define_insn "*smulsi3_highpart_insn"
7342   [(set (match_operand:SI 0 "register_operand" "=d")
7343         (truncate:SI
7344           (lshiftrt:DI
7345             (mult:DI (sign_extend:DI
7346                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7347                      (sign_extend:DI
7348                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7349             (const_int 32))))
7350    (clobber (match_scratch:SI 3 "=1"))
7351    (clobber (reg:CC FLAGS_REG))]
7352   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7353   "imul{l}\t%2"
7354   [(set_attr "type" "imul")
7355    (set (attr "athlon_decode")
7356      (if_then_else (eq_attr "cpu" "athlon")
7357         (const_string "vector")
7358         (const_string "double")))
7359    (set_attr "mode" "SI")])
7361 (define_insn "*smulsi3_highpart_zext"
7362   [(set (match_operand:DI 0 "register_operand" "=d")
7363         (zero_extend:DI (truncate:SI
7364           (lshiftrt:DI
7365             (mult:DI (sign_extend:DI
7366                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7367                      (sign_extend:DI
7368                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7369             (const_int 32)))))
7370    (clobber (match_scratch:SI 3 "=1"))
7371    (clobber (reg:CC FLAGS_REG))]
7372   "TARGET_64BIT
7373    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7374   "imul{l}\t%2"
7375   [(set_attr "type" "imul")
7376    (set (attr "athlon_decode")
7377      (if_then_else (eq_attr "cpu" "athlon")
7378         (const_string "vector")
7379         (const_string "double")))
7380    (set_attr "mode" "SI")])
7382 ;; The patterns that match these are at the end of this file.
7384 (define_expand "mulxf3"
7385   [(set (match_operand:XF 0 "register_operand" "")
7386         (mult:XF (match_operand:XF 1 "register_operand" "")
7387                  (match_operand:XF 2 "register_operand" "")))]
7388   "TARGET_80387"
7389   "")
7391 (define_expand "muldf3"
7392   [(set (match_operand:DF 0 "register_operand" "")
7393         (mult:DF (match_operand:DF 1 "register_operand" "")
7394                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7395   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7396   "")
7398 (define_expand "mulsf3"
7399   [(set (match_operand:SF 0 "register_operand" "")
7400         (mult:SF (match_operand:SF 1 "register_operand" "")
7401                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7402   "TARGET_80387 || TARGET_SSE_MATH"
7403   "")
7405 ;; Divide instructions
7407 (define_insn "divqi3"
7408   [(set (match_operand:QI 0 "register_operand" "=a")
7409         (div:QI (match_operand:HI 1 "register_operand" "0")
7410                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7411    (clobber (reg:CC FLAGS_REG))]
7412   "TARGET_QIMODE_MATH"
7413   "idiv{b}\t%2"
7414   [(set_attr "type" "idiv")
7415    (set_attr "mode" "QI")])
7417 (define_insn "udivqi3"
7418   [(set (match_operand:QI 0 "register_operand" "=a")
7419         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7420                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7421    (clobber (reg:CC FLAGS_REG))]
7422   "TARGET_QIMODE_MATH"
7423   "div{b}\t%2"
7424   [(set_attr "type" "idiv")
7425    (set_attr "mode" "QI")])
7427 ;; The patterns that match these are at the end of this file.
7429 (define_expand "divxf3"
7430   [(set (match_operand:XF 0 "register_operand" "")
7431         (div:XF (match_operand:XF 1 "register_operand" "")
7432                 (match_operand:XF 2 "register_operand" "")))]
7433   "TARGET_80387"
7434   "")
7436 (define_expand "divdf3"
7437   [(set (match_operand:DF 0 "register_operand" "")
7438         (div:DF (match_operand:DF 1 "register_operand" "")
7439                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7440    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7441    "")
7443 (define_expand "divsf3"
7444   [(set (match_operand:SF 0 "register_operand" "")
7445         (div:SF (match_operand:SF 1 "register_operand" "")
7446                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7447   "TARGET_80387 || TARGET_SSE_MATH"
7448   "")
7450 ;; Remainder instructions.
7452 (define_expand "divmoddi4"
7453   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7454                    (div:DI (match_operand:DI 1 "register_operand" "")
7455                            (match_operand:DI 2 "nonimmediate_operand" "")))
7456               (set (match_operand:DI 3 "register_operand" "")
7457                    (mod:DI (match_dup 1) (match_dup 2)))
7458               (clobber (reg:CC FLAGS_REG))])]
7459   "TARGET_64BIT"
7460   "")
7462 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7463 ;; Penalize eax case slightly because it results in worse scheduling
7464 ;; of code.
7465 (define_insn "*divmoddi4_nocltd_rex64"
7466   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7467         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7468                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7469    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7470         (mod:DI (match_dup 2) (match_dup 3)))
7471    (clobber (reg:CC FLAGS_REG))]
7472   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7473   "#"
7474   [(set_attr "type" "multi")])
7476 (define_insn "*divmoddi4_cltd_rex64"
7477   [(set (match_operand:DI 0 "register_operand" "=a")
7478         (div:DI (match_operand:DI 2 "register_operand" "a")
7479                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7480    (set (match_operand:DI 1 "register_operand" "=&d")
7481         (mod:DI (match_dup 2) (match_dup 3)))
7482    (clobber (reg:CC FLAGS_REG))]
7483   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7484   "#"
7485   [(set_attr "type" "multi")])
7487 (define_insn "*divmoddi_noext_rex64"
7488   [(set (match_operand:DI 0 "register_operand" "=a")
7489         (div:DI (match_operand:DI 1 "register_operand" "0")
7490                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7491    (set (match_operand:DI 3 "register_operand" "=d")
7492         (mod:DI (match_dup 1) (match_dup 2)))
7493    (use (match_operand:DI 4 "register_operand" "3"))
7494    (clobber (reg:CC FLAGS_REG))]
7495   "TARGET_64BIT"
7496   "idiv{q}\t%2"
7497   [(set_attr "type" "idiv")
7498    (set_attr "mode" "DI")])
7500 (define_split
7501   [(set (match_operand:DI 0 "register_operand" "")
7502         (div:DI (match_operand:DI 1 "register_operand" "")
7503                 (match_operand:DI 2 "nonimmediate_operand" "")))
7504    (set (match_operand:DI 3 "register_operand" "")
7505         (mod:DI (match_dup 1) (match_dup 2)))
7506    (clobber (reg:CC FLAGS_REG))]
7507   "TARGET_64BIT && reload_completed"
7508   [(parallel [(set (match_dup 3)
7509                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7510               (clobber (reg:CC FLAGS_REG))])
7511    (parallel [(set (match_dup 0)
7512                    (div:DI (reg:DI 0) (match_dup 2)))
7513               (set (match_dup 3)
7514                    (mod:DI (reg:DI 0) (match_dup 2)))
7515               (use (match_dup 3))
7516               (clobber (reg:CC FLAGS_REG))])]
7518   /* Avoid use of cltd in favor of a mov+shift.  */
7519   if (!TARGET_USE_CLTD && !optimize_size)
7520     {
7521       if (true_regnum (operands[1]))
7522         emit_move_insn (operands[0], operands[1]);
7523       else
7524         emit_move_insn (operands[3], operands[1]);
7525       operands[4] = operands[3];
7526     }
7527   else
7528     {
7529       gcc_assert (!true_regnum (operands[1]));
7530       operands[4] = operands[1];
7531     }
7535 (define_expand "divmodsi4"
7536   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7537                    (div:SI (match_operand:SI 1 "register_operand" "")
7538                            (match_operand:SI 2 "nonimmediate_operand" "")))
7539               (set (match_operand:SI 3 "register_operand" "")
7540                    (mod:SI (match_dup 1) (match_dup 2)))
7541               (clobber (reg:CC FLAGS_REG))])]
7542   ""
7543   "")
7545 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7546 ;; Penalize eax case slightly because it results in worse scheduling
7547 ;; of code.
7548 (define_insn "*divmodsi4_nocltd"
7549   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7550         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7551                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7552    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7553         (mod:SI (match_dup 2) (match_dup 3)))
7554    (clobber (reg:CC FLAGS_REG))]
7555   "!optimize_size && !TARGET_USE_CLTD"
7556   "#"
7557   [(set_attr "type" "multi")])
7559 (define_insn "*divmodsi4_cltd"
7560   [(set (match_operand:SI 0 "register_operand" "=a")
7561         (div:SI (match_operand:SI 2 "register_operand" "a")
7562                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7563    (set (match_operand:SI 1 "register_operand" "=&d")
7564         (mod:SI (match_dup 2) (match_dup 3)))
7565    (clobber (reg:CC FLAGS_REG))]
7566   "optimize_size || TARGET_USE_CLTD"
7567   "#"
7568   [(set_attr "type" "multi")])
7570 (define_insn "*divmodsi_noext"
7571   [(set (match_operand:SI 0 "register_operand" "=a")
7572         (div:SI (match_operand:SI 1 "register_operand" "0")
7573                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7574    (set (match_operand:SI 3 "register_operand" "=d")
7575         (mod:SI (match_dup 1) (match_dup 2)))
7576    (use (match_operand:SI 4 "register_operand" "3"))
7577    (clobber (reg:CC FLAGS_REG))]
7578   ""
7579   "idiv{l}\t%2"
7580   [(set_attr "type" "idiv")
7581    (set_attr "mode" "SI")])
7583 (define_split
7584   [(set (match_operand:SI 0 "register_operand" "")
7585         (div:SI (match_operand:SI 1 "register_operand" "")
7586                 (match_operand:SI 2 "nonimmediate_operand" "")))
7587    (set (match_operand:SI 3 "register_operand" "")
7588         (mod:SI (match_dup 1) (match_dup 2)))
7589    (clobber (reg:CC FLAGS_REG))]
7590   "reload_completed"
7591   [(parallel [(set (match_dup 3)
7592                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7593               (clobber (reg:CC FLAGS_REG))])
7594    (parallel [(set (match_dup 0)
7595                    (div:SI (reg:SI 0) (match_dup 2)))
7596               (set (match_dup 3)
7597                    (mod:SI (reg:SI 0) (match_dup 2)))
7598               (use (match_dup 3))
7599               (clobber (reg:CC FLAGS_REG))])]
7601   /* Avoid use of cltd in favor of a mov+shift.  */
7602   if (!TARGET_USE_CLTD && !optimize_size)
7603     {
7604       if (true_regnum (operands[1]))
7605         emit_move_insn (operands[0], operands[1]);
7606       else
7607         emit_move_insn (operands[3], operands[1]);
7608       operands[4] = operands[3];
7609     }
7610   else
7611     {
7612       gcc_assert (!true_regnum (operands[1]));
7613       operands[4] = operands[1];
7614     }
7616 ;; %%% Split me.
7617 (define_insn "divmodhi4"
7618   [(set (match_operand:HI 0 "register_operand" "=a")
7619         (div:HI (match_operand:HI 1 "register_operand" "0")
7620                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7621    (set (match_operand:HI 3 "register_operand" "=&d")
7622         (mod:HI (match_dup 1) (match_dup 2)))
7623    (clobber (reg:CC FLAGS_REG))]
7624   "TARGET_HIMODE_MATH"
7625   "cwtd\;idiv{w}\t%2"
7626   [(set_attr "type" "multi")
7627    (set_attr "length_immediate" "0")
7628    (set_attr "mode" "SI")])
7630 (define_insn "udivmoddi4"
7631   [(set (match_operand:DI 0 "register_operand" "=a")
7632         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7633                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7634    (set (match_operand:DI 3 "register_operand" "=&d")
7635         (umod:DI (match_dup 1) (match_dup 2)))
7636    (clobber (reg:CC FLAGS_REG))]
7637   "TARGET_64BIT"
7638   "xor{q}\t%3, %3\;div{q}\t%2"
7639   [(set_attr "type" "multi")
7640    (set_attr "length_immediate" "0")
7641    (set_attr "mode" "DI")])
7643 (define_insn "*udivmoddi4_noext"
7644   [(set (match_operand:DI 0 "register_operand" "=a")
7645         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7646                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7647    (set (match_operand:DI 3 "register_operand" "=d")
7648         (umod:DI (match_dup 1) (match_dup 2)))
7649    (use (match_dup 3))
7650    (clobber (reg:CC FLAGS_REG))]
7651   "TARGET_64BIT"
7652   "div{q}\t%2"
7653   [(set_attr "type" "idiv")
7654    (set_attr "mode" "DI")])
7656 (define_split
7657   [(set (match_operand:DI 0 "register_operand" "")
7658         (udiv:DI (match_operand:DI 1 "register_operand" "")
7659                  (match_operand:DI 2 "nonimmediate_operand" "")))
7660    (set (match_operand:DI 3 "register_operand" "")
7661         (umod:DI (match_dup 1) (match_dup 2)))
7662    (clobber (reg:CC FLAGS_REG))]
7663   "TARGET_64BIT && reload_completed"
7664   [(set (match_dup 3) (const_int 0))
7665    (parallel [(set (match_dup 0)
7666                    (udiv:DI (match_dup 1) (match_dup 2)))
7667               (set (match_dup 3)
7668                    (umod:DI (match_dup 1) (match_dup 2)))
7669               (use (match_dup 3))
7670               (clobber (reg:CC FLAGS_REG))])]
7671   "")
7673 (define_insn "udivmodsi4"
7674   [(set (match_operand:SI 0 "register_operand" "=a")
7675         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7676                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7677    (set (match_operand:SI 3 "register_operand" "=&d")
7678         (umod:SI (match_dup 1) (match_dup 2)))
7679    (clobber (reg:CC FLAGS_REG))]
7680   ""
7681   "xor{l}\t%3, %3\;div{l}\t%2"
7682   [(set_attr "type" "multi")
7683    (set_attr "length_immediate" "0")
7684    (set_attr "mode" "SI")])
7686 (define_insn "*udivmodsi4_noext"
7687   [(set (match_operand:SI 0 "register_operand" "=a")
7688         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7689                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7690    (set (match_operand:SI 3 "register_operand" "=d")
7691         (umod:SI (match_dup 1) (match_dup 2)))
7692    (use (match_dup 3))
7693    (clobber (reg:CC FLAGS_REG))]
7694   ""
7695   "div{l}\t%2"
7696   [(set_attr "type" "idiv")
7697    (set_attr "mode" "SI")])
7699 (define_split
7700   [(set (match_operand:SI 0 "register_operand" "")
7701         (udiv:SI (match_operand:SI 1 "register_operand" "")
7702                  (match_operand:SI 2 "nonimmediate_operand" "")))
7703    (set (match_operand:SI 3 "register_operand" "")
7704         (umod:SI (match_dup 1) (match_dup 2)))
7705    (clobber (reg:CC FLAGS_REG))]
7706   "reload_completed"
7707   [(set (match_dup 3) (const_int 0))
7708    (parallel [(set (match_dup 0)
7709                    (udiv:SI (match_dup 1) (match_dup 2)))
7710               (set (match_dup 3)
7711                    (umod:SI (match_dup 1) (match_dup 2)))
7712               (use (match_dup 3))
7713               (clobber (reg:CC FLAGS_REG))])]
7714   "")
7716 (define_expand "udivmodhi4"
7717   [(set (match_dup 4) (const_int 0))
7718    (parallel [(set (match_operand:HI 0 "register_operand" "")
7719                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7720                             (match_operand:HI 2 "nonimmediate_operand" "")))
7721               (set (match_operand:HI 3 "register_operand" "")
7722                    (umod:HI (match_dup 1) (match_dup 2)))
7723               (use (match_dup 4))
7724               (clobber (reg:CC FLAGS_REG))])]
7725   "TARGET_HIMODE_MATH"
7726   "operands[4] = gen_reg_rtx (HImode);")
7728 (define_insn "*udivmodhi_noext"
7729   [(set (match_operand:HI 0 "register_operand" "=a")
7730         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7731                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7732    (set (match_operand:HI 3 "register_operand" "=d")
7733         (umod:HI (match_dup 1) (match_dup 2)))
7734    (use (match_operand:HI 4 "register_operand" "3"))
7735    (clobber (reg:CC FLAGS_REG))]
7736   ""
7737   "div{w}\t%2"
7738   [(set_attr "type" "idiv")
7739    (set_attr "mode" "HI")])
7741 ;; We cannot use div/idiv for double division, because it causes
7742 ;; "division by zero" on the overflow and that's not what we expect
7743 ;; from truncate.  Because true (non truncating) double division is
7744 ;; never generated, we can't create this insn anyway.
7746 ;(define_insn ""
7747 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7748 ;       (truncate:SI
7749 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7750 ;                  (zero_extend:DI
7751 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7752 ;   (set (match_operand:SI 3 "register_operand" "=d")
7753 ;       (truncate:SI
7754 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7755 ;   (clobber (reg:CC FLAGS_REG))]
7756 ;  ""
7757 ;  "div{l}\t{%2, %0|%0, %2}"
7758 ;  [(set_attr "type" "idiv")])
7760 ;;- Logical AND instructions
7762 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7763 ;; Note that this excludes ah.
7765 (define_insn "*testdi_1_rex64"
7766   [(set (reg FLAGS_REG)
7767         (compare
7768           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7769                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7770           (const_int 0)))]
7771   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7772    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7773   "@
7774    test{l}\t{%k1, %k0|%k0, %k1}
7775    test{l}\t{%k1, %k0|%k0, %k1}
7776    test{q}\t{%1, %0|%0, %1}
7777    test{q}\t{%1, %0|%0, %1}
7778    test{q}\t{%1, %0|%0, %1}"
7779   [(set_attr "type" "test")
7780    (set_attr "modrm" "0,1,0,1,1")
7781    (set_attr "mode" "SI,SI,DI,DI,DI")
7782    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7784 (define_insn "testsi_1"
7785   [(set (reg FLAGS_REG)
7786         (compare
7787           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7788                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7789           (const_int 0)))]
7790   "ix86_match_ccmode (insn, CCNOmode)
7791    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7792   "test{l}\t{%1, %0|%0, %1}"
7793   [(set_attr "type" "test")
7794    (set_attr "modrm" "0,1,1")
7795    (set_attr "mode" "SI")
7796    (set_attr "pent_pair" "uv,np,uv")])
7798 (define_expand "testsi_ccno_1"
7799   [(set (reg:CCNO FLAGS_REG)
7800         (compare:CCNO
7801           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7802                   (match_operand:SI 1 "nonmemory_operand" ""))
7803           (const_int 0)))]
7804   ""
7805   "")
7807 (define_insn "*testhi_1"
7808   [(set (reg FLAGS_REG)
7809         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7810                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7811                  (const_int 0)))]
7812   "ix86_match_ccmode (insn, CCNOmode)
7813    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7814   "test{w}\t{%1, %0|%0, %1}"
7815   [(set_attr "type" "test")
7816    (set_attr "modrm" "0,1,1")
7817    (set_attr "mode" "HI")
7818    (set_attr "pent_pair" "uv,np,uv")])
7820 (define_expand "testqi_ccz_1"
7821   [(set (reg:CCZ FLAGS_REG)
7822         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7823                              (match_operand:QI 1 "nonmemory_operand" ""))
7824                  (const_int 0)))]
7825   ""
7826   "")
7828 (define_insn "*testqi_1_maybe_si"
7829   [(set (reg FLAGS_REG)
7830         (compare
7831           (and:QI
7832             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7833             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7834           (const_int 0)))]
7835    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7836     && ix86_match_ccmode (insn,
7837                          GET_CODE (operands[1]) == CONST_INT
7838                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7840   if (which_alternative == 3)
7841     {
7842       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7843         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7844       return "test{l}\t{%1, %k0|%k0, %1}";
7845     }
7846   return "test{b}\t{%1, %0|%0, %1}";
7848   [(set_attr "type" "test")
7849    (set_attr "modrm" "0,1,1,1")
7850    (set_attr "mode" "QI,QI,QI,SI")
7851    (set_attr "pent_pair" "uv,np,uv,np")])
7853 (define_insn "*testqi_1"
7854   [(set (reg FLAGS_REG)
7855         (compare
7856           (and:QI
7857             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7858             (match_operand:QI 1 "general_operand" "n,n,qn"))
7859           (const_int 0)))]
7860   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7861    && ix86_match_ccmode (insn, CCNOmode)"
7862   "test{b}\t{%1, %0|%0, %1}"
7863   [(set_attr "type" "test")
7864    (set_attr "modrm" "0,1,1")
7865    (set_attr "mode" "QI")
7866    (set_attr "pent_pair" "uv,np,uv")])
7868 (define_expand "testqi_ext_ccno_0"
7869   [(set (reg:CCNO FLAGS_REG)
7870         (compare:CCNO
7871           (and:SI
7872             (zero_extract:SI
7873               (match_operand 0 "ext_register_operand" "")
7874               (const_int 8)
7875               (const_int 8))
7876             (match_operand 1 "const_int_operand" ""))
7877           (const_int 0)))]
7878   ""
7879   "")
7881 (define_insn "*testqi_ext_0"
7882   [(set (reg FLAGS_REG)
7883         (compare
7884           (and:SI
7885             (zero_extract:SI
7886               (match_operand 0 "ext_register_operand" "Q")
7887               (const_int 8)
7888               (const_int 8))
7889             (match_operand 1 "const_int_operand" "n"))
7890           (const_int 0)))]
7891   "ix86_match_ccmode (insn, CCNOmode)"
7892   "test{b}\t{%1, %h0|%h0, %1}"
7893   [(set_attr "type" "test")
7894    (set_attr "mode" "QI")
7895    (set_attr "length_immediate" "1")
7896    (set_attr "pent_pair" "np")])
7898 (define_insn "*testqi_ext_1"
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             (zero_extend:SI
7907               (match_operand:QI 1 "general_operand" "Qm")))
7908           (const_int 0)))]
7909   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7910    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7911   "test{b}\t{%1, %h0|%h0, %1}"
7912   [(set_attr "type" "test")
7913    (set_attr "mode" "QI")])
7915 (define_insn "*testqi_ext_1_rex64"
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 "register_operand" "Q")))
7925           (const_int 0)))]
7926   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7927   "test{b}\t{%1, %h0|%h0, %1}"
7928   [(set_attr "type" "test")
7929    (set_attr "mode" "QI")])
7931 (define_insn "*testqi_ext_2"
7932   [(set (reg FLAGS_REG)
7933         (compare
7934           (and:SI
7935             (zero_extract:SI
7936               (match_operand 0 "ext_register_operand" "Q")
7937               (const_int 8)
7938               (const_int 8))
7939             (zero_extract:SI
7940               (match_operand 1 "ext_register_operand" "Q")
7941               (const_int 8)
7942               (const_int 8)))
7943           (const_int 0)))]
7944   "ix86_match_ccmode (insn, CCNOmode)"
7945   "test{b}\t{%h1, %h0|%h0, %h1}"
7946   [(set_attr "type" "test")
7947    (set_attr "mode" "QI")])
7949 ;; Combine likes to form bit extractions for some tests.  Humor it.
7950 (define_insn "*testqi_ext_3"
7951   [(set (reg FLAGS_REG)
7952         (compare (zero_extract:SI
7953                    (match_operand 0 "nonimmediate_operand" "rm")
7954                    (match_operand:SI 1 "const_int_operand" "")
7955                    (match_operand:SI 2 "const_int_operand" ""))
7956                  (const_int 0)))]
7957   "ix86_match_ccmode (insn, CCNOmode)
7958    && INTVAL (operands[1]) > 0
7959    && INTVAL (operands[2]) >= 0
7960    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7961    && (GET_MODE (operands[0]) == SImode
7962        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7963        || GET_MODE (operands[0]) == HImode
7964        || GET_MODE (operands[0]) == QImode)"
7965   "#")
7967 (define_insn "*testqi_ext_3_rex64"
7968   [(set (reg FLAGS_REG)
7969         (compare (zero_extract:DI
7970                    (match_operand 0 "nonimmediate_operand" "rm")
7971                    (match_operand:DI 1 "const_int_operand" "")
7972                    (match_operand:DI 2 "const_int_operand" ""))
7973                  (const_int 0)))]
7974   "TARGET_64BIT
7975    && ix86_match_ccmode (insn, CCNOmode)
7976    && INTVAL (operands[1]) > 0
7977    && INTVAL (operands[2]) >= 0
7978    /* Ensure that resulting mask is zero or sign extended operand.  */
7979    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7980        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7981            && INTVAL (operands[1]) > 32))
7982    && (GET_MODE (operands[0]) == SImode
7983        || GET_MODE (operands[0]) == DImode
7984        || GET_MODE (operands[0]) == HImode
7985        || GET_MODE (operands[0]) == QImode)"
7986   "#")
7988 (define_split
7989   [(set (match_operand 0 "flags_reg_operand" "")
7990         (match_operator 1 "compare_operator"
7991           [(zero_extract
7992              (match_operand 2 "nonimmediate_operand" "")
7993              (match_operand 3 "const_int_operand" "")
7994              (match_operand 4 "const_int_operand" ""))
7995            (const_int 0)]))]
7996   "ix86_match_ccmode (insn, CCNOmode)"
7997   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7999   rtx val = operands[2];
8000   HOST_WIDE_INT len = INTVAL (operands[3]);
8001   HOST_WIDE_INT pos = INTVAL (operands[4]);
8002   HOST_WIDE_INT mask;
8003   enum machine_mode mode, submode;
8005   mode = GET_MODE (val);
8006   if (GET_CODE (val) == MEM)
8007     {
8008       /* ??? Combine likes to put non-volatile mem extractions in QImode
8009          no matter the size of the test.  So find a mode that works.  */
8010       if (! MEM_VOLATILE_P (val))
8011         {
8012           mode = smallest_mode_for_size (pos + len, MODE_INT);
8013           val = adjust_address (val, mode, 0);
8014         }
8015     }
8016   else if (GET_CODE (val) == SUBREG
8017            && (submode = GET_MODE (SUBREG_REG (val)),
8018                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8019            && pos + len <= GET_MODE_BITSIZE (submode))
8020     {
8021       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8022       mode = submode;
8023       val = SUBREG_REG (val);
8024     }
8025   else if (mode == HImode && pos + len <= 8)
8026     {
8027       /* Small HImode tests can be converted to QImode.  */
8028       mode = QImode;
8029       val = gen_lowpart (QImode, val);
8030     }
8032   if (len == HOST_BITS_PER_WIDE_INT)
8033     mask = -1;
8034   else
8035     mask = ((HOST_WIDE_INT)1 << len) - 1;
8036   mask <<= pos;
8038   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8041 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8042 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8043 ;; this is relatively important trick.
8044 ;; Do the conversion only post-reload to avoid limiting of the register class
8045 ;; to QI regs.
8046 (define_split
8047   [(set (match_operand 0 "flags_reg_operand" "")
8048         (match_operator 1 "compare_operator"
8049           [(and (match_operand 2 "register_operand" "")
8050                 (match_operand 3 "const_int_operand" ""))
8051            (const_int 0)]))]
8052    "reload_completed
8053     && QI_REG_P (operands[2])
8054     && GET_MODE (operands[2]) != QImode
8055     && ((ix86_match_ccmode (insn, CCZmode)
8056          && !(INTVAL (operands[3]) & ~(255 << 8)))
8057         || (ix86_match_ccmode (insn, CCNOmode)
8058             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8059   [(set (match_dup 0)
8060         (match_op_dup 1
8061           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8062                    (match_dup 3))
8063            (const_int 0)]))]
8064   "operands[2] = gen_lowpart (SImode, operands[2]);
8065    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8067 (define_split
8068   [(set (match_operand 0 "flags_reg_operand" "")
8069         (match_operator 1 "compare_operator"
8070           [(and (match_operand 2 "nonimmediate_operand" "")
8071                 (match_operand 3 "const_int_operand" ""))
8072            (const_int 0)]))]
8073    "reload_completed
8074     && GET_MODE (operands[2]) != QImode
8075     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8076     && ((ix86_match_ccmode (insn, CCZmode)
8077          && !(INTVAL (operands[3]) & ~255))
8078         || (ix86_match_ccmode (insn, CCNOmode)
8079             && !(INTVAL (operands[3]) & ~127)))"
8080   [(set (match_dup 0)
8081         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8082                          (const_int 0)]))]
8083   "operands[2] = gen_lowpart (QImode, operands[2]);
8084    operands[3] = gen_lowpart (QImode, operands[3]);")
8087 ;; %%% This used to optimize known byte-wide and operations to memory,
8088 ;; and sometimes to QImode registers.  If this is considered useful,
8089 ;; it should be done with splitters.
8091 (define_expand "anddi3"
8092   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8093         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8094                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8095    (clobber (reg:CC FLAGS_REG))]
8096   "TARGET_64BIT"
8097   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8099 (define_insn "*anddi_1_rex64"
8100   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8101         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8102                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8103    (clobber (reg:CC FLAGS_REG))]
8104   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8106   switch (get_attr_type (insn))
8107     {
8108     case TYPE_IMOVX:
8109       {
8110         enum machine_mode mode;
8112         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8113         if (INTVAL (operands[2]) == 0xff)
8114           mode = QImode;
8115         else
8116           {
8117             gcc_assert (INTVAL (operands[2]) == 0xffff);
8118             mode = HImode;
8119           }
8121         operands[1] = gen_lowpart (mode, operands[1]);
8122         if (mode == QImode)
8123           return "movz{bq|x}\t{%1,%0|%0, %1}";
8124         else
8125           return "movz{wq|x}\t{%1,%0|%0, %1}";
8126       }
8128     default:
8129       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8130       if (get_attr_mode (insn) == MODE_SI)
8131         return "and{l}\t{%k2, %k0|%k0, %k2}";
8132       else
8133         return "and{q}\t{%2, %0|%0, %2}";
8134     }
8136   [(set_attr "type" "alu,alu,alu,imovx")
8137    (set_attr "length_immediate" "*,*,*,0")
8138    (set_attr "mode" "SI,DI,DI,DI")])
8140 (define_insn "*anddi_2"
8141   [(set (reg FLAGS_REG)
8142         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8143                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8144                  (const_int 0)))
8145    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8146         (and:DI (match_dup 1) (match_dup 2)))]
8147   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8148    && ix86_binary_operator_ok (AND, DImode, operands)"
8149   "@
8150    and{l}\t{%k2, %k0|%k0, %k2}
8151    and{q}\t{%2, %0|%0, %2}
8152    and{q}\t{%2, %0|%0, %2}"
8153   [(set_attr "type" "alu")
8154    (set_attr "mode" "SI,DI,DI")])
8156 (define_expand "andsi3"
8157   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8158         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8159                 (match_operand:SI 2 "general_operand" "")))
8160    (clobber (reg:CC FLAGS_REG))]
8161   ""
8162   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8164 (define_insn "*andsi_1"
8165   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8166         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8167                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8168    (clobber (reg:CC FLAGS_REG))]
8169   "ix86_binary_operator_ok (AND, SImode, operands)"
8171   switch (get_attr_type (insn))
8172     {
8173     case TYPE_IMOVX:
8174       {
8175         enum machine_mode mode;
8177         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8178         if (INTVAL (operands[2]) == 0xff)
8179           mode = QImode;
8180         else
8181           {
8182             gcc_assert (INTVAL (operands[2]) == 0xffff);
8183             mode = HImode;
8184           }
8186         operands[1] = gen_lowpart (mode, operands[1]);
8187         if (mode == QImode)
8188           return "movz{bl|x}\t{%1,%0|%0, %1}";
8189         else
8190           return "movz{wl|x}\t{%1,%0|%0, %1}";
8191       }
8193     default:
8194       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8195       return "and{l}\t{%2, %0|%0, %2}";
8196     }
8198   [(set_attr "type" "alu,alu,imovx")
8199    (set_attr "length_immediate" "*,*,0")
8200    (set_attr "mode" "SI")])
8202 (define_split
8203   [(set (match_operand 0 "register_operand" "")
8204         (and (match_dup 0)
8205              (const_int -65536)))
8206    (clobber (reg:CC FLAGS_REG))]
8207   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8208   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8209   "operands[1] = gen_lowpart (HImode, operands[0]);")
8211 (define_split
8212   [(set (match_operand 0 "ext_register_operand" "")
8213         (and (match_dup 0)
8214              (const_int -256)))
8215    (clobber (reg:CC FLAGS_REG))]
8216   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8217   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8218   "operands[1] = gen_lowpart (QImode, operands[0]);")
8220 (define_split
8221   [(set (match_operand 0 "ext_register_operand" "")
8222         (and (match_dup 0)
8223              (const_int -65281)))
8224    (clobber (reg:CC FLAGS_REG))]
8225   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8226   [(parallel [(set (zero_extract:SI (match_dup 0)
8227                                     (const_int 8)
8228                                     (const_int 8))
8229                    (xor:SI
8230                      (zero_extract:SI (match_dup 0)
8231                                       (const_int 8)
8232                                       (const_int 8))
8233                      (zero_extract:SI (match_dup 0)
8234                                       (const_int 8)
8235                                       (const_int 8))))
8236               (clobber (reg:CC FLAGS_REG))])]
8237   "operands[0] = gen_lowpart (SImode, operands[0]);")
8239 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8240 (define_insn "*andsi_1_zext"
8241   [(set (match_operand:DI 0 "register_operand" "=r")
8242         (zero_extend:DI
8243           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8244                   (match_operand:SI 2 "general_operand" "rim"))))
8245    (clobber (reg:CC FLAGS_REG))]
8246   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8247   "and{l}\t{%2, %k0|%k0, %2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "SI")])
8251 (define_insn "*andsi_2"
8252   [(set (reg FLAGS_REG)
8253         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8254                          (match_operand:SI 2 "general_operand" "rim,ri"))
8255                  (const_int 0)))
8256    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8257         (and:SI (match_dup 1) (match_dup 2)))]
8258   "ix86_match_ccmode (insn, CCNOmode)
8259    && ix86_binary_operator_ok (AND, SImode, operands)"
8260   "and{l}\t{%2, %0|%0, %2}"
8261   [(set_attr "type" "alu")
8262    (set_attr "mode" "SI")])
8264 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8265 (define_insn "*andsi_2_zext"
8266   [(set (reg FLAGS_REG)
8267         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8268                          (match_operand:SI 2 "general_operand" "rim"))
8269                  (const_int 0)))
8270    (set (match_operand:DI 0 "register_operand" "=r")
8271         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8272   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8273    && ix86_binary_operator_ok (AND, SImode, operands)"
8274   "and{l}\t{%2, %k0|%k0, %2}"
8275   [(set_attr "type" "alu")
8276    (set_attr "mode" "SI")])
8278 (define_expand "andhi3"
8279   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8280         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8281                 (match_operand:HI 2 "general_operand" "")))
8282    (clobber (reg:CC FLAGS_REG))]
8283   "TARGET_HIMODE_MATH"
8284   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8286 (define_insn "*andhi_1"
8287   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8288         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8289                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8290    (clobber (reg:CC FLAGS_REG))]
8291   "ix86_binary_operator_ok (AND, HImode, operands)"
8293   switch (get_attr_type (insn))
8294     {
8295     case TYPE_IMOVX:
8296       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8297       gcc_assert (INTVAL (operands[2]) == 0xff);
8298       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8300     default:
8301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8303       return "and{w}\t{%2, %0|%0, %2}";
8304     }
8306   [(set_attr "type" "alu,alu,imovx")
8307    (set_attr "length_immediate" "*,*,0")
8308    (set_attr "mode" "HI,HI,SI")])
8310 (define_insn "*andhi_2"
8311   [(set (reg FLAGS_REG)
8312         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8313                          (match_operand:HI 2 "general_operand" "rim,ri"))
8314                  (const_int 0)))
8315    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8316         (and:HI (match_dup 1) (match_dup 2)))]
8317   "ix86_match_ccmode (insn, CCNOmode)
8318    && ix86_binary_operator_ok (AND, HImode, operands)"
8319   "and{w}\t{%2, %0|%0, %2}"
8320   [(set_attr "type" "alu")
8321    (set_attr "mode" "HI")])
8323 (define_expand "andqi3"
8324   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8325         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8326                 (match_operand:QI 2 "general_operand" "")))
8327    (clobber (reg:CC FLAGS_REG))]
8328   "TARGET_QIMODE_MATH"
8329   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8331 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8332 (define_insn "*andqi_1"
8333   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8334         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8335                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8336    (clobber (reg:CC FLAGS_REG))]
8337   "ix86_binary_operator_ok (AND, QImode, operands)"
8338   "@
8339    and{b}\t{%2, %0|%0, %2}
8340    and{b}\t{%2, %0|%0, %2}
8341    and{l}\t{%k2, %k0|%k0, %k2}"
8342   [(set_attr "type" "alu")
8343    (set_attr "mode" "QI,QI,SI")])
8345 (define_insn "*andqi_1_slp"
8346   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8347         (and:QI (match_dup 0)
8348                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8349    (clobber (reg:CC FLAGS_REG))]
8350   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8351    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8352   "and{b}\t{%1, %0|%0, %1}"
8353   [(set_attr "type" "alu1")
8354    (set_attr "mode" "QI")])
8356 (define_insn "*andqi_2_maybe_si"
8357   [(set (reg FLAGS_REG)
8358         (compare (and:QI
8359                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8360                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8361                  (const_int 0)))
8362    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8363         (and:QI (match_dup 1) (match_dup 2)))]
8364   "ix86_binary_operator_ok (AND, QImode, operands)
8365    && ix86_match_ccmode (insn,
8366                          GET_CODE (operands[2]) == CONST_INT
8367                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8369   if (which_alternative == 2)
8370     {
8371       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8372         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8373       return "and{l}\t{%2, %k0|%k0, %2}";
8374     }
8375   return "and{b}\t{%2, %0|%0, %2}";
8377   [(set_attr "type" "alu")
8378    (set_attr "mode" "QI,QI,SI")])
8380 (define_insn "*andqi_2"
8381   [(set (reg FLAGS_REG)
8382         (compare (and:QI
8383                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8384                    (match_operand:QI 2 "general_operand" "qim,qi"))
8385                  (const_int 0)))
8386    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8387         (and:QI (match_dup 1) (match_dup 2)))]
8388   "ix86_match_ccmode (insn, CCNOmode)
8389    && ix86_binary_operator_ok (AND, QImode, operands)"
8390   "and{b}\t{%2, %0|%0, %2}"
8391   [(set_attr "type" "alu")
8392    (set_attr "mode" "QI")])
8394 (define_insn "*andqi_2_slp"
8395   [(set (reg FLAGS_REG)
8396         (compare (and:QI
8397                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8398                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8399                  (const_int 0)))
8400    (set (strict_low_part (match_dup 0))
8401         (and:QI (match_dup 0) (match_dup 1)))]
8402   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8403    && ix86_match_ccmode (insn, CCNOmode)
8404    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8405   "and{b}\t{%1, %0|%0, %1}"
8406   [(set_attr "type" "alu1")
8407    (set_attr "mode" "QI")])
8409 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8410 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8411 ;; for a QImode operand, which of course failed.
8413 (define_insn "andqi_ext_0"
8414   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8415                          (const_int 8)
8416                          (const_int 8))
8417         (and:SI
8418           (zero_extract:SI
8419             (match_operand 1 "ext_register_operand" "0")
8420             (const_int 8)
8421             (const_int 8))
8422           (match_operand 2 "const_int_operand" "n")))
8423    (clobber (reg:CC FLAGS_REG))]
8424   ""
8425   "and{b}\t{%2, %h0|%h0, %2}"
8426   [(set_attr "type" "alu")
8427    (set_attr "length_immediate" "1")
8428    (set_attr "mode" "QI")])
8430 ;; Generated by peephole translating test to and.  This shows up
8431 ;; often in fp comparisons.
8433 (define_insn "*andqi_ext_0_cc"
8434   [(set (reg FLAGS_REG)
8435         (compare
8436           (and:SI
8437             (zero_extract:SI
8438               (match_operand 1 "ext_register_operand" "0")
8439               (const_int 8)
8440               (const_int 8))
8441             (match_operand 2 "const_int_operand" "n"))
8442           (const_int 0)))
8443    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8444                          (const_int 8)
8445                          (const_int 8))
8446         (and:SI
8447           (zero_extract:SI
8448             (match_dup 1)
8449             (const_int 8)
8450             (const_int 8))
8451           (match_dup 2)))]
8452   "ix86_match_ccmode (insn, CCNOmode)"
8453   "and{b}\t{%2, %h0|%h0, %2}"
8454   [(set_attr "type" "alu")
8455    (set_attr "length_immediate" "1")
8456    (set_attr "mode" "QI")])
8458 (define_insn "*andqi_ext_1"
8459   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8460                          (const_int 8)
8461                          (const_int 8))
8462         (and:SI
8463           (zero_extract:SI
8464             (match_operand 1 "ext_register_operand" "0")
8465             (const_int 8)
8466             (const_int 8))
8467           (zero_extend:SI
8468             (match_operand:QI 2 "general_operand" "Qm"))))
8469    (clobber (reg:CC FLAGS_REG))]
8470   "!TARGET_64BIT"
8471   "and{b}\t{%2, %h0|%h0, %2}"
8472   [(set_attr "type" "alu")
8473    (set_attr "length_immediate" "0")
8474    (set_attr "mode" "QI")])
8476 (define_insn "*andqi_ext_1_rex64"
8477   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8478                          (const_int 8)
8479                          (const_int 8))
8480         (and:SI
8481           (zero_extract:SI
8482             (match_operand 1 "ext_register_operand" "0")
8483             (const_int 8)
8484             (const_int 8))
8485           (zero_extend:SI
8486             (match_operand 2 "ext_register_operand" "Q"))))
8487    (clobber (reg:CC FLAGS_REG))]
8488   "TARGET_64BIT"
8489   "and{b}\t{%2, %h0|%h0, %2}"
8490   [(set_attr "type" "alu")
8491    (set_attr "length_immediate" "0")
8492    (set_attr "mode" "QI")])
8494 (define_insn "*andqi_ext_2"
8495   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8496                          (const_int 8)
8497                          (const_int 8))
8498         (and:SI
8499           (zero_extract:SI
8500             (match_operand 1 "ext_register_operand" "%0")
8501             (const_int 8)
8502             (const_int 8))
8503           (zero_extract:SI
8504             (match_operand 2 "ext_register_operand" "Q")
8505             (const_int 8)
8506             (const_int 8))))
8507    (clobber (reg:CC FLAGS_REG))]
8508   ""
8509   "and{b}\t{%h2, %h0|%h0, %h2}"
8510   [(set_attr "type" "alu")
8511    (set_attr "length_immediate" "0")
8512    (set_attr "mode" "QI")])
8514 ;; Convert wide AND instructions with immediate operand to shorter QImode
8515 ;; equivalents when possible.
8516 ;; Don't do the splitting with memory operands, since it introduces risk
8517 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8518 ;; for size, but that can (should?) be handled by generic code instead.
8519 (define_split
8520   [(set (match_operand 0 "register_operand" "")
8521         (and (match_operand 1 "register_operand" "")
8522              (match_operand 2 "const_int_operand" "")))
8523    (clobber (reg:CC FLAGS_REG))]
8524    "reload_completed
8525     && QI_REG_P (operands[0])
8526     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8527     && !(~INTVAL (operands[2]) & ~(255 << 8))
8528     && GET_MODE (operands[0]) != QImode"
8529   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8530                    (and:SI (zero_extract:SI (match_dup 1)
8531                                             (const_int 8) (const_int 8))
8532                            (match_dup 2)))
8533               (clobber (reg:CC FLAGS_REG))])]
8534   "operands[0] = gen_lowpart (SImode, operands[0]);
8535    operands[1] = gen_lowpart (SImode, operands[1]);
8536    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8538 ;; Since AND can be encoded with sign extended immediate, this is only
8539 ;; profitable when 7th bit is not set.
8540 (define_split
8541   [(set (match_operand 0 "register_operand" "")
8542         (and (match_operand 1 "general_operand" "")
8543              (match_operand 2 "const_int_operand" "")))
8544    (clobber (reg:CC FLAGS_REG))]
8545    "reload_completed
8546     && ANY_QI_REG_P (operands[0])
8547     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8548     && !(~INTVAL (operands[2]) & ~255)
8549     && !(INTVAL (operands[2]) & 128)
8550     && GET_MODE (operands[0]) != QImode"
8551   [(parallel [(set (strict_low_part (match_dup 0))
8552                    (and:QI (match_dup 1)
8553                            (match_dup 2)))
8554               (clobber (reg:CC FLAGS_REG))])]
8555   "operands[0] = gen_lowpart (QImode, operands[0]);
8556    operands[1] = gen_lowpart (QImode, operands[1]);
8557    operands[2] = gen_lowpart (QImode, operands[2]);")
8559 ;; Logical inclusive OR instructions
8561 ;; %%% This used to optimize known byte-wide and operations to memory.
8562 ;; If this is considered useful, it should be done with splitters.
8564 (define_expand "iordi3"
8565   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8566         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8567                 (match_operand:DI 2 "x86_64_general_operand" "")))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "TARGET_64BIT"
8570   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8572 (define_insn "*iordi_1_rex64"
8573   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8574         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8575                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8576    (clobber (reg:CC FLAGS_REG))]
8577   "TARGET_64BIT
8578    && ix86_binary_operator_ok (IOR, DImode, operands)"
8579   "or{q}\t{%2, %0|%0, %2}"
8580   [(set_attr "type" "alu")
8581    (set_attr "mode" "DI")])
8583 (define_insn "*iordi_2_rex64"
8584   [(set (reg FLAGS_REG)
8585         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8586                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8587                  (const_int 0)))
8588    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8589         (ior:DI (match_dup 1) (match_dup 2)))]
8590   "TARGET_64BIT
8591    && ix86_match_ccmode (insn, CCNOmode)
8592    && ix86_binary_operator_ok (IOR, DImode, operands)"
8593   "or{q}\t{%2, %0|%0, %2}"
8594   [(set_attr "type" "alu")
8595    (set_attr "mode" "DI")])
8597 (define_insn "*iordi_3_rex64"
8598   [(set (reg FLAGS_REG)
8599         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8600                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8601                  (const_int 0)))
8602    (clobber (match_scratch:DI 0 "=r"))]
8603   "TARGET_64BIT
8604    && ix86_match_ccmode (insn, CCNOmode)
8605    && ix86_binary_operator_ok (IOR, DImode, operands)"
8606   "or{q}\t{%2, %0|%0, %2}"
8607   [(set_attr "type" "alu")
8608    (set_attr "mode" "DI")])
8611 (define_expand "iorsi3"
8612   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8613         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8614                 (match_operand:SI 2 "general_operand" "")))
8615    (clobber (reg:CC FLAGS_REG))]
8616   ""
8617   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8619 (define_insn "*iorsi_1"
8620   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8621         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8622                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8623    (clobber (reg:CC FLAGS_REG))]
8624   "ix86_binary_operator_ok (IOR, SImode, operands)"
8625   "or{l}\t{%2, %0|%0, %2}"
8626   [(set_attr "type" "alu")
8627    (set_attr "mode" "SI")])
8629 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8630 (define_insn "*iorsi_1_zext"
8631   [(set (match_operand:DI 0 "register_operand" "=rm")
8632         (zero_extend:DI
8633           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8634                   (match_operand:SI 2 "general_operand" "rim"))))
8635    (clobber (reg:CC FLAGS_REG))]
8636   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8637   "or{l}\t{%2, %k0|%k0, %2}"
8638   [(set_attr "type" "alu")
8639    (set_attr "mode" "SI")])
8641 (define_insn "*iorsi_1_zext_imm"
8642   [(set (match_operand:DI 0 "register_operand" "=rm")
8643         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8644                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8645    (clobber (reg:CC FLAGS_REG))]
8646   "TARGET_64BIT"
8647   "or{l}\t{%2, %k0|%k0, %2}"
8648   [(set_attr "type" "alu")
8649    (set_attr "mode" "SI")])
8651 (define_insn "*iorsi_2"
8652   [(set (reg FLAGS_REG)
8653         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8654                          (match_operand:SI 2 "general_operand" "rim,ri"))
8655                  (const_int 0)))
8656    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8657         (ior:SI (match_dup 1) (match_dup 2)))]
8658   "ix86_match_ccmode (insn, CCNOmode)
8659    && ix86_binary_operator_ok (IOR, SImode, operands)"
8660   "or{l}\t{%2, %0|%0, %2}"
8661   [(set_attr "type" "alu")
8662    (set_attr "mode" "SI")])
8664 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8665 ;; ??? Special case for immediate operand is missing - it is tricky.
8666 (define_insn "*iorsi_2_zext"
8667   [(set (reg FLAGS_REG)
8668         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8669                          (match_operand:SI 2 "general_operand" "rim"))
8670                  (const_int 0)))
8671    (set (match_operand:DI 0 "register_operand" "=r")
8672         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8673   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8674    && ix86_binary_operator_ok (IOR, SImode, operands)"
8675   "or{l}\t{%2, %k0|%k0, %2}"
8676   [(set_attr "type" "alu")
8677    (set_attr "mode" "SI")])
8679 (define_insn "*iorsi_2_zext_imm"
8680   [(set (reg FLAGS_REG)
8681         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8682                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8683                  (const_int 0)))
8684    (set (match_operand:DI 0 "register_operand" "=r")
8685         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8686   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8687    && ix86_binary_operator_ok (IOR, SImode, operands)"
8688   "or{l}\t{%2, %k0|%k0, %2}"
8689   [(set_attr "type" "alu")
8690    (set_attr "mode" "SI")])
8692 (define_insn "*iorsi_3"
8693   [(set (reg FLAGS_REG)
8694         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8695                          (match_operand:SI 2 "general_operand" "rim"))
8696                  (const_int 0)))
8697    (clobber (match_scratch:SI 0 "=r"))]
8698   "ix86_match_ccmode (insn, CCNOmode)
8699    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8700   "or{l}\t{%2, %0|%0, %2}"
8701   [(set_attr "type" "alu")
8702    (set_attr "mode" "SI")])
8704 (define_expand "iorhi3"
8705   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8706         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8707                 (match_operand:HI 2 "general_operand" "")))
8708    (clobber (reg:CC FLAGS_REG))]
8709   "TARGET_HIMODE_MATH"
8710   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8712 (define_insn "*iorhi_1"
8713   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8714         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8715                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8716    (clobber (reg:CC FLAGS_REG))]
8717   "ix86_binary_operator_ok (IOR, HImode, operands)"
8718   "or{w}\t{%2, %0|%0, %2}"
8719   [(set_attr "type" "alu")
8720    (set_attr "mode" "HI")])
8722 (define_insn "*iorhi_2"
8723   [(set (reg FLAGS_REG)
8724         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8725                          (match_operand:HI 2 "general_operand" "rim,ri"))
8726                  (const_int 0)))
8727    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8728         (ior:HI (match_dup 1) (match_dup 2)))]
8729   "ix86_match_ccmode (insn, CCNOmode)
8730    && ix86_binary_operator_ok (IOR, HImode, operands)"
8731   "or{w}\t{%2, %0|%0, %2}"
8732   [(set_attr "type" "alu")
8733    (set_attr "mode" "HI")])
8735 (define_insn "*iorhi_3"
8736   [(set (reg FLAGS_REG)
8737         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8738                          (match_operand:HI 2 "general_operand" "rim"))
8739                  (const_int 0)))
8740    (clobber (match_scratch:HI 0 "=r"))]
8741   "ix86_match_ccmode (insn, CCNOmode)
8742    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8743   "or{w}\t{%2, %0|%0, %2}"
8744   [(set_attr "type" "alu")
8745    (set_attr "mode" "HI")])
8747 (define_expand "iorqi3"
8748   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8749         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8750                 (match_operand:QI 2 "general_operand" "")))
8751    (clobber (reg:CC FLAGS_REG))]
8752   "TARGET_QIMODE_MATH"
8753   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8755 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8756 (define_insn "*iorqi_1"
8757   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8758         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8759                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "ix86_binary_operator_ok (IOR, QImode, operands)"
8762   "@
8763    or{b}\t{%2, %0|%0, %2}
8764    or{b}\t{%2, %0|%0, %2}
8765    or{l}\t{%k2, %k0|%k0, %k2}"
8766   [(set_attr "type" "alu")
8767    (set_attr "mode" "QI,QI,SI")])
8769 (define_insn "*iorqi_1_slp"
8770   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8771         (ior:QI (match_dup 0)
8772                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8773    (clobber (reg:CC FLAGS_REG))]
8774   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8775    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8776   "or{b}\t{%1, %0|%0, %1}"
8777   [(set_attr "type" "alu1")
8778    (set_attr "mode" "QI")])
8780 (define_insn "*iorqi_2"
8781   [(set (reg FLAGS_REG)
8782         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8783                          (match_operand:QI 2 "general_operand" "qim,qi"))
8784                  (const_int 0)))
8785    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8786         (ior:QI (match_dup 1) (match_dup 2)))]
8787   "ix86_match_ccmode (insn, CCNOmode)
8788    && ix86_binary_operator_ok (IOR, QImode, operands)"
8789   "or{b}\t{%2, %0|%0, %2}"
8790   [(set_attr "type" "alu")
8791    (set_attr "mode" "QI")])
8793 (define_insn "*iorqi_2_slp"
8794   [(set (reg FLAGS_REG)
8795         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8796                          (match_operand:QI 1 "general_operand" "qim,qi"))
8797                  (const_int 0)))
8798    (set (strict_low_part (match_dup 0))
8799         (ior:QI (match_dup 0) (match_dup 1)))]
8800   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8801    && ix86_match_ccmode (insn, CCNOmode)
8802    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8803   "or{b}\t{%1, %0|%0, %1}"
8804   [(set_attr "type" "alu1")
8805    (set_attr "mode" "QI")])
8807 (define_insn "*iorqi_3"
8808   [(set (reg FLAGS_REG)
8809         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8810                          (match_operand:QI 2 "general_operand" "qim"))
8811                  (const_int 0)))
8812    (clobber (match_scratch:QI 0 "=q"))]
8813   "ix86_match_ccmode (insn, CCNOmode)
8814    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8815   "or{b}\t{%2, %0|%0, %2}"
8816   [(set_attr "type" "alu")
8817    (set_attr "mode" "QI")])
8819 (define_insn "iorqi_ext_0"
8820   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8821                          (const_int 8)
8822                          (const_int 8))
8823         (ior:SI
8824           (zero_extract:SI
8825             (match_operand 1 "ext_register_operand" "0")
8826             (const_int 8)
8827             (const_int 8))
8828           (match_operand 2 "const_int_operand" "n")))
8829    (clobber (reg:CC FLAGS_REG))]
8830   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8831   "or{b}\t{%2, %h0|%h0, %2}"
8832   [(set_attr "type" "alu")
8833    (set_attr "length_immediate" "1")
8834    (set_attr "mode" "QI")])
8836 (define_insn "*iorqi_ext_1"
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           (zero_extend:SI
8846             (match_operand:QI 2 "general_operand" "Qm"))))
8847    (clobber (reg:CC FLAGS_REG))]
8848   "!TARGET_64BIT
8849    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8850   "or{b}\t{%2, %h0|%h0, %2}"
8851   [(set_attr "type" "alu")
8852    (set_attr "length_immediate" "0")
8853    (set_attr "mode" "QI")])
8855 (define_insn "*iorqi_ext_1_rex64"
8856   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8857                          (const_int 8)
8858                          (const_int 8))
8859         (ior:SI
8860           (zero_extract:SI
8861             (match_operand 1 "ext_register_operand" "0")
8862             (const_int 8)
8863             (const_int 8))
8864           (zero_extend:SI
8865             (match_operand 2 "ext_register_operand" "Q"))))
8866    (clobber (reg:CC FLAGS_REG))]
8867   "TARGET_64BIT
8868    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8869   "or{b}\t{%2, %h0|%h0, %2}"
8870   [(set_attr "type" "alu")
8871    (set_attr "length_immediate" "0")
8872    (set_attr "mode" "QI")])
8874 (define_insn "*iorqi_ext_2"
8875   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8876                          (const_int 8)
8877                          (const_int 8))
8878         (ior:SI
8879           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8880                            (const_int 8)
8881                            (const_int 8))
8882           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8883                            (const_int 8)
8884                            (const_int 8))))
8885    (clobber (reg:CC FLAGS_REG))]
8886   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8887   "ior{b}\t{%h2, %h0|%h0, %h2}"
8888   [(set_attr "type" "alu")
8889    (set_attr "length_immediate" "0")
8890    (set_attr "mode" "QI")])
8892 (define_split
8893   [(set (match_operand 0 "register_operand" "")
8894         (ior (match_operand 1 "register_operand" "")
8895              (match_operand 2 "const_int_operand" "")))
8896    (clobber (reg:CC FLAGS_REG))]
8897    "reload_completed
8898     && QI_REG_P (operands[0])
8899     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8900     && !(INTVAL (operands[2]) & ~(255 << 8))
8901     && GET_MODE (operands[0]) != QImode"
8902   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8903                    (ior:SI (zero_extract:SI (match_dup 1)
8904                                             (const_int 8) (const_int 8))
8905                            (match_dup 2)))
8906               (clobber (reg:CC FLAGS_REG))])]
8907   "operands[0] = gen_lowpart (SImode, operands[0]);
8908    operands[1] = gen_lowpart (SImode, operands[1]);
8909    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8911 ;; Since OR can be encoded with sign extended immediate, this is only
8912 ;; profitable when 7th bit is set.
8913 (define_split
8914   [(set (match_operand 0 "register_operand" "")
8915         (ior (match_operand 1 "general_operand" "")
8916              (match_operand 2 "const_int_operand" "")))
8917    (clobber (reg:CC FLAGS_REG))]
8918    "reload_completed
8919     && ANY_QI_REG_P (operands[0])
8920     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8921     && !(INTVAL (operands[2]) & ~255)
8922     && (INTVAL (operands[2]) & 128)
8923     && GET_MODE (operands[0]) != QImode"
8924   [(parallel [(set (strict_low_part (match_dup 0))
8925                    (ior:QI (match_dup 1)
8926                            (match_dup 2)))
8927               (clobber (reg:CC FLAGS_REG))])]
8928   "operands[0] = gen_lowpart (QImode, operands[0]);
8929    operands[1] = gen_lowpart (QImode, operands[1]);
8930    operands[2] = gen_lowpart (QImode, operands[2]);")
8932 ;; Logical XOR instructions
8934 ;; %%% This used to optimize known byte-wide and operations to memory.
8935 ;; If this is considered useful, it should be done with splitters.
8937 (define_expand "xordi3"
8938   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8939         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8940                 (match_operand:DI 2 "x86_64_general_operand" "")))
8941    (clobber (reg:CC FLAGS_REG))]
8942   "TARGET_64BIT"
8943   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8945 (define_insn "*xordi_1_rex64"
8946   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8947         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8948                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8949    (clobber (reg:CC FLAGS_REG))]
8950   "TARGET_64BIT
8951    && ix86_binary_operator_ok (XOR, DImode, operands)"
8952   "@
8953    xor{q}\t{%2, %0|%0, %2}
8954    xor{q}\t{%2, %0|%0, %2}"
8955   [(set_attr "type" "alu")
8956    (set_attr "mode" "DI,DI")])
8958 (define_insn "*xordi_2_rex64"
8959   [(set (reg FLAGS_REG)
8960         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8961                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8962                  (const_int 0)))
8963    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8964         (xor:DI (match_dup 1) (match_dup 2)))]
8965   "TARGET_64BIT
8966    && ix86_match_ccmode (insn, CCNOmode)
8967    && ix86_binary_operator_ok (XOR, DImode, operands)"
8968   "@
8969    xor{q}\t{%2, %0|%0, %2}
8970    xor{q}\t{%2, %0|%0, %2}"
8971   [(set_attr "type" "alu")
8972    (set_attr "mode" "DI,DI")])
8974 (define_insn "*xordi_3_rex64"
8975   [(set (reg FLAGS_REG)
8976         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8977                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8978                  (const_int 0)))
8979    (clobber (match_scratch:DI 0 "=r"))]
8980   "TARGET_64BIT
8981    && ix86_match_ccmode (insn, CCNOmode)
8982    && ix86_binary_operator_ok (XOR, DImode, operands)"
8983   "xor{q}\t{%2, %0|%0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "DI")])
8987 (define_expand "xorsi3"
8988   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8989         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8990                 (match_operand:SI 2 "general_operand" "")))
8991    (clobber (reg:CC FLAGS_REG))]
8992   ""
8993   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8995 (define_insn "*xorsi_1"
8996   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8997         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8998                 (match_operand:SI 2 "general_operand" "ri,rm")))
8999    (clobber (reg:CC FLAGS_REG))]
9000   "ix86_binary_operator_ok (XOR, SImode, operands)"
9001   "xor{l}\t{%2, %0|%0, %2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "SI")])
9005 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9006 ;; Add speccase for immediates
9007 (define_insn "*xorsi_1_zext"
9008   [(set (match_operand:DI 0 "register_operand" "=r")
9009         (zero_extend:DI
9010           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9011                   (match_operand:SI 2 "general_operand" "rim"))))
9012    (clobber (reg:CC FLAGS_REG))]
9013   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9014   "xor{l}\t{%2, %k0|%k0, %2}"
9015   [(set_attr "type" "alu")
9016    (set_attr "mode" "SI")])
9018 (define_insn "*xorsi_1_zext_imm"
9019   [(set (match_operand:DI 0 "register_operand" "=r")
9020         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9021                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9022    (clobber (reg:CC FLAGS_REG))]
9023   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9024   "xor{l}\t{%2, %k0|%k0, %2}"
9025   [(set_attr "type" "alu")
9026    (set_attr "mode" "SI")])
9028 (define_insn "*xorsi_2"
9029   [(set (reg FLAGS_REG)
9030         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9031                          (match_operand:SI 2 "general_operand" "rim,ri"))
9032                  (const_int 0)))
9033    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9034         (xor:SI (match_dup 1) (match_dup 2)))]
9035   "ix86_match_ccmode (insn, CCNOmode)
9036    && ix86_binary_operator_ok (XOR, SImode, operands)"
9037   "xor{l}\t{%2, %0|%0, %2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "mode" "SI")])
9041 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9042 ;; ??? Special case for immediate operand is missing - it is tricky.
9043 (define_insn "*xorsi_2_zext"
9044   [(set (reg FLAGS_REG)
9045         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9046                          (match_operand:SI 2 "general_operand" "rim"))
9047                  (const_int 0)))
9048    (set (match_operand:DI 0 "register_operand" "=r")
9049         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9050   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9051    && ix86_binary_operator_ok (XOR, SImode, operands)"
9052   "xor{l}\t{%2, %k0|%k0, %2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "SI")])
9056 (define_insn "*xorsi_2_zext_imm"
9057   [(set (reg FLAGS_REG)
9058         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9059                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9060                  (const_int 0)))
9061    (set (match_operand:DI 0 "register_operand" "=r")
9062         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9063   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9064    && ix86_binary_operator_ok (XOR, SImode, operands)"
9065   "xor{l}\t{%2, %k0|%k0, %2}"
9066   [(set_attr "type" "alu")
9067    (set_attr "mode" "SI")])
9069 (define_insn "*xorsi_3"
9070   [(set (reg FLAGS_REG)
9071         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9072                          (match_operand:SI 2 "general_operand" "rim"))
9073                  (const_int 0)))
9074    (clobber (match_scratch:SI 0 "=r"))]
9075   "ix86_match_ccmode (insn, CCNOmode)
9076    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9077   "xor{l}\t{%2, %0|%0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "mode" "SI")])
9081 (define_expand "xorhi3"
9082   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9083         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9084                 (match_operand:HI 2 "general_operand" "")))
9085    (clobber (reg:CC FLAGS_REG))]
9086   "TARGET_HIMODE_MATH"
9087   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9089 (define_insn "*xorhi_1"
9090   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9091         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9092                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   "ix86_binary_operator_ok (XOR, HImode, operands)"
9095   "xor{w}\t{%2, %0|%0, %2}"
9096   [(set_attr "type" "alu")
9097    (set_attr "mode" "HI")])
9099 (define_insn "*xorhi_2"
9100   [(set (reg FLAGS_REG)
9101         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9102                          (match_operand:HI 2 "general_operand" "rim,ri"))
9103                  (const_int 0)))
9104    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9105         (xor:HI (match_dup 1) (match_dup 2)))]
9106   "ix86_match_ccmode (insn, CCNOmode)
9107    && ix86_binary_operator_ok (XOR, HImode, operands)"
9108   "xor{w}\t{%2, %0|%0, %2}"
9109   [(set_attr "type" "alu")
9110    (set_attr "mode" "HI")])
9112 (define_insn "*xorhi_3"
9113   [(set (reg FLAGS_REG)
9114         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9115                          (match_operand:HI 2 "general_operand" "rim"))
9116                  (const_int 0)))
9117    (clobber (match_scratch:HI 0 "=r"))]
9118   "ix86_match_ccmode (insn, CCNOmode)
9119    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9120   "xor{w}\t{%2, %0|%0, %2}"
9121   [(set_attr "type" "alu")
9122    (set_attr "mode" "HI")])
9124 (define_expand "xorqi3"
9125   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9126         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9127                 (match_operand:QI 2 "general_operand" "")))
9128    (clobber (reg:CC FLAGS_REG))]
9129   "TARGET_QIMODE_MATH"
9130   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9132 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9133 (define_insn "*xorqi_1"
9134   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9135         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9136                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "ix86_binary_operator_ok (XOR, QImode, operands)"
9139   "@
9140    xor{b}\t{%2, %0|%0, %2}
9141    xor{b}\t{%2, %0|%0, %2}
9142    xor{l}\t{%k2, %k0|%k0, %k2}"
9143   [(set_attr "type" "alu")
9144    (set_attr "mode" "QI,QI,SI")])
9146 (define_insn "*xorqi_1_slp"
9147   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9148         (xor:QI (match_dup 0)
9149                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9150    (clobber (reg:CC FLAGS_REG))]
9151   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9152    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9153   "xor{b}\t{%1, %0|%0, %1}"
9154   [(set_attr "type" "alu1")
9155    (set_attr "mode" "QI")])
9157 (define_insn "xorqi_ext_0"
9158   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159                          (const_int 8)
9160                          (const_int 8))
9161         (xor:SI
9162           (zero_extract:SI
9163             (match_operand 1 "ext_register_operand" "0")
9164             (const_int 8)
9165             (const_int 8))
9166           (match_operand 2 "const_int_operand" "n")))
9167    (clobber (reg:CC FLAGS_REG))]
9168   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9169   "xor{b}\t{%2, %h0|%h0, %2}"
9170   [(set_attr "type" "alu")
9171    (set_attr "length_immediate" "1")
9172    (set_attr "mode" "QI")])
9174 (define_insn "*xorqi_ext_1"
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           (zero_extend:SI
9184             (match_operand:QI 2 "general_operand" "Qm"))))
9185    (clobber (reg:CC FLAGS_REG))]
9186   "!TARGET_64BIT
9187    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9188   "xor{b}\t{%2, %h0|%h0, %2}"
9189   [(set_attr "type" "alu")
9190    (set_attr "length_immediate" "0")
9191    (set_attr "mode" "QI")])
9193 (define_insn "*xorqi_ext_1_rex64"
9194   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9195                          (const_int 8)
9196                          (const_int 8))
9197         (xor:SI
9198           (zero_extract:SI
9199             (match_operand 1 "ext_register_operand" "0")
9200             (const_int 8)
9201             (const_int 8))
9202           (zero_extend:SI
9203             (match_operand 2 "ext_register_operand" "Q"))))
9204    (clobber (reg:CC FLAGS_REG))]
9205   "TARGET_64BIT
9206    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9207   "xor{b}\t{%2, %h0|%h0, %2}"
9208   [(set_attr "type" "alu")
9209    (set_attr "length_immediate" "0")
9210    (set_attr "mode" "QI")])
9212 (define_insn "*xorqi_ext_2"
9213   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9214                          (const_int 8)
9215                          (const_int 8))
9216         (xor:SI
9217           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9218                            (const_int 8)
9219                            (const_int 8))
9220           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9221                            (const_int 8)
9222                            (const_int 8))))
9223    (clobber (reg:CC FLAGS_REG))]
9224   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9225   "xor{b}\t{%h2, %h0|%h0, %h2}"
9226   [(set_attr "type" "alu")
9227    (set_attr "length_immediate" "0")
9228    (set_attr "mode" "QI")])
9230 (define_insn "*xorqi_cc_1"
9231   [(set (reg FLAGS_REG)
9232         (compare
9233           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9234                   (match_operand:QI 2 "general_operand" "qim,qi"))
9235           (const_int 0)))
9236    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9237         (xor:QI (match_dup 1) (match_dup 2)))]
9238   "ix86_match_ccmode (insn, CCNOmode)
9239    && ix86_binary_operator_ok (XOR, QImode, operands)"
9240   "xor{b}\t{%2, %0|%0, %2}"
9241   [(set_attr "type" "alu")
9242    (set_attr "mode" "QI")])
9244 (define_insn "*xorqi_2_slp"
9245   [(set (reg FLAGS_REG)
9246         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9247                          (match_operand:QI 1 "general_operand" "qim,qi"))
9248                  (const_int 0)))
9249    (set (strict_low_part (match_dup 0))
9250         (xor:QI (match_dup 0) (match_dup 1)))]
9251   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9252    && ix86_match_ccmode (insn, CCNOmode)
9253    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9254   "xor{b}\t{%1, %0|%0, %1}"
9255   [(set_attr "type" "alu1")
9256    (set_attr "mode" "QI")])
9258 (define_insn "*xorqi_cc_2"
9259   [(set (reg FLAGS_REG)
9260         (compare
9261           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9262                   (match_operand:QI 2 "general_operand" "qim"))
9263           (const_int 0)))
9264    (clobber (match_scratch:QI 0 "=q"))]
9265   "ix86_match_ccmode (insn, CCNOmode)
9266    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9267   "xor{b}\t{%2, %0|%0, %2}"
9268   [(set_attr "type" "alu")
9269    (set_attr "mode" "QI")])
9271 (define_insn "*xorqi_cc_ext_1"
9272   [(set (reg FLAGS_REG)
9273         (compare
9274           (xor:SI
9275             (zero_extract:SI
9276               (match_operand 1 "ext_register_operand" "0")
9277               (const_int 8)
9278               (const_int 8))
9279             (match_operand:QI 2 "general_operand" "qmn"))
9280           (const_int 0)))
9281    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9282                          (const_int 8)
9283                          (const_int 8))
9284         (xor:SI
9285           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9286           (match_dup 2)))]
9287   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9288   "xor{b}\t{%2, %h0|%h0, %2}"
9289   [(set_attr "type" "alu")
9290    (set_attr "mode" "QI")])
9292 (define_insn "*xorqi_cc_ext_1_rex64"
9293   [(set (reg FLAGS_REG)
9294         (compare
9295           (xor:SI
9296             (zero_extract:SI
9297               (match_operand 1 "ext_register_operand" "0")
9298               (const_int 8)
9299               (const_int 8))
9300             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9301           (const_int 0)))
9302    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9303                          (const_int 8)
9304                          (const_int 8))
9305         (xor:SI
9306           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9307           (match_dup 2)))]
9308   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9309   "xor{b}\t{%2, %h0|%h0, %2}"
9310   [(set_attr "type" "alu")
9311    (set_attr "mode" "QI")])
9313 (define_expand "xorqi_cc_ext_1"
9314   [(parallel [
9315      (set (reg:CCNO FLAGS_REG)
9316           (compare:CCNO
9317             (xor:SI
9318               (zero_extract:SI
9319                 (match_operand 1 "ext_register_operand" "")
9320                 (const_int 8)
9321                 (const_int 8))
9322               (match_operand:QI 2 "general_operand" ""))
9323             (const_int 0)))
9324      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9325                            (const_int 8)
9326                            (const_int 8))
9327           (xor:SI
9328             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9329             (match_dup 2)))])]
9330   ""
9331   "")
9333 (define_split
9334   [(set (match_operand 0 "register_operand" "")
9335         (xor (match_operand 1 "register_operand" "")
9336              (match_operand 2 "const_int_operand" "")))
9337    (clobber (reg:CC FLAGS_REG))]
9338    "reload_completed
9339     && QI_REG_P (operands[0])
9340     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9341     && !(INTVAL (operands[2]) & ~(255 << 8))
9342     && GET_MODE (operands[0]) != QImode"
9343   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9344                    (xor:SI (zero_extract:SI (match_dup 1)
9345                                             (const_int 8) (const_int 8))
9346                            (match_dup 2)))
9347               (clobber (reg:CC FLAGS_REG))])]
9348   "operands[0] = gen_lowpart (SImode, operands[0]);
9349    operands[1] = gen_lowpart (SImode, operands[1]);
9350    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9352 ;; Since XOR can be encoded with sign extended immediate, this is only
9353 ;; profitable when 7th bit is set.
9354 (define_split
9355   [(set (match_operand 0 "register_operand" "")
9356         (xor (match_operand 1 "general_operand" "")
9357              (match_operand 2 "const_int_operand" "")))
9358    (clobber (reg:CC FLAGS_REG))]
9359    "reload_completed
9360     && ANY_QI_REG_P (operands[0])
9361     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9362     && !(INTVAL (operands[2]) & ~255)
9363     && (INTVAL (operands[2]) & 128)
9364     && GET_MODE (operands[0]) != QImode"
9365   [(parallel [(set (strict_low_part (match_dup 0))
9366                    (xor:QI (match_dup 1)
9367                            (match_dup 2)))
9368               (clobber (reg:CC FLAGS_REG))])]
9369   "operands[0] = gen_lowpart (QImode, operands[0]);
9370    operands[1] = gen_lowpart (QImode, operands[1]);
9371    operands[2] = gen_lowpart (QImode, operands[2]);")
9373 ;; Negation instructions
9375 (define_expand "negti2"
9376   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9377                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9378               (clobber (reg:CC FLAGS_REG))])]
9379   "TARGET_64BIT"
9380   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9382 (define_insn "*negti2_1"
9383   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9384         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9385    (clobber (reg:CC FLAGS_REG))]
9386   "TARGET_64BIT
9387    && ix86_unary_operator_ok (NEG, TImode, operands)"
9388   "#")
9390 (define_split
9391   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9392         (neg:TI (match_operand:TI 1 "general_operand" "")))
9393    (clobber (reg:CC FLAGS_REG))]
9394   "TARGET_64BIT && reload_completed"
9395   [(parallel
9396     [(set (reg:CCZ FLAGS_REG)
9397           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9398      (set (match_dup 0) (neg:DI (match_dup 2)))])
9399    (parallel
9400     [(set (match_dup 1)
9401           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9402                             (match_dup 3))
9403                    (const_int 0)))
9404      (clobber (reg:CC FLAGS_REG))])
9405    (parallel
9406     [(set (match_dup 1)
9407           (neg:DI (match_dup 1)))
9408      (clobber (reg:CC FLAGS_REG))])]
9409   "split_ti (operands+1, 1, operands+2, operands+3);
9410    split_ti (operands+0, 1, operands+0, operands+1);")
9412 (define_expand "negdi2"
9413   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9414                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9415               (clobber (reg:CC FLAGS_REG))])]
9416   ""
9417   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9419 (define_insn "*negdi2_1"
9420   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9421         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9422    (clobber (reg:CC FLAGS_REG))]
9423   "!TARGET_64BIT
9424    && ix86_unary_operator_ok (NEG, DImode, operands)"
9425   "#")
9427 (define_split
9428   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9429         (neg:DI (match_operand:DI 1 "general_operand" "")))
9430    (clobber (reg:CC FLAGS_REG))]
9431   "!TARGET_64BIT && reload_completed"
9432   [(parallel
9433     [(set (reg:CCZ FLAGS_REG)
9434           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9435      (set (match_dup 0) (neg:SI (match_dup 2)))])
9436    (parallel
9437     [(set (match_dup 1)
9438           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9439                             (match_dup 3))
9440                    (const_int 0)))
9441      (clobber (reg:CC FLAGS_REG))])
9442    (parallel
9443     [(set (match_dup 1)
9444           (neg:SI (match_dup 1)))
9445      (clobber (reg:CC FLAGS_REG))])]
9446   "split_di (operands+1, 1, operands+2, operands+3);
9447    split_di (operands+0, 1, operands+0, operands+1);")
9449 (define_insn "*negdi2_1_rex64"
9450   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9451         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9452    (clobber (reg:CC FLAGS_REG))]
9453   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9454   "neg{q}\t%0"
9455   [(set_attr "type" "negnot")
9456    (set_attr "mode" "DI")])
9458 ;; The problem with neg is that it does not perform (compare x 0),
9459 ;; it really performs (compare 0 x), which leaves us with the zero
9460 ;; flag being the only useful item.
9462 (define_insn "*negdi2_cmpz_rex64"
9463   [(set (reg:CCZ FLAGS_REG)
9464         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9465                      (const_int 0)))
9466    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9467         (neg:DI (match_dup 1)))]
9468   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9469   "neg{q}\t%0"
9470   [(set_attr "type" "negnot")
9471    (set_attr "mode" "DI")])
9474 (define_expand "negsi2"
9475   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9476                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9477               (clobber (reg:CC FLAGS_REG))])]
9478   ""
9479   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9481 (define_insn "*negsi2_1"
9482   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9483         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9484    (clobber (reg:CC FLAGS_REG))]
9485   "ix86_unary_operator_ok (NEG, SImode, operands)"
9486   "neg{l}\t%0"
9487   [(set_attr "type" "negnot")
9488    (set_attr "mode" "SI")])
9490 ;; Combine is quite creative about this pattern.
9491 (define_insn "*negsi2_1_zext"
9492   [(set (match_operand:DI 0 "register_operand" "=r")
9493         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9494                                         (const_int 32)))
9495                      (const_int 32)))
9496    (clobber (reg:CC FLAGS_REG))]
9497   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9498   "neg{l}\t%k0"
9499   [(set_attr "type" "negnot")
9500    (set_attr "mode" "SI")])
9502 ;; The problem with neg is that it does not perform (compare x 0),
9503 ;; it really performs (compare 0 x), which leaves us with the zero
9504 ;; flag being the only useful item.
9506 (define_insn "*negsi2_cmpz"
9507   [(set (reg:CCZ FLAGS_REG)
9508         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9509                      (const_int 0)))
9510    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9511         (neg:SI (match_dup 1)))]
9512   "ix86_unary_operator_ok (NEG, SImode, operands)"
9513   "neg{l}\t%0"
9514   [(set_attr "type" "negnot")
9515    (set_attr "mode" "SI")])
9517 (define_insn "*negsi2_cmpz_zext"
9518   [(set (reg:CCZ FLAGS_REG)
9519         (compare:CCZ (lshiftrt:DI
9520                        (neg:DI (ashift:DI
9521                                  (match_operand:DI 1 "register_operand" "0")
9522                                  (const_int 32)))
9523                        (const_int 32))
9524                      (const_int 0)))
9525    (set (match_operand:DI 0 "register_operand" "=r")
9526         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9527                                         (const_int 32)))
9528                      (const_int 32)))]
9529   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9530   "neg{l}\t%k0"
9531   [(set_attr "type" "negnot")
9532    (set_attr "mode" "SI")])
9534 (define_expand "neghi2"
9535   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9536                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9537               (clobber (reg:CC FLAGS_REG))])]
9538   "TARGET_HIMODE_MATH"
9539   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9541 (define_insn "*neghi2_1"
9542   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9543         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9544    (clobber (reg:CC FLAGS_REG))]
9545   "ix86_unary_operator_ok (NEG, HImode, operands)"
9546   "neg{w}\t%0"
9547   [(set_attr "type" "negnot")
9548    (set_attr "mode" "HI")])
9550 (define_insn "*neghi2_cmpz"
9551   [(set (reg:CCZ FLAGS_REG)
9552         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9553                      (const_int 0)))
9554    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9555         (neg:HI (match_dup 1)))]
9556   "ix86_unary_operator_ok (NEG, HImode, operands)"
9557   "neg{w}\t%0"
9558   [(set_attr "type" "negnot")
9559    (set_attr "mode" "HI")])
9561 (define_expand "negqi2"
9562   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9563                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9564               (clobber (reg:CC FLAGS_REG))])]
9565   "TARGET_QIMODE_MATH"
9566   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9568 (define_insn "*negqi2_1"
9569   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9570         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9571    (clobber (reg:CC FLAGS_REG))]
9572   "ix86_unary_operator_ok (NEG, QImode, operands)"
9573   "neg{b}\t%0"
9574   [(set_attr "type" "negnot")
9575    (set_attr "mode" "QI")])
9577 (define_insn "*negqi2_cmpz"
9578   [(set (reg:CCZ FLAGS_REG)
9579         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9580                      (const_int 0)))
9581    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9582         (neg:QI (match_dup 1)))]
9583   "ix86_unary_operator_ok (NEG, QImode, operands)"
9584   "neg{b}\t%0"
9585   [(set_attr "type" "negnot")
9586    (set_attr "mode" "QI")])
9588 ;; Changing of sign for FP values is doable using integer unit too.
9590 (define_expand "negsf2"
9591   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9592         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9593   "TARGET_80387 || TARGET_SSE_MATH"
9594   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9596 (define_expand "abssf2"
9597   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9598         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9599   "TARGET_80387 || TARGET_SSE_MATH"
9600   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9602 (define_insn "*absnegsf2_mixed"
9603   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9604         (match_operator:SF 3 "absneg_operator"
9605           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9606    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9607    (clobber (reg:CC FLAGS_REG))]
9608   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9609    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9610   "#")
9612 (define_insn "*absnegsf2_sse"
9613   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9614         (match_operator:SF 3 "absneg_operator"
9615           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9616    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9617    (clobber (reg:CC FLAGS_REG))]
9618   "TARGET_SSE_MATH
9619    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9620   "#")
9622 (define_insn "*absnegsf2_i387"
9623   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9624         (match_operator:SF 3 "absneg_operator"
9625           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9626    (use (match_operand 2 "" ""))
9627    (clobber (reg:CC FLAGS_REG))]
9628   "TARGET_80387 && !TARGET_SSE_MATH
9629    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9630   "#")
9632 (define_expand "copysignsf3"
9633   [(match_operand:SF 0 "register_operand" "")
9634    (match_operand:SF 1 "nonmemory_operand" "")
9635    (match_operand:SF 2 "register_operand" "")]
9636   "TARGET_SSE_MATH"
9638   ix86_expand_copysign (operands);
9639   DONE;
9642 (define_insn_and_split "copysignsf3_const"
9643   [(set (match_operand:SF 0 "register_operand"          "=x")
9644         (unspec:SF
9645           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9646            (match_operand:SF 2 "register_operand"       "0")
9647            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9648           UNSPEC_COPYSIGN))]
9649   "TARGET_SSE_MATH"
9650   "#"
9651   "&& reload_completed"
9652   [(const_int 0)]
9654   ix86_split_copysign_const (operands);
9655   DONE;
9658 (define_insn "copysignsf3_var"
9659   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9660         (unspec:SF
9661           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9662            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9663            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9664            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9665           UNSPEC_COPYSIGN))
9666    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9667   "TARGET_SSE_MATH"
9668   "#")
9670 (define_split
9671   [(set (match_operand:SF 0 "register_operand" "")
9672         (unspec:SF
9673           [(match_operand:SF 2 "register_operand" "")
9674            (match_operand:SF 3 "register_operand" "")
9675            (match_operand:V4SF 4 "" "")
9676            (match_operand:V4SF 5 "" "")]
9677           UNSPEC_COPYSIGN))
9678    (clobber (match_scratch:V4SF 1 ""))]
9679   "TARGET_SSE_MATH && reload_completed"
9680   [(const_int 0)]
9682   ix86_split_copysign_var (operands);
9683   DONE;
9686 (define_expand "negdf2"
9687   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9688         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9689   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9690   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9692 (define_expand "absdf2"
9693   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9694         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9695   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9696   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9698 (define_insn "*absnegdf2_mixed"
9699   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9700         (match_operator:DF 3 "absneg_operator"
9701           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9702    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9703    (clobber (reg:CC FLAGS_REG))]
9704   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9705    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9706   "#")
9708 (define_insn "*absnegdf2_sse"
9709   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9710         (match_operator:DF 3 "absneg_operator"
9711           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9712    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9713    (clobber (reg:CC FLAGS_REG))]
9714   "TARGET_SSE2 && TARGET_SSE_MATH
9715    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9716   "#")
9718 (define_insn "*absnegdf2_i387"
9719   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9720         (match_operator:DF 3 "absneg_operator"
9721           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9722    (use (match_operand 2 "" ""))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9725    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9726   "#")
9728 (define_expand "copysigndf3"
9729   [(match_operand:DF 0 "register_operand" "")
9730    (match_operand:DF 1 "nonmemory_operand" "")
9731    (match_operand:DF 2 "register_operand" "")]
9732   "TARGET_SSE2 && TARGET_SSE_MATH"
9734   ix86_expand_copysign (operands);
9735   DONE;
9738 (define_insn_and_split "copysigndf3_const"
9739   [(set (match_operand:DF 0 "register_operand"          "=x")
9740         (unspec:DF
9741           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9742            (match_operand:DF 2 "register_operand"       "0")
9743            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9744           UNSPEC_COPYSIGN))]
9745   "TARGET_SSE2 && TARGET_SSE_MATH"
9746   "#"
9747   "&& reload_completed"
9748   [(const_int 0)]
9750   ix86_split_copysign_const (operands);
9751   DONE;
9754 (define_insn "copysigndf3_var"
9755   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9756         (unspec:DF
9757           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9758            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9759            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9760            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9761           UNSPEC_COPYSIGN))
9762    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9763   "TARGET_SSE2 && TARGET_SSE_MATH"
9764   "#")
9766 (define_split
9767   [(set (match_operand:DF 0 "register_operand" "")
9768         (unspec:DF
9769           [(match_operand:DF 2 "register_operand" "")
9770            (match_operand:DF 3 "register_operand" "")
9771            (match_operand:V2DF 4 "" "")
9772            (match_operand:V2DF 5 "" "")]
9773           UNSPEC_COPYSIGN))
9774    (clobber (match_scratch:V2DF 1 ""))]
9775   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9776   [(const_int 0)]
9778   ix86_split_copysign_var (operands);
9779   DONE;
9782 (define_expand "negxf2"
9783   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9784         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9785   "TARGET_80387"
9786   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9788 (define_expand "absxf2"
9789   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9790         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9791   "TARGET_80387"
9792   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9794 (define_insn "*absnegxf2_i387"
9795   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9796         (match_operator:XF 3 "absneg_operator"
9797           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9798    (use (match_operand 2 "" ""))
9799    (clobber (reg:CC FLAGS_REG))]
9800   "TARGET_80387
9801    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9802   "#")
9804 ;; Splitters for fp abs and neg.
9806 (define_split
9807   [(set (match_operand 0 "fp_register_operand" "")
9808         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9809    (use (match_operand 2 "" ""))
9810    (clobber (reg:CC FLAGS_REG))]
9811   "reload_completed"
9812   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9814 (define_split
9815   [(set (match_operand 0 "register_operand" "")
9816         (match_operator 3 "absneg_operator"
9817           [(match_operand 1 "register_operand" "")]))
9818    (use (match_operand 2 "nonimmediate_operand" ""))
9819    (clobber (reg:CC FLAGS_REG))]
9820   "reload_completed && SSE_REG_P (operands[0])"
9821   [(set (match_dup 0) (match_dup 3))]
9823   enum machine_mode mode = GET_MODE (operands[0]);
9824   enum machine_mode vmode = GET_MODE (operands[2]);
9825   rtx tmp;
9827   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9828   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9829   if (operands_match_p (operands[0], operands[2]))
9830     {
9831       tmp = operands[1];
9832       operands[1] = operands[2];
9833       operands[2] = tmp;
9834     }
9835   if (GET_CODE (operands[3]) == ABS)
9836     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9837   else
9838     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9839   operands[3] = tmp;
9842 (define_split
9843   [(set (match_operand:SF 0 "register_operand" "")
9844         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9845    (use (match_operand:V4SF 2 "" ""))
9846    (clobber (reg:CC FLAGS_REG))]
9847   "reload_completed"
9848   [(parallel [(set (match_dup 0) (match_dup 1))
9849               (clobber (reg:CC FLAGS_REG))])]
9851   rtx tmp;
9852   operands[0] = gen_lowpart (SImode, operands[0]);
9853   if (GET_CODE (operands[1]) == ABS)
9854     {
9855       tmp = gen_int_mode (0x7fffffff, SImode);
9856       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9857     }
9858   else
9859     {
9860       tmp = gen_int_mode (0x80000000, SImode);
9861       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9862     }
9863   operands[1] = tmp;
9866 (define_split
9867   [(set (match_operand:DF 0 "register_operand" "")
9868         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9869    (use (match_operand 2 "" ""))
9870    (clobber (reg:CC FLAGS_REG))]
9871   "reload_completed"
9872   [(parallel [(set (match_dup 0) (match_dup 1))
9873               (clobber (reg:CC FLAGS_REG))])]
9875   rtx tmp;
9876   if (TARGET_64BIT)
9877     {
9878       tmp = gen_lowpart (DImode, operands[0]);
9879       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9880       operands[0] = tmp;
9882       if (GET_CODE (operands[1]) == ABS)
9883         tmp = const0_rtx;
9884       else
9885         tmp = gen_rtx_NOT (DImode, tmp);
9886     }
9887   else
9888     {
9889       operands[0] = gen_highpart (SImode, operands[0]);
9890       if (GET_CODE (operands[1]) == ABS)
9891         {
9892           tmp = gen_int_mode (0x7fffffff, SImode);
9893           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9894         }
9895       else
9896         {
9897           tmp = gen_int_mode (0x80000000, SImode);
9898           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9899         }
9900     }
9901   operands[1] = tmp;
9904 (define_split
9905   [(set (match_operand:XF 0 "register_operand" "")
9906         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9907    (use (match_operand 2 "" ""))
9908    (clobber (reg:CC FLAGS_REG))]
9909   "reload_completed"
9910   [(parallel [(set (match_dup 0) (match_dup 1))
9911               (clobber (reg:CC FLAGS_REG))])]
9913   rtx tmp;
9914   operands[0] = gen_rtx_REG (SImode,
9915                              true_regnum (operands[0])
9916                              + (TARGET_64BIT ? 1 : 2));
9917   if (GET_CODE (operands[1]) == ABS)
9918     {
9919       tmp = GEN_INT (0x7fff);
9920       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9921     }
9922   else
9923     {
9924       tmp = GEN_INT (0x8000);
9925       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9926     }
9927   operands[1] = tmp;
9930 (define_split
9931   [(set (match_operand 0 "memory_operand" "")
9932         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9933    (use (match_operand 2 "" ""))
9934    (clobber (reg:CC FLAGS_REG))]
9935   "reload_completed"
9936   [(parallel [(set (match_dup 0) (match_dup 1))
9937               (clobber (reg:CC FLAGS_REG))])]
9939   enum machine_mode mode = GET_MODE (operands[0]);
9940   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9941   rtx tmp;
9943   operands[0] = adjust_address (operands[0], QImode, size - 1);
9944   if (GET_CODE (operands[1]) == ABS)
9945     {
9946       tmp = gen_int_mode (0x7f, QImode);
9947       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9948     }
9949   else
9950     {
9951       tmp = gen_int_mode (0x80, QImode);
9952       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9953     }
9954   operands[1] = tmp;
9957 ;; Conditionalize these after reload. If they match before reload, we
9958 ;; lose the clobber and ability to use integer instructions.
9960 (define_insn "*negsf2_1"
9961   [(set (match_operand:SF 0 "register_operand" "=f")
9962         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9963   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9964   "fchs"
9965   [(set_attr "type" "fsgn")
9966    (set_attr "mode" "SF")])
9968 (define_insn "*negdf2_1"
9969   [(set (match_operand:DF 0 "register_operand" "=f")
9970         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9971   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9972   "fchs"
9973   [(set_attr "type" "fsgn")
9974    (set_attr "mode" "DF")])
9976 (define_insn "*negxf2_1"
9977   [(set (match_operand:XF 0 "register_operand" "=f")
9978         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9979   "TARGET_80387"
9980   "fchs"
9981   [(set_attr "type" "fsgn")
9982    (set_attr "mode" "XF")])
9984 (define_insn "*abssf2_1"
9985   [(set (match_operand:SF 0 "register_operand" "=f")
9986         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9987   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9988   "fabs"
9989   [(set_attr "type" "fsgn")
9990    (set_attr "mode" "SF")])
9992 (define_insn "*absdf2_1"
9993   [(set (match_operand:DF 0 "register_operand" "=f")
9994         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9995   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9996   "fabs"
9997   [(set_attr "type" "fsgn")
9998    (set_attr "mode" "DF")])
10000 (define_insn "*absxf2_1"
10001   [(set (match_operand:XF 0 "register_operand" "=f")
10002         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10003   "TARGET_80387"
10004   "fabs"
10005   [(set_attr "type" "fsgn")
10006    (set_attr "mode" "DF")])
10008 (define_insn "*negextendsfdf2"
10009   [(set (match_operand:DF 0 "register_operand" "=f")
10010         (neg:DF (float_extend:DF
10011                   (match_operand:SF 1 "register_operand" "0"))))]
10012   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10013   "fchs"
10014   [(set_attr "type" "fsgn")
10015    (set_attr "mode" "DF")])
10017 (define_insn "*negextenddfxf2"
10018   [(set (match_operand:XF 0 "register_operand" "=f")
10019         (neg:XF (float_extend:XF
10020                   (match_operand:DF 1 "register_operand" "0"))))]
10021   "TARGET_80387"
10022   "fchs"
10023   [(set_attr "type" "fsgn")
10024    (set_attr "mode" "XF")])
10026 (define_insn "*negextendsfxf2"
10027   [(set (match_operand:XF 0 "register_operand" "=f")
10028         (neg:XF (float_extend:XF
10029                   (match_operand:SF 1 "register_operand" "0"))))]
10030   "TARGET_80387"
10031   "fchs"
10032   [(set_attr "type" "fsgn")
10033    (set_attr "mode" "XF")])
10035 (define_insn "*absextendsfdf2"
10036   [(set (match_operand:DF 0 "register_operand" "=f")
10037         (abs:DF (float_extend:DF
10038                   (match_operand:SF 1 "register_operand" "0"))))]
10039   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10040   "fabs"
10041   [(set_attr "type" "fsgn")
10042    (set_attr "mode" "DF")])
10044 (define_insn "*absextenddfxf2"
10045   [(set (match_operand:XF 0 "register_operand" "=f")
10046         (abs:XF (float_extend:XF
10047           (match_operand:DF 1 "register_operand" "0"))))]
10048   "TARGET_80387"
10049   "fabs"
10050   [(set_attr "type" "fsgn")
10051    (set_attr "mode" "XF")])
10053 (define_insn "*absextendsfxf2"
10054   [(set (match_operand:XF 0 "register_operand" "=f")
10055         (abs:XF (float_extend:XF
10056           (match_operand:SF 1 "register_operand" "0"))))]
10057   "TARGET_80387"
10058   "fabs"
10059   [(set_attr "type" "fsgn")
10060    (set_attr "mode" "XF")])
10062 ;; One complement instructions
10064 (define_expand "one_cmpldi2"
10065   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10066         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10067   "TARGET_64BIT"
10068   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10070 (define_insn "*one_cmpldi2_1_rex64"
10071   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10072         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10073   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10074   "not{q}\t%0"
10075   [(set_attr "type" "negnot")
10076    (set_attr "mode" "DI")])
10078 (define_insn "*one_cmpldi2_2_rex64"
10079   [(set (reg FLAGS_REG)
10080         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10081                  (const_int 0)))
10082    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10083         (not:DI (match_dup 1)))]
10084   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10085    && ix86_unary_operator_ok (NOT, DImode, operands)"
10086   "#"
10087   [(set_attr "type" "alu1")
10088    (set_attr "mode" "DI")])
10090 (define_split
10091   [(set (match_operand 0 "flags_reg_operand" "")
10092         (match_operator 2 "compare_operator"
10093           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10094            (const_int 0)]))
10095    (set (match_operand:DI 1 "nonimmediate_operand" "")
10096         (not:DI (match_dup 3)))]
10097   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10098   [(parallel [(set (match_dup 0)
10099                    (match_op_dup 2
10100                      [(xor:DI (match_dup 3) (const_int -1))
10101                       (const_int 0)]))
10102               (set (match_dup 1)
10103                    (xor:DI (match_dup 3) (const_int -1)))])]
10104   "")
10106 (define_expand "one_cmplsi2"
10107   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10108         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10109   ""
10110   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10112 (define_insn "*one_cmplsi2_1"
10113   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10114         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10115   "ix86_unary_operator_ok (NOT, SImode, operands)"
10116   "not{l}\t%0"
10117   [(set_attr "type" "negnot")
10118    (set_attr "mode" "SI")])
10120 ;; ??? Currently never generated - xor is used instead.
10121 (define_insn "*one_cmplsi2_1_zext"
10122   [(set (match_operand:DI 0 "register_operand" "=r")
10123         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10124   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10125   "not{l}\t%k0"
10126   [(set_attr "type" "negnot")
10127    (set_attr "mode" "SI")])
10129 (define_insn "*one_cmplsi2_2"
10130   [(set (reg FLAGS_REG)
10131         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10132                  (const_int 0)))
10133    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10134         (not:SI (match_dup 1)))]
10135   "ix86_match_ccmode (insn, CCNOmode)
10136    && ix86_unary_operator_ok (NOT, SImode, operands)"
10137   "#"
10138   [(set_attr "type" "alu1")
10139    (set_attr "mode" "SI")])
10141 (define_split
10142   [(set (match_operand 0 "flags_reg_operand" "")
10143         (match_operator 2 "compare_operator"
10144           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10145            (const_int 0)]))
10146    (set (match_operand:SI 1 "nonimmediate_operand" "")
10147         (not:SI (match_dup 3)))]
10148   "ix86_match_ccmode (insn, CCNOmode)"
10149   [(parallel [(set (match_dup 0)
10150                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10151                                     (const_int 0)]))
10152               (set (match_dup 1)
10153                    (xor:SI (match_dup 3) (const_int -1)))])]
10154   "")
10156 ;; ??? Currently never generated - xor is used instead.
10157 (define_insn "*one_cmplsi2_2_zext"
10158   [(set (reg FLAGS_REG)
10159         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10160                  (const_int 0)))
10161    (set (match_operand:DI 0 "register_operand" "=r")
10162         (zero_extend:DI (not:SI (match_dup 1))))]
10163   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10164    && ix86_unary_operator_ok (NOT, SImode, operands)"
10165   "#"
10166   [(set_attr "type" "alu1")
10167    (set_attr "mode" "SI")])
10169 (define_split
10170   [(set (match_operand 0 "flags_reg_operand" "")
10171         (match_operator 2 "compare_operator"
10172           [(not:SI (match_operand:SI 3 "register_operand" ""))
10173            (const_int 0)]))
10174    (set (match_operand:DI 1 "register_operand" "")
10175         (zero_extend:DI (not:SI (match_dup 3))))]
10176   "ix86_match_ccmode (insn, CCNOmode)"
10177   [(parallel [(set (match_dup 0)
10178                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10179                                     (const_int 0)]))
10180               (set (match_dup 1)
10181                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10182   "")
10184 (define_expand "one_cmplhi2"
10185   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10186         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10187   "TARGET_HIMODE_MATH"
10188   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10190 (define_insn "*one_cmplhi2_1"
10191   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10192         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10193   "ix86_unary_operator_ok (NOT, HImode, operands)"
10194   "not{w}\t%0"
10195   [(set_attr "type" "negnot")
10196    (set_attr "mode" "HI")])
10198 (define_insn "*one_cmplhi2_2"
10199   [(set (reg FLAGS_REG)
10200         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10201                  (const_int 0)))
10202    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10203         (not:HI (match_dup 1)))]
10204   "ix86_match_ccmode (insn, CCNOmode)
10205    && ix86_unary_operator_ok (NEG, HImode, operands)"
10206   "#"
10207   [(set_attr "type" "alu1")
10208    (set_attr "mode" "HI")])
10210 (define_split
10211   [(set (match_operand 0 "flags_reg_operand" "")
10212         (match_operator 2 "compare_operator"
10213           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10214            (const_int 0)]))
10215    (set (match_operand:HI 1 "nonimmediate_operand" "")
10216         (not:HI (match_dup 3)))]
10217   "ix86_match_ccmode (insn, CCNOmode)"
10218   [(parallel [(set (match_dup 0)
10219                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10220                                     (const_int 0)]))
10221               (set (match_dup 1)
10222                    (xor:HI (match_dup 3) (const_int -1)))])]
10223   "")
10225 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10226 (define_expand "one_cmplqi2"
10227   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10228         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10229   "TARGET_QIMODE_MATH"
10230   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10232 (define_insn "*one_cmplqi2_1"
10233   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10234         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10235   "ix86_unary_operator_ok (NOT, QImode, operands)"
10236   "@
10237    not{b}\t%0
10238    not{l}\t%k0"
10239   [(set_attr "type" "negnot")
10240    (set_attr "mode" "QI,SI")])
10242 (define_insn "*one_cmplqi2_2"
10243   [(set (reg FLAGS_REG)
10244         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10245                  (const_int 0)))
10246    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10247         (not:QI (match_dup 1)))]
10248   "ix86_match_ccmode (insn, CCNOmode)
10249    && ix86_unary_operator_ok (NOT, QImode, operands)"
10250   "#"
10251   [(set_attr "type" "alu1")
10252    (set_attr "mode" "QI")])
10254 (define_split
10255   [(set (match_operand 0 "flags_reg_operand" "")
10256         (match_operator 2 "compare_operator"
10257           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10258            (const_int 0)]))
10259    (set (match_operand:QI 1 "nonimmediate_operand" "")
10260         (not:QI (match_dup 3)))]
10261   "ix86_match_ccmode (insn, CCNOmode)"
10262   [(parallel [(set (match_dup 0)
10263                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10264                                     (const_int 0)]))
10265               (set (match_dup 1)
10266                    (xor:QI (match_dup 3) (const_int -1)))])]
10267   "")
10269 ;; Arithmetic shift instructions
10271 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10272 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10273 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10274 ;; from the assembler input.
10276 ;; This instruction shifts the target reg/mem as usual, but instead of
10277 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10278 ;; is a left shift double, bits are taken from the high order bits of
10279 ;; reg, else if the insn is a shift right double, bits are taken from the
10280 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10281 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10283 ;; Since sh[lr]d does not change the `reg' operand, that is done
10284 ;; separately, making all shifts emit pairs of shift double and normal
10285 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10286 ;; support a 63 bit shift, each shift where the count is in a reg expands
10287 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10289 ;; If the shift count is a constant, we need never emit more than one
10290 ;; shift pair, instead using moves and sign extension for counts greater
10291 ;; than 31.
10293 (define_expand "ashlti3"
10294   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10295                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10296                               (match_operand:QI 2 "nonmemory_operand" "")))
10297               (clobber (reg:CC FLAGS_REG))])]
10298   "TARGET_64BIT"
10300   if (! immediate_operand (operands[2], QImode))
10301     {
10302       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10303       DONE;
10304     }
10305   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10306   DONE;
10309 (define_insn "ashlti3_1"
10310   [(set (match_operand:TI 0 "register_operand" "=r")
10311         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10312                    (match_operand:QI 2 "register_operand" "c")))
10313    (clobber (match_scratch:DI 3 "=&r"))
10314    (clobber (reg:CC FLAGS_REG))]
10315   "TARGET_64BIT"
10316   "#"
10317   [(set_attr "type" "multi")])
10319 (define_insn "*ashlti3_2"
10320   [(set (match_operand:TI 0 "register_operand" "=r")
10321         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10322                    (match_operand:QI 2 "immediate_operand" "O")))
10323    (clobber (reg:CC FLAGS_REG))]
10324   "TARGET_64BIT"
10325   "#"
10326   [(set_attr "type" "multi")])
10328 (define_split
10329   [(set (match_operand:TI 0 "register_operand" "")
10330         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10331                    (match_operand:QI 2 "register_operand" "")))
10332    (clobber (match_scratch:DI 3 ""))
10333    (clobber (reg:CC FLAGS_REG))]
10334   "TARGET_64BIT && reload_completed"
10335   [(const_int 0)]
10336   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10338 (define_split
10339   [(set (match_operand:TI 0 "register_operand" "")
10340         (ashift:TI (match_operand:TI 1 "register_operand" "")
10341                    (match_operand:QI 2 "immediate_operand" "")))
10342    (clobber (reg:CC FLAGS_REG))]
10343   "TARGET_64BIT && reload_completed"
10344   [(const_int 0)]
10345   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10347 (define_insn "x86_64_shld"
10348   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10349         (ior:DI (ashift:DI (match_dup 0)
10350                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10351                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10352                   (minus:QI (const_int 64) (match_dup 2)))))
10353    (clobber (reg:CC FLAGS_REG))]
10354   "TARGET_64BIT"
10355   "@
10356    shld{q}\t{%2, %1, %0|%0, %1, %2}
10357    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10358   [(set_attr "type" "ishift")
10359    (set_attr "prefix_0f" "1")
10360    (set_attr "mode" "DI")
10361    (set_attr "athlon_decode" "vector")])
10363 (define_expand "x86_64_shift_adj"
10364   [(set (reg:CCZ FLAGS_REG)
10365         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10366                              (const_int 64))
10367                      (const_int 0)))
10368    (set (match_operand:DI 0 "register_operand" "")
10369         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10370                          (match_operand:DI 1 "register_operand" "")
10371                          (match_dup 0)))
10372    (set (match_dup 1)
10373         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10374                          (match_operand:DI 3 "register_operand" "r")
10375                          (match_dup 1)))]
10376   "TARGET_64BIT"
10377   "")
10379 (define_expand "ashldi3"
10380   [(set (match_operand:DI 0 "shiftdi_operand" "")
10381         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10382                    (match_operand:QI 2 "nonmemory_operand" "")))]
10383   ""
10384   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10386 (define_insn "*ashldi3_1_rex64"
10387   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10388         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10389                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10390    (clobber (reg:CC FLAGS_REG))]
10391   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10393   switch (get_attr_type (insn))
10394     {
10395     case TYPE_ALU:
10396       gcc_assert (operands[2] == const1_rtx);
10397       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10398       return "add{q}\t{%0, %0|%0, %0}";
10400     case TYPE_LEA:
10401       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10402       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10403       operands[1] = gen_rtx_MULT (DImode, operands[1],
10404                                   GEN_INT (1 << INTVAL (operands[2])));
10405       return "lea{q}\t{%a1, %0|%0, %a1}";
10407     default:
10408       if (REG_P (operands[2]))
10409         return "sal{q}\t{%b2, %0|%0, %b2}";
10410       else if (operands[2] == const1_rtx
10411                && (TARGET_SHIFT1 || optimize_size))
10412         return "sal{q}\t%0";
10413       else
10414         return "sal{q}\t{%2, %0|%0, %2}";
10415     }
10417   [(set (attr "type")
10418      (cond [(eq_attr "alternative" "1")
10419               (const_string "lea")
10420             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10421                           (const_int 0))
10422                       (match_operand 0 "register_operand" ""))
10423                  (match_operand 2 "const1_operand" ""))
10424               (const_string "alu")
10425            ]
10426            (const_string "ishift")))
10427    (set_attr "mode" "DI")])
10429 ;; Convert lea to the lea pattern to avoid flags dependency.
10430 (define_split
10431   [(set (match_operand:DI 0 "register_operand" "")
10432         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10433                    (match_operand:QI 2 "immediate_operand" "")))
10434    (clobber (reg:CC FLAGS_REG))]
10435   "TARGET_64BIT && reload_completed
10436    && true_regnum (operands[0]) != true_regnum (operands[1])"
10437   [(set (match_dup 0)
10438         (mult:DI (match_dup 1)
10439                  (match_dup 2)))]
10440   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10442 ;; This pattern can't accept a variable shift count, since shifts by
10443 ;; zero don't affect the flags.  We assume that shifts by constant
10444 ;; zero are optimized away.
10445 (define_insn "*ashldi3_cmp_rex64"
10446   [(set (reg FLAGS_REG)
10447         (compare
10448           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10449                      (match_operand:QI 2 "immediate_operand" "e"))
10450           (const_int 0)))
10451    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10452         (ashift:DI (match_dup 1) (match_dup 2)))]
10453   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10454    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10455    && (optimize_size
10456        || !TARGET_PARTIAL_FLAG_REG_STALL
10457        || (operands[2] == const1_rtx
10458            && (TARGET_SHIFT1
10459                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10461   switch (get_attr_type (insn))
10462     {
10463     case TYPE_ALU:
10464       gcc_assert (operands[2] == const1_rtx);
10465       return "add{q}\t{%0, %0|%0, %0}";
10467     default:
10468       if (REG_P (operands[2]))
10469         return "sal{q}\t{%b2, %0|%0, %b2}";
10470       else if (operands[2] == const1_rtx
10471                && (TARGET_SHIFT1 || optimize_size))
10472         return "sal{q}\t%0";
10473       else
10474         return "sal{q}\t{%2, %0|%0, %2}";
10475     }
10477   [(set (attr "type")
10478      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10479                           (const_int 0))
10480                       (match_operand 0 "register_operand" ""))
10481                  (match_operand 2 "const1_operand" ""))
10482               (const_string "alu")
10483            ]
10484            (const_string "ishift")))
10485    (set_attr "mode" "DI")])
10487 (define_insn "*ashldi3_cconly_rex64"
10488   [(set (reg FLAGS_REG)
10489         (compare
10490           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10491                      (match_operand:QI 2 "immediate_operand" "e"))
10492           (const_int 0)))
10493    (clobber (match_scratch:DI 0 "=r"))]
10494   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10495    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10496    && (optimize_size
10497        || !TARGET_PARTIAL_FLAG_REG_STALL
10498        || (operands[2] == const1_rtx
10499            && (TARGET_SHIFT1
10500                || TARGET_DOUBLE_WITH_ADD)))"
10502   switch (get_attr_type (insn))
10503     {
10504     case TYPE_ALU:
10505       gcc_assert (operands[2] == const1_rtx);
10506       return "add{q}\t{%0, %0|%0, %0}";
10508     default:
10509       if (REG_P (operands[2]))
10510         return "sal{q}\t{%b2, %0|%0, %b2}";
10511       else if (operands[2] == const1_rtx
10512                && (TARGET_SHIFT1 || optimize_size))
10513         return "sal{q}\t%0";
10514       else
10515         return "sal{q}\t{%2, %0|%0, %2}";
10516     }
10518   [(set (attr "type")
10519      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10520                           (const_int 0))
10521                       (match_operand 0 "register_operand" ""))
10522                  (match_operand 2 "const1_operand" ""))
10523               (const_string "alu")
10524            ]
10525            (const_string "ishift")))
10526    (set_attr "mode" "DI")])
10528 (define_insn "*ashldi3_1"
10529   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10530         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10531                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10532    (clobber (reg:CC FLAGS_REG))]
10533   "!TARGET_64BIT"
10534   "#"
10535   [(set_attr "type" "multi")])
10537 ;; By default we don't ask for a scratch register, because when DImode
10538 ;; values are manipulated, registers are already at a premium.  But if
10539 ;; we have one handy, we won't turn it away.
10540 (define_peephole2
10541   [(match_scratch:SI 3 "r")
10542    (parallel [(set (match_operand:DI 0 "register_operand" "")
10543                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10544                               (match_operand:QI 2 "nonmemory_operand" "")))
10545               (clobber (reg:CC FLAGS_REG))])
10546    (match_dup 3)]
10547   "!TARGET_64BIT && TARGET_CMOVE"
10548   [(const_int 0)]
10549   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10551 (define_split
10552   [(set (match_operand:DI 0 "register_operand" "")
10553         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10554                    (match_operand:QI 2 "nonmemory_operand" "")))
10555    (clobber (reg:CC FLAGS_REG))]
10556   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10557                      ? flow2_completed : reload_completed)"
10558   [(const_int 0)]
10559   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10561 (define_insn "x86_shld_1"
10562   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10563         (ior:SI (ashift:SI (match_dup 0)
10564                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10565                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10566                   (minus:QI (const_int 32) (match_dup 2)))))
10567    (clobber (reg:CC FLAGS_REG))]
10568   ""
10569   "@
10570    shld{l}\t{%2, %1, %0|%0, %1, %2}
10571    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10572   [(set_attr "type" "ishift")
10573    (set_attr "prefix_0f" "1")
10574    (set_attr "mode" "SI")
10575    (set_attr "pent_pair" "np")
10576    (set_attr "athlon_decode" "vector")])
10578 (define_expand "x86_shift_adj_1"
10579   [(set (reg:CCZ FLAGS_REG)
10580         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10581                              (const_int 32))
10582                      (const_int 0)))
10583    (set (match_operand:SI 0 "register_operand" "")
10584         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10585                          (match_operand:SI 1 "register_operand" "")
10586                          (match_dup 0)))
10587    (set (match_dup 1)
10588         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10589                          (match_operand:SI 3 "register_operand" "r")
10590                          (match_dup 1)))]
10591   "TARGET_CMOVE"
10592   "")
10594 (define_expand "x86_shift_adj_2"
10595   [(use (match_operand:SI 0 "register_operand" ""))
10596    (use (match_operand:SI 1 "register_operand" ""))
10597    (use (match_operand:QI 2 "register_operand" ""))]
10598   ""
10600   rtx label = gen_label_rtx ();
10601   rtx tmp;
10603   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10605   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10606   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10607   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10608                               gen_rtx_LABEL_REF (VOIDmode, label),
10609                               pc_rtx);
10610   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10611   JUMP_LABEL (tmp) = label;
10613   emit_move_insn (operands[0], operands[1]);
10614   ix86_expand_clear (operands[1]);
10616   emit_label (label);
10617   LABEL_NUSES (label) = 1;
10619   DONE;
10622 (define_expand "ashlsi3"
10623   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10624         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10625                    (match_operand:QI 2 "nonmemory_operand" "")))
10626    (clobber (reg:CC FLAGS_REG))]
10627   ""
10628   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10630 (define_insn "*ashlsi3_1"
10631   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10632         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10633                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10634    (clobber (reg:CC FLAGS_REG))]
10635   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10637   switch (get_attr_type (insn))
10638     {
10639     case TYPE_ALU:
10640       gcc_assert (operands[2] == const1_rtx);
10641       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10642       return "add{l}\t{%0, %0|%0, %0}";
10644     case TYPE_LEA:
10645       return "#";
10647     default:
10648       if (REG_P (operands[2]))
10649         return "sal{l}\t{%b2, %0|%0, %b2}";
10650       else if (operands[2] == const1_rtx
10651                && (TARGET_SHIFT1 || optimize_size))
10652         return "sal{l}\t%0";
10653       else
10654         return "sal{l}\t{%2, %0|%0, %2}";
10655     }
10657   [(set (attr "type")
10658      (cond [(eq_attr "alternative" "1")
10659               (const_string "lea")
10660             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10661                           (const_int 0))
10662                       (match_operand 0 "register_operand" ""))
10663                  (match_operand 2 "const1_operand" ""))
10664               (const_string "alu")
10665            ]
10666            (const_string "ishift")))
10667    (set_attr "mode" "SI")])
10669 ;; Convert lea to the lea pattern to avoid flags dependency.
10670 (define_split
10671   [(set (match_operand 0 "register_operand" "")
10672         (ashift (match_operand 1 "index_register_operand" "")
10673                 (match_operand:QI 2 "const_int_operand" "")))
10674    (clobber (reg:CC FLAGS_REG))]
10675   "reload_completed
10676    && true_regnum (operands[0]) != true_regnum (operands[1])
10677    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10678   [(const_int 0)]
10680   rtx pat;
10681   enum machine_mode mode = GET_MODE (operands[0]);
10683   if (GET_MODE_SIZE (mode) < 4)
10684     operands[0] = gen_lowpart (SImode, operands[0]);
10685   if (mode != Pmode)
10686     operands[1] = gen_lowpart (Pmode, operands[1]);
10687   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10689   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10690   if (Pmode != SImode)
10691     pat = gen_rtx_SUBREG (SImode, pat, 0);
10692   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10693   DONE;
10696 ;; Rare case of shifting RSP is handled by generating move and shift
10697 (define_split
10698   [(set (match_operand 0 "register_operand" "")
10699         (ashift (match_operand 1 "register_operand" "")
10700                 (match_operand:QI 2 "const_int_operand" "")))
10701    (clobber (reg:CC FLAGS_REG))]
10702   "reload_completed
10703    && true_regnum (operands[0]) != true_regnum (operands[1])"
10704   [(const_int 0)]
10706   rtx pat, clob;
10707   emit_move_insn (operands[0], operands[1]);
10708   pat = gen_rtx_SET (VOIDmode, operands[0],
10709                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10710                                      operands[0], operands[2]));
10711   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10712   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10713   DONE;
10716 (define_insn "*ashlsi3_1_zext"
10717   [(set (match_operand:DI 0 "register_operand" "=r,r")
10718         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10719                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10720    (clobber (reg:CC FLAGS_REG))]
10721   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10723   switch (get_attr_type (insn))
10724     {
10725     case TYPE_ALU:
10726       gcc_assert (operands[2] == const1_rtx);
10727       return "add{l}\t{%k0, %k0|%k0, %k0}";
10729     case TYPE_LEA:
10730       return "#";
10732     default:
10733       if (REG_P (operands[2]))
10734         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10735       else if (operands[2] == const1_rtx
10736                && (TARGET_SHIFT1 || optimize_size))
10737         return "sal{l}\t%k0";
10738       else
10739         return "sal{l}\t{%2, %k0|%k0, %2}";
10740     }
10742   [(set (attr "type")
10743      (cond [(eq_attr "alternative" "1")
10744               (const_string "lea")
10745             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10746                      (const_int 0))
10747                  (match_operand 2 "const1_operand" ""))
10748               (const_string "alu")
10749            ]
10750            (const_string "ishift")))
10751    (set_attr "mode" "SI")])
10753 ;; Convert lea to the lea pattern to avoid flags dependency.
10754 (define_split
10755   [(set (match_operand:DI 0 "register_operand" "")
10756         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10757                                 (match_operand:QI 2 "const_int_operand" ""))))
10758    (clobber (reg:CC FLAGS_REG))]
10759   "TARGET_64BIT && reload_completed
10760    && true_regnum (operands[0]) != true_regnum (operands[1])"
10761   [(set (match_dup 0) (zero_extend:DI
10762                         (subreg:SI (mult:SI (match_dup 1)
10763                                             (match_dup 2)) 0)))]
10765   operands[1] = gen_lowpart (Pmode, operands[1]);
10766   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10769 ;; This pattern can't accept a variable shift count, since shifts by
10770 ;; zero don't affect the flags.  We assume that shifts by constant
10771 ;; zero are optimized away.
10772 (define_insn "*ashlsi3_cmp"
10773   [(set (reg FLAGS_REG)
10774         (compare
10775           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10776                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10777           (const_int 0)))
10778    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10779         (ashift:SI (match_dup 1) (match_dup 2)))]
10780   "ix86_match_ccmode (insn, CCGOCmode)
10781    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10782    && (optimize_size
10783        || !TARGET_PARTIAL_FLAG_REG_STALL
10784        || (operands[2] == const1_rtx
10785            && (TARGET_SHIFT1
10786                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10788   switch (get_attr_type (insn))
10789     {
10790     case TYPE_ALU:
10791       gcc_assert (operands[2] == const1_rtx);
10792       return "add{l}\t{%0, %0|%0, %0}";
10794     default:
10795       if (REG_P (operands[2]))
10796         return "sal{l}\t{%b2, %0|%0, %b2}";
10797       else if (operands[2] == const1_rtx
10798                && (TARGET_SHIFT1 || optimize_size))
10799         return "sal{l}\t%0";
10800       else
10801         return "sal{l}\t{%2, %0|%0, %2}";
10802     }
10804   [(set (attr "type")
10805      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10806                           (const_int 0))
10807                       (match_operand 0 "register_operand" ""))
10808                  (match_operand 2 "const1_operand" ""))
10809               (const_string "alu")
10810            ]
10811            (const_string "ishift")))
10812    (set_attr "mode" "SI")])
10814 (define_insn "*ashlsi3_cconly"
10815   [(set (reg FLAGS_REG)
10816         (compare
10817           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10818                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10819           (const_int 0)))
10820    (clobber (match_scratch:SI 0 "=r"))]
10821   "ix86_match_ccmode (insn, CCGOCmode)
10822    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10823    && (optimize_size
10824        || !TARGET_PARTIAL_FLAG_REG_STALL
10825        || (operands[2] == const1_rtx
10826            && (TARGET_SHIFT1
10827                || TARGET_DOUBLE_WITH_ADD)))"
10829   switch (get_attr_type (insn))
10830     {
10831     case TYPE_ALU:
10832       gcc_assert (operands[2] == const1_rtx);
10833       return "add{l}\t{%0, %0|%0, %0}";
10835     default:
10836       if (REG_P (operands[2]))
10837         return "sal{l}\t{%b2, %0|%0, %b2}";
10838       else if (operands[2] == const1_rtx
10839                && (TARGET_SHIFT1 || optimize_size))
10840         return "sal{l}\t%0";
10841       else
10842         return "sal{l}\t{%2, %0|%0, %2}";
10843     }
10845   [(set (attr "type")
10846      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10847                           (const_int 0))
10848                       (match_operand 0 "register_operand" ""))
10849                  (match_operand 2 "const1_operand" ""))
10850               (const_string "alu")
10851            ]
10852            (const_string "ishift")))
10853    (set_attr "mode" "SI")])
10855 (define_insn "*ashlsi3_cmp_zext"
10856   [(set (reg FLAGS_REG)
10857         (compare
10858           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10859                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10860           (const_int 0)))
10861    (set (match_operand:DI 0 "register_operand" "=r")
10862         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10863   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10864    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10865    && (optimize_size
10866        || !TARGET_PARTIAL_FLAG_REG_STALL
10867        || (operands[2] == const1_rtx
10868            && (TARGET_SHIFT1
10869                || TARGET_DOUBLE_WITH_ADD)))"
10871   switch (get_attr_type (insn))
10872     {
10873     case TYPE_ALU:
10874       gcc_assert (operands[2] == const1_rtx);
10875       return "add{l}\t{%k0, %k0|%k0, %k0}";
10877     default:
10878       if (REG_P (operands[2]))
10879         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10880       else if (operands[2] == const1_rtx
10881                && (TARGET_SHIFT1 || optimize_size))
10882         return "sal{l}\t%k0";
10883       else
10884         return "sal{l}\t{%2, %k0|%k0, %2}";
10885     }
10887   [(set (attr "type")
10888      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10889                      (const_int 0))
10890                  (match_operand 2 "const1_operand" ""))
10891               (const_string "alu")
10892            ]
10893            (const_string "ishift")))
10894    (set_attr "mode" "SI")])
10896 (define_expand "ashlhi3"
10897   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10898         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10899                    (match_operand:QI 2 "nonmemory_operand" "")))
10900    (clobber (reg:CC FLAGS_REG))]
10901   "TARGET_HIMODE_MATH"
10902   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10904 (define_insn "*ashlhi3_1_lea"
10905   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10906         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10907                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10908    (clobber (reg:CC FLAGS_REG))]
10909   "!TARGET_PARTIAL_REG_STALL
10910    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10912   switch (get_attr_type (insn))
10913     {
10914     case TYPE_LEA:
10915       return "#";
10916     case TYPE_ALU:
10917       gcc_assert (operands[2] == const1_rtx);
10918       return "add{w}\t{%0, %0|%0, %0}";
10920     default:
10921       if (REG_P (operands[2]))
10922         return "sal{w}\t{%b2, %0|%0, %b2}";
10923       else if (operands[2] == const1_rtx
10924                && (TARGET_SHIFT1 || optimize_size))
10925         return "sal{w}\t%0";
10926       else
10927         return "sal{w}\t{%2, %0|%0, %2}";
10928     }
10930   [(set (attr "type")
10931      (cond [(eq_attr "alternative" "1")
10932               (const_string "lea")
10933             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10934                           (const_int 0))
10935                       (match_operand 0 "register_operand" ""))
10936                  (match_operand 2 "const1_operand" ""))
10937               (const_string "alu")
10938            ]
10939            (const_string "ishift")))
10940    (set_attr "mode" "HI,SI")])
10942 (define_insn "*ashlhi3_1"
10943   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10944         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10945                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10946    (clobber (reg:CC FLAGS_REG))]
10947   "TARGET_PARTIAL_REG_STALL
10948    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10950   switch (get_attr_type (insn))
10951     {
10952     case TYPE_ALU:
10953       gcc_assert (operands[2] == const1_rtx);
10954       return "add{w}\t{%0, %0|%0, %0}";
10956     default:
10957       if (REG_P (operands[2]))
10958         return "sal{w}\t{%b2, %0|%0, %b2}";
10959       else if (operands[2] == const1_rtx
10960                && (TARGET_SHIFT1 || optimize_size))
10961         return "sal{w}\t%0";
10962       else
10963         return "sal{w}\t{%2, %0|%0, %2}";
10964     }
10966   [(set (attr "type")
10967      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10968                           (const_int 0))
10969                       (match_operand 0 "register_operand" ""))
10970                  (match_operand 2 "const1_operand" ""))
10971               (const_string "alu")
10972            ]
10973            (const_string "ishift")))
10974    (set_attr "mode" "HI")])
10976 ;; This pattern can't accept a variable shift count, since shifts by
10977 ;; zero don't affect the flags.  We assume that shifts by constant
10978 ;; zero are optimized away.
10979 (define_insn "*ashlhi3_cmp"
10980   [(set (reg FLAGS_REG)
10981         (compare
10982           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10983                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10984           (const_int 0)))
10985    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10986         (ashift:HI (match_dup 1) (match_dup 2)))]
10987   "ix86_match_ccmode (insn, CCGOCmode)
10988    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10989    && (optimize_size
10990        || !TARGET_PARTIAL_FLAG_REG_STALL
10991        || (operands[2] == const1_rtx
10992            && (TARGET_SHIFT1
10993                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10995   switch (get_attr_type (insn))
10996     {
10997     case TYPE_ALU:
10998       gcc_assert (operands[2] == const1_rtx);
10999       return "add{w}\t{%0, %0|%0, %0}";
11001     default:
11002       if (REG_P (operands[2]))
11003         return "sal{w}\t{%b2, %0|%0, %b2}";
11004       else if (operands[2] == const1_rtx
11005                && (TARGET_SHIFT1 || optimize_size))
11006         return "sal{w}\t%0";
11007       else
11008         return "sal{w}\t{%2, %0|%0, %2}";
11009     }
11011   [(set (attr "type")
11012      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11013                           (const_int 0))
11014                       (match_operand 0 "register_operand" ""))
11015                  (match_operand 2 "const1_operand" ""))
11016               (const_string "alu")
11017            ]
11018            (const_string "ishift")))
11019    (set_attr "mode" "HI")])
11021 (define_insn "*ashlhi3_cconly"
11022   [(set (reg FLAGS_REG)
11023         (compare
11024           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11025                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11026           (const_int 0)))
11027    (clobber (match_scratch:HI 0 "=r"))]
11028   "ix86_match_ccmode (insn, CCGOCmode)
11029    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11030    && (optimize_size
11031        || !TARGET_PARTIAL_FLAG_REG_STALL
11032        || (operands[2] == const1_rtx
11033            && (TARGET_SHIFT1
11034                || TARGET_DOUBLE_WITH_ADD)))"
11036   switch (get_attr_type (insn))
11037     {
11038     case TYPE_ALU:
11039       gcc_assert (operands[2] == const1_rtx);
11040       return "add{w}\t{%0, %0|%0, %0}";
11042     default:
11043       if (REG_P (operands[2]))
11044         return "sal{w}\t{%b2, %0|%0, %b2}";
11045       else if (operands[2] == const1_rtx
11046                && (TARGET_SHIFT1 || optimize_size))
11047         return "sal{w}\t%0";
11048       else
11049         return "sal{w}\t{%2, %0|%0, %2}";
11050     }
11052   [(set (attr "type")
11053      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11054                           (const_int 0))
11055                       (match_operand 0 "register_operand" ""))
11056                  (match_operand 2 "const1_operand" ""))
11057               (const_string "alu")
11058            ]
11059            (const_string "ishift")))
11060    (set_attr "mode" "HI")])
11062 (define_expand "ashlqi3"
11063   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11064         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11065                    (match_operand:QI 2 "nonmemory_operand" "")))
11066    (clobber (reg:CC FLAGS_REG))]
11067   "TARGET_QIMODE_MATH"
11068   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11070 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11072 (define_insn "*ashlqi3_1_lea"
11073   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11074         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11075                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11076    (clobber (reg:CC FLAGS_REG))]
11077   "!TARGET_PARTIAL_REG_STALL
11078    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11080   switch (get_attr_type (insn))
11081     {
11082     case TYPE_LEA:
11083       return "#";
11084     case TYPE_ALU:
11085       gcc_assert (operands[2] == const1_rtx);
11086       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11087         return "add{l}\t{%k0, %k0|%k0, %k0}";
11088       else
11089         return "add{b}\t{%0, %0|%0, %0}";
11091     default:
11092       if (REG_P (operands[2]))
11093         {
11094           if (get_attr_mode (insn) == MODE_SI)
11095             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11096           else
11097             return "sal{b}\t{%b2, %0|%0, %b2}";
11098         }
11099       else if (operands[2] == const1_rtx
11100                && (TARGET_SHIFT1 || optimize_size))
11101         {
11102           if (get_attr_mode (insn) == MODE_SI)
11103             return "sal{l}\t%0";
11104           else
11105             return "sal{b}\t%0";
11106         }
11107       else
11108         {
11109           if (get_attr_mode (insn) == MODE_SI)
11110             return "sal{l}\t{%2, %k0|%k0, %2}";
11111           else
11112             return "sal{b}\t{%2, %0|%0, %2}";
11113         }
11114     }
11116   [(set (attr "type")
11117      (cond [(eq_attr "alternative" "2")
11118               (const_string "lea")
11119             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11120                           (const_int 0))
11121                       (match_operand 0 "register_operand" ""))
11122                  (match_operand 2 "const1_operand" ""))
11123               (const_string "alu")
11124            ]
11125            (const_string "ishift")))
11126    (set_attr "mode" "QI,SI,SI")])
11128 (define_insn "*ashlqi3_1"
11129   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11130         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11131                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11132    (clobber (reg:CC FLAGS_REG))]
11133   "TARGET_PARTIAL_REG_STALL
11134    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11136   switch (get_attr_type (insn))
11137     {
11138     case TYPE_ALU:
11139       gcc_assert (operands[2] == const1_rtx);
11140       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11141         return "add{l}\t{%k0, %k0|%k0, %k0}";
11142       else
11143         return "add{b}\t{%0, %0|%0, %0}";
11145     default:
11146       if (REG_P (operands[2]))
11147         {
11148           if (get_attr_mode (insn) == MODE_SI)
11149             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11150           else
11151             return "sal{b}\t{%b2, %0|%0, %b2}";
11152         }
11153       else if (operands[2] == const1_rtx
11154                && (TARGET_SHIFT1 || optimize_size))
11155         {
11156           if (get_attr_mode (insn) == MODE_SI)
11157             return "sal{l}\t%0";
11158           else
11159             return "sal{b}\t%0";
11160         }
11161       else
11162         {
11163           if (get_attr_mode (insn) == MODE_SI)
11164             return "sal{l}\t{%2, %k0|%k0, %2}";
11165           else
11166             return "sal{b}\t{%2, %0|%0, %2}";
11167         }
11168     }
11170   [(set (attr "type")
11171      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11172                           (const_int 0))
11173                       (match_operand 0 "register_operand" ""))
11174                  (match_operand 2 "const1_operand" ""))
11175               (const_string "alu")
11176            ]
11177            (const_string "ishift")))
11178    (set_attr "mode" "QI,SI")])
11180 ;; This pattern can't accept a variable shift count, since shifts by
11181 ;; zero don't affect the flags.  We assume that shifts by constant
11182 ;; zero are optimized away.
11183 (define_insn "*ashlqi3_cmp"
11184   [(set (reg FLAGS_REG)
11185         (compare
11186           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11187                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11188           (const_int 0)))
11189    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11190         (ashift:QI (match_dup 1) (match_dup 2)))]
11191   "ix86_match_ccmode (insn, CCGOCmode)
11192    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11193    && (optimize_size
11194        || !TARGET_PARTIAL_FLAG_REG_STALL
11195        || (operands[2] == const1_rtx
11196            && (TARGET_SHIFT1
11197                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11199   switch (get_attr_type (insn))
11200     {
11201     case TYPE_ALU:
11202       gcc_assert (operands[2] == const1_rtx);
11203       return "add{b}\t{%0, %0|%0, %0}";
11205     default:
11206       if (REG_P (operands[2]))
11207         return "sal{b}\t{%b2, %0|%0, %b2}";
11208       else if (operands[2] == const1_rtx
11209                && (TARGET_SHIFT1 || optimize_size))
11210         return "sal{b}\t%0";
11211       else
11212         return "sal{b}\t{%2, %0|%0, %2}";
11213     }
11215   [(set (attr "type")
11216      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11217                           (const_int 0))
11218                       (match_operand 0 "register_operand" ""))
11219                  (match_operand 2 "const1_operand" ""))
11220               (const_string "alu")
11221            ]
11222            (const_string "ishift")))
11223    (set_attr "mode" "QI")])
11225 (define_insn "*ashlqi3_cconly"
11226   [(set (reg FLAGS_REG)
11227         (compare
11228           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11229                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11230           (const_int 0)))
11231    (clobber (match_scratch:QI 0 "=q"))]
11232   "ix86_match_ccmode (insn, CCGOCmode)
11233    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11234    && (optimize_size
11235        || !TARGET_PARTIAL_FLAG_REG_STALL
11236        || (operands[2] == const1_rtx
11237            && (TARGET_SHIFT1
11238                || TARGET_DOUBLE_WITH_ADD)))"
11240   switch (get_attr_type (insn))
11241     {
11242     case TYPE_ALU:
11243       gcc_assert (operands[2] == const1_rtx);
11244       return "add{b}\t{%0, %0|%0, %0}";
11246     default:
11247       if (REG_P (operands[2]))
11248         return "sal{b}\t{%b2, %0|%0, %b2}";
11249       else if (operands[2] == const1_rtx
11250                && (TARGET_SHIFT1 || optimize_size))
11251         return "sal{b}\t%0";
11252       else
11253         return "sal{b}\t{%2, %0|%0, %2}";
11254     }
11256   [(set (attr "type")
11257      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11258                           (const_int 0))
11259                       (match_operand 0 "register_operand" ""))
11260                  (match_operand 2 "const1_operand" ""))
11261               (const_string "alu")
11262            ]
11263            (const_string "ishift")))
11264    (set_attr "mode" "QI")])
11266 ;; See comment above `ashldi3' about how this works.
11268 (define_expand "ashrti3"
11269   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11270                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11271                                 (match_operand:QI 2 "nonmemory_operand" "")))
11272               (clobber (reg:CC FLAGS_REG))])]
11273   "TARGET_64BIT"
11275   if (! immediate_operand (operands[2], QImode))
11276     {
11277       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11278       DONE;
11279     }
11280   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11281   DONE;
11284 (define_insn "ashrti3_1"
11285   [(set (match_operand:TI 0 "register_operand" "=r")
11286         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11287                      (match_operand:QI 2 "register_operand" "c")))
11288    (clobber (match_scratch:DI 3 "=&r"))
11289    (clobber (reg:CC FLAGS_REG))]
11290   "TARGET_64BIT"
11291   "#"
11292   [(set_attr "type" "multi")])
11294 (define_insn "*ashrti3_2"
11295   [(set (match_operand:TI 0 "register_operand" "=r")
11296         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11297                      (match_operand:QI 2 "immediate_operand" "O")))
11298    (clobber (reg:CC FLAGS_REG))]
11299   "TARGET_64BIT"
11300   "#"
11301   [(set_attr "type" "multi")])
11303 (define_split
11304   [(set (match_operand:TI 0 "register_operand" "")
11305         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11306                      (match_operand:QI 2 "register_operand" "")))
11307    (clobber (match_scratch:DI 3 ""))
11308    (clobber (reg:CC FLAGS_REG))]
11309   "TARGET_64BIT && reload_completed"
11310   [(const_int 0)]
11311   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11313 (define_split
11314   [(set (match_operand:TI 0 "register_operand" "")
11315         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11316                      (match_operand:QI 2 "immediate_operand" "")))
11317    (clobber (reg:CC FLAGS_REG))]
11318   "TARGET_64BIT && reload_completed"
11319   [(const_int 0)]
11320   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11322 (define_insn "x86_64_shrd"
11323   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11324         (ior:DI (ashiftrt:DI (match_dup 0)
11325                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11326                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11327                   (minus:QI (const_int 64) (match_dup 2)))))
11328    (clobber (reg:CC FLAGS_REG))]
11329   "TARGET_64BIT"
11330   "@
11331    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11332    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11333   [(set_attr "type" "ishift")
11334    (set_attr "prefix_0f" "1")
11335    (set_attr "mode" "DI")
11336    (set_attr "athlon_decode" "vector")])
11338 (define_expand "ashrdi3"
11339   [(set (match_operand:DI 0 "shiftdi_operand" "")
11340         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11341                      (match_operand:QI 2 "nonmemory_operand" "")))]
11342   ""
11343   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11345 (define_insn "*ashrdi3_63_rex64"
11346   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11347         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11348                      (match_operand:DI 2 "const_int_operand" "i,i")))
11349    (clobber (reg:CC FLAGS_REG))]
11350   "TARGET_64BIT && INTVAL (operands[2]) == 63
11351    && (TARGET_USE_CLTD || optimize_size)
11352    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11353   "@
11354    {cqto|cqo}
11355    sar{q}\t{%2, %0|%0, %2}"
11356   [(set_attr "type" "imovx,ishift")
11357    (set_attr "prefix_0f" "0,*")
11358    (set_attr "length_immediate" "0,*")
11359    (set_attr "modrm" "0,1")
11360    (set_attr "mode" "DI")])
11362 (define_insn "*ashrdi3_1_one_bit_rex64"
11363   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11364         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11365                      (match_operand:QI 2 "const1_operand" "")))
11366    (clobber (reg:CC FLAGS_REG))]
11367   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11368    && (TARGET_SHIFT1 || optimize_size)"
11369   "sar{q}\t%0"
11370   [(set_attr "type" "ishift")
11371    (set (attr "length")
11372      (if_then_else (match_operand:DI 0 "register_operand" "")
11373         (const_string "2")
11374         (const_string "*")))])
11376 (define_insn "*ashrdi3_1_rex64"
11377   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11378         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11379                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11380    (clobber (reg:CC FLAGS_REG))]
11381   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11382   "@
11383    sar{q}\t{%2, %0|%0, %2}
11384    sar{q}\t{%b2, %0|%0, %b2}"
11385   [(set_attr "type" "ishift")
11386    (set_attr "mode" "DI")])
11388 ;; This pattern can't accept a variable shift count, since shifts by
11389 ;; zero don't affect the flags.  We assume that shifts by constant
11390 ;; zero are optimized away.
11391 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11392   [(set (reg FLAGS_REG)
11393         (compare
11394           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11395                        (match_operand:QI 2 "const1_operand" ""))
11396           (const_int 0)))
11397    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11398         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11399   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11400    && (TARGET_SHIFT1 || optimize_size)
11401    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11402   "sar{q}\t%0"
11403   [(set_attr "type" "ishift")
11404    (set (attr "length")
11405      (if_then_else (match_operand:DI 0 "register_operand" "")
11406         (const_string "2")
11407         (const_string "*")))])
11409 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11410   [(set (reg FLAGS_REG)
11411         (compare
11412           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11413                        (match_operand:QI 2 "const1_operand" ""))
11414           (const_int 0)))
11415    (clobber (match_scratch:DI 0 "=r"))]
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" "2")])
11423 ;; This pattern can't accept a variable shift count, since shifts by
11424 ;; zero don't affect the flags.  We assume that shifts by constant
11425 ;; zero are optimized away.
11426 (define_insn "*ashrdi3_cmp_rex64"
11427   [(set (reg FLAGS_REG)
11428         (compare
11429           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11430                        (match_operand:QI 2 "const_int_operand" "n"))
11431           (const_int 0)))
11432    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11433         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11434   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11435    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11436    && (optimize_size
11437        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11438   "sar{q}\t{%2, %0|%0, %2}"
11439   [(set_attr "type" "ishift")
11440    (set_attr "mode" "DI")])
11442 (define_insn "*ashrdi3_cconly_rex64"
11443   [(set (reg FLAGS_REG)
11444         (compare
11445           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11446                        (match_operand:QI 2 "const_int_operand" "n"))
11447           (const_int 0)))
11448    (clobber (match_scratch:DI 0 "=r"))]
11449   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11450    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11451    && (optimize_size
11452        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11453   "sar{q}\t{%2, %0|%0, %2}"
11454   [(set_attr "type" "ishift")
11455    (set_attr "mode" "DI")])
11457 (define_insn "*ashrdi3_1"
11458   [(set (match_operand:DI 0 "register_operand" "=r")
11459         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11460                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11461    (clobber (reg:CC FLAGS_REG))]
11462   "!TARGET_64BIT"
11463   "#"
11464   [(set_attr "type" "multi")])
11466 ;; By default we don't ask for a scratch register, because when DImode
11467 ;; values are manipulated, registers are already at a premium.  But if
11468 ;; we have one handy, we won't turn it away.
11469 (define_peephole2
11470   [(match_scratch:SI 3 "r")
11471    (parallel [(set (match_operand:DI 0 "register_operand" "")
11472                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11473                                 (match_operand:QI 2 "nonmemory_operand" "")))
11474               (clobber (reg:CC FLAGS_REG))])
11475    (match_dup 3)]
11476   "!TARGET_64BIT && TARGET_CMOVE"
11477   [(const_int 0)]
11478   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11480 (define_split
11481   [(set (match_operand:DI 0 "register_operand" "")
11482         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11483                      (match_operand:QI 2 "nonmemory_operand" "")))
11484    (clobber (reg:CC FLAGS_REG))]
11485   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11486                      ? flow2_completed : reload_completed)"
11487   [(const_int 0)]
11488   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11490 (define_insn "x86_shrd_1"
11491   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11492         (ior:SI (ashiftrt:SI (match_dup 0)
11493                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11494                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11495                   (minus:QI (const_int 32) (match_dup 2)))))
11496    (clobber (reg:CC FLAGS_REG))]
11497   ""
11498   "@
11499    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11500    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11501   [(set_attr "type" "ishift")
11502    (set_attr "prefix_0f" "1")
11503    (set_attr "pent_pair" "np")
11504    (set_attr "mode" "SI")])
11506 (define_expand "x86_shift_adj_3"
11507   [(use (match_operand:SI 0 "register_operand" ""))
11508    (use (match_operand:SI 1 "register_operand" ""))
11509    (use (match_operand:QI 2 "register_operand" ""))]
11510   ""
11512   rtx label = gen_label_rtx ();
11513   rtx tmp;
11515   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11517   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11518   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11519   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11520                               gen_rtx_LABEL_REF (VOIDmode, label),
11521                               pc_rtx);
11522   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11523   JUMP_LABEL (tmp) = label;
11525   emit_move_insn (operands[0], operands[1]);
11526   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11528   emit_label (label);
11529   LABEL_NUSES (label) = 1;
11531   DONE;
11534 (define_insn "ashrsi3_31"
11535   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11536         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11537                      (match_operand:SI 2 "const_int_operand" "i,i")))
11538    (clobber (reg:CC FLAGS_REG))]
11539   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11540    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11541   "@
11542    {cltd|cdq}
11543    sar{l}\t{%2, %0|%0, %2}"
11544   [(set_attr "type" "imovx,ishift")
11545    (set_attr "prefix_0f" "0,*")
11546    (set_attr "length_immediate" "0,*")
11547    (set_attr "modrm" "0,1")
11548    (set_attr "mode" "SI")])
11550 (define_insn "*ashrsi3_31_zext"
11551   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11552         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11553                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11554    (clobber (reg:CC FLAGS_REG))]
11555   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11556    && INTVAL (operands[2]) == 31
11557    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11558   "@
11559    {cltd|cdq}
11560    sar{l}\t{%2, %k0|%k0, %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_expand "ashrsi3"
11568   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11569         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11570                      (match_operand:QI 2 "nonmemory_operand" "")))
11571    (clobber (reg:CC FLAGS_REG))]
11572   ""
11573   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11575 (define_insn "*ashrsi3_1_one_bit"
11576   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11577         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11578                      (match_operand:QI 2 "const1_operand" "")))
11579    (clobber (reg:CC FLAGS_REG))]
11580   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11581    && (TARGET_SHIFT1 || optimize_size)"
11582   "sar{l}\t%0"
11583   [(set_attr "type" "ishift")
11584    (set (attr "length")
11585      (if_then_else (match_operand:SI 0 "register_operand" "")
11586         (const_string "2")
11587         (const_string "*")))])
11589 (define_insn "*ashrsi3_1_one_bit_zext"
11590   [(set (match_operand:DI 0 "register_operand" "=r")
11591         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11592                                      (match_operand:QI 2 "const1_operand" ""))))
11593    (clobber (reg:CC FLAGS_REG))]
11594   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11595    && (TARGET_SHIFT1 || optimize_size)"
11596   "sar{l}\t%k0"
11597   [(set_attr "type" "ishift")
11598    (set_attr "length" "2")])
11600 (define_insn "*ashrsi3_1"
11601   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11602         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11603                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11604    (clobber (reg:CC FLAGS_REG))]
11605   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11606   "@
11607    sar{l}\t{%2, %0|%0, %2}
11608    sar{l}\t{%b2, %0|%0, %b2}"
11609   [(set_attr "type" "ishift")
11610    (set_attr "mode" "SI")])
11612 (define_insn "*ashrsi3_1_zext"
11613   [(set (match_operand:DI 0 "register_operand" "=r,r")
11614         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11615                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11616    (clobber (reg:CC FLAGS_REG))]
11617   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11618   "@
11619    sar{l}\t{%2, %k0|%k0, %2}
11620    sar{l}\t{%b2, %k0|%k0, %b2}"
11621   [(set_attr "type" "ishift")
11622    (set_attr "mode" "SI")])
11624 ;; This pattern can't accept a variable shift count, since shifts by
11625 ;; zero don't affect the flags.  We assume that shifts by constant
11626 ;; zero are optimized away.
11627 (define_insn "*ashrsi3_one_bit_cmp"
11628   [(set (reg FLAGS_REG)
11629         (compare
11630           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11631                        (match_operand:QI 2 "const1_operand" ""))
11632           (const_int 0)))
11633    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11634         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11635   "ix86_match_ccmode (insn, CCGOCmode)
11636    && (TARGET_SHIFT1 || optimize_size)
11637    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11638   "sar{l}\t%0"
11639   [(set_attr "type" "ishift")
11640    (set (attr "length")
11641      (if_then_else (match_operand:SI 0 "register_operand" "")
11642         (const_string "2")
11643         (const_string "*")))])
11645 (define_insn "*ashrsi3_one_bit_cconly"
11646   [(set (reg FLAGS_REG)
11647         (compare
11648           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11649                        (match_operand:QI 2 "const1_operand" ""))
11650           (const_int 0)))
11651    (clobber (match_scratch:SI 0 "=r"))]
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" "2")])
11659 (define_insn "*ashrsi3_one_bit_cmp_zext"
11660   [(set (reg FLAGS_REG)
11661         (compare
11662           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11663                        (match_operand:QI 2 "const1_operand" ""))
11664           (const_int 0)))
11665    (set (match_operand:DI 0 "register_operand" "=r")
11666         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11667   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11668    && (TARGET_SHIFT1 || optimize_size)
11669    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11670   "sar{l}\t%k0"
11671   [(set_attr "type" "ishift")
11672    (set_attr "length" "2")])
11674 ;; This pattern can't accept a variable shift count, since shifts by
11675 ;; zero don't affect the flags.  We assume that shifts by constant
11676 ;; zero are optimized away.
11677 (define_insn "*ashrsi3_cmp"
11678   [(set (reg FLAGS_REG)
11679         (compare
11680           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11681                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11682           (const_int 0)))
11683    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11684         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11685   "ix86_match_ccmode (insn, CCGOCmode)
11686    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11687    && (optimize_size
11688        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11689   "sar{l}\t{%2, %0|%0, %2}"
11690   [(set_attr "type" "ishift")
11691    (set_attr "mode" "SI")])
11693 (define_insn "*ashrsi3_cconly"
11694   [(set (reg FLAGS_REG)
11695         (compare
11696           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11697                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11698           (const_int 0)))
11699    (clobber (match_scratch:SI 0 "=r"))]
11700   "ix86_match_ccmode (insn, CCGOCmode)
11701    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11702    && (optimize_size
11703        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11704   "sar{l}\t{%2, %0|%0, %2}"
11705   [(set_attr "type" "ishift")
11706    (set_attr "mode" "SI")])
11708 (define_insn "*ashrsi3_cmp_zext"
11709   [(set (reg FLAGS_REG)
11710         (compare
11711           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11712                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11713           (const_int 0)))
11714    (set (match_operand:DI 0 "register_operand" "=r")
11715         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11716   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11717    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11718    && (optimize_size
11719        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11720   "sar{l}\t{%2, %k0|%k0, %2}"
11721   [(set_attr "type" "ishift")
11722    (set_attr "mode" "SI")])
11724 (define_expand "ashrhi3"
11725   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11726         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11727                      (match_operand:QI 2 "nonmemory_operand" "")))
11728    (clobber (reg:CC FLAGS_REG))]
11729   "TARGET_HIMODE_MATH"
11730   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11732 (define_insn "*ashrhi3_1_one_bit"
11733   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11734         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11735                      (match_operand:QI 2 "const1_operand" "")))
11736    (clobber (reg:CC FLAGS_REG))]
11737   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11738    && (TARGET_SHIFT1 || optimize_size)"
11739   "sar{w}\t%0"
11740   [(set_attr "type" "ishift")
11741    (set (attr "length")
11742      (if_then_else (match_operand 0 "register_operand" "")
11743         (const_string "2")
11744         (const_string "*")))])
11746 (define_insn "*ashrhi3_1"
11747   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11748         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11749                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11750    (clobber (reg:CC FLAGS_REG))]
11751   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11752   "@
11753    sar{w}\t{%2, %0|%0, %2}
11754    sar{w}\t{%b2, %0|%0, %b2}"
11755   [(set_attr "type" "ishift")
11756    (set_attr "mode" "HI")])
11758 ;; This pattern can't accept a variable shift count, since shifts by
11759 ;; zero don't affect the flags.  We assume that shifts by constant
11760 ;; zero are optimized away.
11761 (define_insn "*ashrhi3_one_bit_cmp"
11762   [(set (reg FLAGS_REG)
11763         (compare
11764           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11765                        (match_operand:QI 2 "const1_operand" ""))
11766           (const_int 0)))
11767    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11768         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11769   "ix86_match_ccmode (insn, CCGOCmode)
11770    && (TARGET_SHIFT1 || optimize_size)
11771    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11772   "sar{w}\t%0"
11773   [(set_attr "type" "ishift")
11774    (set (attr "length")
11775      (if_then_else (match_operand 0 "register_operand" "")
11776         (const_string "2")
11777         (const_string "*")))])
11779 (define_insn "*ashrhi3_one_bit_cconly"
11780   [(set (reg FLAGS_REG)
11781         (compare
11782           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11783                        (match_operand:QI 2 "const1_operand" ""))
11784           (const_int 0)))
11785    (clobber (match_scratch:HI 0 "=r"))]
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" "2")])
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags.  We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashrhi3_cmp"
11797   [(set (reg FLAGS_REG)
11798         (compare
11799           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11800                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11801           (const_int 0)))
11802    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11803         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11804   "ix86_match_ccmode (insn, CCGOCmode)
11805    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11806    && (optimize_size
11807        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11808   "sar{w}\t{%2, %0|%0, %2}"
11809   [(set_attr "type" "ishift")
11810    (set_attr "mode" "HI")])
11812 (define_insn "*ashrhi3_cconly"
11813   [(set (reg FLAGS_REG)
11814         (compare
11815           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11816                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11817           (const_int 0)))
11818    (clobber (match_scratch:HI 0 "=r"))]
11819   "ix86_match_ccmode (insn, CCGOCmode)
11820    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11821    && (optimize_size
11822        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11823   "sar{w}\t{%2, %0|%0, %2}"
11824   [(set_attr "type" "ishift")
11825    (set_attr "mode" "HI")])
11827 (define_expand "ashrqi3"
11828   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11829         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11830                      (match_operand:QI 2 "nonmemory_operand" "")))
11831    (clobber (reg:CC FLAGS_REG))]
11832   "TARGET_QIMODE_MATH"
11833   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11835 (define_insn "*ashrqi3_1_one_bit"
11836   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11837         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11838                      (match_operand:QI 2 "const1_operand" "")))
11839    (clobber (reg:CC FLAGS_REG))]
11840   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11841    && (TARGET_SHIFT1 || optimize_size)"
11842   "sar{b}\t%0"
11843   [(set_attr "type" "ishift")
11844    (set (attr "length")
11845      (if_then_else (match_operand 0 "register_operand" "")
11846         (const_string "2")
11847         (const_string "*")))])
11849 (define_insn "*ashrqi3_1_one_bit_slp"
11850   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11851         (ashiftrt:QI (match_dup 0)
11852                      (match_operand:QI 1 "const1_operand" "")))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11855    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11856    && (TARGET_SHIFT1 || optimize_size)"
11857   "sar{b}\t%0"
11858   [(set_attr "type" "ishift1")
11859    (set (attr "length")
11860      (if_then_else (match_operand 0 "register_operand" "")
11861         (const_string "2")
11862         (const_string "*")))])
11864 (define_insn "*ashrqi3_1"
11865   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11866         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11867                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11868    (clobber (reg:CC FLAGS_REG))]
11869   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11870   "@
11871    sar{b}\t{%2, %0|%0, %2}
11872    sar{b}\t{%b2, %0|%0, %b2}"
11873   [(set_attr "type" "ishift")
11874    (set_attr "mode" "QI")])
11876 (define_insn "*ashrqi3_1_slp"
11877   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11878         (ashiftrt:QI (match_dup 0)
11879                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11882    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11883   "@
11884    sar{b}\t{%1, %0|%0, %1}
11885    sar{b}\t{%b1, %0|%0, %b1}"
11886   [(set_attr "type" "ishift1")
11887    (set_attr "mode" "QI")])
11889 ;; This pattern can't accept a variable shift count, since shifts by
11890 ;; zero don't affect the flags.  We assume that shifts by constant
11891 ;; zero are optimized away.
11892 (define_insn "*ashrqi3_one_bit_cmp"
11893   [(set (reg FLAGS_REG)
11894         (compare
11895           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11896                        (match_operand:QI 2 "const1_operand" "I"))
11897           (const_int 0)))
11898    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11899         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11900   "ix86_match_ccmode (insn, CCGOCmode)
11901    && (TARGET_SHIFT1 || optimize_size)
11902    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11903   "sar{b}\t%0"
11904   [(set_attr "type" "ishift")
11905    (set (attr "length")
11906      (if_then_else (match_operand 0 "register_operand" "")
11907         (const_string "2")
11908         (const_string "*")))])
11910 (define_insn "*ashrqi3_one_bit_cconly"
11911   [(set (reg FLAGS_REG)
11912         (compare
11913           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11914                        (match_operand:QI 2 "const1_operand" "I"))
11915           (const_int 0)))
11916    (clobber (match_scratch:QI 0 "=q"))]
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" "2")])
11924 ;; This pattern can't accept a variable shift count, since shifts by
11925 ;; zero don't affect the flags.  We assume that shifts by constant
11926 ;; zero are optimized away.
11927 (define_insn "*ashrqi3_cmp"
11928   [(set (reg FLAGS_REG)
11929         (compare
11930           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11931                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11932           (const_int 0)))
11933    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11934         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11935   "ix86_match_ccmode (insn, CCGOCmode)
11936    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11937    && (optimize_size
11938        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11939   "sar{b}\t{%2, %0|%0, %2}"
11940   [(set_attr "type" "ishift")
11941    (set_attr "mode" "QI")])
11943 (define_insn "*ashrqi3_cconly"
11944   [(set (reg FLAGS_REG)
11945         (compare
11946           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11947                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11948           (const_int 0)))
11949    (clobber (match_scratch:QI 0 "=q"))]
11950   "ix86_match_ccmode (insn, CCGOCmode)
11951    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11952    && (optimize_size
11953        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11954   "sar{b}\t{%2, %0|%0, %2}"
11955   [(set_attr "type" "ishift")
11956    (set_attr "mode" "QI")])
11959 ;; Logical shift instructions
11961 ;; See comment above `ashldi3' about how this works.
11963 (define_expand "lshrti3"
11964   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11965                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11966                                 (match_operand:QI 2 "nonmemory_operand" "")))
11967               (clobber (reg:CC FLAGS_REG))])]
11968   "TARGET_64BIT"
11970   if (! immediate_operand (operands[2], QImode))
11971     {
11972       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11973       DONE;
11974     }
11975   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11976   DONE;
11979 (define_insn "lshrti3_1"
11980   [(set (match_operand:TI 0 "register_operand" "=r")
11981         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11982                      (match_operand:QI 2 "register_operand" "c")))
11983    (clobber (match_scratch:DI 3 "=&r"))
11984    (clobber (reg:CC FLAGS_REG))]
11985   "TARGET_64BIT"
11986   "#"
11987   [(set_attr "type" "multi")])
11989 (define_insn "*lshrti3_2"
11990   [(set (match_operand:TI 0 "register_operand" "=r")
11991         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11992                      (match_operand:QI 2 "immediate_operand" "O")))
11993    (clobber (reg:CC FLAGS_REG))]
11994   "TARGET_64BIT"
11995   "#"
11996   [(set_attr "type" "multi")])
11998 (define_split
11999   [(set (match_operand:TI 0 "register_operand" "")
12000         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12001                      (match_operand:QI 2 "register_operand" "")))
12002    (clobber (match_scratch:DI 3 ""))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "TARGET_64BIT && reload_completed"
12005   [(const_int 0)]
12006   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12008 (define_split
12009   [(set (match_operand:TI 0 "register_operand" "")
12010         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12011                      (match_operand:QI 2 "immediate_operand" "")))
12012    (clobber (reg:CC FLAGS_REG))]
12013   "TARGET_64BIT && reload_completed"
12014   [(const_int 0)]
12015   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12017 (define_expand "lshrdi3"
12018   [(set (match_operand:DI 0 "shiftdi_operand" "")
12019         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12020                      (match_operand:QI 2 "nonmemory_operand" "")))]
12021   ""
12022   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12024 (define_insn "*lshrdi3_1_one_bit_rex64"
12025   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12026         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12027                      (match_operand:QI 2 "const1_operand" "")))
12028    (clobber (reg:CC FLAGS_REG))]
12029   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12030    && (TARGET_SHIFT1 || optimize_size)"
12031   "shr{q}\t%0"
12032   [(set_attr "type" "ishift")
12033    (set (attr "length")
12034      (if_then_else (match_operand:DI 0 "register_operand" "")
12035         (const_string "2")
12036         (const_string "*")))])
12038 (define_insn "*lshrdi3_1_rex64"
12039   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12040         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12041                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12042    (clobber (reg:CC FLAGS_REG))]
12043   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12044   "@
12045    shr{q}\t{%2, %0|%0, %2}
12046    shr{q}\t{%b2, %0|%0, %b2}"
12047   [(set_attr "type" "ishift")
12048    (set_attr "mode" "DI")])
12050 ;; This pattern can't accept a variable shift count, since shifts by
12051 ;; zero don't affect the flags.  We assume that shifts by constant
12052 ;; zero are optimized away.
12053 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12054   [(set (reg FLAGS_REG)
12055         (compare
12056           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12057                        (match_operand:QI 2 "const1_operand" ""))
12058           (const_int 0)))
12059    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12060         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12061   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12062    && (TARGET_SHIFT1 || optimize_size)
12063    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12064   "shr{q}\t%0"
12065   [(set_attr "type" "ishift")
12066    (set (attr "length")
12067      (if_then_else (match_operand:DI 0 "register_operand" "")
12068         (const_string "2")
12069         (const_string "*")))])
12071 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12072   [(set (reg FLAGS_REG)
12073         (compare
12074           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12075                        (match_operand:QI 2 "const1_operand" ""))
12076           (const_int 0)))
12077    (clobber (match_scratch:DI 0 "=r"))]
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" "2")])
12085 ;; This pattern can't accept a variable shift count, since shifts by
12086 ;; zero don't affect the flags.  We assume that shifts by constant
12087 ;; zero are optimized away.
12088 (define_insn "*lshrdi3_cmp_rex64"
12089   [(set (reg FLAGS_REG)
12090         (compare
12091           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12092                        (match_operand:QI 2 "const_int_operand" "e"))
12093           (const_int 0)))
12094    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12095         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12096   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12097    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12098    && (optimize_size
12099        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12100   "shr{q}\t{%2, %0|%0, %2}"
12101   [(set_attr "type" "ishift")
12102    (set_attr "mode" "DI")])
12104 (define_insn "*lshrdi3_cconly_rex64"
12105   [(set (reg FLAGS_REG)
12106         (compare
12107           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12108                        (match_operand:QI 2 "const_int_operand" "e"))
12109           (const_int 0)))
12110    (clobber (match_scratch:DI 0 "=r"))]
12111   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12112    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12113    && (optimize_size
12114        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12115   "shr{q}\t{%2, %0|%0, %2}"
12116   [(set_attr "type" "ishift")
12117    (set_attr "mode" "DI")])
12119 (define_insn "*lshrdi3_1"
12120   [(set (match_operand:DI 0 "register_operand" "=r")
12121         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12122                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12123    (clobber (reg:CC FLAGS_REG))]
12124   "!TARGET_64BIT"
12125   "#"
12126   [(set_attr "type" "multi")])
12128 ;; By default we don't ask for a scratch register, because when DImode
12129 ;; values are manipulated, registers are already at a premium.  But if
12130 ;; we have one handy, we won't turn it away.
12131 (define_peephole2
12132   [(match_scratch:SI 3 "r")
12133    (parallel [(set (match_operand:DI 0 "register_operand" "")
12134                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12135                                 (match_operand:QI 2 "nonmemory_operand" "")))
12136               (clobber (reg:CC FLAGS_REG))])
12137    (match_dup 3)]
12138   "!TARGET_64BIT && TARGET_CMOVE"
12139   [(const_int 0)]
12140   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12142 (define_split
12143   [(set (match_operand:DI 0 "register_operand" "")
12144         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12145                      (match_operand:QI 2 "nonmemory_operand" "")))
12146    (clobber (reg:CC FLAGS_REG))]
12147   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12148                      ? flow2_completed : reload_completed)"
12149   [(const_int 0)]
12150   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12152 (define_expand "lshrsi3"
12153   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12154         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12155                      (match_operand:QI 2 "nonmemory_operand" "")))
12156    (clobber (reg:CC FLAGS_REG))]
12157   ""
12158   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12160 (define_insn "*lshrsi3_1_one_bit"
12161   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12162         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12163                      (match_operand:QI 2 "const1_operand" "")))
12164    (clobber (reg:CC FLAGS_REG))]
12165   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12166    && (TARGET_SHIFT1 || optimize_size)"
12167   "shr{l}\t%0"
12168   [(set_attr "type" "ishift")
12169    (set (attr "length")
12170      (if_then_else (match_operand:SI 0 "register_operand" "")
12171         (const_string "2")
12172         (const_string "*")))])
12174 (define_insn "*lshrsi3_1_one_bit_zext"
12175   [(set (match_operand:DI 0 "register_operand" "=r")
12176         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12177                      (match_operand:QI 2 "const1_operand" "")))
12178    (clobber (reg:CC FLAGS_REG))]
12179   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12180    && (TARGET_SHIFT1 || optimize_size)"
12181   "shr{l}\t%k0"
12182   [(set_attr "type" "ishift")
12183    (set_attr "length" "2")])
12185 (define_insn "*lshrsi3_1"
12186   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12187         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12188                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12189    (clobber (reg:CC FLAGS_REG))]
12190   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12191   "@
12192    shr{l}\t{%2, %0|%0, %2}
12193    shr{l}\t{%b2, %0|%0, %b2}"
12194   [(set_attr "type" "ishift")
12195    (set_attr "mode" "SI")])
12197 (define_insn "*lshrsi3_1_zext"
12198   [(set (match_operand:DI 0 "register_operand" "=r,r")
12199         (zero_extend:DI
12200           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12201                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12202    (clobber (reg:CC FLAGS_REG))]
12203   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12204   "@
12205    shr{l}\t{%2, %k0|%k0, %2}
12206    shr{l}\t{%b2, %k0|%k0, %b2}"
12207   [(set_attr "type" "ishift")
12208    (set_attr "mode" "SI")])
12210 ;; This pattern can't accept a variable shift count, since shifts by
12211 ;; zero don't affect the flags.  We assume that shifts by constant
12212 ;; zero are optimized away.
12213 (define_insn "*lshrsi3_one_bit_cmp"
12214   [(set (reg FLAGS_REG)
12215         (compare
12216           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12217                        (match_operand:QI 2 "const1_operand" ""))
12218           (const_int 0)))
12219    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12220         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12221   "ix86_match_ccmode (insn, CCGOCmode)
12222    && (TARGET_SHIFT1 || optimize_size)
12223    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12224   "shr{l}\t%0"
12225   [(set_attr "type" "ishift")
12226    (set (attr "length")
12227      (if_then_else (match_operand:SI 0 "register_operand" "")
12228         (const_string "2")
12229         (const_string "*")))])
12231 (define_insn "*lshrsi3_one_bit_cconly"
12232   [(set (reg FLAGS_REG)
12233         (compare
12234           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12235                        (match_operand:QI 2 "const1_operand" ""))
12236           (const_int 0)))
12237    (clobber (match_scratch:SI 0 "=r"))]
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" "2")])
12245 (define_insn "*lshrsi3_cmp_one_bit_zext"
12246   [(set (reg FLAGS_REG)
12247         (compare
12248           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12249                        (match_operand:QI 2 "const1_operand" ""))
12250           (const_int 0)))
12251    (set (match_operand:DI 0 "register_operand" "=r")
12252         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12253   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12254    && (TARGET_SHIFT1 || optimize_size)
12255    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12256   "shr{l}\t%k0"
12257   [(set_attr "type" "ishift")
12258    (set_attr "length" "2")])
12260 ;; This pattern can't accept a variable shift count, since shifts by
12261 ;; zero don't affect the flags.  We assume that shifts by constant
12262 ;; zero are optimized away.
12263 (define_insn "*lshrsi3_cmp"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12268           (const_int 0)))
12269    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12270         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12271   "ix86_match_ccmode (insn, CCGOCmode)
12272    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12273    && (optimize_size
12274        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12275   "shr{l}\t{%2, %0|%0, %2}"
12276   [(set_attr "type" "ishift")
12277    (set_attr "mode" "SI")])
12279 (define_insn "*lshrsi3_cconly"
12280   [(set (reg FLAGS_REG)
12281       (compare
12282         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12283                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12284         (const_int 0)))
12285    (clobber (match_scratch:SI 0 "=r"))]
12286   "ix86_match_ccmode (insn, CCGOCmode)
12287    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12288    && (optimize_size
12289        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12290   "shr{l}\t{%2, %0|%0, %2}"
12291   [(set_attr "type" "ishift")
12292    (set_attr "mode" "SI")])
12294 (define_insn "*lshrsi3_cmp_zext"
12295   [(set (reg FLAGS_REG)
12296         (compare
12297           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12298                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12299           (const_int 0)))
12300    (set (match_operand:DI 0 "register_operand" "=r")
12301         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12302   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12303    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12304    && (optimize_size
12305        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12306   "shr{l}\t{%2, %k0|%k0, %2}"
12307   [(set_attr "type" "ishift")
12308    (set_attr "mode" "SI")])
12310 (define_expand "lshrhi3"
12311   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12312         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12313                      (match_operand:QI 2 "nonmemory_operand" "")))
12314    (clobber (reg:CC FLAGS_REG))]
12315   "TARGET_HIMODE_MATH"
12316   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12318 (define_insn "*lshrhi3_1_one_bit"
12319   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12320         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12321                      (match_operand:QI 2 "const1_operand" "")))
12322    (clobber (reg:CC FLAGS_REG))]
12323   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12324    && (TARGET_SHIFT1 || optimize_size)"
12325   "shr{w}\t%0"
12326   [(set_attr "type" "ishift")
12327    (set (attr "length")
12328      (if_then_else (match_operand 0 "register_operand" "")
12329         (const_string "2")
12330         (const_string "*")))])
12332 (define_insn "*lshrhi3_1"
12333   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12334         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12335                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12336    (clobber (reg:CC FLAGS_REG))]
12337   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12338   "@
12339    shr{w}\t{%2, %0|%0, %2}
12340    shr{w}\t{%b2, %0|%0, %b2}"
12341   [(set_attr "type" "ishift")
12342    (set_attr "mode" "HI")])
12344 ;; This pattern can't accept a variable shift count, since shifts by
12345 ;; zero don't affect the flags.  We assume that shifts by constant
12346 ;; zero are optimized away.
12347 (define_insn "*lshrhi3_one_bit_cmp"
12348   [(set (reg FLAGS_REG)
12349         (compare
12350           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12351                        (match_operand:QI 2 "const1_operand" ""))
12352           (const_int 0)))
12353    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12354         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12355   "ix86_match_ccmode (insn, CCGOCmode)
12356    && (TARGET_SHIFT1 || optimize_size)
12357    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12358   "shr{w}\t%0"
12359   [(set_attr "type" "ishift")
12360    (set (attr "length")
12361      (if_then_else (match_operand:SI 0 "register_operand" "")
12362         (const_string "2")
12363         (const_string "*")))])
12365 (define_insn "*lshrhi3_one_bit_cconly"
12366   [(set (reg FLAGS_REG)
12367         (compare
12368           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12369                        (match_operand:QI 2 "const1_operand" ""))
12370           (const_int 0)))
12371    (clobber (match_scratch:HI 0 "=r"))]
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" "2")])
12379 ;; This pattern can't accept a variable shift count, since shifts by
12380 ;; zero don't affect the flags.  We assume that shifts by constant
12381 ;; zero are optimized away.
12382 (define_insn "*lshrhi3_cmp"
12383   [(set (reg FLAGS_REG)
12384         (compare
12385           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12386                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12387           (const_int 0)))
12388    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12389         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12390   "ix86_match_ccmode (insn, CCGOCmode)
12391    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12392    && (optimize_size
12393        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12394   "shr{w}\t{%2, %0|%0, %2}"
12395   [(set_attr "type" "ishift")
12396    (set_attr "mode" "HI")])
12398 (define_insn "*lshrhi3_cconly"
12399   [(set (reg FLAGS_REG)
12400         (compare
12401           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12402                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12403           (const_int 0)))
12404    (clobber (match_scratch:HI 0 "=r"))]
12405   "ix86_match_ccmode (insn, CCGOCmode)
12406    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12407    && (optimize_size
12408        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12409   "shr{w}\t{%2, %0|%0, %2}"
12410   [(set_attr "type" "ishift")
12411    (set_attr "mode" "HI")])
12413 (define_expand "lshrqi3"
12414   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12415         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12416                      (match_operand:QI 2 "nonmemory_operand" "")))
12417    (clobber (reg:CC FLAGS_REG))]
12418   "TARGET_QIMODE_MATH"
12419   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12421 (define_insn "*lshrqi3_1_one_bit"
12422   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12423         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12424                      (match_operand:QI 2 "const1_operand" "")))
12425    (clobber (reg:CC FLAGS_REG))]
12426   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12427    && (TARGET_SHIFT1 || optimize_size)"
12428   "shr{b}\t%0"
12429   [(set_attr "type" "ishift")
12430    (set (attr "length")
12431      (if_then_else (match_operand 0 "register_operand" "")
12432         (const_string "2")
12433         (const_string "*")))])
12435 (define_insn "*lshrqi3_1_one_bit_slp"
12436   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12437         (lshiftrt:QI (match_dup 0)
12438                      (match_operand:QI 1 "const1_operand" "")))
12439    (clobber (reg:CC FLAGS_REG))]
12440   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12441    && (TARGET_SHIFT1 || optimize_size)"
12442   "shr{b}\t%0"
12443   [(set_attr "type" "ishift1")
12444    (set (attr "length")
12445      (if_then_else (match_operand 0 "register_operand" "")
12446         (const_string "2")
12447         (const_string "*")))])
12449 (define_insn "*lshrqi3_1"
12450   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12451         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12452                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12453    (clobber (reg:CC FLAGS_REG))]
12454   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12455   "@
12456    shr{b}\t{%2, %0|%0, %2}
12457    shr{b}\t{%b2, %0|%0, %b2}"
12458   [(set_attr "type" "ishift")
12459    (set_attr "mode" "QI")])
12461 (define_insn "*lshrqi3_1_slp"
12462   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12463         (lshiftrt:QI (match_dup 0)
12464                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12465    (clobber (reg:CC FLAGS_REG))]
12466   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12468   "@
12469    shr{b}\t{%1, %0|%0, %1}
12470    shr{b}\t{%b1, %0|%0, %b1}"
12471   [(set_attr "type" "ishift1")
12472    (set_attr "mode" "QI")])
12474 ;; This pattern can't accept a variable shift count, since shifts by
12475 ;; zero don't affect the flags.  We assume that shifts by constant
12476 ;; zero are optimized away.
12477 (define_insn "*lshrqi2_one_bit_cmp"
12478   [(set (reg FLAGS_REG)
12479         (compare
12480           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12481                        (match_operand:QI 2 "const1_operand" ""))
12482           (const_int 0)))
12483    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12484         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12485   "ix86_match_ccmode (insn, CCGOCmode)
12486    && (TARGET_SHIFT1 || optimize_size)
12487    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12488   "shr{b}\t%0"
12489   [(set_attr "type" "ishift")
12490    (set (attr "length")
12491      (if_then_else (match_operand:SI 0 "register_operand" "")
12492         (const_string "2")
12493         (const_string "*")))])
12495 (define_insn "*lshrqi2_one_bit_cconly"
12496   [(set (reg FLAGS_REG)
12497         (compare
12498           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12499                        (match_operand:QI 2 "const1_operand" ""))
12500           (const_int 0)))
12501    (clobber (match_scratch:QI 0 "=q"))]
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" "2")])
12509 ;; This pattern can't accept a variable shift count, since shifts by
12510 ;; zero don't affect the flags.  We assume that shifts by constant
12511 ;; zero are optimized away.
12512 (define_insn "*lshrqi2_cmp"
12513   [(set (reg FLAGS_REG)
12514         (compare
12515           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12516                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12517           (const_int 0)))
12518    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12519         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12520   "ix86_match_ccmode (insn, CCGOCmode)
12521    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12522    && (optimize_size
12523        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12524   "shr{b}\t{%2, %0|%0, %2}"
12525   [(set_attr "type" "ishift")
12526    (set_attr "mode" "QI")])
12528 (define_insn "*lshrqi2_cconly"
12529   [(set (reg FLAGS_REG)
12530         (compare
12531           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12532                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12533           (const_int 0)))
12534    (clobber (match_scratch:QI 0 "=q"))]
12535   "ix86_match_ccmode (insn, CCGOCmode)
12536    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12537    && (optimize_size
12538        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12539   "shr{b}\t{%2, %0|%0, %2}"
12540   [(set_attr "type" "ishift")
12541    (set_attr "mode" "QI")])
12543 ;; Rotate instructions
12545 (define_expand "rotldi3"
12546   [(set (match_operand:DI 0 "shiftdi_operand" "")
12547         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12548                    (match_operand:QI 2 "nonmemory_operand" "")))
12549    (clobber (reg:CC FLAGS_REG))]
12550  ""
12552   if (TARGET_64BIT)
12553     {
12554       ix86_expand_binary_operator (ROTATE, DImode, operands);
12555       DONE;
12556     }
12557   if (!const_1_to_31_operand (operands[2], VOIDmode))
12558     FAIL;
12559   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12560   DONE;
12563 ;; Implement rotation using two double-precision shift instructions
12564 ;; and a scratch register.
12565 (define_insn_and_split "ix86_rotldi3"
12566  [(set (match_operand:DI 0 "register_operand" "=r")
12567        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12568                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12569   (clobber (reg:CC FLAGS_REG))
12570   (clobber (match_scratch:SI 3 "=&r"))]
12571  "!TARGET_64BIT"
12572  ""
12573  "&& reload_completed"
12574  [(set (match_dup 3) (match_dup 4))
12575   (parallel
12576    [(set (match_dup 4)
12577          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12578                  (lshiftrt:SI (match_dup 5)
12579                               (minus:QI (const_int 32) (match_dup 2)))))
12580     (clobber (reg:CC FLAGS_REG))])
12581   (parallel
12582    [(set (match_dup 5)
12583          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12584                  (lshiftrt:SI (match_dup 3)
12585                               (minus:QI (const_int 32) (match_dup 2)))))
12586     (clobber (reg:CC FLAGS_REG))])]
12587  "split_di (operands, 1, operands + 4, operands + 5);")
12589 (define_insn "*rotlsi3_1_one_bit_rex64"
12590   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12591         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12592                    (match_operand:QI 2 "const1_operand" "")))
12593    (clobber (reg:CC FLAGS_REG))]
12594   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12595    && (TARGET_SHIFT1 || optimize_size)"
12596   "rol{q}\t%0"
12597   [(set_attr "type" "rotate")
12598    (set (attr "length")
12599      (if_then_else (match_operand:DI 0 "register_operand" "")
12600         (const_string "2")
12601         (const_string "*")))])
12603 (define_insn "*rotldi3_1_rex64"
12604   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12605         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12606                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12607    (clobber (reg:CC FLAGS_REG))]
12608   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12609   "@
12610    rol{q}\t{%2, %0|%0, %2}
12611    rol{q}\t{%b2, %0|%0, %b2}"
12612   [(set_attr "type" "rotate")
12613    (set_attr "mode" "DI")])
12615 (define_expand "rotlsi3"
12616   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12617         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12618                    (match_operand:QI 2 "nonmemory_operand" "")))
12619    (clobber (reg:CC FLAGS_REG))]
12620   ""
12621   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12623 (define_insn "*rotlsi3_1_one_bit"
12624   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12625         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12626                    (match_operand:QI 2 "const1_operand" "")))
12627    (clobber (reg:CC FLAGS_REG))]
12628   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12629    && (TARGET_SHIFT1 || optimize_size)"
12630   "rol{l}\t%0"
12631   [(set_attr "type" "rotate")
12632    (set (attr "length")
12633      (if_then_else (match_operand:SI 0 "register_operand" "")
12634         (const_string "2")
12635         (const_string "*")))])
12637 (define_insn "*rotlsi3_1_one_bit_zext"
12638   [(set (match_operand:DI 0 "register_operand" "=r")
12639         (zero_extend:DI
12640           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12641                      (match_operand:QI 2 "const1_operand" ""))))
12642    (clobber (reg:CC FLAGS_REG))]
12643   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12644    && (TARGET_SHIFT1 || optimize_size)"
12645   "rol{l}\t%k0"
12646   [(set_attr "type" "rotate")
12647    (set_attr "length" "2")])
12649 (define_insn "*rotlsi3_1"
12650   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12651         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12652                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12653    (clobber (reg:CC FLAGS_REG))]
12654   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12655   "@
12656    rol{l}\t{%2, %0|%0, %2}
12657    rol{l}\t{%b2, %0|%0, %b2}"
12658   [(set_attr "type" "rotate")
12659    (set_attr "mode" "SI")])
12661 (define_insn "*rotlsi3_1_zext"
12662   [(set (match_operand:DI 0 "register_operand" "=r,r")
12663         (zero_extend:DI
12664           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12665                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12666    (clobber (reg:CC FLAGS_REG))]
12667   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12668   "@
12669    rol{l}\t{%2, %k0|%k0, %2}
12670    rol{l}\t{%b2, %k0|%k0, %b2}"
12671   [(set_attr "type" "rotate")
12672    (set_attr "mode" "SI")])
12674 (define_expand "rotlhi3"
12675   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12676         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12677                    (match_operand:QI 2 "nonmemory_operand" "")))
12678    (clobber (reg:CC FLAGS_REG))]
12679   "TARGET_HIMODE_MATH"
12680   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12682 (define_insn "*rotlhi3_1_one_bit"
12683   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12684         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12685                    (match_operand:QI 2 "const1_operand" "")))
12686    (clobber (reg:CC FLAGS_REG))]
12687   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12688    && (TARGET_SHIFT1 || optimize_size)"
12689   "rol{w}\t%0"
12690   [(set_attr "type" "rotate")
12691    (set (attr "length")
12692      (if_then_else (match_operand 0 "register_operand" "")
12693         (const_string "2")
12694         (const_string "*")))])
12696 (define_insn "*rotlhi3_1"
12697   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12698         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12699                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12700    (clobber (reg:CC FLAGS_REG))]
12701   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12702   "@
12703    rol{w}\t{%2, %0|%0, %2}
12704    rol{w}\t{%b2, %0|%0, %b2}"
12705   [(set_attr "type" "rotate")
12706    (set_attr "mode" "HI")])
12708 (define_expand "rotlqi3"
12709   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12710         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12711                    (match_operand:QI 2 "nonmemory_operand" "")))
12712    (clobber (reg:CC FLAGS_REG))]
12713   "TARGET_QIMODE_MATH"
12714   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12716 (define_insn "*rotlqi3_1_one_bit_slp"
12717   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12718         (rotate:QI (match_dup 0)
12719                    (match_operand:QI 1 "const1_operand" "")))
12720    (clobber (reg:CC FLAGS_REG))]
12721   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12722    && (TARGET_SHIFT1 || optimize_size)"
12723   "rol{b}\t%0"
12724   [(set_attr "type" "rotate1")
12725    (set (attr "length")
12726      (if_then_else (match_operand 0 "register_operand" "")
12727         (const_string "2")
12728         (const_string "*")))])
12730 (define_insn "*rotlqi3_1_one_bit"
12731   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12732         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12733                    (match_operand:QI 2 "const1_operand" "")))
12734    (clobber (reg:CC FLAGS_REG))]
12735   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12736    && (TARGET_SHIFT1 || optimize_size)"
12737   "rol{b}\t%0"
12738   [(set_attr "type" "rotate")
12739    (set (attr "length")
12740      (if_then_else (match_operand 0 "register_operand" "")
12741         (const_string "2")
12742         (const_string "*")))])
12744 (define_insn "*rotlqi3_1_slp"
12745   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12746         (rotate:QI (match_dup 0)
12747                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12748    (clobber (reg:CC FLAGS_REG))]
12749   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12750    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12751   "@
12752    rol{b}\t{%1, %0|%0, %1}
12753    rol{b}\t{%b1, %0|%0, %b1}"
12754   [(set_attr "type" "rotate1")
12755    (set_attr "mode" "QI")])
12757 (define_insn "*rotlqi3_1"
12758   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12759         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12760                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12761    (clobber (reg:CC FLAGS_REG))]
12762   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12763   "@
12764    rol{b}\t{%2, %0|%0, %2}
12765    rol{b}\t{%b2, %0|%0, %b2}"
12766   [(set_attr "type" "rotate")
12767    (set_attr "mode" "QI")])
12769 (define_expand "rotrdi3"
12770   [(set (match_operand:DI 0 "shiftdi_operand" "")
12771         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12772                    (match_operand:QI 2 "nonmemory_operand" "")))
12773    (clobber (reg:CC FLAGS_REG))]
12774  ""
12776   if (TARGET_64BIT)
12777     {
12778       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12779       DONE;
12780     }
12781   if (!const_1_to_31_operand (operands[2], VOIDmode))
12782     FAIL;
12783   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12784   DONE;
12787 ;; Implement rotation using two double-precision shift instructions
12788 ;; and a scratch register.
12789 (define_insn_and_split "ix86_rotrdi3"
12790  [(set (match_operand:DI 0 "register_operand" "=r")
12791        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12792                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12793   (clobber (reg:CC FLAGS_REG))
12794   (clobber (match_scratch:SI 3 "=&r"))]
12795  "!TARGET_64BIT"
12796  ""
12797  "&& reload_completed"
12798  [(set (match_dup 3) (match_dup 4))
12799   (parallel
12800    [(set (match_dup 4)
12801          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12802                  (ashift:SI (match_dup 5)
12803                             (minus:QI (const_int 32) (match_dup 2)))))
12804     (clobber (reg:CC FLAGS_REG))])
12805   (parallel
12806    [(set (match_dup 5)
12807          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12808                  (ashift:SI (match_dup 3)
12809                             (minus:QI (const_int 32) (match_dup 2)))))
12810     (clobber (reg:CC FLAGS_REG))])]
12811  "split_di (operands, 1, operands + 4, operands + 5);")
12813 (define_insn "*rotrdi3_1_one_bit_rex64"
12814   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12815         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12816                      (match_operand:QI 2 "const1_operand" "")))
12817    (clobber (reg:CC FLAGS_REG))]
12818   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12819    && (TARGET_SHIFT1 || optimize_size)"
12820   "ror{q}\t%0"
12821   [(set_attr "type" "rotate")
12822    (set (attr "length")
12823      (if_then_else (match_operand:DI 0 "register_operand" "")
12824         (const_string "2")
12825         (const_string "*")))])
12827 (define_insn "*rotrdi3_1_rex64"
12828   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12829         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12830                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12831    (clobber (reg:CC FLAGS_REG))]
12832   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12833   "@
12834    ror{q}\t{%2, %0|%0, %2}
12835    ror{q}\t{%b2, %0|%0, %b2}"
12836   [(set_attr "type" "rotate")
12837    (set_attr "mode" "DI")])
12839 (define_expand "rotrsi3"
12840   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12841         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12842                      (match_operand:QI 2 "nonmemory_operand" "")))
12843    (clobber (reg:CC FLAGS_REG))]
12844   ""
12845   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12847 (define_insn "*rotrsi3_1_one_bit"
12848   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12849         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12850                      (match_operand:QI 2 "const1_operand" "")))
12851    (clobber (reg:CC FLAGS_REG))]
12852   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12853    && (TARGET_SHIFT1 || optimize_size)"
12854   "ror{l}\t%0"
12855   [(set_attr "type" "rotate")
12856    (set (attr "length")
12857      (if_then_else (match_operand:SI 0 "register_operand" "")
12858         (const_string "2")
12859         (const_string "*")))])
12861 (define_insn "*rotrsi3_1_one_bit_zext"
12862   [(set (match_operand:DI 0 "register_operand" "=r")
12863         (zero_extend:DI
12864           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12865                        (match_operand:QI 2 "const1_operand" ""))))
12866    (clobber (reg:CC FLAGS_REG))]
12867   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12868    && (TARGET_SHIFT1 || optimize_size)"
12869   "ror{l}\t%k0"
12870   [(set_attr "type" "rotate")
12871    (set (attr "length")
12872      (if_then_else (match_operand:SI 0 "register_operand" "")
12873         (const_string "2")
12874         (const_string "*")))])
12876 (define_insn "*rotrsi3_1"
12877   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12878         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12879                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12880    (clobber (reg:CC FLAGS_REG))]
12881   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12882   "@
12883    ror{l}\t{%2, %0|%0, %2}
12884    ror{l}\t{%b2, %0|%0, %b2}"
12885   [(set_attr "type" "rotate")
12886    (set_attr "mode" "SI")])
12888 (define_insn "*rotrsi3_1_zext"
12889   [(set (match_operand:DI 0 "register_operand" "=r,r")
12890         (zero_extend:DI
12891           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12892                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12893    (clobber (reg:CC FLAGS_REG))]
12894   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12895   "@
12896    ror{l}\t{%2, %k0|%k0, %2}
12897    ror{l}\t{%b2, %k0|%k0, %b2}"
12898   [(set_attr "type" "rotate")
12899    (set_attr "mode" "SI")])
12901 (define_expand "rotrhi3"
12902   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12903         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12904                      (match_operand:QI 2 "nonmemory_operand" "")))
12905    (clobber (reg:CC FLAGS_REG))]
12906   "TARGET_HIMODE_MATH"
12907   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12909 (define_insn "*rotrhi3_one_bit"
12910   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12911         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12912                      (match_operand:QI 2 "const1_operand" "")))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12915    && (TARGET_SHIFT1 || optimize_size)"
12916   "ror{w}\t%0"
12917   [(set_attr "type" "rotate")
12918    (set (attr "length")
12919      (if_then_else (match_operand 0 "register_operand" "")
12920         (const_string "2")
12921         (const_string "*")))])
12923 (define_insn "*rotrhi3"
12924   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12925         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12926                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12927    (clobber (reg:CC FLAGS_REG))]
12928   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12929   "@
12930    ror{w}\t{%2, %0|%0, %2}
12931    ror{w}\t{%b2, %0|%0, %b2}"
12932   [(set_attr "type" "rotate")
12933    (set_attr "mode" "HI")])
12935 (define_expand "rotrqi3"
12936   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12937         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12938                      (match_operand:QI 2 "nonmemory_operand" "")))
12939    (clobber (reg:CC FLAGS_REG))]
12940   "TARGET_QIMODE_MATH"
12941   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12943 (define_insn "*rotrqi3_1_one_bit"
12944   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12945         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12946                      (match_operand:QI 2 "const1_operand" "")))
12947    (clobber (reg:CC FLAGS_REG))]
12948   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12949    && (TARGET_SHIFT1 || optimize_size)"
12950   "ror{b}\t%0"
12951   [(set_attr "type" "rotate")
12952    (set (attr "length")
12953      (if_then_else (match_operand 0 "register_operand" "")
12954         (const_string "2")
12955         (const_string "*")))])
12957 (define_insn "*rotrqi3_1_one_bit_slp"
12958   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12959         (rotatert:QI (match_dup 0)
12960                      (match_operand:QI 1 "const1_operand" "")))
12961    (clobber (reg:CC FLAGS_REG))]
12962   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12963    && (TARGET_SHIFT1 || optimize_size)"
12964   "ror{b}\t%0"
12965   [(set_attr "type" "rotate1")
12966    (set (attr "length")
12967      (if_then_else (match_operand 0 "register_operand" "")
12968         (const_string "2")
12969         (const_string "*")))])
12971 (define_insn "*rotrqi3_1"
12972   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12973         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12974                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12975    (clobber (reg:CC FLAGS_REG))]
12976   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12977   "@
12978    ror{b}\t{%2, %0|%0, %2}
12979    ror{b}\t{%b2, %0|%0, %b2}"
12980   [(set_attr "type" "rotate")
12981    (set_attr "mode" "QI")])
12983 (define_insn "*rotrqi3_1_slp"
12984   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12985         (rotatert:QI (match_dup 0)
12986                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12987    (clobber (reg:CC FLAGS_REG))]
12988   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12989    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12990   "@
12991    ror{b}\t{%1, %0|%0, %1}
12992    ror{b}\t{%b1, %0|%0, %b1}"
12993   [(set_attr "type" "rotate1")
12994    (set_attr "mode" "QI")])
12996 ;; Bit set / bit test instructions
12998 (define_expand "extv"
12999   [(set (match_operand:SI 0 "register_operand" "")
13000         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13001                          (match_operand:SI 2 "const8_operand" "")
13002                          (match_operand:SI 3 "const8_operand" "")))]
13003   ""
13005   /* Handle extractions from %ah et al.  */
13006   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13007     FAIL;
13009   /* From mips.md: extract_bit_field doesn't verify that our source
13010      matches the predicate, so check it again here.  */
13011   if (! ext_register_operand (operands[1], VOIDmode))
13012     FAIL;
13015 (define_expand "extzv"
13016   [(set (match_operand:SI 0 "register_operand" "")
13017         (zero_extract:SI (match_operand 1 "ext_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 "insv"
13033   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13034                       (match_operand 1 "const8_operand" "")
13035                       (match_operand 2 "const8_operand" ""))
13036         (match_operand 3 "register_operand" ""))]
13037   ""
13039   /* Handle insertions to %ah et al.  */
13040   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13041     FAIL;
13043   /* From mips.md: insert_bit_field doesn't verify that our source
13044      matches the predicate, so check it again here.  */
13045   if (! ext_register_operand (operands[0], VOIDmode))
13046     FAIL;
13048   if (TARGET_64BIT)
13049     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13050   else
13051     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13053   DONE;
13056 ;; %%% bts, btr, btc, bt.
13057 ;; In general these instructions are *slow* when applied to memory,
13058 ;; since they enforce atomic operation.  When applied to registers,
13059 ;; it depends on the cpu implementation.  They're never faster than
13060 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13061 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13062 ;; within the instruction itself, so operating on bits in the high
13063 ;; 32-bits of a register becomes easier.
13065 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13066 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13067 ;; negdf respectively, so they can never be disabled entirely.
13069 (define_insn "*btsq"
13070   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13071                          (const_int 1)
13072                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13073         (const_int 1))
13074    (clobber (reg:CC FLAGS_REG))]
13075   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13076   "bts{q} %1,%0"
13077   [(set_attr "type" "alu1")])
13079 (define_insn "*btrq"
13080   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13081                          (const_int 1)
13082                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13083         (const_int 0))
13084    (clobber (reg:CC FLAGS_REG))]
13085   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13086   "btr{q} %1,%0"
13087   [(set_attr "type" "alu1")])
13089 (define_insn "*btcq"
13090   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13091                          (const_int 1)
13092                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13093         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13094    (clobber (reg:CC FLAGS_REG))]
13095   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13096   "btc{q} %1,%0"
13097   [(set_attr "type" "alu1")])
13099 ;; Allow Nocona to avoid these instructions if a register is available.
13101 (define_peephole2
13102   [(match_scratch:DI 2 "r")
13103    (parallel [(set (zero_extract:DI
13104                      (match_operand:DI 0 "register_operand" "")
13105                      (const_int 1)
13106                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13107                    (const_int 1))
13108               (clobber (reg:CC FLAGS_REG))])]
13109   "TARGET_64BIT && !TARGET_USE_BT"
13110   [(const_int 0)]
13112   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13113   rtx op1;
13115   if (HOST_BITS_PER_WIDE_INT >= 64)
13116     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13117   else if (i < HOST_BITS_PER_WIDE_INT)
13118     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13119   else
13120     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13122   op1 = immed_double_const (lo, hi, DImode);
13123   if (i >= 31)
13124     {
13125       emit_move_insn (operands[2], op1);
13126       op1 = operands[2];
13127     }
13129   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13130   DONE;
13133 (define_peephole2
13134   [(match_scratch:DI 2 "r")
13135    (parallel [(set (zero_extract:DI
13136                      (match_operand:DI 0 "register_operand" "")
13137                      (const_int 1)
13138                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13139                    (const_int 0))
13140               (clobber (reg:CC FLAGS_REG))])]
13141   "TARGET_64BIT && !TARGET_USE_BT"
13142   [(const_int 0)]
13144   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13145   rtx op1;
13147   if (HOST_BITS_PER_WIDE_INT >= 64)
13148     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13149   else if (i < HOST_BITS_PER_WIDE_INT)
13150     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13151   else
13152     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13154   op1 = immed_double_const (~lo, ~hi, DImode);
13155   if (i >= 32)
13156     {
13157       emit_move_insn (operands[2], op1);
13158       op1 = operands[2];
13159     }
13161   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13162   DONE;
13165 (define_peephole2
13166   [(match_scratch:DI 2 "r")
13167    (parallel [(set (zero_extract:DI
13168                      (match_operand:DI 0 "register_operand" "")
13169                      (const_int 1)
13170                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13171               (not:DI (zero_extract:DI
13172                         (match_dup 0) (const_int 1) (match_dup 1))))
13173               (clobber (reg:CC FLAGS_REG))])]
13174   "TARGET_64BIT && !TARGET_USE_BT"
13175   [(const_int 0)]
13177   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13178   rtx op1;
13180   if (HOST_BITS_PER_WIDE_INT >= 64)
13181     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13182   else if (i < HOST_BITS_PER_WIDE_INT)
13183     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13184   else
13185     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13187   op1 = immed_double_const (lo, hi, DImode);
13188   if (i >= 31)
13189     {
13190       emit_move_insn (operands[2], op1);
13191       op1 = operands[2];
13192     }
13194   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13195   DONE;
13198 ;; Store-flag instructions.
13200 ;; For all sCOND expanders, also expand the compare or test insn that
13201 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13203 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13204 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13205 ;; way, which can later delete the movzx if only QImode is needed.
13207 (define_expand "seq"
13208   [(set (match_operand:QI 0 "register_operand" "")
13209         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13210   ""
13211   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13213 (define_expand "sne"
13214   [(set (match_operand:QI 0 "register_operand" "")
13215         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13216   ""
13217   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13219 (define_expand "sgt"
13220   [(set (match_operand:QI 0 "register_operand" "")
13221         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13222   ""
13223   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13225 (define_expand "sgtu"
13226   [(set (match_operand:QI 0 "register_operand" "")
13227         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13228   ""
13229   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13231 (define_expand "slt"
13232   [(set (match_operand:QI 0 "register_operand" "")
13233         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13234   ""
13235   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13237 (define_expand "sltu"
13238   [(set (match_operand:QI 0 "register_operand" "")
13239         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13240   ""
13241   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13243 (define_expand "sge"
13244   [(set (match_operand:QI 0 "register_operand" "")
13245         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13246   ""
13247   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13249 (define_expand "sgeu"
13250   [(set (match_operand:QI 0 "register_operand" "")
13251         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252   ""
13253   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13255 (define_expand "sle"
13256   [(set (match_operand:QI 0 "register_operand" "")
13257         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258   ""
13259   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13261 (define_expand "sleu"
13262   [(set (match_operand:QI 0 "register_operand" "")
13263         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264   ""
13265   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13267 (define_expand "sunordered"
13268   [(set (match_operand:QI 0 "register_operand" "")
13269         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13270   "TARGET_80387 || TARGET_SSE"
13271   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13273 (define_expand "sordered"
13274   [(set (match_operand:QI 0 "register_operand" "")
13275         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13276   "TARGET_80387"
13277   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13279 (define_expand "suneq"
13280   [(set (match_operand:QI 0 "register_operand" "")
13281         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13282   "TARGET_80387 || TARGET_SSE"
13283   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13285 (define_expand "sunge"
13286   [(set (match_operand:QI 0 "register_operand" "")
13287         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13288   "TARGET_80387 || TARGET_SSE"
13289   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13291 (define_expand "sungt"
13292   [(set (match_operand:QI 0 "register_operand" "")
13293         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294   "TARGET_80387 || TARGET_SSE"
13295   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13297 (define_expand "sunle"
13298   [(set (match_operand:QI 0 "register_operand" "")
13299         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13300   "TARGET_80387 || TARGET_SSE"
13301   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13303 (define_expand "sunlt"
13304   [(set (match_operand:QI 0 "register_operand" "")
13305         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13306   "TARGET_80387 || TARGET_SSE"
13307   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13309 (define_expand "sltgt"
13310   [(set (match_operand:QI 0 "register_operand" "")
13311         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13312   "TARGET_80387 || TARGET_SSE"
13313   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13315 (define_insn "*setcc_1"
13316   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13317         (match_operator:QI 1 "ix86_comparison_operator"
13318           [(reg FLAGS_REG) (const_int 0)]))]
13319   ""
13320   "set%C1\t%0"
13321   [(set_attr "type" "setcc")
13322    (set_attr "mode" "QI")])
13324 (define_insn "*setcc_2"
13325   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13326         (match_operator:QI 1 "ix86_comparison_operator"
13327           [(reg FLAGS_REG) (const_int 0)]))]
13328   ""
13329   "set%C1\t%0"
13330   [(set_attr "type" "setcc")
13331    (set_attr "mode" "QI")])
13333 ;; In general it is not safe to assume too much about CCmode registers,
13334 ;; so simplify-rtx stops when it sees a second one.  Under certain
13335 ;; conditions this is safe on x86, so help combine not create
13337 ;;      seta    %al
13338 ;;      testb   %al, %al
13339 ;;      sete    %al
13341 (define_split
13342   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13343         (ne:QI (match_operator 1 "ix86_comparison_operator"
13344                  [(reg FLAGS_REG) (const_int 0)])
13345             (const_int 0)))]
13346   ""
13347   [(set (match_dup 0) (match_dup 1))]
13349   PUT_MODE (operands[1], QImode);
13352 (define_split
13353   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13354         (ne:QI (match_operator 1 "ix86_comparison_operator"
13355                  [(reg FLAGS_REG) (const_int 0)])
13356             (const_int 0)))]
13357   ""
13358   [(set (match_dup 0) (match_dup 1))]
13360   PUT_MODE (operands[1], QImode);
13363 (define_split
13364   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13365         (eq:QI (match_operator 1 "ix86_comparison_operator"
13366                  [(reg FLAGS_REG) (const_int 0)])
13367             (const_int 0)))]
13368   ""
13369   [(set (match_dup 0) (match_dup 1))]
13371   rtx new_op1 = copy_rtx (operands[1]);
13372   operands[1] = new_op1;
13373   PUT_MODE (new_op1, QImode);
13374   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13375                                              GET_MODE (XEXP (new_op1, 0))));
13377   /* Make sure that (a) the CCmode we have for the flags is strong
13378      enough for the reversed compare or (b) we have a valid FP compare.  */
13379   if (! ix86_comparison_operator (new_op1, VOIDmode))
13380     FAIL;
13383 (define_split
13384   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13385         (eq:QI (match_operator 1 "ix86_comparison_operator"
13386                  [(reg FLAGS_REG) (const_int 0)])
13387             (const_int 0)))]
13388   ""
13389   [(set (match_dup 0) (match_dup 1))]
13391   rtx new_op1 = copy_rtx (operands[1]);
13392   operands[1] = new_op1;
13393   PUT_MODE (new_op1, QImode);
13394   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13395                                              GET_MODE (XEXP (new_op1, 0))));
13397   /* Make sure that (a) the CCmode we have for the flags is strong
13398      enough for the reversed compare or (b) we have a valid FP compare.  */
13399   if (! ix86_comparison_operator (new_op1, VOIDmode))
13400     FAIL;
13403 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13404 ;; subsequent logical operations are used to imitate conditional moves.
13405 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13406 ;; it directly.
13408 (define_insn "*sse_setccsf"
13409   [(set (match_operand:SF 0 "register_operand" "=x")
13410         (match_operator:SF 1 "sse_comparison_operator"
13411           [(match_operand:SF 2 "register_operand" "0")
13412            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13413   "TARGET_SSE"
13414   "cmp%D1ss\t{%3, %0|%0, %3}"
13415   [(set_attr "type" "ssecmp")
13416    (set_attr "mode" "SF")])
13418 (define_insn "*sse_setccdf"
13419   [(set (match_operand:DF 0 "register_operand" "=Y")
13420         (match_operator:DF 1 "sse_comparison_operator"
13421           [(match_operand:DF 2 "register_operand" "0")
13422            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13423   "TARGET_SSE2"
13424   "cmp%D1sd\t{%3, %0|%0, %3}"
13425   [(set_attr "type" "ssecmp")
13426    (set_attr "mode" "DF")])
13428 ;; Basic conditional jump instructions.
13429 ;; We ignore the overflow flag for signed branch instructions.
13431 ;; For all bCOND expanders, also expand the compare or test insn that
13432 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13434 (define_expand "beq"
13435   [(set (pc)
13436         (if_then_else (match_dup 1)
13437                       (label_ref (match_operand 0 "" ""))
13438                       (pc)))]
13439   ""
13440   "ix86_expand_branch (EQ, operands[0]); DONE;")
13442 (define_expand "bne"
13443   [(set (pc)
13444         (if_then_else (match_dup 1)
13445                       (label_ref (match_operand 0 "" ""))
13446                       (pc)))]
13447   ""
13448   "ix86_expand_branch (NE, operands[0]); DONE;")
13450 (define_expand "bgt"
13451   [(set (pc)
13452         (if_then_else (match_dup 1)
13453                       (label_ref (match_operand 0 "" ""))
13454                       (pc)))]
13455   ""
13456   "ix86_expand_branch (GT, operands[0]); DONE;")
13458 (define_expand "bgtu"
13459   [(set (pc)
13460         (if_then_else (match_dup 1)
13461                       (label_ref (match_operand 0 "" ""))
13462                       (pc)))]
13463   ""
13464   "ix86_expand_branch (GTU, operands[0]); DONE;")
13466 (define_expand "blt"
13467   [(set (pc)
13468         (if_then_else (match_dup 1)
13469                       (label_ref (match_operand 0 "" ""))
13470                       (pc)))]
13471   ""
13472   "ix86_expand_branch (LT, operands[0]); DONE;")
13474 (define_expand "bltu"
13475   [(set (pc)
13476         (if_then_else (match_dup 1)
13477                       (label_ref (match_operand 0 "" ""))
13478                       (pc)))]
13479   ""
13480   "ix86_expand_branch (LTU, operands[0]); DONE;")
13482 (define_expand "bge"
13483   [(set (pc)
13484         (if_then_else (match_dup 1)
13485                       (label_ref (match_operand 0 "" ""))
13486                       (pc)))]
13487   ""
13488   "ix86_expand_branch (GE, operands[0]); DONE;")
13490 (define_expand "bgeu"
13491   [(set (pc)
13492         (if_then_else (match_dup 1)
13493                       (label_ref (match_operand 0 "" ""))
13494                       (pc)))]
13495   ""
13496   "ix86_expand_branch (GEU, operands[0]); DONE;")
13498 (define_expand "ble"
13499   [(set (pc)
13500         (if_then_else (match_dup 1)
13501                       (label_ref (match_operand 0 "" ""))
13502                       (pc)))]
13503   ""
13504   "ix86_expand_branch (LE, operands[0]); DONE;")
13506 (define_expand "bleu"
13507   [(set (pc)
13508         (if_then_else (match_dup 1)
13509                       (label_ref (match_operand 0 "" ""))
13510                       (pc)))]
13511   ""
13512   "ix86_expand_branch (LEU, operands[0]); DONE;")
13514 (define_expand "bunordered"
13515   [(set (pc)
13516         (if_then_else (match_dup 1)
13517                       (label_ref (match_operand 0 "" ""))
13518                       (pc)))]
13519   "TARGET_80387 || TARGET_SSE_MATH"
13520   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13522 (define_expand "bordered"
13523   [(set (pc)
13524         (if_then_else (match_dup 1)
13525                       (label_ref (match_operand 0 "" ""))
13526                       (pc)))]
13527   "TARGET_80387 || TARGET_SSE_MATH"
13528   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13530 (define_expand "buneq"
13531   [(set (pc)
13532         (if_then_else (match_dup 1)
13533                       (label_ref (match_operand 0 "" ""))
13534                       (pc)))]
13535   "TARGET_80387 || TARGET_SSE_MATH"
13536   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13538 (define_expand "bunge"
13539   [(set (pc)
13540         (if_then_else (match_dup 1)
13541                       (label_ref (match_operand 0 "" ""))
13542                       (pc)))]
13543   "TARGET_80387 || TARGET_SSE_MATH"
13544   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13546 (define_expand "bungt"
13547   [(set (pc)
13548         (if_then_else (match_dup 1)
13549                       (label_ref (match_operand 0 "" ""))
13550                       (pc)))]
13551   "TARGET_80387 || TARGET_SSE_MATH"
13552   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13554 (define_expand "bunle"
13555   [(set (pc)
13556         (if_then_else (match_dup 1)
13557                       (label_ref (match_operand 0 "" ""))
13558                       (pc)))]
13559   "TARGET_80387 || TARGET_SSE_MATH"
13560   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13562 (define_expand "bunlt"
13563   [(set (pc)
13564         (if_then_else (match_dup 1)
13565                       (label_ref (match_operand 0 "" ""))
13566                       (pc)))]
13567   "TARGET_80387 || TARGET_SSE_MATH"
13568   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13570 (define_expand "bltgt"
13571   [(set (pc)
13572         (if_then_else (match_dup 1)
13573                       (label_ref (match_operand 0 "" ""))
13574                       (pc)))]
13575   "TARGET_80387 || TARGET_SSE_MATH"
13576   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13578 (define_insn "*jcc_1"
13579   [(set (pc)
13580         (if_then_else (match_operator 1 "ix86_comparison_operator"
13581                                       [(reg FLAGS_REG) (const_int 0)])
13582                       (label_ref (match_operand 0 "" ""))
13583                       (pc)))]
13584   ""
13585   "%+j%C1\t%l0"
13586   [(set_attr "type" "ibr")
13587    (set_attr "modrm" "0")
13588    (set (attr "length")
13589            (if_then_else (and (ge (minus (match_dup 0) (pc))
13590                                   (const_int -126))
13591                               (lt (minus (match_dup 0) (pc))
13592                                   (const_int 128)))
13593              (const_int 2)
13594              (const_int 6)))])
13596 (define_insn "*jcc_2"
13597   [(set (pc)
13598         (if_then_else (match_operator 1 "ix86_comparison_operator"
13599                                       [(reg FLAGS_REG) (const_int 0)])
13600                       (pc)
13601                       (label_ref (match_operand 0 "" ""))))]
13602   ""
13603   "%+j%c1\t%l0"
13604   [(set_attr "type" "ibr")
13605    (set_attr "modrm" "0")
13606    (set (attr "length")
13607            (if_then_else (and (ge (minus (match_dup 0) (pc))
13608                                   (const_int -126))
13609                               (lt (minus (match_dup 0) (pc))
13610                                   (const_int 128)))
13611              (const_int 2)
13612              (const_int 6)))])
13614 ;; In general it is not safe to assume too much about CCmode registers,
13615 ;; so simplify-rtx stops when it sees a second one.  Under certain
13616 ;; conditions this is safe on x86, so help combine not create
13618 ;;      seta    %al
13619 ;;      testb   %al, %al
13620 ;;      je      Lfoo
13622 (define_split
13623   [(set (pc)
13624         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13625                                       [(reg FLAGS_REG) (const_int 0)])
13626                           (const_int 0))
13627                       (label_ref (match_operand 1 "" ""))
13628                       (pc)))]
13629   ""
13630   [(set (pc)
13631         (if_then_else (match_dup 0)
13632                       (label_ref (match_dup 1))
13633                       (pc)))]
13635   PUT_MODE (operands[0], VOIDmode);
13638 (define_split
13639   [(set (pc)
13640         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13641                                       [(reg FLAGS_REG) (const_int 0)])
13642                           (const_int 0))
13643                       (label_ref (match_operand 1 "" ""))
13644                       (pc)))]
13645   ""
13646   [(set (pc)
13647         (if_then_else (match_dup 0)
13648                       (label_ref (match_dup 1))
13649                       (pc)))]
13651   rtx new_op0 = copy_rtx (operands[0]);
13652   operands[0] = new_op0;
13653   PUT_MODE (new_op0, VOIDmode);
13654   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13655                                              GET_MODE (XEXP (new_op0, 0))));
13657   /* Make sure that (a) the CCmode we have for the flags is strong
13658      enough for the reversed compare or (b) we have a valid FP compare.  */
13659   if (! ix86_comparison_operator (new_op0, VOIDmode))
13660     FAIL;
13663 ;; Define combination compare-and-branch fp compare instructions to use
13664 ;; during early optimization.  Splitting the operation apart early makes
13665 ;; for bad code when we want to reverse the operation.
13667 (define_insn "*fp_jcc_1_mixed"
13668   [(set (pc)
13669         (if_then_else (match_operator 0 "comparison_operator"
13670                         [(match_operand 1 "register_operand" "f,x")
13671                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13672           (label_ref (match_operand 3 "" ""))
13673           (pc)))
13674    (clobber (reg:CCFP FPSR_REG))
13675    (clobber (reg:CCFP FLAGS_REG))]
13676   "TARGET_MIX_SSE_I387
13677    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13678    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13679    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13680   "#")
13682 (define_insn "*fp_jcc_1_sse"
13683   [(set (pc)
13684         (if_then_else (match_operator 0 "comparison_operator"
13685                         [(match_operand 1 "register_operand" "x")
13686                          (match_operand 2 "nonimmediate_operand" "xm")])
13687           (label_ref (match_operand 3 "" ""))
13688           (pc)))
13689    (clobber (reg:CCFP FPSR_REG))
13690    (clobber (reg:CCFP FLAGS_REG))]
13691   "TARGET_SSE_MATH
13692    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13693    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13694    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13695   "#")
13697 (define_insn "*fp_jcc_1_387"
13698   [(set (pc)
13699         (if_then_else (match_operator 0 "comparison_operator"
13700                         [(match_operand 1 "register_operand" "f")
13701                          (match_operand 2 "register_operand" "f")])
13702           (label_ref (match_operand 3 "" ""))
13703           (pc)))
13704    (clobber (reg:CCFP FPSR_REG))
13705    (clobber (reg:CCFP FLAGS_REG))]
13706   "TARGET_CMOVE && TARGET_80387
13707    && FLOAT_MODE_P (GET_MODE (operands[1]))
13708    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13709    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13710   "#")
13712 (define_insn "*fp_jcc_2_mixed"
13713   [(set (pc)
13714         (if_then_else (match_operator 0 "comparison_operator"
13715                         [(match_operand 1 "register_operand" "f,x")
13716                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13717           (pc)
13718           (label_ref (match_operand 3 "" ""))))
13719    (clobber (reg:CCFP FPSR_REG))
13720    (clobber (reg:CCFP FLAGS_REG))]
13721   "TARGET_MIX_SSE_I387
13722    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13723    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13724    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13725   "#")
13727 (define_insn "*fp_jcc_2_sse"
13728   [(set (pc)
13729         (if_then_else (match_operator 0 "comparison_operator"
13730                         [(match_operand 1 "register_operand" "x")
13731                          (match_operand 2 "nonimmediate_operand" "xm")])
13732           (pc)
13733           (label_ref (match_operand 3 "" ""))))
13734    (clobber (reg:CCFP FPSR_REG))
13735    (clobber (reg:CCFP FLAGS_REG))]
13736   "TARGET_SSE_MATH
13737    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13738    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13739    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13740   "#")
13742 (define_insn "*fp_jcc_2_387"
13743   [(set (pc)
13744         (if_then_else (match_operator 0 "comparison_operator"
13745                         [(match_operand 1 "register_operand" "f")
13746                          (match_operand 2 "register_operand" "f")])
13747           (pc)
13748           (label_ref (match_operand 3 "" ""))))
13749    (clobber (reg:CCFP FPSR_REG))
13750    (clobber (reg:CCFP FLAGS_REG))]
13751   "TARGET_CMOVE && TARGET_80387
13752    && FLOAT_MODE_P (GET_MODE (operands[1]))
13753    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13754    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13755   "#")
13757 (define_insn "*fp_jcc_3_387"
13758   [(set (pc)
13759         (if_then_else (match_operator 0 "comparison_operator"
13760                         [(match_operand 1 "register_operand" "f")
13761                          (match_operand 2 "nonimmediate_operand" "fm")])
13762           (label_ref (match_operand 3 "" ""))
13763           (pc)))
13764    (clobber (reg:CCFP FPSR_REG))
13765    (clobber (reg:CCFP FLAGS_REG))
13766    (clobber (match_scratch:HI 4 "=a"))]
13767   "TARGET_80387
13768    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13769    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13770    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13771    && SELECT_CC_MODE (GET_CODE (operands[0]),
13772                       operands[1], operands[2]) == CCFPmode
13773    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13774   "#")
13776 (define_insn "*fp_jcc_4_387"
13777   [(set (pc)
13778         (if_then_else (match_operator 0 "comparison_operator"
13779                         [(match_operand 1 "register_operand" "f")
13780                          (match_operand 2 "nonimmediate_operand" "fm")])
13781           (pc)
13782           (label_ref (match_operand 3 "" ""))))
13783    (clobber (reg:CCFP FPSR_REG))
13784    (clobber (reg:CCFP FLAGS_REG))
13785    (clobber (match_scratch:HI 4 "=a"))]
13786   "TARGET_80387
13787    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13788    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13789    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13790    && SELECT_CC_MODE (GET_CODE (operands[0]),
13791                       operands[1], operands[2]) == CCFPmode
13792    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13793   "#")
13795 (define_insn "*fp_jcc_5_387"
13796   [(set (pc)
13797         (if_then_else (match_operator 0 "comparison_operator"
13798                         [(match_operand 1 "register_operand" "f")
13799                          (match_operand 2 "register_operand" "f")])
13800           (label_ref (match_operand 3 "" ""))
13801           (pc)))
13802    (clobber (reg:CCFP FPSR_REG))
13803    (clobber (reg:CCFP FLAGS_REG))
13804    (clobber (match_scratch:HI 4 "=a"))]
13805   "TARGET_80387
13806    && FLOAT_MODE_P (GET_MODE (operands[1]))
13807    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13808    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13809   "#")
13811 (define_insn "*fp_jcc_6_387"
13812   [(set (pc)
13813         (if_then_else (match_operator 0 "comparison_operator"
13814                         [(match_operand 1 "register_operand" "f")
13815                          (match_operand 2 "register_operand" "f")])
13816           (pc)
13817           (label_ref (match_operand 3 "" ""))))
13818    (clobber (reg:CCFP FPSR_REG))
13819    (clobber (reg:CCFP FLAGS_REG))
13820    (clobber (match_scratch:HI 4 "=a"))]
13821   "TARGET_80387
13822    && FLOAT_MODE_P (GET_MODE (operands[1]))
13823    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13824    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13825   "#")
13827 (define_insn "*fp_jcc_7_387"
13828   [(set (pc)
13829         (if_then_else (match_operator 0 "comparison_operator"
13830                         [(match_operand 1 "register_operand" "f")
13831                          (match_operand 2 "const0_operand" "X")])
13832           (label_ref (match_operand 3 "" ""))
13833           (pc)))
13834    (clobber (reg:CCFP FPSR_REG))
13835    (clobber (reg:CCFP FLAGS_REG))
13836    (clobber (match_scratch:HI 4 "=a"))]
13837   "TARGET_80387
13838    && FLOAT_MODE_P (GET_MODE (operands[1]))
13839    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13840    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13841    && SELECT_CC_MODE (GET_CODE (operands[0]),
13842                       operands[1], operands[2]) == CCFPmode
13843    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13844   "#")
13846 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13847 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13848 ;; with a precedence over other operators and is always put in the first
13849 ;; place. Swap condition and operands to match ficom instruction.
13851 (define_insn "*fp_jcc_8<mode>_387"
13852   [(set (pc)
13853         (if_then_else (match_operator 0 "comparison_operator"
13854                         [(match_operator 1 "float_operator"
13855                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13856                            (match_operand 3 "register_operand" "f,f")])
13857           (label_ref (match_operand 4 "" ""))
13858           (pc)))
13859    (clobber (reg:CCFP FPSR_REG))
13860    (clobber (reg:CCFP FLAGS_REG))
13861    (clobber (match_scratch:HI 5 "=a,a"))]
13862   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13863    && FLOAT_MODE_P (GET_MODE (operands[3]))
13864    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13865    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13866    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13867    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13868   "#")
13870 (define_split
13871   [(set (pc)
13872         (if_then_else (match_operator 0 "comparison_operator"
13873                         [(match_operand 1 "register_operand" "")
13874                          (match_operand 2 "nonimmediate_operand" "")])
13875           (match_operand 3 "" "")
13876           (match_operand 4 "" "")))
13877    (clobber (reg:CCFP FPSR_REG))
13878    (clobber (reg:CCFP FLAGS_REG))]
13879   "reload_completed"
13880   [(const_int 0)]
13882   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13883                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13884   DONE;
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 "general_operand" "")])
13892           (match_operand 3 "" "")
13893           (match_operand 4 "" "")))
13894    (clobber (reg:CCFP FPSR_REG))
13895    (clobber (reg:CCFP FLAGS_REG))
13896    (clobber (match_scratch:HI 5 "=a"))]
13897   "reload_completed"
13898   [(const_int 0)]
13900   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13901                         operands[3], operands[4], operands[5], NULL_RTX);
13902   DONE;
13905 (define_split
13906   [(set (pc)
13907         (if_then_else (match_operator 0 "comparison_operator"
13908                         [(match_operator 1 "float_operator"
13909                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13910                            (match_operand 3 "register_operand" "")])
13911           (match_operand 4 "" "")
13912           (match_operand 5 "" "")))
13913    (clobber (reg:CCFP FPSR_REG))
13914    (clobber (reg:CCFP FLAGS_REG))
13915    (clobber (match_scratch:HI 6 "=a"))]
13916   "reload_completed"
13917   [(const_int 0)]
13919   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13920   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13921                         operands[3], operands[7],
13922                         operands[4], operands[5], operands[6], NULL_RTX);
13923   DONE;
13926 ;; %%% Kill this when reload knows how to do it.
13927 (define_split
13928   [(set (pc)
13929         (if_then_else (match_operator 0 "comparison_operator"
13930                         [(match_operator 1 "float_operator"
13931                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13932                            (match_operand 3 "register_operand" "")])
13933           (match_operand 4 "" "")
13934           (match_operand 5 "" "")))
13935    (clobber (reg:CCFP FPSR_REG))
13936    (clobber (reg:CCFP FLAGS_REG))
13937    (clobber (match_scratch:HI 6 "=a"))]
13938   "reload_completed"
13939   [(const_int 0)]
13941   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13942   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13943   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13944                         operands[3], operands[7],
13945                         operands[4], operands[5], operands[6], operands[2]);
13946   DONE;
13949 ;; Unconditional and other jump instructions
13951 (define_insn "jump"
13952   [(set (pc)
13953         (label_ref (match_operand 0 "" "")))]
13954   ""
13955   "jmp\t%l0"
13956   [(set_attr "type" "ibr")
13957    (set (attr "length")
13958            (if_then_else (and (ge (minus (match_dup 0) (pc))
13959                                   (const_int -126))
13960                               (lt (minus (match_dup 0) (pc))
13961                                   (const_int 128)))
13962              (const_int 2)
13963              (const_int 5)))
13964    (set_attr "modrm" "0")])
13966 (define_expand "indirect_jump"
13967   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13968   ""
13969   "")
13971 (define_insn "*indirect_jump"
13972   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13973   "!TARGET_64BIT"
13974   "jmp\t%A0"
13975   [(set_attr "type" "ibr")
13976    (set_attr "length_immediate" "0")])
13978 (define_insn "*indirect_jump_rtx64"
13979   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13980   "TARGET_64BIT"
13981   "jmp\t%A0"
13982   [(set_attr "type" "ibr")
13983    (set_attr "length_immediate" "0")])
13985 (define_expand "tablejump"
13986   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13987               (use (label_ref (match_operand 1 "" "")))])]
13988   ""
13990   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13991      relative.  Convert the relative address to an absolute address.  */
13992   if (flag_pic)
13993     {
13994       rtx op0, op1;
13995       enum rtx_code code;
13997       if (TARGET_64BIT)
13998         {
13999           code = PLUS;
14000           op0 = operands[0];
14001           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14002         }
14003       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14004         {
14005           code = PLUS;
14006           op0 = operands[0];
14007           op1 = pic_offset_table_rtx;
14008         }
14009       else
14010         {
14011           code = MINUS;
14012           op0 = pic_offset_table_rtx;
14013           op1 = operands[0];
14014         }
14016       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14017                                          OPTAB_DIRECT);
14018     }
14021 (define_insn "*tablejump_1"
14022   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14023    (use (label_ref (match_operand 1 "" "")))]
14024   "!TARGET_64BIT"
14025   "jmp\t%A0"
14026   [(set_attr "type" "ibr")
14027    (set_attr "length_immediate" "0")])
14029 (define_insn "*tablejump_1_rtx64"
14030   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14031    (use (label_ref (match_operand 1 "" "")))]
14032   "TARGET_64BIT"
14033   "jmp\t%A0"
14034   [(set_attr "type" "ibr")
14035    (set_attr "length_immediate" "0")])
14037 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14039 (define_peephole2
14040   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14041    (set (match_operand:QI 1 "register_operand" "")
14042         (match_operator:QI 2 "ix86_comparison_operator"
14043           [(reg FLAGS_REG) (const_int 0)]))
14044    (set (match_operand 3 "q_regs_operand" "")
14045         (zero_extend (match_dup 1)))]
14046   "(peep2_reg_dead_p (3, operands[1])
14047     || operands_match_p (operands[1], operands[3]))
14048    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14049   [(set (match_dup 4) (match_dup 0))
14050    (set (strict_low_part (match_dup 5))
14051         (match_dup 2))]
14053   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14054   operands[5] = gen_lowpart (QImode, operands[3]);
14055   ix86_expand_clear (operands[3]);
14058 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14060 (define_peephole2
14061   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14062    (set (match_operand:QI 1 "register_operand" "")
14063         (match_operator:QI 2 "ix86_comparison_operator"
14064           [(reg FLAGS_REG) (const_int 0)]))
14065    (parallel [(set (match_operand 3 "q_regs_operand" "")
14066                    (zero_extend (match_dup 1)))
14067               (clobber (reg:CC FLAGS_REG))])]
14068   "(peep2_reg_dead_p (3, operands[1])
14069     || operands_match_p (operands[1], operands[3]))
14070    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14071   [(set (match_dup 4) (match_dup 0))
14072    (set (strict_low_part (match_dup 5))
14073         (match_dup 2))]
14075   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14076   operands[5] = gen_lowpart (QImode, operands[3]);
14077   ix86_expand_clear (operands[3]);
14080 ;; Call instructions.
14082 ;; The predicates normally associated with named expanders are not properly
14083 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14084 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14086 ;; Call subroutine returning no value.
14088 (define_expand "call_pop"
14089   [(parallel [(call (match_operand:QI 0 "" "")
14090                     (match_operand:SI 1 "" ""))
14091               (set (reg:SI SP_REG)
14092                    (plus:SI (reg:SI SP_REG)
14093                             (match_operand:SI 3 "" "")))])]
14094   "!TARGET_64BIT"
14096   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14097   DONE;
14100 (define_insn "*call_pop_0"
14101   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14102          (match_operand:SI 1 "" ""))
14103    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14104                             (match_operand:SI 2 "immediate_operand" "")))]
14105   "!TARGET_64BIT"
14107   if (SIBLING_CALL_P (insn))
14108     return "jmp\t%P0";
14109   else
14110     return "call\t%P0";
14112   [(set_attr "type" "call")])
14114 (define_insn "*call_pop_1"
14115   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14116          (match_operand:SI 1 "" ""))
14117    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14118                             (match_operand:SI 2 "immediate_operand" "i")))]
14119   "!TARGET_64BIT"
14121   if (constant_call_address_operand (operands[0], Pmode))
14122     {
14123       if (SIBLING_CALL_P (insn))
14124         return "jmp\t%P0";
14125       else
14126         return "call\t%P0";
14127     }
14128   if (SIBLING_CALL_P (insn))
14129     return "jmp\t%A0";
14130   else
14131     return "call\t%A0";
14133   [(set_attr "type" "call")])
14135 (define_expand "call"
14136   [(call (match_operand:QI 0 "" "")
14137          (match_operand 1 "" ""))
14138    (use (match_operand 2 "" ""))]
14139   ""
14141   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14142   DONE;
14145 (define_expand "sibcall"
14146   [(call (match_operand:QI 0 "" "")
14147          (match_operand 1 "" ""))
14148    (use (match_operand 2 "" ""))]
14149   ""
14151   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14152   DONE;
14155 (define_insn "*call_0"
14156   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14157          (match_operand 1 "" ""))]
14158   ""
14160   if (SIBLING_CALL_P (insn))
14161     return "jmp\t%P0";
14162   else
14163     return "call\t%P0";
14165   [(set_attr "type" "call")])
14167 (define_insn "*call_1"
14168   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14169          (match_operand 1 "" ""))]
14170   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14172   if (constant_call_address_operand (operands[0], Pmode))
14173     return "call\t%P0";
14174   return "call\t%A0";
14176   [(set_attr "type" "call")])
14178 (define_insn "*sibcall_1"
14179   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14180          (match_operand 1 "" ""))]
14181   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14183   if (constant_call_address_operand (operands[0], Pmode))
14184     return "jmp\t%P0";
14185   return "jmp\t%A0";
14187   [(set_attr "type" "call")])
14189 (define_insn "*call_1_rex64"
14190   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14191          (match_operand 1 "" ""))]
14192   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14194   if (constant_call_address_operand (operands[0], Pmode))
14195     return "call\t%P0";
14196   return "call\t%A0";
14198   [(set_attr "type" "call")])
14200 (define_insn "*sibcall_1_rex64"
14201   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14202          (match_operand 1 "" ""))]
14203   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14204   "jmp\t%P0"
14205   [(set_attr "type" "call")])
14207 (define_insn "*sibcall_1_rex64_v"
14208   [(call (mem:QI (reg:DI R11_REG))
14209          (match_operand 0 "" ""))]
14210   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14211   "jmp\t*%%r11"
14212   [(set_attr "type" "call")])
14215 ;; Call subroutine, returning value in operand 0
14217 (define_expand "call_value_pop"
14218   [(parallel [(set (match_operand 0 "" "")
14219                    (call (match_operand:QI 1 "" "")
14220                          (match_operand:SI 2 "" "")))
14221               (set (reg:SI SP_REG)
14222                    (plus:SI (reg:SI SP_REG)
14223                             (match_operand:SI 4 "" "")))])]
14224   "!TARGET_64BIT"
14226   ix86_expand_call (operands[0], operands[1], operands[2],
14227                     operands[3], operands[4], 0);
14228   DONE;
14231 (define_expand "call_value"
14232   [(set (match_operand 0 "" "")
14233         (call (match_operand:QI 1 "" "")
14234               (match_operand:SI 2 "" "")))
14235    (use (match_operand:SI 3 "" ""))]
14236   ;; Operand 2 not used on the i386.
14237   ""
14239   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14240   DONE;
14243 (define_expand "sibcall_value"
14244   [(set (match_operand 0 "" "")
14245         (call (match_operand:QI 1 "" "")
14246               (match_operand:SI 2 "" "")))
14247    (use (match_operand:SI 3 "" ""))]
14248   ;; Operand 2 not used on the i386.
14249   ""
14251   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14252   DONE;
14255 ;; Call subroutine returning any type.
14257 (define_expand "untyped_call"
14258   [(parallel [(call (match_operand 0 "" "")
14259                     (const_int 0))
14260               (match_operand 1 "" "")
14261               (match_operand 2 "" "")])]
14262   ""
14264   int i;
14266   /* In order to give reg-stack an easier job in validating two
14267      coprocessor registers as containing a possible return value,
14268      simply pretend the untyped call returns a complex long double
14269      value.  */
14271   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14272                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14273                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14274                     NULL, 0);
14276   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14277     {
14278       rtx set = XVECEXP (operands[2], 0, i);
14279       emit_move_insn (SET_DEST (set), SET_SRC (set));
14280     }
14282   /* The optimizer does not know that the call sets the function value
14283      registers we stored in the result block.  We avoid problems by
14284      claiming that all hard registers are used and clobbered at this
14285      point.  */
14286   emit_insn (gen_blockage (const0_rtx));
14288   DONE;
14291 ;; Prologue and epilogue instructions
14293 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14294 ;; all of memory.  This blocks insns from being moved across this point.
14296 (define_insn "blockage"
14297   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14298   ""
14299   ""
14300   [(set_attr "length" "0")])
14302 ;; Insn emitted into the body of a function to return from a function.
14303 ;; This is only done if the function's epilogue is known to be simple.
14304 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14306 (define_expand "return"
14307   [(return)]
14308   "ix86_can_use_return_insn_p ()"
14310   if (current_function_pops_args)
14311     {
14312       rtx popc = GEN_INT (current_function_pops_args);
14313       emit_jump_insn (gen_return_pop_internal (popc));
14314       DONE;
14315     }
14318 (define_insn "return_internal"
14319   [(return)]
14320   "reload_completed"
14321   "ret"
14322   [(set_attr "length" "1")
14323    (set_attr "length_immediate" "0")
14324    (set_attr "modrm" "0")])
14326 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14327 ;; instruction Athlon and K8 have.
14329 (define_insn "return_internal_long"
14330   [(return)
14331    (unspec [(const_int 0)] UNSPEC_REP)]
14332   "reload_completed"
14333   "rep {;} ret"
14334   [(set_attr "length" "1")
14335    (set_attr "length_immediate" "0")
14336    (set_attr "prefix_rep" "1")
14337    (set_attr "modrm" "0")])
14339 (define_insn "return_pop_internal"
14340   [(return)
14341    (use (match_operand:SI 0 "const_int_operand" ""))]
14342   "reload_completed"
14343   "ret\t%0"
14344   [(set_attr "length" "3")
14345    (set_attr "length_immediate" "2")
14346    (set_attr "modrm" "0")])
14348 (define_insn "return_indirect_internal"
14349   [(return)
14350    (use (match_operand:SI 0 "register_operand" "r"))]
14351   "reload_completed"
14352   "jmp\t%A0"
14353   [(set_attr "type" "ibr")
14354    (set_attr "length_immediate" "0")])
14356 (define_insn "nop"
14357   [(const_int 0)]
14358   ""
14359   "nop"
14360   [(set_attr "length" "1")
14361    (set_attr "length_immediate" "0")
14362    (set_attr "modrm" "0")])
14364 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14365 ;; branch prediction penalty for the third jump in a 16-byte
14366 ;; block on K8.
14368 (define_insn "align"
14369   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14370   ""
14372 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14373   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14374 #else
14375   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14376      The align insn is used to avoid 3 jump instructions in the row to improve
14377      branch prediction and the benefits hardly outweigh the cost of extra 8
14378      nops on the average inserted by full alignment pseudo operation.  */
14379 #endif
14380   return "";
14382   [(set_attr "length" "16")])
14384 (define_expand "prologue"
14385   [(const_int 1)]
14386   ""
14387   "ix86_expand_prologue (); DONE;")
14389 (define_insn "set_got"
14390   [(set (match_operand:SI 0 "register_operand" "=r")
14391         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14392    (clobber (reg:CC FLAGS_REG))]
14393   "!TARGET_64BIT"
14394   { return output_set_got (operands[0], NULL_RTX); }
14395   [(set_attr "type" "multi")
14396    (set_attr "length" "12")])
14398 (define_insn "set_got_labelled"
14399   [(set (match_operand:SI 0 "register_operand" "=r")
14400         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14401          UNSPEC_SET_GOT))
14402    (clobber (reg:CC FLAGS_REG))]
14403   "!TARGET_64BIT"
14404   { return output_set_got (operands[0], operands[1]); }
14405   [(set_attr "type" "multi")
14406    (set_attr "length" "12")])
14408 (define_insn "set_got_rex64"
14409   [(set (match_operand:DI 0 "register_operand" "=r")
14410         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14411   "TARGET_64BIT"
14412   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14413   [(set_attr "type" "lea")
14414    (set_attr "length" "6")])
14416 (define_expand "epilogue"
14417   [(const_int 1)]
14418   ""
14419   "ix86_expand_epilogue (1); DONE;")
14421 (define_expand "sibcall_epilogue"
14422   [(const_int 1)]
14423   ""
14424   "ix86_expand_epilogue (0); DONE;")
14426 (define_expand "eh_return"
14427   [(use (match_operand 0 "register_operand" ""))]
14428   ""
14430   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14432   /* Tricky bit: we write the address of the handler to which we will
14433      be returning into someone else's stack frame, one word below the
14434      stack address we wish to restore.  */
14435   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14436   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14437   tmp = gen_rtx_MEM (Pmode, tmp);
14438   emit_move_insn (tmp, ra);
14440   if (Pmode == SImode)
14441     emit_jump_insn (gen_eh_return_si (sa));
14442   else
14443     emit_jump_insn (gen_eh_return_di (sa));
14444   emit_barrier ();
14445   DONE;
14448 (define_insn_and_split "eh_return_si"
14449   [(set (pc)
14450         (unspec [(match_operand:SI 0 "register_operand" "c")]
14451                  UNSPEC_EH_RETURN))]
14452   "!TARGET_64BIT"
14453   "#"
14454   "reload_completed"
14455   [(const_int 1)]
14456   "ix86_expand_epilogue (2); DONE;")
14458 (define_insn_and_split "eh_return_di"
14459   [(set (pc)
14460         (unspec [(match_operand:DI 0 "register_operand" "c")]
14461                  UNSPEC_EH_RETURN))]
14462   "TARGET_64BIT"
14463   "#"
14464   "reload_completed"
14465   [(const_int 1)]
14466   "ix86_expand_epilogue (2); DONE;")
14468 (define_insn "leave"
14469   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14470    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14471    (clobber (mem:BLK (scratch)))]
14472   "!TARGET_64BIT"
14473   "leave"
14474   [(set_attr "type" "leave")])
14476 (define_insn "leave_rex64"
14477   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14478    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14479    (clobber (mem:BLK (scratch)))]
14480   "TARGET_64BIT"
14481   "leave"
14482   [(set_attr "type" "leave")])
14484 (define_expand "ffssi2"
14485   [(parallel
14486      [(set (match_operand:SI 0 "register_operand" "")
14487            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14488       (clobber (match_scratch:SI 2 ""))
14489       (clobber (reg:CC FLAGS_REG))])]
14490   ""
14491   "")
14493 (define_insn_and_split "*ffs_cmove"
14494   [(set (match_operand:SI 0 "register_operand" "=r")
14495         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14496    (clobber (match_scratch:SI 2 "=&r"))
14497    (clobber (reg:CC FLAGS_REG))]
14498   "TARGET_CMOVE"
14499   "#"
14500   "&& reload_completed"
14501   [(set (match_dup 2) (const_int -1))
14502    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14503               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14504    (set (match_dup 0) (if_then_else:SI
14505                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14506                         (match_dup 2)
14507                         (match_dup 0)))
14508    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14509               (clobber (reg:CC FLAGS_REG))])]
14510   "")
14512 (define_insn_and_split "*ffs_no_cmove"
14513   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14514         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14515    (clobber (match_scratch:SI 2 "=&q"))
14516    (clobber (reg:CC FLAGS_REG))]
14517   ""
14518   "#"
14519   "reload_completed"
14520   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14521               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14522    (set (strict_low_part (match_dup 3))
14523         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14524    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14525               (clobber (reg:CC FLAGS_REG))])
14526    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14527               (clobber (reg:CC FLAGS_REG))])
14528    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14529               (clobber (reg:CC FLAGS_REG))])]
14531   operands[3] = gen_lowpart (QImode, operands[2]);
14532   ix86_expand_clear (operands[2]);
14535 (define_insn "*ffssi_1"
14536   [(set (reg:CCZ FLAGS_REG)
14537         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14538                      (const_int 0)))
14539    (set (match_operand:SI 0 "register_operand" "=r")
14540         (ctz:SI (match_dup 1)))]
14541   ""
14542   "bsf{l}\t{%1, %0|%0, %1}"
14543   [(set_attr "prefix_0f" "1")])
14545 (define_expand "ffsdi2"
14546   [(parallel
14547      [(set (match_operand:DI 0 "register_operand" "")
14548            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14549       (clobber (match_scratch:DI 2 ""))
14550       (clobber (reg:CC FLAGS_REG))])]
14551   "TARGET_64BIT && TARGET_CMOVE"
14552   "")
14554 (define_insn_and_split "*ffs_rex64"
14555   [(set (match_operand:DI 0 "register_operand" "=r")
14556         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14557    (clobber (match_scratch:DI 2 "=&r"))
14558    (clobber (reg:CC FLAGS_REG))]
14559   "TARGET_64BIT && TARGET_CMOVE"
14560   "#"
14561   "&& reload_completed"
14562   [(set (match_dup 2) (const_int -1))
14563    (parallel [(set (reg:CCZ FLAGS_REG)
14564                    (compare:CCZ (match_dup 1) (const_int 0)))
14565               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14566    (set (match_dup 0) (if_then_else:DI
14567                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14568                         (match_dup 2)
14569                         (match_dup 0)))
14570    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14571               (clobber (reg:CC FLAGS_REG))])]
14572   "")
14574 (define_insn "*ffsdi_1"
14575   [(set (reg:CCZ FLAGS_REG)
14576         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14577                      (const_int 0)))
14578    (set (match_operand:DI 0 "register_operand" "=r")
14579         (ctz:DI (match_dup 1)))]
14580   "TARGET_64BIT"
14581   "bsf{q}\t{%1, %0|%0, %1}"
14582   [(set_attr "prefix_0f" "1")])
14584 (define_insn "ctzsi2"
14585   [(set (match_operand:SI 0 "register_operand" "=r")
14586         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14587    (clobber (reg:CC FLAGS_REG))]
14588   ""
14589   "bsf{l}\t{%1, %0|%0, %1}"
14590   [(set_attr "prefix_0f" "1")])
14592 (define_insn "ctzdi2"
14593   [(set (match_operand:DI 0 "register_operand" "=r")
14594         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14595    (clobber (reg:CC FLAGS_REG))]
14596   "TARGET_64BIT"
14597   "bsf{q}\t{%1, %0|%0, %1}"
14598   [(set_attr "prefix_0f" "1")])
14600 (define_expand "clzsi2"
14601   [(parallel
14602      [(set (match_operand:SI 0 "register_operand" "")
14603            (minus:SI (const_int 31)
14604                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14605       (clobber (reg:CC FLAGS_REG))])
14606    (parallel
14607      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14608       (clobber (reg:CC FLAGS_REG))])]
14609   ""
14610   "")
14612 (define_insn "*bsr"
14613   [(set (match_operand:SI 0 "register_operand" "=r")
14614         (minus:SI (const_int 31)
14615                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14616    (clobber (reg:CC FLAGS_REG))]
14617   ""
14618   "bsr{l}\t{%1, %0|%0, %1}"
14619   [(set_attr "prefix_0f" "1")])
14621 (define_insn "bswapsi2"
14622   [(set (match_operand:SI 0 "register_operand" "=r")
14623         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14624    (clobber (reg:CC FLAGS_REG))]
14625   "TARGET_BSWAP"
14626   "bswap\t%k0"
14627   [(set_attr "prefix_0f" "1")
14628    (set_attr "length" "2")])
14630 (define_insn "bswapdi2"
14631   [(set (match_operand:DI 0 "register_operand" "=r")
14632         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14633    (clobber (reg:CC FLAGS_REG))]
14634   "TARGET_64BIT && TARGET_BSWAP"
14635   "bswap\t%0"
14636   [(set_attr "prefix_0f" "1")
14637    (set_attr "length" "3")])
14639 (define_expand "clzdi2"
14640   [(parallel
14641      [(set (match_operand:DI 0 "register_operand" "")
14642            (minus:DI (const_int 63)
14643                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14644       (clobber (reg:CC FLAGS_REG))])
14645    (parallel
14646      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14647       (clobber (reg:CC FLAGS_REG))])]
14648   "TARGET_64BIT"
14649   "")
14651 (define_insn "*bsr_rex64"
14652   [(set (match_operand:DI 0 "register_operand" "=r")
14653         (minus:DI (const_int 63)
14654                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14655    (clobber (reg:CC FLAGS_REG))]
14656   "TARGET_64BIT"
14657   "bsr{q}\t{%1, %0|%0, %1}"
14658   [(set_attr "prefix_0f" "1")])
14660 ;; Thread-local storage patterns for ELF.
14662 ;; Note that these code sequences must appear exactly as shown
14663 ;; in order to allow linker relaxation.
14665 (define_insn "*tls_global_dynamic_32_gnu"
14666   [(set (match_operand:SI 0 "register_operand" "=a")
14667         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14668                     (match_operand:SI 2 "tls_symbolic_operand" "")
14669                     (match_operand:SI 3 "call_insn_operand" "")]
14670                     UNSPEC_TLS_GD))
14671    (clobber (match_scratch:SI 4 "=d"))
14672    (clobber (match_scratch:SI 5 "=c"))
14673    (clobber (reg:CC FLAGS_REG))]
14674   "!TARGET_64BIT && TARGET_GNU_TLS"
14675   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14676   [(set_attr "type" "multi")
14677    (set_attr "length" "12")])
14679 (define_insn "*tls_global_dynamic_32_sun"
14680   [(set (match_operand:SI 0 "register_operand" "=a")
14681         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14682                     (match_operand:SI 2 "tls_symbolic_operand" "")
14683                     (match_operand:SI 3 "call_insn_operand" "")]
14684                     UNSPEC_TLS_GD))
14685    (clobber (match_scratch:SI 4 "=d"))
14686    (clobber (match_scratch:SI 5 "=c"))
14687    (clobber (reg:CC FLAGS_REG))]
14688   "!TARGET_64BIT && TARGET_SUN_TLS"
14689   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14690         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14691   [(set_attr "type" "multi")
14692    (set_attr "length" "14")])
14694 (define_expand "tls_global_dynamic_32"
14695   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14696                    (unspec:SI
14697                     [(match_dup 2)
14698                      (match_operand:SI 1 "tls_symbolic_operand" "")
14699                      (match_dup 3)]
14700                     UNSPEC_TLS_GD))
14701               (clobber (match_scratch:SI 4 ""))
14702               (clobber (match_scratch:SI 5 ""))
14703               (clobber (reg:CC FLAGS_REG))])]
14704   ""
14706   if (flag_pic)
14707     operands[2] = pic_offset_table_rtx;
14708   else
14709     {
14710       operands[2] = gen_reg_rtx (Pmode);
14711       emit_insn (gen_set_got (operands[2]));
14712     }
14713   if (TARGET_GNU2_TLS)
14714     {
14715        emit_insn (gen_tls_dynamic_gnu2_32
14716                   (operands[0], operands[1], operands[2]));
14717        DONE;
14718     }
14719   operands[3] = ix86_tls_get_addr ();
14722 (define_insn "*tls_global_dynamic_64"
14723   [(set (match_operand:DI 0 "register_operand" "=a")
14724         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14725                  (match_operand:DI 3 "" "")))
14726    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14727               UNSPEC_TLS_GD)]
14728   "TARGET_64BIT"
14729   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14730   [(set_attr "type" "multi")
14731    (set_attr "length" "16")])
14733 (define_expand "tls_global_dynamic_64"
14734   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14735                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14736               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14737                          UNSPEC_TLS_GD)])]
14738   ""
14740   if (TARGET_GNU2_TLS)
14741     {
14742        emit_insn (gen_tls_dynamic_gnu2_64
14743                   (operands[0], operands[1]));
14744        DONE;
14745     }
14746   operands[2] = ix86_tls_get_addr ();
14749 (define_insn "*tls_local_dynamic_base_32_gnu"
14750   [(set (match_operand:SI 0 "register_operand" "=a")
14751         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14752                     (match_operand:SI 2 "call_insn_operand" "")]
14753                    UNSPEC_TLS_LD_BASE))
14754    (clobber (match_scratch:SI 3 "=d"))
14755    (clobber (match_scratch:SI 4 "=c"))
14756    (clobber (reg:CC FLAGS_REG))]
14757   "!TARGET_64BIT && TARGET_GNU_TLS"
14758   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14759   [(set_attr "type" "multi")
14760    (set_attr "length" "11")])
14762 (define_insn "*tls_local_dynamic_base_32_sun"
14763   [(set (match_operand:SI 0 "register_operand" "=a")
14764         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14765                     (match_operand:SI 2 "call_insn_operand" "")]
14766                    UNSPEC_TLS_LD_BASE))
14767    (clobber (match_scratch:SI 3 "=d"))
14768    (clobber (match_scratch:SI 4 "=c"))
14769    (clobber (reg:CC FLAGS_REG))]
14770   "!TARGET_64BIT && TARGET_SUN_TLS"
14771   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14772         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14773   [(set_attr "type" "multi")
14774    (set_attr "length" "13")])
14776 (define_expand "tls_local_dynamic_base_32"
14777   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14778                    (unspec:SI [(match_dup 1) (match_dup 2)]
14779                               UNSPEC_TLS_LD_BASE))
14780               (clobber (match_scratch:SI 3 ""))
14781               (clobber (match_scratch:SI 4 ""))
14782               (clobber (reg:CC FLAGS_REG))])]
14783   ""
14785   if (flag_pic)
14786     operands[1] = pic_offset_table_rtx;
14787   else
14788     {
14789       operands[1] = gen_reg_rtx (Pmode);
14790       emit_insn (gen_set_got (operands[1]));
14791     }
14792   if (TARGET_GNU2_TLS)
14793     {
14794        emit_insn (gen_tls_dynamic_gnu2_32
14795                   (operands[0], ix86_tls_module_base (), operands[1]));
14796        DONE;
14797     }
14798   operands[2] = ix86_tls_get_addr ();
14801 (define_insn "*tls_local_dynamic_base_64"
14802   [(set (match_operand:DI 0 "register_operand" "=a")
14803         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14804                  (match_operand:DI 2 "" "")))
14805    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14806   "TARGET_64BIT"
14807   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14808   [(set_attr "type" "multi")
14809    (set_attr "length" "12")])
14811 (define_expand "tls_local_dynamic_base_64"
14812   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14813                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14814               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14815   ""
14817   if (TARGET_GNU2_TLS)
14818     {
14819        emit_insn (gen_tls_dynamic_gnu2_64
14820                   (operands[0], ix86_tls_module_base ()));
14821        DONE;
14822     }
14823   operands[1] = ix86_tls_get_addr ();
14826 ;; Local dynamic of a single variable is a lose.  Show combine how
14827 ;; to convert that back to global dynamic.
14829 (define_insn_and_split "*tls_local_dynamic_32_once"
14830   [(set (match_operand:SI 0 "register_operand" "=a")
14831         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14832                              (match_operand:SI 2 "call_insn_operand" "")]
14833                             UNSPEC_TLS_LD_BASE)
14834                  (const:SI (unspec:SI
14835                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14836                             UNSPEC_DTPOFF))))
14837    (clobber (match_scratch:SI 4 "=d"))
14838    (clobber (match_scratch:SI 5 "=c"))
14839    (clobber (reg:CC FLAGS_REG))]
14840   ""
14841   "#"
14842   ""
14843   [(parallel [(set (match_dup 0)
14844                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14845                               UNSPEC_TLS_GD))
14846               (clobber (match_dup 4))
14847               (clobber (match_dup 5))
14848               (clobber (reg:CC FLAGS_REG))])]
14849   "")
14851 ;; Load and add the thread base pointer from %gs:0.
14853 (define_insn "*load_tp_si"
14854   [(set (match_operand:SI 0 "register_operand" "=r")
14855         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14856   "!TARGET_64BIT"
14857   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14858   [(set_attr "type" "imov")
14859    (set_attr "modrm" "0")
14860    (set_attr "length" "7")
14861    (set_attr "memory" "load")
14862    (set_attr "imm_disp" "false")])
14864 (define_insn "*add_tp_si"
14865   [(set (match_operand:SI 0 "register_operand" "=r")
14866         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14867                  (match_operand:SI 1 "register_operand" "0")))
14868    (clobber (reg:CC FLAGS_REG))]
14869   "!TARGET_64BIT"
14870   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14871   [(set_attr "type" "alu")
14872    (set_attr "modrm" "0")
14873    (set_attr "length" "7")
14874    (set_attr "memory" "load")
14875    (set_attr "imm_disp" "false")])
14877 (define_insn "*load_tp_di"
14878   [(set (match_operand:DI 0 "register_operand" "=r")
14879         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14880   "TARGET_64BIT"
14881   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14882   [(set_attr "type" "imov")
14883    (set_attr "modrm" "0")
14884    (set_attr "length" "7")
14885    (set_attr "memory" "load")
14886    (set_attr "imm_disp" "false")])
14888 (define_insn "*add_tp_di"
14889   [(set (match_operand:DI 0 "register_operand" "=r")
14890         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14891                  (match_operand:DI 1 "register_operand" "0")))
14892    (clobber (reg:CC FLAGS_REG))]
14893   "TARGET_64BIT"
14894   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14895   [(set_attr "type" "alu")
14896    (set_attr "modrm" "0")
14897    (set_attr "length" "7")
14898    (set_attr "memory" "load")
14899    (set_attr "imm_disp" "false")])
14901 ;; GNU2 TLS patterns can be split.
14903 (define_expand "tls_dynamic_gnu2_32"
14904   [(set (match_dup 3)
14905         (plus:SI (match_operand:SI 2 "register_operand" "")
14906                  (const:SI
14907                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14908                              UNSPEC_TLSDESC))))
14909    (parallel
14910     [(set (match_operand:SI 0 "register_operand" "")
14911           (unspec:SI [(match_dup 1) (match_dup 3)
14912                       (match_dup 2) (reg:SI SP_REG)]
14913                       UNSPEC_TLSDESC))
14914      (clobber (reg:CC FLAGS_REG))])]
14915   "!TARGET_64BIT && TARGET_GNU2_TLS"
14917   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14918   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14921 (define_insn "*tls_dynamic_lea_32"
14922   [(set (match_operand:SI 0 "register_operand" "=r")
14923         (plus:SI (match_operand:SI 1 "register_operand" "b")
14924                  (const:SI
14925                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14926                               UNSPEC_TLSDESC))))]
14927   "!TARGET_64BIT && TARGET_GNU2_TLS"
14928   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14929   [(set_attr "type" "lea")
14930    (set_attr "mode" "SI")
14931    (set_attr "length" "6")
14932    (set_attr "length_address" "4")])
14934 (define_insn "*tls_dynamic_call_32"
14935   [(set (match_operand:SI 0 "register_operand" "=a")
14936         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14937                     (match_operand:SI 2 "register_operand" "0")
14938                     ;; we have to make sure %ebx still points to the GOT
14939                     (match_operand:SI 3 "register_operand" "b")
14940                     (reg:SI SP_REG)]
14941                    UNSPEC_TLSDESC))
14942    (clobber (reg:CC FLAGS_REG))]
14943   "!TARGET_64BIT && TARGET_GNU2_TLS"
14944   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14945   [(set_attr "type" "call")
14946    (set_attr "length" "2")
14947    (set_attr "length_address" "0")])
14949 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14950   [(set (match_operand:SI 0 "register_operand" "=&a")
14951         (plus:SI
14952          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14953                      (match_operand:SI 4 "" "")
14954                      (match_operand:SI 2 "register_operand" "b")
14955                      (reg:SI SP_REG)]
14956                     UNSPEC_TLSDESC)
14957          (const:SI (unspec:SI
14958                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14959                     UNSPEC_DTPOFF))))
14960    (clobber (reg:CC FLAGS_REG))]
14961   "!TARGET_64BIT && TARGET_GNU2_TLS"
14962   "#"
14963   ""
14964   [(set (match_dup 0) (match_dup 5))]
14966   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14967   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14970 (define_expand "tls_dynamic_gnu2_64"
14971   [(set (match_dup 2)
14972         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14973                    UNSPEC_TLSDESC))
14974    (parallel
14975     [(set (match_operand:DI 0 "register_operand" "")
14976           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14977                      UNSPEC_TLSDESC))
14978      (clobber (reg:CC FLAGS_REG))])]
14979   "TARGET_64BIT && TARGET_GNU2_TLS"
14981   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14982   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14985 (define_insn "*tls_dynamic_lea_64"
14986   [(set (match_operand:DI 0 "register_operand" "=r")
14987         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14988                    UNSPEC_TLSDESC))]
14989   "TARGET_64BIT && TARGET_GNU2_TLS"
14990   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14991   [(set_attr "type" "lea")
14992    (set_attr "mode" "DI")
14993    (set_attr "length" "7")
14994    (set_attr "length_address" "4")])
14996 (define_insn "*tls_dynamic_call_64"
14997   [(set (match_operand:DI 0 "register_operand" "=a")
14998         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14999                     (match_operand:DI 2 "register_operand" "0")
15000                     (reg:DI SP_REG)]
15001                    UNSPEC_TLSDESC))
15002    (clobber (reg:CC FLAGS_REG))]
15003   "TARGET_64BIT && TARGET_GNU2_TLS"
15004   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15005   [(set_attr "type" "call")
15006    (set_attr "length" "2")
15007    (set_attr "length_address" "0")])
15009 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15010   [(set (match_operand:DI 0 "register_operand" "=&a")
15011         (plus:DI
15012          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15013                      (match_operand:DI 3 "" "")
15014                      (reg:DI SP_REG)]
15015                     UNSPEC_TLSDESC)
15016          (const:DI (unspec:DI
15017                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15018                     UNSPEC_DTPOFF))))
15019    (clobber (reg:CC FLAGS_REG))]
15020   "TARGET_64BIT && TARGET_GNU2_TLS"
15021   "#"
15022   ""
15023   [(set (match_dup 0) (match_dup 4))]
15025   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15026   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15031 ;; These patterns match the binary 387 instructions for addM3, subM3,
15032 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15033 ;; SFmode.  The first is the normal insn, the second the same insn but
15034 ;; with one operand a conversion, and the third the same insn but with
15035 ;; the other operand a conversion.  The conversion may be SFmode or
15036 ;; SImode if the target mode DFmode, but only SImode if the target mode
15037 ;; is SFmode.
15039 ;; Gcc is slightly more smart about handling normal two address instructions
15040 ;; so use special patterns for add and mull.
15042 (define_insn "*fop_sf_comm_mixed"
15043   [(set (match_operand:SF 0 "register_operand" "=f,x")
15044         (match_operator:SF 3 "binary_fp_operator"
15045                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15046                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15047   "TARGET_MIX_SSE_I387
15048    && COMMUTATIVE_ARITH_P (operands[3])
15049    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15050   "* return output_387_binary_op (insn, operands);"
15051   [(set (attr "type")
15052         (if_then_else (eq_attr "alternative" "1")
15053            (if_then_else (match_operand:SF 3 "mult_operator" "")
15054               (const_string "ssemul")
15055               (const_string "sseadd"))
15056            (if_then_else (match_operand:SF 3 "mult_operator" "")
15057               (const_string "fmul")
15058               (const_string "fop"))))
15059    (set_attr "mode" "SF")])
15061 (define_insn "*fop_sf_comm_sse"
15062   [(set (match_operand:SF 0 "register_operand" "=x")
15063         (match_operator:SF 3 "binary_fp_operator"
15064                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15065                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15066   "TARGET_SSE_MATH
15067    && COMMUTATIVE_ARITH_P (operands[3])
15068    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15069   "* return output_387_binary_op (insn, operands);"
15070   [(set (attr "type")
15071         (if_then_else (match_operand:SF 3 "mult_operator" "")
15072            (const_string "ssemul")
15073            (const_string "sseadd")))
15074    (set_attr "mode" "SF")])
15076 (define_insn "*fop_sf_comm_i387"
15077   [(set (match_operand:SF 0 "register_operand" "=f")
15078         (match_operator:SF 3 "binary_fp_operator"
15079                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15080                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15081   "TARGET_80387
15082    && COMMUTATIVE_ARITH_P (operands[3])
15083    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15084   "* return output_387_binary_op (insn, operands);"
15085   [(set (attr "type")
15086         (if_then_else (match_operand:SF 3 "mult_operator" "")
15087            (const_string "fmul")
15088            (const_string "fop")))
15089    (set_attr "mode" "SF")])
15091 (define_insn "*fop_sf_1_mixed"
15092   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15093         (match_operator:SF 3 "binary_fp_operator"
15094                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15095                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15096   "TARGET_MIX_SSE_I387
15097    && !COMMUTATIVE_ARITH_P (operands[3])
15098    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15099   "* return output_387_binary_op (insn, operands);"
15100   [(set (attr "type")
15101         (cond [(and (eq_attr "alternative" "2")
15102                     (match_operand:SF 3 "mult_operator" ""))
15103                  (const_string "ssemul")
15104                (and (eq_attr "alternative" "2")
15105                     (match_operand:SF 3 "div_operator" ""))
15106                  (const_string "ssediv")
15107                (eq_attr "alternative" "2")
15108                  (const_string "sseadd")
15109                (match_operand:SF 3 "mult_operator" "")
15110                  (const_string "fmul")
15111                (match_operand:SF 3 "div_operator" "")
15112                  (const_string "fdiv")
15113               ]
15114               (const_string "fop")))
15115    (set_attr "mode" "SF")])
15117 (define_insn "*fop_sf_1_sse"
15118   [(set (match_operand:SF 0 "register_operand" "=x")
15119         (match_operator:SF 3 "binary_fp_operator"
15120                         [(match_operand:SF 1 "register_operand" "0")
15121                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15122   "TARGET_SSE_MATH
15123    && !COMMUTATIVE_ARITH_P (operands[3])"
15124   "* return output_387_binary_op (insn, operands);"
15125   [(set (attr "type")
15126         (cond [(match_operand:SF 3 "mult_operator" "")
15127                  (const_string "ssemul")
15128                (match_operand:SF 3 "div_operator" "")
15129                  (const_string "ssediv")
15130               ]
15131               (const_string "sseadd")))
15132    (set_attr "mode" "SF")])
15134 ;; This pattern is not fully shadowed by the pattern above.
15135 (define_insn "*fop_sf_1_i387"
15136   [(set (match_operand:SF 0 "register_operand" "=f,f")
15137         (match_operator:SF 3 "binary_fp_operator"
15138                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15139                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15140   "TARGET_80387 && !TARGET_SSE_MATH
15141    && !COMMUTATIVE_ARITH_P (operands[3])
15142    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15143   "* return output_387_binary_op (insn, operands);"
15144   [(set (attr "type")
15145         (cond [(match_operand:SF 3 "mult_operator" "")
15146                  (const_string "fmul")
15147                (match_operand:SF 3 "div_operator" "")
15148                  (const_string "fdiv")
15149               ]
15150               (const_string "fop")))
15151    (set_attr "mode" "SF")])
15153 ;; ??? Add SSE splitters for these!
15154 (define_insn "*fop_sf_2<mode>_i387"
15155   [(set (match_operand:SF 0 "register_operand" "=f,f")
15156         (match_operator:SF 3 "binary_fp_operator"
15157           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15158            (match_operand:SF 2 "register_operand" "0,0")]))]
15159   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15160   "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
15169    (set_attr "mode" "<MODE>")])
15171 (define_insn "*fop_sf_3<mode>_i387"
15172   [(set (match_operand:SF 0 "register_operand" "=f,f")
15173         (match_operator:SF 3 "binary_fp_operator"
15174           [(match_operand:SF 1 "register_operand" "0,0")
15175            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
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_df_comm_mixed"
15189   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15190         (match_operator:DF 3 "binary_fp_operator"
15191                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15192                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15193   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15194    && COMMUTATIVE_ARITH_P (operands[3])
15195    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15196   "* return output_387_binary_op (insn, operands);"
15197   [(set (attr "type")
15198         (if_then_else (eq_attr "alternative" "1")
15199            (if_then_else (match_operand:DF 3 "mult_operator" "")
15200               (const_string "ssemul")
15201               (const_string "sseadd"))
15202            (if_then_else (match_operand:DF 3 "mult_operator" "")
15203               (const_string "fmul")
15204               (const_string "fop"))))
15205    (set_attr "mode" "DF")])
15207 (define_insn "*fop_df_comm_sse"
15208   [(set (match_operand:DF 0 "register_operand" "=Y")
15209         (match_operator:DF 3 "binary_fp_operator"
15210                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15211                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15212   "TARGET_SSE2 && TARGET_SSE_MATH
15213    && COMMUTATIVE_ARITH_P (operands[3])
15214    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15215   "* return output_387_binary_op (insn, operands);"
15216   [(set (attr "type")
15217         (if_then_else (match_operand:DF 3 "mult_operator" "")
15218            (const_string "ssemul")
15219            (const_string "sseadd")))
15220    (set_attr "mode" "DF")])
15222 (define_insn "*fop_df_comm_i387"
15223   [(set (match_operand:DF 0 "register_operand" "=f")
15224         (match_operator:DF 3 "binary_fp_operator"
15225                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15226                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15227   "TARGET_80387
15228    && COMMUTATIVE_ARITH_P (operands[3])
15229    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15230   "* return output_387_binary_op (insn, operands);"
15231   [(set (attr "type")
15232         (if_then_else (match_operand:DF 3 "mult_operator" "")
15233            (const_string "fmul")
15234            (const_string "fop")))
15235    (set_attr "mode" "DF")])
15237 (define_insn "*fop_df_1_mixed"
15238   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15239         (match_operator:DF 3 "binary_fp_operator"
15240                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15241                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15242   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15243    && !COMMUTATIVE_ARITH_P (operands[3])
15244    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15245   "* return output_387_binary_op (insn, operands);"
15246   [(set (attr "type")
15247         (cond [(and (eq_attr "alternative" "2")
15248                     (match_operand:DF 3 "mult_operator" ""))
15249                  (const_string "ssemul")
15250                (and (eq_attr "alternative" "2")
15251                     (match_operand:DF 3 "div_operator" ""))
15252                  (const_string "ssediv")
15253                (eq_attr "alternative" "2")
15254                  (const_string "sseadd")
15255                (match_operand:DF 3 "mult_operator" "")
15256                  (const_string "fmul")
15257                (match_operand:DF 3 "div_operator" "")
15258                  (const_string "fdiv")
15259               ]
15260               (const_string "fop")))
15261    (set_attr "mode" "DF")])
15263 (define_insn "*fop_df_1_sse"
15264   [(set (match_operand:DF 0 "register_operand" "=Y")
15265         (match_operator:DF 3 "binary_fp_operator"
15266                         [(match_operand:DF 1 "register_operand" "0")
15267                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15268   "TARGET_SSE2 && TARGET_SSE_MATH
15269    && !COMMUTATIVE_ARITH_P (operands[3])"
15270   "* return output_387_binary_op (insn, operands);"
15271   [(set_attr "mode" "DF")
15272    (set (attr "type")
15273         (cond [(match_operand:DF 3 "mult_operator" "")
15274                  (const_string "ssemul")
15275                (match_operand:DF 3 "div_operator" "")
15276                  (const_string "ssediv")
15277               ]
15278               (const_string "sseadd")))])
15280 ;; This pattern is not fully shadowed by the pattern above.
15281 (define_insn "*fop_df_1_i387"
15282   [(set (match_operand:DF 0 "register_operand" "=f,f")
15283         (match_operator:DF 3 "binary_fp_operator"
15284                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15285                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15286   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15287    && !COMMUTATIVE_ARITH_P (operands[3])
15288    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15289   "* return output_387_binary_op (insn, operands);"
15290   [(set (attr "type")
15291         (cond [(match_operand:DF 3 "mult_operator" "")
15292                  (const_string "fmul")
15293                (match_operand:DF 3 "div_operator" "")
15294                  (const_string "fdiv")
15295               ]
15296               (const_string "fop")))
15297    (set_attr "mode" "DF")])
15299 ;; ??? Add SSE splitters for these!
15300 (define_insn "*fop_df_2<mode>_i387"
15301   [(set (match_operand:DF 0 "register_operand" "=f,f")
15302         (match_operator:DF 3 "binary_fp_operator"
15303            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15304             (match_operand:DF 2 "register_operand" "0,0")]))]
15305   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15306    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15307   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15308   [(set (attr "type")
15309         (cond [(match_operand:DF 3 "mult_operator" "")
15310                  (const_string "fmul")
15311                (match_operand:DF 3 "div_operator" "")
15312                  (const_string "fdiv")
15313               ]
15314               (const_string "fop")))
15315    (set_attr "fp_int_src" "true")
15316    (set_attr "mode" "<MODE>")])
15318 (define_insn "*fop_df_3<mode>_i387"
15319   [(set (match_operand:DF 0 "register_operand" "=f,f")
15320         (match_operator:DF 3 "binary_fp_operator"
15321            [(match_operand:DF 1 "register_operand" "0,0")
15322             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15323   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15324    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15325   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15326   [(set (attr "type")
15327         (cond [(match_operand:DF 3 "mult_operator" "")
15328                  (const_string "fmul")
15329                (match_operand:DF 3 "div_operator" "")
15330                  (const_string "fdiv")
15331               ]
15332               (const_string "fop")))
15333    (set_attr "fp_int_src" "true")
15334    (set_attr "mode" "<MODE>")])
15336 (define_insn "*fop_df_4_i387"
15337   [(set (match_operand:DF 0 "register_operand" "=f,f")
15338         (match_operator:DF 3 "binary_fp_operator"
15339            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15340             (match_operand:DF 2 "register_operand" "0,f")]))]
15341   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15342    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15343   "* return output_387_binary_op (insn, operands);"
15344   [(set (attr "type")
15345         (cond [(match_operand:DF 3 "mult_operator" "")
15346                  (const_string "fmul")
15347                (match_operand:DF 3 "div_operator" "")
15348                  (const_string "fdiv")
15349               ]
15350               (const_string "fop")))
15351    (set_attr "mode" "SF")])
15353 (define_insn "*fop_df_5_i387"
15354   [(set (match_operand:DF 0 "register_operand" "=f,f")
15355         (match_operator:DF 3 "binary_fp_operator"
15356           [(match_operand:DF 1 "register_operand" "0,f")
15357            (float_extend:DF
15358             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15359   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
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_6_i387"
15371   [(set (match_operand:DF 0 "register_operand" "=f,f")
15372         (match_operator:DF 3 "binary_fp_operator"
15373           [(float_extend:DF
15374             (match_operand:SF 1 "register_operand" "0,f"))
15375            (float_extend:DF
15376             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15377   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15378   "* return output_387_binary_op (insn, operands);"
15379   [(set (attr "type")
15380         (cond [(match_operand:DF 3 "mult_operator" "")
15381                  (const_string "fmul")
15382                (match_operand:DF 3 "div_operator" "")
15383                  (const_string "fdiv")
15384               ]
15385               (const_string "fop")))
15386    (set_attr "mode" "SF")])
15388 (define_insn "*fop_xf_comm_i387"
15389   [(set (match_operand:XF 0 "register_operand" "=f")
15390         (match_operator:XF 3 "binary_fp_operator"
15391                         [(match_operand:XF 1 "register_operand" "%0")
15392                          (match_operand:XF 2 "register_operand" "f")]))]
15393   "TARGET_80387
15394    && COMMUTATIVE_ARITH_P (operands[3])"
15395   "* return output_387_binary_op (insn, operands);"
15396   [(set (attr "type")
15397         (if_then_else (match_operand:XF 3 "mult_operator" "")
15398            (const_string "fmul")
15399            (const_string "fop")))
15400    (set_attr "mode" "XF")])
15402 (define_insn "*fop_xf_1_i387"
15403   [(set (match_operand:XF 0 "register_operand" "=f,f")
15404         (match_operator:XF 3 "binary_fp_operator"
15405                         [(match_operand:XF 1 "register_operand" "0,f")
15406                          (match_operand:XF 2 "register_operand" "f,0")]))]
15407   "TARGET_80387
15408    && !COMMUTATIVE_ARITH_P (operands[3])"
15409   "* return output_387_binary_op (insn, operands);"
15410   [(set (attr "type")
15411         (cond [(match_operand:XF 3 "mult_operator" "")
15412                  (const_string "fmul")
15413                (match_operand:XF 3 "div_operator" "")
15414                  (const_string "fdiv")
15415               ]
15416               (const_string "fop")))
15417    (set_attr "mode" "XF")])
15419 (define_insn "*fop_xf_2<mode>_i387"
15420   [(set (match_operand:XF 0 "register_operand" "=f,f")
15421         (match_operator:XF 3 "binary_fp_operator"
15422            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15423             (match_operand:XF 2 "register_operand" "0,0")]))]
15424   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15425   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15426   [(set (attr "type")
15427         (cond [(match_operand:XF 3 "mult_operator" "")
15428                  (const_string "fmul")
15429                (match_operand:XF 3 "div_operator" "")
15430                  (const_string "fdiv")
15431               ]
15432               (const_string "fop")))
15433    (set_attr "fp_int_src" "true")
15434    (set_attr "mode" "<MODE>")])
15436 (define_insn "*fop_xf_3<mode>_i387"
15437   [(set (match_operand:XF 0 "register_operand" "=f,f")
15438         (match_operator:XF 3 "binary_fp_operator"
15439           [(match_operand:XF 1 "register_operand" "0,0")
15440            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
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_4_i387"
15454   [(set (match_operand:XF 0 "register_operand" "=f,f")
15455         (match_operator:XF 3 "binary_fp_operator"
15456            [(float_extend:XF
15457               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15458             (match_operand:XF 2 "register_operand" "0,f")]))]
15459   "TARGET_80387"
15460   "* return output_387_binary_op (insn, operands);"
15461   [(set (attr "type")
15462         (cond [(match_operand:XF 3 "mult_operator" "")
15463                  (const_string "fmul")
15464                (match_operand:XF 3 "div_operator" "")
15465                  (const_string "fdiv")
15466               ]
15467               (const_string "fop")))
15468    (set_attr "mode" "SF")])
15470 (define_insn "*fop_xf_5_i387"
15471   [(set (match_operand:XF 0 "register_operand" "=f,f")
15472         (match_operator:XF 3 "binary_fp_operator"
15473           [(match_operand:XF 1 "register_operand" "0,f")
15474            (float_extend:XF
15475              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15476   "TARGET_80387"
15477   "* return output_387_binary_op (insn, operands);"
15478   [(set (attr "type")
15479         (cond [(match_operand:XF 3 "mult_operator" "")
15480                  (const_string "fmul")
15481                (match_operand:XF 3 "div_operator" "")
15482                  (const_string "fdiv")
15483               ]
15484               (const_string "fop")))
15485    (set_attr "mode" "SF")])
15487 (define_insn "*fop_xf_6_i387"
15488   [(set (match_operand:XF 0 "register_operand" "=f,f")
15489         (match_operator:XF 3 "binary_fp_operator"
15490           [(float_extend:XF
15491              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15492            (float_extend:XF
15493              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15494   "TARGET_80387"
15495   "* return output_387_binary_op (insn, operands);"
15496   [(set (attr "type")
15497         (cond [(match_operand:XF 3 "mult_operator" "")
15498                  (const_string "fmul")
15499                (match_operand:XF 3 "div_operator" "")
15500                  (const_string "fdiv")
15501               ]
15502               (const_string "fop")))
15503    (set_attr "mode" "SF")])
15505 (define_split
15506   [(set (match_operand 0 "register_operand" "")
15507         (match_operator 3 "binary_fp_operator"
15508            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15509             (match_operand 2 "register_operand" "")]))]
15510   "TARGET_80387 && reload_completed
15511    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15512   [(const_int 0)]
15514   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15515   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15516   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15517                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15518                                           GET_MODE (operands[3]),
15519                                           operands[4],
15520                                           operands[2])));
15521   ix86_free_from_memory (GET_MODE (operands[1]));
15522   DONE;
15525 (define_split
15526   [(set (match_operand 0 "register_operand" "")
15527         (match_operator 3 "binary_fp_operator"
15528            [(match_operand 1 "register_operand" "")
15529             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15530   "TARGET_80387 && reload_completed
15531    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15532   [(const_int 0)]
15534   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15535   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15536   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15537                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15538                                           GET_MODE (operands[3]),
15539                                           operands[1],
15540                                           operands[4])));
15541   ix86_free_from_memory (GET_MODE (operands[2]));
15542   DONE;
15545 ;; FPU special functions.
15547 ;; This pattern implements a no-op XFmode truncation for
15548 ;; all fancy i386 XFmode math functions.
15550 (define_insn "truncxf<mode>2_i387_noop_unspec"
15551   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15552         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15553         UNSPEC_TRUNC_NOOP))]
15554   "TARGET_USE_FANCY_MATH_387"
15555   "* return output_387_reg_move (insn, operands);"
15556   [(set_attr "type" "fmov")
15557    (set_attr "mode" "<MODE>")])
15559 (define_insn "sqrtxf2"
15560   [(set (match_operand:XF 0 "register_operand" "=f")
15561         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15562   "TARGET_USE_FANCY_MATH_387"
15563   "fsqrt"
15564   [(set_attr "type" "fpspc")
15565    (set_attr "mode" "XF")
15566    (set_attr "athlon_decode" "direct")])
15568 (define_insn "sqrt_extend<mode>xf2_i387"
15569   [(set (match_operand:XF 0 "register_operand" "=f")
15570         (sqrt:XF
15571           (float_extend:XF
15572             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15573   "TARGET_USE_FANCY_MATH_387"
15574   "fsqrt"
15575   [(set_attr "type" "fpspc")
15576    (set_attr "mode" "XF")
15577    (set_attr "athlon_decode" "direct")])
15579 (define_insn "*sqrt<mode>2_sse"
15580   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15581         (sqrt:SSEMODEF
15582           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15583   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15584   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15585   [(set_attr "type" "sse")
15586    (set_attr "mode" "<MODE>")
15587    (set_attr "athlon_decode" "*")])
15589 (define_expand "sqrt<mode>2"
15590   [(set (match_operand:X87MODEF12 0 "register_operand" "")
15591         (sqrt:X87MODEF12
15592           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15593   "TARGET_USE_FANCY_MATH_387
15594    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15596   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15597     {
15598       rtx op0 = gen_reg_rtx (XFmode);
15599       rtx op1 = force_reg (<MODE>mode, operands[1]);
15601       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15602       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15603       DONE;
15604    }
15607 (define_insn "fpremxf4_i387"
15608   [(set (match_operand:XF 0 "register_operand" "=f")
15609         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15610                     (match_operand:XF 3 "register_operand" "1")]
15611                    UNSPEC_FPREM_F))
15612    (set (match_operand:XF 1 "register_operand" "=u")
15613         (unspec:XF [(match_dup 2) (match_dup 3)]
15614                    UNSPEC_FPREM_U))
15615    (set (reg:CCFP FPSR_REG)
15616         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15617   "TARGET_USE_FANCY_MATH_387"
15618   "fprem"
15619   [(set_attr "type" "fpspc")
15620    (set_attr "mode" "XF")])
15622 (define_expand "fmodxf3"
15623   [(use (match_operand:XF 0 "register_operand" ""))
15624    (use (match_operand:XF 1 "register_operand" ""))
15625    (use (match_operand:XF 2 "register_operand" ""))]
15626   "TARGET_USE_FANCY_MATH_387"
15628   rtx label = gen_label_rtx ();
15630   emit_label (label);
15632   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15633                                 operands[1], operands[2]));
15634   ix86_emit_fp_unordered_jump (label);
15636   emit_move_insn (operands[0], operands[1]);
15637   DONE;
15640 (define_expand "fmod<mode>3"
15641   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15642    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15643    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15644   "TARGET_USE_FANCY_MATH_387"
15646   rtx label = gen_label_rtx ();
15648   rtx op1 = gen_reg_rtx (XFmode);
15649   rtx op2 = gen_reg_rtx (XFmode);
15651   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15652   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15654   emit_label (label);
15655   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15656   ix86_emit_fp_unordered_jump (label);
15658   /* Truncate the result properly for strict SSE math.  */
15659   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15660       && !TARGET_MIX_SSE_I387)
15661     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15662   else
15663     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15665   DONE;
15668 (define_insn "fprem1xf4_i387"
15669   [(set (match_operand:XF 0 "register_operand" "=f")
15670         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15671                     (match_operand:XF 3 "register_operand" "1")]
15672                    UNSPEC_FPREM1_F))
15673    (set (match_operand:XF 1 "register_operand" "=u")
15674         (unspec:XF [(match_dup 2) (match_dup 3)]
15675                    UNSPEC_FPREM1_U))
15676    (set (reg:CCFP FPSR_REG)
15677         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15678   "TARGET_USE_FANCY_MATH_387"
15679   "fprem1"
15680   [(set_attr "type" "fpspc")
15681    (set_attr "mode" "XF")])
15683 (define_expand "remainderxf3"
15684   [(use (match_operand:XF 0 "register_operand" ""))
15685    (use (match_operand:XF 1 "register_operand" ""))
15686    (use (match_operand:XF 2 "register_operand" ""))]
15687   "TARGET_USE_FANCY_MATH_387"
15689   rtx label = gen_label_rtx ();
15691   emit_label (label);
15693   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15694                                  operands[1], operands[2]));
15695   ix86_emit_fp_unordered_jump (label);
15697   emit_move_insn (operands[0], operands[1]);
15698   DONE;
15701 (define_expand "remainder<mode>3"
15702   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15703    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15704    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15705   "TARGET_USE_FANCY_MATH_387"
15707   rtx label = gen_label_rtx ();
15709   rtx op1 = gen_reg_rtx (XFmode);
15710   rtx op2 = gen_reg_rtx (XFmode);
15712   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15713   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15715   emit_label (label);
15717   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15718   ix86_emit_fp_unordered_jump (label);
15720   /* Truncate the result properly for strict SSE math.  */
15721   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15722       && !TARGET_MIX_SSE_I387)
15723     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15724   else
15725     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15727   DONE;
15730 (define_insn "*sindf2"
15731   [(set (match_operand:DF 0 "register_operand" "=f")
15732         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15733   "TARGET_USE_FANCY_MATH_387
15734    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15735    && flag_unsafe_math_optimizations"
15736   "fsin"
15737   [(set_attr "type" "fpspc")
15738    (set_attr "mode" "DF")])
15740 (define_insn "*sinsf2"
15741   [(set (match_operand:SF 0 "register_operand" "=f")
15742         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15743   "TARGET_USE_FANCY_MATH_387
15744    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15745    && flag_unsafe_math_optimizations"
15746   "fsin"
15747   [(set_attr "type" "fpspc")
15748    (set_attr "mode" "SF")])
15750 (define_insn "*sinextendsfdf2"
15751   [(set (match_operand:DF 0 "register_operand" "=f")
15752         (unspec:DF [(float_extend:DF
15753                      (match_operand:SF 1 "register_operand" "0"))]
15754                    UNSPEC_SIN))]
15755   "TARGET_USE_FANCY_MATH_387
15756    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15757    && flag_unsafe_math_optimizations"
15758   "fsin"
15759   [(set_attr "type" "fpspc")
15760    (set_attr "mode" "DF")])
15762 (define_insn "*sinxf2"
15763   [(set (match_operand:XF 0 "register_operand" "=f")
15764         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15765   "TARGET_USE_FANCY_MATH_387
15766    && flag_unsafe_math_optimizations"
15767   "fsin"
15768   [(set_attr "type" "fpspc")
15769    (set_attr "mode" "XF")])
15771 (define_insn "*cosdf2"
15772   [(set (match_operand:DF 0 "register_operand" "=f")
15773         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15774   "TARGET_USE_FANCY_MATH_387
15775    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15776    && flag_unsafe_math_optimizations"
15777   "fcos"
15778   [(set_attr "type" "fpspc")
15779    (set_attr "mode" "DF")])
15781 (define_insn "*cossf2"
15782   [(set (match_operand:SF 0 "register_operand" "=f")
15783         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15784   "TARGET_USE_FANCY_MATH_387
15785    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15786    && flag_unsafe_math_optimizations"
15787   "fcos"
15788   [(set_attr "type" "fpspc")
15789    (set_attr "mode" "SF")])
15791 (define_insn "*cosextendsfdf2"
15792   [(set (match_operand:DF 0 "register_operand" "=f")
15793         (unspec:DF [(float_extend:DF
15794                      (match_operand:SF 1 "register_operand" "0"))]
15795                    UNSPEC_COS))]
15796   "TARGET_USE_FANCY_MATH_387
15797    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15798    && flag_unsafe_math_optimizations"
15799   "fcos"
15800   [(set_attr "type" "fpspc")
15801    (set_attr "mode" "DF")])
15803 (define_insn "*cosxf2"
15804   [(set (match_operand:XF 0 "register_operand" "=f")
15805         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15806   "TARGET_USE_FANCY_MATH_387
15807    && flag_unsafe_math_optimizations"
15808   "fcos"
15809   [(set_attr "type" "fpspc")
15810    (set_attr "mode" "XF")])
15812 ;; With sincos pattern defined, sin and cos builtin function will be
15813 ;; expanded to sincos pattern with one of its outputs left unused.
15814 ;; Cse pass  will detected, if two sincos patterns can be combined,
15815 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15816 ;; depending on the unused output.
15818 (define_insn "sincosdf3"
15819   [(set (match_operand:DF 0 "register_operand" "=f")
15820         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15821                    UNSPEC_SINCOS_COS))
15822    (set (match_operand:DF 1 "register_operand" "=u")
15823         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15824   "TARGET_USE_FANCY_MATH_387
15825    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15826    && flag_unsafe_math_optimizations"
15827   "fsincos"
15828   [(set_attr "type" "fpspc")
15829    (set_attr "mode" "DF")])
15831 (define_split
15832   [(set (match_operand:DF 0 "register_operand" "")
15833         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15834                    UNSPEC_SINCOS_COS))
15835    (set (match_operand:DF 1 "register_operand" "")
15836         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15837   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15838    && !reload_completed && !reload_in_progress"
15839   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15840   "")
15842 (define_split
15843   [(set (match_operand:DF 0 "register_operand" "")
15844         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15845                    UNSPEC_SINCOS_COS))
15846    (set (match_operand:DF 1 "register_operand" "")
15847         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15848   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15849    && !reload_completed && !reload_in_progress"
15850   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15851   "")
15853 (define_insn "sincossf3"
15854   [(set (match_operand:SF 0 "register_operand" "=f")
15855         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15856                    UNSPEC_SINCOS_COS))
15857    (set (match_operand:SF 1 "register_operand" "=u")
15858         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15859   "TARGET_USE_FANCY_MATH_387
15860    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15861    && flag_unsafe_math_optimizations"
15862   "fsincos"
15863   [(set_attr "type" "fpspc")
15864    (set_attr "mode" "SF")])
15866 (define_split
15867   [(set (match_operand:SF 0 "register_operand" "")
15868         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15869                    UNSPEC_SINCOS_COS))
15870    (set (match_operand:SF 1 "register_operand" "")
15871         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15872   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15873    && !reload_completed && !reload_in_progress"
15874   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15875   "")
15877 (define_split
15878   [(set (match_operand:SF 0 "register_operand" "")
15879         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15880                    UNSPEC_SINCOS_COS))
15881    (set (match_operand:SF 1 "register_operand" "")
15882         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15883   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15884    && !reload_completed && !reload_in_progress"
15885   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15886   "")
15888 (define_insn "*sincosextendsfdf3"
15889   [(set (match_operand:DF 0 "register_operand" "=f")
15890         (unspec:DF [(float_extend:DF
15891                      (match_operand:SF 2 "register_operand" "0"))]
15892                    UNSPEC_SINCOS_COS))
15893    (set (match_operand:DF 1 "register_operand" "=u")
15894         (unspec:DF [(float_extend:DF
15895                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15896   "TARGET_USE_FANCY_MATH_387
15897    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15898    && flag_unsafe_math_optimizations"
15899   "fsincos"
15900   [(set_attr "type" "fpspc")
15901    (set_attr "mode" "DF")])
15903 (define_split
15904   [(set (match_operand:DF 0 "register_operand" "")
15905         (unspec:DF [(float_extend:DF
15906                      (match_operand:SF 2 "register_operand" ""))]
15907                    UNSPEC_SINCOS_COS))
15908    (set (match_operand:DF 1 "register_operand" "")
15909         (unspec:DF [(float_extend:DF
15910                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15911   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15912    && !reload_completed && !reload_in_progress"
15913   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15914                                    (match_dup 2))] UNSPEC_SIN))]
15915   "")
15917 (define_split
15918   [(set (match_operand:DF 0 "register_operand" "")
15919         (unspec:DF [(float_extend:DF
15920                      (match_operand:SF 2 "register_operand" ""))]
15921                    UNSPEC_SINCOS_COS))
15922    (set (match_operand:DF 1 "register_operand" "")
15923         (unspec:DF [(float_extend:DF
15924                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15925   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15926    && !reload_completed && !reload_in_progress"
15927   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15928                                    (match_dup 2))] UNSPEC_COS))]
15929   "")
15931 (define_insn "sincosxf3"
15932   [(set (match_operand:XF 0 "register_operand" "=f")
15933         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15934                    UNSPEC_SINCOS_COS))
15935    (set (match_operand:XF 1 "register_operand" "=u")
15936         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15937   "TARGET_USE_FANCY_MATH_387
15938    && flag_unsafe_math_optimizations"
15939   "fsincos"
15940   [(set_attr "type" "fpspc")
15941    (set_attr "mode" "XF")])
15943 (define_split
15944   [(set (match_operand:XF 0 "register_operand" "")
15945         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15946                    UNSPEC_SINCOS_COS))
15947    (set (match_operand:XF 1 "register_operand" "")
15948         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15949   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15950    && !reload_completed && !reload_in_progress"
15951   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15952   "")
15954 (define_split
15955   [(set (match_operand:XF 0 "register_operand" "")
15956         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15957                    UNSPEC_SINCOS_COS))
15958    (set (match_operand:XF 1 "register_operand" "")
15959         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15960   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15961    && !reload_completed && !reload_in_progress"
15962   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15963   "")
15965 (define_insn "*tandf3_1"
15966   [(set (match_operand:DF 0 "register_operand" "=f")
15967         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15968                    UNSPEC_TAN_ONE))
15969    (set (match_operand:DF 1 "register_operand" "=u")
15970         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15971   "TARGET_USE_FANCY_MATH_387
15972    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15973    && flag_unsafe_math_optimizations"
15974   "fptan"
15975   [(set_attr "type" "fpspc")
15976    (set_attr "mode" "DF")])
15978 ;; optimize sequence: fptan
15979 ;;                    fstp    %st(0)
15980 ;;                    fld1
15981 ;; into fptan insn.
15983 (define_peephole2
15984   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15985                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15986                              UNSPEC_TAN_ONE))
15987              (set (match_operand:DF 1 "register_operand" "")
15988                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15989    (set (match_dup 0)
15990         (match_operand:DF 3 "immediate_operand" ""))]
15991   "standard_80387_constant_p (operands[3]) == 2"
15992   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15993              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15994   "")
15996 (define_expand "tandf2"
15997   [(parallel [(set (match_dup 2)
15998                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15999                               UNSPEC_TAN_ONE))
16000               (set (match_operand:DF 0 "register_operand" "")
16001                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16002   "TARGET_USE_FANCY_MATH_387
16003    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16004    && flag_unsafe_math_optimizations"
16006   operands[2] = gen_reg_rtx (DFmode);
16009 (define_insn "*tansf3_1"
16010   [(set (match_operand:SF 0 "register_operand" "=f")
16011         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16012                    UNSPEC_TAN_ONE))
16013    (set (match_operand:SF 1 "register_operand" "=u")
16014         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16015   "TARGET_USE_FANCY_MATH_387
16016    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16017    && flag_unsafe_math_optimizations"
16018   "fptan"
16019   [(set_attr "type" "fpspc")
16020    (set_attr "mode" "SF")])
16022 ;; optimize sequence: fptan
16023 ;;                    fstp    %st(0)
16024 ;;                    fld1
16025 ;; into fptan insn.
16027 (define_peephole2
16028   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16029                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16030                              UNSPEC_TAN_ONE))
16031              (set (match_operand:SF 1 "register_operand" "")
16032                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16033    (set (match_dup 0)
16034         (match_operand:SF 3 "immediate_operand" ""))]
16035   "standard_80387_constant_p (operands[3]) == 2"
16036   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16037              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16038   "")
16040 (define_expand "tansf2"
16041   [(parallel [(set (match_dup 2)
16042                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16043                               UNSPEC_TAN_ONE))
16044               (set (match_operand:SF 0 "register_operand" "")
16045                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16046   "TARGET_USE_FANCY_MATH_387
16047    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16048    && flag_unsafe_math_optimizations"
16050   operands[2] = gen_reg_rtx (SFmode);
16053 (define_insn "*tanxf3_1"
16054   [(set (match_operand:XF 0 "register_operand" "=f")
16055         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16056                    UNSPEC_TAN_ONE))
16057    (set (match_operand:XF 1 "register_operand" "=u")
16058         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16059   "TARGET_USE_FANCY_MATH_387
16060    && flag_unsafe_math_optimizations"
16061   "fptan"
16062   [(set_attr "type" "fpspc")
16063    (set_attr "mode" "XF")])
16065 ;; optimize sequence: fptan
16066 ;;                    fstp    %st(0)
16067 ;;                    fld1
16068 ;; into fptan insn.
16070 (define_peephole2
16071   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16072                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16073                              UNSPEC_TAN_ONE))
16074              (set (match_operand:XF 1 "register_operand" "")
16075                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16076    (set (match_dup 0)
16077         (match_operand:XF 3 "immediate_operand" ""))]
16078   "standard_80387_constant_p (operands[3]) == 2"
16079   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16080              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16081   "")
16083 (define_expand "tanxf2"
16084   [(parallel [(set (match_dup 2)
16085                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16086                               UNSPEC_TAN_ONE))
16087               (set (match_operand:XF 0 "register_operand" "")
16088                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16089   "TARGET_USE_FANCY_MATH_387
16090    && flag_unsafe_math_optimizations"
16092   operands[2] = gen_reg_rtx (XFmode);
16095 (define_insn "atan2df3_1"
16096   [(set (match_operand:DF 0 "register_operand" "=f")
16097         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16098                     (match_operand:DF 1 "register_operand" "u")]
16099                    UNSPEC_FPATAN))
16100    (clobber (match_scratch:DF 3 "=1"))]
16101   "TARGET_USE_FANCY_MATH_387
16102    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16103    && flag_unsafe_math_optimizations"
16104   "fpatan"
16105   [(set_attr "type" "fpspc")
16106    (set_attr "mode" "DF")])
16108 (define_expand "atan2df3"
16109   [(use (match_operand:DF 0 "register_operand" ""))
16110    (use (match_operand:DF 2 "register_operand" ""))
16111    (use (match_operand:DF 1 "register_operand" ""))]
16112   "TARGET_USE_FANCY_MATH_387
16113    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16114    && flag_unsafe_math_optimizations"
16116   rtx copy = gen_reg_rtx (DFmode);
16117   emit_move_insn (copy, operands[1]);
16118   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16119   DONE;
16122 (define_expand "atandf2"
16123   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16124                    (unspec:DF [(match_dup 2)
16125                                (match_operand:DF 1 "register_operand" "")]
16126                     UNSPEC_FPATAN))
16127               (clobber (match_scratch:DF 3 ""))])]
16128   "TARGET_USE_FANCY_MATH_387
16129    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16130    && flag_unsafe_math_optimizations"
16132   operands[2] = gen_reg_rtx (DFmode);
16133   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16136 (define_insn "atan2sf3_1"
16137   [(set (match_operand:SF 0 "register_operand" "=f")
16138         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16139                     (match_operand:SF 1 "register_operand" "u")]
16140                    UNSPEC_FPATAN))
16141    (clobber (match_scratch:SF 3 "=1"))]
16142   "TARGET_USE_FANCY_MATH_387
16143    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16144    && flag_unsafe_math_optimizations"
16145   "fpatan"
16146   [(set_attr "type" "fpspc")
16147    (set_attr "mode" "SF")])
16149 (define_expand "atan2sf3"
16150   [(use (match_operand:SF 0 "register_operand" ""))
16151    (use (match_operand:SF 2 "register_operand" ""))
16152    (use (match_operand:SF 1 "register_operand" ""))]
16153   "TARGET_USE_FANCY_MATH_387
16154    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16155    && flag_unsafe_math_optimizations"
16157   rtx copy = gen_reg_rtx (SFmode);
16158   emit_move_insn (copy, operands[1]);
16159   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16160   DONE;
16163 (define_expand "atansf2"
16164   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16165                    (unspec:SF [(match_dup 2)
16166                                (match_operand:SF 1 "register_operand" "")]
16167                     UNSPEC_FPATAN))
16168               (clobber (match_scratch:SF 3 ""))])]
16169   "TARGET_USE_FANCY_MATH_387
16170    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16171    && flag_unsafe_math_optimizations"
16173   operands[2] = gen_reg_rtx (SFmode);
16174   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16177 (define_insn "atan2xf3_1"
16178   [(set (match_operand:XF 0 "register_operand" "=f")
16179         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16180                     (match_operand:XF 1 "register_operand" "u")]
16181                    UNSPEC_FPATAN))
16182    (clobber (match_scratch:XF 3 "=1"))]
16183   "TARGET_USE_FANCY_MATH_387
16184    && flag_unsafe_math_optimizations"
16185   "fpatan"
16186   [(set_attr "type" "fpspc")
16187    (set_attr "mode" "XF")])
16189 (define_expand "atan2xf3"
16190   [(use (match_operand:XF 0 "register_operand" ""))
16191    (use (match_operand:XF 2 "register_operand" ""))
16192    (use (match_operand:XF 1 "register_operand" ""))]
16193   "TARGET_USE_FANCY_MATH_387
16194    && flag_unsafe_math_optimizations"
16196   rtx copy = gen_reg_rtx (XFmode);
16197   emit_move_insn (copy, operands[1]);
16198   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16199   DONE;
16202 (define_expand "atanxf2"
16203   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16204                    (unspec:XF [(match_dup 2)
16205                                (match_operand:XF 1 "register_operand" "")]
16206                     UNSPEC_FPATAN))
16207               (clobber (match_scratch:XF 3 ""))])]
16208   "TARGET_USE_FANCY_MATH_387
16209    && flag_unsafe_math_optimizations"
16211   operands[2] = gen_reg_rtx (XFmode);
16212   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16215 (define_expand "asindf2"
16216   [(set (match_dup 2)
16217         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16218    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16219    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16220    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16221    (parallel [(set (match_dup 7)
16222                    (unspec:XF [(match_dup 6) (match_dup 2)]
16223                               UNSPEC_FPATAN))
16224               (clobber (match_scratch:XF 8 ""))])
16225    (set (match_operand:DF 0 "register_operand" "")
16226         (float_truncate:DF (match_dup 7)))]
16227   "TARGET_USE_FANCY_MATH_387
16228    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16229    && flag_unsafe_math_optimizations && !optimize_size"
16231   int i;
16233   for (i=2; i<8; i++)
16234     operands[i] = gen_reg_rtx (XFmode);
16236   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16239 (define_expand "asinsf2"
16240   [(set (match_dup 2)
16241         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16242    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16243    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16244    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16245    (parallel [(set (match_dup 7)
16246                    (unspec:XF [(match_dup 6) (match_dup 2)]
16247                               UNSPEC_FPATAN))
16248               (clobber (match_scratch:XF 8 ""))])
16249    (set (match_operand:SF 0 "register_operand" "")
16250         (float_truncate:SF (match_dup 7)))]
16251   "TARGET_USE_FANCY_MATH_387
16252    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16253    && flag_unsafe_math_optimizations && !optimize_size"
16255   int i;
16257   for (i=2; i<8; i++)
16258     operands[i] = gen_reg_rtx (XFmode);
16260   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16263 (define_expand "asinxf2"
16264   [(set (match_dup 2)
16265         (mult:XF (match_operand:XF 1 "register_operand" "")
16266                  (match_dup 1)))
16267    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16268    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16269    (parallel [(set (match_operand:XF 0 "register_operand" "")
16270                    (unspec:XF [(match_dup 5) (match_dup 1)]
16271                               UNSPEC_FPATAN))
16272               (clobber (match_scratch:XF 6 ""))])]
16273   "TARGET_USE_FANCY_MATH_387
16274    && flag_unsafe_math_optimizations && !optimize_size"
16276   int i;
16278   for (i=2; i<6; i++)
16279     operands[i] = gen_reg_rtx (XFmode);
16281   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16284 (define_expand "acosdf2"
16285   [(set (match_dup 2)
16286         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16287    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16288    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16289    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16290    (parallel [(set (match_dup 7)
16291                    (unspec:XF [(match_dup 2) (match_dup 6)]
16292                               UNSPEC_FPATAN))
16293               (clobber (match_scratch:XF 8 ""))])
16294    (set (match_operand:DF 0 "register_operand" "")
16295         (float_truncate:DF (match_dup 7)))]
16296   "TARGET_USE_FANCY_MATH_387
16297    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16298    && flag_unsafe_math_optimizations && !optimize_size"
16300   int i;
16302   for (i=2; i<8; i++)
16303     operands[i] = gen_reg_rtx (XFmode);
16305   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16308 (define_expand "acossf2"
16309   [(set (match_dup 2)
16310         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16311    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16312    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16313    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16314    (parallel [(set (match_dup 7)
16315                    (unspec:XF [(match_dup 2) (match_dup 6)]
16316                               UNSPEC_FPATAN))
16317               (clobber (match_scratch:XF 8 ""))])
16318    (set (match_operand:SF 0 "register_operand" "")
16319         (float_truncate:SF (match_dup 7)))]
16320   "TARGET_USE_FANCY_MATH_387
16321    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16322    && flag_unsafe_math_optimizations && !optimize_size"
16324   int i;
16326   for (i=2; i<8; i++)
16327     operands[i] = gen_reg_rtx (XFmode);
16329   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16332 (define_expand "acosxf2"
16333   [(set (match_dup 2)
16334         (mult:XF (match_operand:XF 1 "register_operand" "")
16335                  (match_dup 1)))
16336    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16337    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16338    (parallel [(set (match_operand:XF 0 "register_operand" "")
16339                    (unspec:XF [(match_dup 1) (match_dup 5)]
16340                               UNSPEC_FPATAN))
16341               (clobber (match_scratch:XF 6 ""))])]
16342   "TARGET_USE_FANCY_MATH_387
16343    && flag_unsafe_math_optimizations && !optimize_size"
16345   int i;
16347   for (i=2; i<6; i++)
16348     operands[i] = gen_reg_rtx (XFmode);
16350   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16353 (define_insn "fyl2x_xf3"
16354   [(set (match_operand:XF 0 "register_operand" "=f")
16355         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16356                     (match_operand:XF 1 "register_operand" "u")]
16357                    UNSPEC_FYL2X))
16358    (clobber (match_scratch:XF 3 "=1"))]
16359   "TARGET_USE_FANCY_MATH_387
16360    && flag_unsafe_math_optimizations"
16361   "fyl2x"
16362   [(set_attr "type" "fpspc")
16363    (set_attr "mode" "XF")])
16365 (define_expand "logsf2"
16366   [(set (match_dup 2)
16367         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16368    (parallel [(set (match_dup 4)
16369                    (unspec:XF [(match_dup 2)
16370                                (match_dup 3)] UNSPEC_FYL2X))
16371               (clobber (match_scratch:XF 5 ""))])
16372    (set (match_operand:SF 0 "register_operand" "")
16373         (float_truncate:SF (match_dup 4)))]
16374   "TARGET_USE_FANCY_MATH_387
16375    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16376    && flag_unsafe_math_optimizations"
16378   rtx temp;
16380   operands[2] = gen_reg_rtx (XFmode);
16381   operands[3] = gen_reg_rtx (XFmode);
16382   operands[4] = gen_reg_rtx (XFmode);
16384   temp = standard_80387_constant_rtx (4); /* fldln2 */
16385   emit_move_insn (operands[3], temp);
16388 (define_expand "logdf2"
16389   [(set (match_dup 2)
16390         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16391    (parallel [(set (match_dup 4)
16392                    (unspec:XF [(match_dup 2)
16393                                (match_dup 3)] UNSPEC_FYL2X))
16394               (clobber (match_scratch:XF 5 ""))])
16395    (set (match_operand:DF 0 "register_operand" "")
16396         (float_truncate:DF (match_dup 4)))]
16397   "TARGET_USE_FANCY_MATH_387
16398    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16399    && flag_unsafe_math_optimizations"
16401   rtx temp;
16403   operands[2] = gen_reg_rtx (XFmode);
16404   operands[3] = gen_reg_rtx (XFmode);
16405   operands[4] = gen_reg_rtx (XFmode);
16407   temp = standard_80387_constant_rtx (4); /* fldln2 */
16408   emit_move_insn (operands[3], temp);
16411 (define_expand "logxf2"
16412   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16413                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16414                                (match_dup 2)] UNSPEC_FYL2X))
16415               (clobber (match_scratch:XF 3 ""))])]
16416   "TARGET_USE_FANCY_MATH_387
16417    && flag_unsafe_math_optimizations"
16419   rtx temp;
16421   operands[2] = gen_reg_rtx (XFmode);
16422   temp = standard_80387_constant_rtx (4); /* fldln2 */
16423   emit_move_insn (operands[2], temp);
16426 (define_expand "log10sf2"
16427   [(set (match_dup 2)
16428         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16429    (parallel [(set (match_dup 4)
16430                    (unspec:XF [(match_dup 2)
16431                                (match_dup 3)] UNSPEC_FYL2X))
16432               (clobber (match_scratch:XF 5 ""))])
16433    (set (match_operand:SF 0 "register_operand" "")
16434         (float_truncate:SF (match_dup 4)))]
16435   "TARGET_USE_FANCY_MATH_387
16436    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16437    && flag_unsafe_math_optimizations"
16439   rtx temp;
16441   operands[2] = gen_reg_rtx (XFmode);
16442   operands[3] = gen_reg_rtx (XFmode);
16443   operands[4] = gen_reg_rtx (XFmode);
16445   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16446   emit_move_insn (operands[3], temp);
16449 (define_expand "log10df2"
16450   [(set (match_dup 2)
16451         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16452    (parallel [(set (match_dup 4)
16453                    (unspec:XF [(match_dup 2)
16454                                (match_dup 3)] UNSPEC_FYL2X))
16455               (clobber (match_scratch:XF 5 ""))])
16456    (set (match_operand:DF 0 "register_operand" "")
16457         (float_truncate:DF (match_dup 4)))]
16458   "TARGET_USE_FANCY_MATH_387
16459    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16460    && flag_unsafe_math_optimizations"
16462   rtx temp;
16464   operands[2] = gen_reg_rtx (XFmode);
16465   operands[3] = gen_reg_rtx (XFmode);
16466   operands[4] = gen_reg_rtx (XFmode);
16468   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16469   emit_move_insn (operands[3], temp);
16472 (define_expand "log10xf2"
16473   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16474                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16475                                (match_dup 2)] UNSPEC_FYL2X))
16476               (clobber (match_scratch:XF 3 ""))])]
16477   "TARGET_USE_FANCY_MATH_387
16478    && flag_unsafe_math_optimizations"
16480   rtx temp;
16482   operands[2] = gen_reg_rtx (XFmode);
16483   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16484   emit_move_insn (operands[2], temp);
16487 (define_expand "log2sf2"
16488   [(set (match_dup 2)
16489         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16490    (parallel [(set (match_dup 4)
16491                    (unspec:XF [(match_dup 2)
16492                                (match_dup 3)] UNSPEC_FYL2X))
16493               (clobber (match_scratch:XF 5 ""))])
16494    (set (match_operand:SF 0 "register_operand" "")
16495         (float_truncate:SF (match_dup 4)))]
16496   "TARGET_USE_FANCY_MATH_387
16497    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16498    && flag_unsafe_math_optimizations"
16500   operands[2] = gen_reg_rtx (XFmode);
16501   operands[3] = gen_reg_rtx (XFmode);
16502   operands[4] = gen_reg_rtx (XFmode);
16504   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16507 (define_expand "log2df2"
16508   [(set (match_dup 2)
16509         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16510    (parallel [(set (match_dup 4)
16511                    (unspec:XF [(match_dup 2)
16512                                (match_dup 3)] UNSPEC_FYL2X))
16513               (clobber (match_scratch:XF 5 ""))])
16514    (set (match_operand:DF 0 "register_operand" "")
16515         (float_truncate:DF (match_dup 4)))]
16516   "TARGET_USE_FANCY_MATH_387
16517    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16518    && flag_unsafe_math_optimizations"
16520   operands[2] = gen_reg_rtx (XFmode);
16521   operands[3] = gen_reg_rtx (XFmode);
16522   operands[4] = gen_reg_rtx (XFmode);
16524   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16527 (define_expand "log2xf2"
16528   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16529                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16530                                (match_dup 2)] UNSPEC_FYL2X))
16531               (clobber (match_scratch:XF 3 ""))])]
16532   "TARGET_USE_FANCY_MATH_387
16533    && flag_unsafe_math_optimizations"
16535   operands[2] = gen_reg_rtx (XFmode);
16536   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16539 (define_insn "fyl2xp1_xf3"
16540   [(set (match_operand:XF 0 "register_operand" "=f")
16541         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16542                     (match_operand:XF 1 "register_operand" "u")]
16543                    UNSPEC_FYL2XP1))
16544    (clobber (match_scratch:XF 3 "=1"))]
16545   "TARGET_USE_FANCY_MATH_387
16546    && flag_unsafe_math_optimizations"
16547   "fyl2xp1"
16548   [(set_attr "type" "fpspc")
16549    (set_attr "mode" "XF")])
16551 (define_expand "log1psf2"
16552   [(use (match_operand:SF 0 "register_operand" ""))
16553    (use (match_operand:SF 1 "register_operand" ""))]
16554   "TARGET_USE_FANCY_MATH_387
16555    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16556    && flag_unsafe_math_optimizations && !optimize_size"
16558   rtx op0 = gen_reg_rtx (XFmode);
16559   rtx op1 = gen_reg_rtx (XFmode);
16561   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16562   ix86_emit_i387_log1p (op0, op1);
16563   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16564   DONE;
16567 (define_expand "log1pdf2"
16568   [(use (match_operand:DF 0 "register_operand" ""))
16569    (use (match_operand:DF 1 "register_operand" ""))]
16570   "TARGET_USE_FANCY_MATH_387
16571    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16572    && flag_unsafe_math_optimizations && !optimize_size"
16574   rtx op0 = gen_reg_rtx (XFmode);
16575   rtx op1 = gen_reg_rtx (XFmode);
16577   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16578   ix86_emit_i387_log1p (op0, op1);
16579   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16580   DONE;
16583 (define_expand "log1pxf2"
16584   [(use (match_operand:XF 0 "register_operand" ""))
16585    (use (match_operand:XF 1 "register_operand" ""))]
16586   "TARGET_USE_FANCY_MATH_387
16587    && flag_unsafe_math_optimizations && !optimize_size"
16589   ix86_emit_i387_log1p (operands[0], operands[1]);
16590   DONE;
16593 (define_insn "*fxtractxf3"
16594   [(set (match_operand:XF 0 "register_operand" "=f")
16595         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16596                    UNSPEC_XTRACT_FRACT))
16597    (set (match_operand:XF 1 "register_operand" "=u")
16598         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16599   "TARGET_USE_FANCY_MATH_387
16600    && flag_unsafe_math_optimizations"
16601   "fxtract"
16602   [(set_attr "type" "fpspc")
16603    (set_attr "mode" "XF")])
16605 (define_expand "logbsf2"
16606   [(set (match_dup 2)
16607         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16608    (parallel [(set (match_dup 3)
16609                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16610               (set (match_dup 4)
16611                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16612    (set (match_operand:SF 0 "register_operand" "")
16613         (float_truncate:SF (match_dup 4)))]
16614   "TARGET_USE_FANCY_MATH_387
16615    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16616    && flag_unsafe_math_optimizations"
16618   operands[2] = gen_reg_rtx (XFmode);
16619   operands[3] = gen_reg_rtx (XFmode);
16620   operands[4] = gen_reg_rtx (XFmode);
16623 (define_expand "logbdf2"
16624   [(set (match_dup 2)
16625         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16626    (parallel [(set (match_dup 3)
16627                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16628               (set (match_dup 4)
16629                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16630    (set (match_operand:DF 0 "register_operand" "")
16631         (float_truncate:DF (match_dup 4)))]
16632   "TARGET_USE_FANCY_MATH_387
16633    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16634    && flag_unsafe_math_optimizations"
16636   operands[2] = gen_reg_rtx (XFmode);
16637   operands[3] = gen_reg_rtx (XFmode);
16638   operands[4] = gen_reg_rtx (XFmode);
16641 (define_expand "logbxf2"
16642   [(parallel [(set (match_dup 2)
16643                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16644                               UNSPEC_XTRACT_FRACT))
16645               (set (match_operand:XF 0 "register_operand" "")
16646                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16647   "TARGET_USE_FANCY_MATH_387
16648    && flag_unsafe_math_optimizations"
16650   operands[2] = gen_reg_rtx (XFmode);
16653 (define_expand "ilogbsi2"
16654   [(parallel [(set (match_dup 2)
16655                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16656                               UNSPEC_XTRACT_FRACT))
16657               (set (match_operand:XF 3 "register_operand" "")
16658                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16659    (parallel [(set (match_operand:SI 0 "register_operand" "")
16660                    (fix:SI (match_dup 3)))
16661               (clobber (reg:CC FLAGS_REG))])]
16662   "TARGET_USE_FANCY_MATH_387
16663    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16664    && flag_unsafe_math_optimizations && !optimize_size"
16666   operands[2] = gen_reg_rtx (XFmode);
16667   operands[3] = gen_reg_rtx (XFmode);
16670 (define_insn "*f2xm1xf2"
16671   [(set (match_operand:XF 0 "register_operand" "=f")
16672         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16673          UNSPEC_F2XM1))]
16674   "TARGET_USE_FANCY_MATH_387
16675    && flag_unsafe_math_optimizations"
16676   "f2xm1"
16677   [(set_attr "type" "fpspc")
16678    (set_attr "mode" "XF")])
16680 (define_insn "*fscalexf4"
16681   [(set (match_operand:XF 0 "register_operand" "=f")
16682         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16683                     (match_operand:XF 3 "register_operand" "1")]
16684                    UNSPEC_FSCALE_FRACT))
16685    (set (match_operand:XF 1 "register_operand" "=u")
16686         (unspec:XF [(match_dup 2) (match_dup 3)]
16687                    UNSPEC_FSCALE_EXP))]
16688   "TARGET_USE_FANCY_MATH_387
16689    && flag_unsafe_math_optimizations"
16690   "fscale"
16691   [(set_attr "type" "fpspc")
16692    (set_attr "mode" "XF")])
16694 (define_expand "expsf2"
16695   [(set (match_dup 2)
16696         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16697    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16698    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16699    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16700    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16701    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16702    (parallel [(set (match_dup 10)
16703                    (unspec:XF [(match_dup 9) (match_dup 5)]
16704                               UNSPEC_FSCALE_FRACT))
16705               (set (match_dup 11)
16706                    (unspec:XF [(match_dup 9) (match_dup 5)]
16707                               UNSPEC_FSCALE_EXP))])
16708    (set (match_operand:SF 0 "register_operand" "")
16709         (float_truncate:SF (match_dup 10)))]
16710   "TARGET_USE_FANCY_MATH_387
16711    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16712    && flag_unsafe_math_optimizations && !optimize_size"
16714   rtx temp;
16715   int i;
16717   for (i=2; i<12; i++)
16718     operands[i] = gen_reg_rtx (XFmode);
16719   temp = standard_80387_constant_rtx (5); /* fldl2e */
16720   emit_move_insn (operands[3], temp);
16721   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16724 (define_expand "expdf2"
16725   [(set (match_dup 2)
16726         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16727    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16728    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16729    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16730    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16731    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16732    (parallel [(set (match_dup 10)
16733                    (unspec:XF [(match_dup 9) (match_dup 5)]
16734                               UNSPEC_FSCALE_FRACT))
16735               (set (match_dup 11)
16736                    (unspec:XF [(match_dup 9) (match_dup 5)]
16737                               UNSPEC_FSCALE_EXP))])
16738    (set (match_operand:DF 0 "register_operand" "")
16739         (float_truncate:DF (match_dup 10)))]
16740   "TARGET_USE_FANCY_MATH_387
16741    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16742    && flag_unsafe_math_optimizations && !optimize_size"
16744   rtx temp;
16745   int i;
16747   for (i=2; i<12; i++)
16748     operands[i] = gen_reg_rtx (XFmode);
16749   temp = standard_80387_constant_rtx (5); /* fldl2e */
16750   emit_move_insn (operands[3], temp);
16751   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16754 (define_expand "expxf2"
16755   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16756                                (match_dup 2)))
16757    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16758    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16759    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16760    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16761    (parallel [(set (match_operand:XF 0 "register_operand" "")
16762                    (unspec:XF [(match_dup 8) (match_dup 4)]
16763                               UNSPEC_FSCALE_FRACT))
16764               (set (match_dup 9)
16765                    (unspec:XF [(match_dup 8) (match_dup 4)]
16766                               UNSPEC_FSCALE_EXP))])]
16767   "TARGET_USE_FANCY_MATH_387
16768    && flag_unsafe_math_optimizations && !optimize_size"
16770   rtx temp;
16771   int i;
16773   for (i=2; i<10; i++)
16774     operands[i] = gen_reg_rtx (XFmode);
16775   temp = standard_80387_constant_rtx (5); /* fldl2e */
16776   emit_move_insn (operands[2], temp);
16777   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16780 (define_expand "exp10sf2"
16781   [(set (match_dup 2)
16782         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16783    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16784    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16785    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16786    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16787    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16788    (parallel [(set (match_dup 10)
16789                    (unspec:XF [(match_dup 9) (match_dup 5)]
16790                               UNSPEC_FSCALE_FRACT))
16791               (set (match_dup 11)
16792                    (unspec:XF [(match_dup 9) (match_dup 5)]
16793                               UNSPEC_FSCALE_EXP))])
16794    (set (match_operand:SF 0 "register_operand" "")
16795         (float_truncate:SF (match_dup 10)))]
16796   "TARGET_USE_FANCY_MATH_387
16797    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16798    && flag_unsafe_math_optimizations && !optimize_size"
16800   rtx temp;
16801   int i;
16803   for (i=2; i<12; i++)
16804     operands[i] = gen_reg_rtx (XFmode);
16805   temp = standard_80387_constant_rtx (6); /* fldl2t */
16806   emit_move_insn (operands[3], temp);
16807   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16810 (define_expand "exp10df2"
16811   [(set (match_dup 2)
16812         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16813    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16814    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16815    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16816    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16817    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16818    (parallel [(set (match_dup 10)
16819                    (unspec:XF [(match_dup 9) (match_dup 5)]
16820                               UNSPEC_FSCALE_FRACT))
16821               (set (match_dup 11)
16822                    (unspec:XF [(match_dup 9) (match_dup 5)]
16823                               UNSPEC_FSCALE_EXP))])
16824    (set (match_operand:DF 0 "register_operand" "")
16825         (float_truncate:DF (match_dup 10)))]
16826   "TARGET_USE_FANCY_MATH_387
16827    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16828    && flag_unsafe_math_optimizations && !optimize_size"
16830   rtx temp;
16831   int i;
16833   for (i=2; i<12; i++)
16834     operands[i] = gen_reg_rtx (XFmode);
16835   temp = standard_80387_constant_rtx (6); /* fldl2t */
16836   emit_move_insn (operands[3], temp);
16837   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16840 (define_expand "exp10xf2"
16841   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16842                                (match_dup 2)))
16843    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16844    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16845    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16846    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16847    (parallel [(set (match_operand:XF 0 "register_operand" "")
16848                    (unspec:XF [(match_dup 8) (match_dup 4)]
16849                               UNSPEC_FSCALE_FRACT))
16850               (set (match_dup 9)
16851                    (unspec:XF [(match_dup 8) (match_dup 4)]
16852                               UNSPEC_FSCALE_EXP))])]
16853   "TARGET_USE_FANCY_MATH_387
16854    && flag_unsafe_math_optimizations && !optimize_size"
16856   rtx temp;
16857   int i;
16859   for (i=2; i<10; i++)
16860     operands[i] = gen_reg_rtx (XFmode);
16861   temp = standard_80387_constant_rtx (6); /* fldl2t */
16862   emit_move_insn (operands[2], temp);
16863   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16866 (define_expand "exp2sf2"
16867   [(set (match_dup 2)
16868         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16869    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16870    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16871    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16872    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16873    (parallel [(set (match_dup 8)
16874                    (unspec:XF [(match_dup 7) (match_dup 3)]
16875                               UNSPEC_FSCALE_FRACT))
16876               (set (match_dup 9)
16877                    (unspec:XF [(match_dup 7) (match_dup 3)]
16878                               UNSPEC_FSCALE_EXP))])
16879    (set (match_operand:SF 0 "register_operand" "")
16880         (float_truncate:SF (match_dup 8)))]
16881   "TARGET_USE_FANCY_MATH_387
16882    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16883    && flag_unsafe_math_optimizations && !optimize_size"
16885   int i;
16887   for (i=2; i<10; i++)
16888     operands[i] = gen_reg_rtx (XFmode);
16889   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16892 (define_expand "exp2df2"
16893   [(set (match_dup 2)
16894         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16895    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16896    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16897    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16898    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16899    (parallel [(set (match_dup 8)
16900                    (unspec:XF [(match_dup 7) (match_dup 3)]
16901                               UNSPEC_FSCALE_FRACT))
16902               (set (match_dup 9)
16903                    (unspec:XF [(match_dup 7) (match_dup 3)]
16904                               UNSPEC_FSCALE_EXP))])
16905    (set (match_operand:DF 0 "register_operand" "")
16906         (float_truncate:DF (match_dup 8)))]
16907   "TARGET_USE_FANCY_MATH_387
16908    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16909    && flag_unsafe_math_optimizations && !optimize_size"
16911   int i;
16913   for (i=2; i<10; i++)
16914     operands[i] = gen_reg_rtx (XFmode);
16915   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16918 (define_expand "exp2xf2"
16919   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16920    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16921    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16922    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16923    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16924    (parallel [(set (match_operand:XF 0 "register_operand" "")
16925                    (unspec:XF [(match_dup 7) (match_dup 3)]
16926                               UNSPEC_FSCALE_FRACT))
16927               (set (match_dup 8)
16928                    (unspec:XF [(match_dup 7) (match_dup 3)]
16929                               UNSPEC_FSCALE_EXP))])]
16930   "TARGET_USE_FANCY_MATH_387
16931    && flag_unsafe_math_optimizations && !optimize_size"
16933   int i;
16935   for (i=2; i<9; i++)
16936     operands[i] = gen_reg_rtx (XFmode);
16937   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16940 (define_expand "expm1df2"
16941   [(set (match_dup 2)
16942         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16943    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16944    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16945    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16946    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16947    (parallel [(set (match_dup 8)
16948                    (unspec:XF [(match_dup 7) (match_dup 5)]
16949                               UNSPEC_FSCALE_FRACT))
16950                    (set (match_dup 9)
16951                    (unspec:XF [(match_dup 7) (match_dup 5)]
16952                               UNSPEC_FSCALE_EXP))])
16953    (parallel [(set (match_dup 11)
16954                    (unspec:XF [(match_dup 10) (match_dup 9)]
16955                               UNSPEC_FSCALE_FRACT))
16956               (set (match_dup 12)
16957                    (unspec:XF [(match_dup 10) (match_dup 9)]
16958                               UNSPEC_FSCALE_EXP))])
16959    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16960    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16961    (set (match_operand:DF 0 "register_operand" "")
16962         (float_truncate:DF (match_dup 14)))]
16963   "TARGET_USE_FANCY_MATH_387
16964    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16965    && flag_unsafe_math_optimizations && !optimize_size"
16967   rtx temp;
16968   int i;
16970   for (i=2; i<15; i++)
16971     operands[i] = gen_reg_rtx (XFmode);
16972   temp = standard_80387_constant_rtx (5); /* fldl2e */
16973   emit_move_insn (operands[3], temp);
16974   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16977 (define_expand "expm1sf2"
16978   [(set (match_dup 2)
16979         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16980    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16981    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16982    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16983    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16984    (parallel [(set (match_dup 8)
16985                    (unspec:XF [(match_dup 7) (match_dup 5)]
16986                               UNSPEC_FSCALE_FRACT))
16987                    (set (match_dup 9)
16988                    (unspec:XF [(match_dup 7) (match_dup 5)]
16989                               UNSPEC_FSCALE_EXP))])
16990    (parallel [(set (match_dup 11)
16991                    (unspec:XF [(match_dup 10) (match_dup 9)]
16992                               UNSPEC_FSCALE_FRACT))
16993               (set (match_dup 12)
16994                    (unspec:XF [(match_dup 10) (match_dup 9)]
16995                               UNSPEC_FSCALE_EXP))])
16996    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16997    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16998    (set (match_operand:SF 0 "register_operand" "")
16999         (float_truncate:SF (match_dup 14)))]
17000   "TARGET_USE_FANCY_MATH_387
17001    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17002    && flag_unsafe_math_optimizations && !optimize_size"
17004   rtx temp;
17005   int i;
17007   for (i=2; i<15; i++)
17008     operands[i] = gen_reg_rtx (XFmode);
17009   temp = standard_80387_constant_rtx (5); /* fldl2e */
17010   emit_move_insn (operands[3], temp);
17011   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17014 (define_expand "expm1xf2"
17015   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17016                                (match_dup 2)))
17017    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17018    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17019    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17020    (parallel [(set (match_dup 7)
17021                    (unspec:XF [(match_dup 6) (match_dup 4)]
17022                               UNSPEC_FSCALE_FRACT))
17023                    (set (match_dup 8)
17024                    (unspec:XF [(match_dup 6) (match_dup 4)]
17025                               UNSPEC_FSCALE_EXP))])
17026    (parallel [(set (match_dup 10)
17027                    (unspec:XF [(match_dup 9) (match_dup 8)]
17028                               UNSPEC_FSCALE_FRACT))
17029               (set (match_dup 11)
17030                    (unspec:XF [(match_dup 9) (match_dup 8)]
17031                               UNSPEC_FSCALE_EXP))])
17032    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17033    (set (match_operand:XF 0 "register_operand" "")
17034         (plus:XF (match_dup 12) (match_dup 7)))]
17035   "TARGET_USE_FANCY_MATH_387
17036    && flag_unsafe_math_optimizations && !optimize_size"
17038   rtx temp;
17039   int i;
17041   for (i=2; i<13; i++)
17042     operands[i] = gen_reg_rtx (XFmode);
17043   temp = standard_80387_constant_rtx (5); /* fldl2e */
17044   emit_move_insn (operands[2], temp);
17045   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17048 (define_expand "ldexpdf3"
17049   [(set (match_dup 3)
17050         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17051    (set (match_dup 4)
17052         (float:XF (match_operand:SI 2 "register_operand" "")))
17053    (parallel [(set (match_dup 5)
17054                    (unspec:XF [(match_dup 3) (match_dup 4)]
17055                               UNSPEC_FSCALE_FRACT))
17056               (set (match_dup 6)
17057                    (unspec:XF [(match_dup 3) (match_dup 4)]
17058                               UNSPEC_FSCALE_EXP))])
17059    (set (match_operand:DF 0 "register_operand" "")
17060         (float_truncate:DF (match_dup 5)))]
17061   "TARGET_USE_FANCY_MATH_387
17062    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17063    && flag_unsafe_math_optimizations && !optimize_size"
17065   int i;
17067   for (i=3; i<7; i++)
17068     operands[i] = gen_reg_rtx (XFmode);
17071 (define_expand "ldexpsf3"
17072   [(set (match_dup 3)
17073         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17074    (set (match_dup 4)
17075         (float:XF (match_operand:SI 2 "register_operand" "")))
17076    (parallel [(set (match_dup 5)
17077                    (unspec:XF [(match_dup 3) (match_dup 4)]
17078                               UNSPEC_FSCALE_FRACT))
17079               (set (match_dup 6)
17080                    (unspec:XF [(match_dup 3) (match_dup 4)]
17081                               UNSPEC_FSCALE_EXP))])
17082    (set (match_operand:SF 0 "register_operand" "")
17083         (float_truncate:SF (match_dup 5)))]
17084   "TARGET_USE_FANCY_MATH_387
17085    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17086    && flag_unsafe_math_optimizations && !optimize_size"
17088   int i;
17090   for (i=3; i<7; i++)
17091     operands[i] = gen_reg_rtx (XFmode);
17094 (define_expand "ldexpxf3"
17095   [(set (match_dup 3)
17096         (float:XF (match_operand:SI 2 "register_operand" "")))
17097    (parallel [(set (match_operand:XF 0 " register_operand" "")
17098                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17099                                (match_dup 3)]
17100                               UNSPEC_FSCALE_FRACT))
17101               (set (match_dup 4)
17102                    (unspec:XF [(match_dup 1) (match_dup 3)]
17103                               UNSPEC_FSCALE_EXP))])]
17104   "TARGET_USE_FANCY_MATH_387
17105    && flag_unsafe_math_optimizations && !optimize_size"
17107   int i;
17109   for (i=3; i<5; i++)
17110     operands[i] = gen_reg_rtx (XFmode);
17114 (define_insn "frndintxf2"
17115   [(set (match_operand:XF 0 "register_operand" "=f")
17116         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17117          UNSPEC_FRNDINT))]
17118   "TARGET_USE_FANCY_MATH_387
17119    && flag_unsafe_math_optimizations"
17120   "frndint"
17121   [(set_attr "type" "fpspc")
17122    (set_attr "mode" "XF")])
17124 (define_expand "rintdf2"
17125   [(use (match_operand:DF 0 "register_operand" ""))
17126    (use (match_operand:DF 1 "register_operand" ""))]
17127   "(TARGET_USE_FANCY_MATH_387
17128     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17129     && flag_unsafe_math_optimizations)
17130    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17131        && !flag_trapping_math
17132        && !optimize_size)"
17134   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17135       && !flag_trapping_math
17136       && !optimize_size)
17137     ix86_expand_rint (operand0, operand1);
17138   else
17139     {
17140       rtx op0 = gen_reg_rtx (XFmode);
17141       rtx op1 = gen_reg_rtx (XFmode);
17143       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17144       emit_insn (gen_frndintxf2 (op0, op1));
17146       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17147     }
17148   DONE;
17151 (define_expand "rintsf2"
17152   [(use (match_operand:SF 0 "register_operand" ""))
17153    (use (match_operand:SF 1 "register_operand" ""))]
17154   "(TARGET_USE_FANCY_MATH_387
17155     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17156     && flag_unsafe_math_optimizations)
17157    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17158        && !flag_trapping_math
17159        && !optimize_size)"
17161   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17162       && !flag_trapping_math
17163       && !optimize_size)
17164     ix86_expand_rint (operand0, operand1);
17165   else
17166     {
17167       rtx op0 = gen_reg_rtx (XFmode);
17168       rtx op1 = gen_reg_rtx (XFmode);
17170       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17171       emit_insn (gen_frndintxf2 (op0, op1));
17173       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17174     }
17175   DONE;
17178 (define_expand "rintxf2"
17179   [(use (match_operand:XF 0 "register_operand" ""))
17180    (use (match_operand:XF 1 "register_operand" ""))]
17181   "TARGET_USE_FANCY_MATH_387
17182    && flag_unsafe_math_optimizations && !optimize_size"
17184   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17185   DONE;
17188 (define_expand "roundsf2"
17189   [(match_operand:SF 0 "register_operand" "")
17190    (match_operand:SF 1 "nonimmediate_operand" "")]
17191   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17192    && !flag_trapping_math && !flag_rounding_math
17193    && !optimize_size"
17195   ix86_expand_round (operand0, operand1);
17196   DONE;
17199 (define_expand "rounddf2"
17200   [(match_operand:DF 0 "register_operand" "")
17201    (match_operand:DF 1 "nonimmediate_operand" "")]
17202   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17203    && !flag_trapping_math && !flag_rounding_math
17204    && !optimize_size"
17206   if (TARGET_64BIT)
17207     ix86_expand_round (operand0, operand1);
17208   else
17209     ix86_expand_rounddf_32 (operand0, operand1);
17210   DONE;
17213 (define_insn_and_split "*fistdi2_1"
17214   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17215         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17216          UNSPEC_FIST))]
17217   "TARGET_USE_FANCY_MATH_387
17218    && !(reload_completed || reload_in_progress)"
17219   "#"
17220   "&& 1"
17221   [(const_int 0)]
17223   if (memory_operand (operands[0], VOIDmode))
17224     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17225   else
17226     {
17227       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17228       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17229                                          operands[2]));
17230     }
17231   DONE;
17233   [(set_attr "type" "fpspc")
17234    (set_attr "mode" "DI")])
17236 (define_insn "fistdi2"
17237   [(set (match_operand:DI 0 "memory_operand" "=m")
17238         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17239          UNSPEC_FIST))
17240    (clobber (match_scratch:XF 2 "=&1f"))]
17241   "TARGET_USE_FANCY_MATH_387"
17242   "* return output_fix_trunc (insn, operands, 0);"
17243   [(set_attr "type" "fpspc")
17244    (set_attr "mode" "DI")])
17246 (define_insn "fistdi2_with_temp"
17247   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17248         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17249          UNSPEC_FIST))
17250    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17251    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17252   "TARGET_USE_FANCY_MATH_387"
17253   "#"
17254   [(set_attr "type" "fpspc")
17255    (set_attr "mode" "DI")])
17257 (define_split
17258   [(set (match_operand:DI 0 "register_operand" "")
17259         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17260          UNSPEC_FIST))
17261    (clobber (match_operand:DI 2 "memory_operand" ""))
17262    (clobber (match_scratch 3 ""))]
17263   "reload_completed"
17264   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17265               (clobber (match_dup 3))])
17266    (set (match_dup 0) (match_dup 2))]
17267   "")
17269 (define_split
17270   [(set (match_operand:DI 0 "memory_operand" "")
17271         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17272          UNSPEC_FIST))
17273    (clobber (match_operand:DI 2 "memory_operand" ""))
17274    (clobber (match_scratch 3 ""))]
17275   "reload_completed"
17276   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17277               (clobber (match_dup 3))])]
17278   "")
17280 (define_insn_and_split "*fist<mode>2_1"
17281   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17282         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17283          UNSPEC_FIST))]
17284   "TARGET_USE_FANCY_MATH_387
17285    && !(reload_completed || reload_in_progress)"
17286   "#"
17287   "&& 1"
17288   [(const_int 0)]
17290   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17291   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17292                                         operands[2]));
17293   DONE;
17295   [(set_attr "type" "fpspc")
17296    (set_attr "mode" "<MODE>")])
17298 (define_insn "fist<mode>2"
17299   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17300         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17301          UNSPEC_FIST))]
17302   "TARGET_USE_FANCY_MATH_387"
17303   "* return output_fix_trunc (insn, operands, 0);"
17304   [(set_attr "type" "fpspc")
17305    (set_attr "mode" "<MODE>")])
17307 (define_insn "fist<mode>2_with_temp"
17308   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17309         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17310          UNSPEC_FIST))
17311    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17312   "TARGET_USE_FANCY_MATH_387"
17313   "#"
17314   [(set_attr "type" "fpspc")
17315    (set_attr "mode" "<MODE>")])
17317 (define_split
17318   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17319         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17320          UNSPEC_FIST))
17321    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17322   "reload_completed"
17323   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17324                        UNSPEC_FIST))
17325    (set (match_dup 0) (match_dup 2))]
17326   "")
17328 (define_split
17329   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17330         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17331          UNSPEC_FIST))
17332    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17333   "reload_completed"
17334   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17335                        UNSPEC_FIST))]
17336   "")
17338 (define_expand "lrintxf<mode>2"
17339   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17340      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17341       UNSPEC_FIST))]
17342   "TARGET_USE_FANCY_MATH_387"
17343   "")
17345 (define_expand "lrint<mode>di2"
17346   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17347      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17348       UNSPEC_FIX_NOTRUNC))]
17349   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17350   "")
17352 (define_expand "lrint<mode>si2"
17353   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17354      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17355       UNSPEC_FIX_NOTRUNC))]
17356   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17357   "")
17359 (define_expand "lround<mode>di2"
17360   [(match_operand:DI 0 "nonimmediate_operand" "")
17361    (match_operand:SSEMODEF 1 "register_operand" "")]
17362   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17363    && !flag_trapping_math && !flag_rounding_math
17364    && !optimize_size"
17366   ix86_expand_lround (operand0, operand1);
17367   DONE;
17370 (define_expand "lround<mode>si2"
17371   [(match_operand:SI 0 "nonimmediate_operand" "")
17372    (match_operand:SSEMODEF 1 "register_operand" "")]
17373   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17374    && !flag_trapping_math && !flag_rounding_math
17375    && !optimize_size"
17377   ix86_expand_lround (operand0, operand1);
17378   DONE;
17381 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17382 (define_insn_and_split "frndintxf2_floor"
17383   [(set (match_operand:XF 0 "register_operand" "=f")
17384         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17385          UNSPEC_FRNDINT_FLOOR))
17386    (clobber (reg:CC FLAGS_REG))]
17387   "TARGET_USE_FANCY_MATH_387
17388    && flag_unsafe_math_optimizations
17389    && !(reload_completed || reload_in_progress)"
17390   "#"
17391   "&& 1"
17392   [(const_int 0)]
17394   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17396   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17397   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17399   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17400                                         operands[2], operands[3]));
17401   DONE;
17403   [(set_attr "type" "frndint")
17404    (set_attr "i387_cw" "floor")
17405    (set_attr "mode" "XF")])
17407 (define_insn "frndintxf2_floor_i387"
17408   [(set (match_operand:XF 0 "register_operand" "=f")
17409         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17410          UNSPEC_FRNDINT_FLOOR))
17411    (use (match_operand:HI 2 "memory_operand" "m"))
17412    (use (match_operand:HI 3 "memory_operand" "m"))]
17413   "TARGET_USE_FANCY_MATH_387
17414    && flag_unsafe_math_optimizations"
17415   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17416   [(set_attr "type" "frndint")
17417    (set_attr "i387_cw" "floor")
17418    (set_attr "mode" "XF")])
17420 (define_expand "floorxf2"
17421   [(use (match_operand:XF 0 "register_operand" ""))
17422    (use (match_operand:XF 1 "register_operand" ""))]
17423   "TARGET_USE_FANCY_MATH_387
17424    && flag_unsafe_math_optimizations && !optimize_size"
17426   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17427   DONE;
17430 (define_expand "floordf2"
17431   [(use (match_operand:DF 0 "register_operand" ""))
17432    (use (match_operand:DF 1 "register_operand" ""))]
17433   "((TARGET_USE_FANCY_MATH_387
17434      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17435      && flag_unsafe_math_optimizations)
17436     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17437         && !flag_trapping_math))
17438    && !optimize_size"
17440   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17441       && !flag_trapping_math)
17442     {
17443       if (TARGET_64BIT)
17444         ix86_expand_floorceil (operand0, operand1, true);
17445       else
17446         ix86_expand_floorceildf_32 (operand0, operand1, true);
17447     }
17448   else
17449     {
17450       rtx op0 = gen_reg_rtx (XFmode);
17451       rtx op1 = gen_reg_rtx (XFmode);
17453       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17454       emit_insn (gen_frndintxf2_floor (op0, op1));
17456       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17457     }
17458   DONE;
17461 (define_expand "floorsf2"
17462   [(use (match_operand:SF 0 "register_operand" ""))
17463    (use (match_operand:SF 1 "register_operand" ""))]
17464   "((TARGET_USE_FANCY_MATH_387
17465      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17466      && flag_unsafe_math_optimizations)
17467     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17468         && !flag_trapping_math))
17469    && !optimize_size"
17471   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17472       && !flag_trapping_math)
17473     ix86_expand_floorceil (operand0, operand1, true);
17474   else
17475     {
17476       rtx op0 = gen_reg_rtx (XFmode);
17477       rtx op1 = gen_reg_rtx (XFmode);
17479       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17480       emit_insn (gen_frndintxf2_floor (op0, op1));
17482       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17483     }
17484   DONE;
17487 (define_insn_and_split "*fist<mode>2_floor_1"
17488   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17489         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17490          UNSPEC_FIST_FLOOR))
17491    (clobber (reg:CC FLAGS_REG))]
17492   "TARGET_USE_FANCY_MATH_387
17493    && flag_unsafe_math_optimizations
17494    && !(reload_completed || reload_in_progress)"
17495   "#"
17496   "&& 1"
17497   [(const_int 0)]
17499   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17501   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17502   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17503   if (memory_operand (operands[0], VOIDmode))
17504     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17505                                       operands[2], operands[3]));
17506   else
17507     {
17508       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17509       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17510                                                   operands[2], operands[3],
17511                                                   operands[4]));
17512     }
17513   DONE;
17515   [(set_attr "type" "fistp")
17516    (set_attr "i387_cw" "floor")
17517    (set_attr "mode" "<MODE>")])
17519 (define_insn "fistdi2_floor"
17520   [(set (match_operand:DI 0 "memory_operand" "=m")
17521         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17522          UNSPEC_FIST_FLOOR))
17523    (use (match_operand:HI 2 "memory_operand" "m"))
17524    (use (match_operand:HI 3 "memory_operand" "m"))
17525    (clobber (match_scratch:XF 4 "=&1f"))]
17526   "TARGET_USE_FANCY_MATH_387
17527    && flag_unsafe_math_optimizations"
17528   "* return output_fix_trunc (insn, operands, 0);"
17529   [(set_attr "type" "fistp")
17530    (set_attr "i387_cw" "floor")
17531    (set_attr "mode" "DI")])
17533 (define_insn "fistdi2_floor_with_temp"
17534   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17535         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17536          UNSPEC_FIST_FLOOR))
17537    (use (match_operand:HI 2 "memory_operand" "m,m"))
17538    (use (match_operand:HI 3 "memory_operand" "m,m"))
17539    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17540    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17541   "TARGET_USE_FANCY_MATH_387
17542    && flag_unsafe_math_optimizations"
17543   "#"
17544   [(set_attr "type" "fistp")
17545    (set_attr "i387_cw" "floor")
17546    (set_attr "mode" "DI")])
17548 (define_split
17549   [(set (match_operand:DI 0 "register_operand" "")
17550         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17551          UNSPEC_FIST_FLOOR))
17552    (use (match_operand:HI 2 "memory_operand" ""))
17553    (use (match_operand:HI 3 "memory_operand" ""))
17554    (clobber (match_operand:DI 4 "memory_operand" ""))
17555    (clobber (match_scratch 5 ""))]
17556   "reload_completed"
17557   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17558               (use (match_dup 2))
17559               (use (match_dup 3))
17560               (clobber (match_dup 5))])
17561    (set (match_dup 0) (match_dup 4))]
17562   "")
17564 (define_split
17565   [(set (match_operand:DI 0 "memory_operand" "")
17566         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17567          UNSPEC_FIST_FLOOR))
17568    (use (match_operand:HI 2 "memory_operand" ""))
17569    (use (match_operand:HI 3 "memory_operand" ""))
17570    (clobber (match_operand:DI 4 "memory_operand" ""))
17571    (clobber (match_scratch 5 ""))]
17572   "reload_completed"
17573   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17574               (use (match_dup 2))
17575               (use (match_dup 3))
17576               (clobber (match_dup 5))])]
17577   "")
17579 (define_insn "fist<mode>2_floor"
17580   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17581         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17582          UNSPEC_FIST_FLOOR))
17583    (use (match_operand:HI 2 "memory_operand" "m"))
17584    (use (match_operand:HI 3 "memory_operand" "m"))]
17585   "TARGET_USE_FANCY_MATH_387
17586    && flag_unsafe_math_optimizations"
17587   "* return output_fix_trunc (insn, operands, 0);"
17588   [(set_attr "type" "fistp")
17589    (set_attr "i387_cw" "floor")
17590    (set_attr "mode" "<MODE>")])
17592 (define_insn "fist<mode>2_floor_with_temp"
17593   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17594         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17595          UNSPEC_FIST_FLOOR))
17596    (use (match_operand:HI 2 "memory_operand" "m,m"))
17597    (use (match_operand:HI 3 "memory_operand" "m,m"))
17598    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17599   "TARGET_USE_FANCY_MATH_387
17600    && flag_unsafe_math_optimizations"
17601   "#"
17602   [(set_attr "type" "fistp")
17603    (set_attr "i387_cw" "floor")
17604    (set_attr "mode" "<MODE>")])
17606 (define_split
17607   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17608         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17609          UNSPEC_FIST_FLOOR))
17610    (use (match_operand:HI 2 "memory_operand" ""))
17611    (use (match_operand:HI 3 "memory_operand" ""))
17612    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17613   "reload_completed"
17614   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17615                                   UNSPEC_FIST_FLOOR))
17616               (use (match_dup 2))
17617               (use (match_dup 3))])
17618    (set (match_dup 0) (match_dup 4))]
17619   "")
17621 (define_split
17622   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17623         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17624          UNSPEC_FIST_FLOOR))
17625    (use (match_operand:HI 2 "memory_operand" ""))
17626    (use (match_operand:HI 3 "memory_operand" ""))
17627    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17628   "reload_completed"
17629   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17630                                   UNSPEC_FIST_FLOOR))
17631               (use (match_dup 2))
17632               (use (match_dup 3))])]
17633   "")
17635 (define_expand "lfloorxf<mode>2"
17636   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17637                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17638                     UNSPEC_FIST_FLOOR))
17639               (clobber (reg:CC FLAGS_REG))])]
17640   "TARGET_USE_FANCY_MATH_387
17641    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17642    && flag_unsafe_math_optimizations"
17643   "")
17645 (define_expand "lfloor<mode>di2"
17646   [(match_operand:DI 0 "nonimmediate_operand" "")
17647    (match_operand:SSEMODEF 1 "register_operand" "")]
17648   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17649    && !flag_trapping_math
17650    && !optimize_size"
17652   ix86_expand_lfloorceil (operand0, operand1, true);
17653   DONE;
17656 (define_expand "lfloor<mode>si2"
17657   [(match_operand:SI 0 "nonimmediate_operand" "")
17658    (match_operand:SSEMODEF 1 "register_operand" "")]
17659   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17660    && !flag_trapping_math
17661    && (!optimize_size || !TARGET_64BIT)"
17663   ix86_expand_lfloorceil (operand0, operand1, true);
17664   DONE;
17667 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17668 (define_insn_and_split "frndintxf2_ceil"
17669   [(set (match_operand:XF 0 "register_operand" "=f")
17670         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17671          UNSPEC_FRNDINT_CEIL))
17672    (clobber (reg:CC FLAGS_REG))]
17673   "TARGET_USE_FANCY_MATH_387
17674    && flag_unsafe_math_optimizations
17675    && !(reload_completed || reload_in_progress)"
17676   "#"
17677   "&& 1"
17678   [(const_int 0)]
17680   ix86_optimize_mode_switching[I387_CEIL] = 1;
17682   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17683   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17685   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17686                                        operands[2], operands[3]));
17687   DONE;
17689   [(set_attr "type" "frndint")
17690    (set_attr "i387_cw" "ceil")
17691    (set_attr "mode" "XF")])
17693 (define_insn "frndintxf2_ceil_i387"
17694   [(set (match_operand:XF 0 "register_operand" "=f")
17695         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17696          UNSPEC_FRNDINT_CEIL))
17697    (use (match_operand:HI 2 "memory_operand" "m"))
17698    (use (match_operand:HI 3 "memory_operand" "m"))]
17699   "TARGET_USE_FANCY_MATH_387
17700    && flag_unsafe_math_optimizations"
17701   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17702   [(set_attr "type" "frndint")
17703    (set_attr "i387_cw" "ceil")
17704    (set_attr "mode" "XF")])
17706 (define_expand "ceilxf2"
17707   [(use (match_operand:XF 0 "register_operand" ""))
17708    (use (match_operand:XF 1 "register_operand" ""))]
17709   "TARGET_USE_FANCY_MATH_387
17710    && flag_unsafe_math_optimizations && !optimize_size"
17712   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17713   DONE;
17716 (define_expand "ceildf2"
17717   [(use (match_operand:DF 0 "register_operand" ""))
17718    (use (match_operand:DF 1 "register_operand" ""))]
17719   "((TARGET_USE_FANCY_MATH_387
17720      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17721      && flag_unsafe_math_optimizations)
17722     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17723         && !flag_trapping_math))
17724    && !optimize_size"
17726   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17727       && !flag_trapping_math)
17728     {
17729       if (TARGET_64BIT)
17730         ix86_expand_floorceil (operand0, operand1, false);
17731       else
17732         ix86_expand_floorceildf_32 (operand0, operand1, false);
17733     }
17734   else
17735     {
17736       rtx op0 = gen_reg_rtx (XFmode);
17737       rtx op1 = gen_reg_rtx (XFmode);
17739       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17740       emit_insn (gen_frndintxf2_ceil (op0, op1));
17742       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17743     }
17744   DONE;
17747 (define_expand "ceilsf2"
17748   [(use (match_operand:SF 0 "register_operand" ""))
17749    (use (match_operand:SF 1 "register_operand" ""))]
17750   "((TARGET_USE_FANCY_MATH_387
17751      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17752      && flag_unsafe_math_optimizations)
17753     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17754         && !flag_trapping_math))
17755    && !optimize_size"
17757   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17758       && !flag_trapping_math)
17759     ix86_expand_floorceil (operand0, operand1, false);
17760   else
17761     {
17762       rtx op0 = gen_reg_rtx (XFmode);
17763       rtx op1 = gen_reg_rtx (XFmode);
17765       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17766       emit_insn (gen_frndintxf2_ceil (op0, op1));
17768       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17769     }
17770   DONE;
17773 (define_insn_and_split "*fist<mode>2_ceil_1"
17774   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17775         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17776          UNSPEC_FIST_CEIL))
17777    (clobber (reg:CC FLAGS_REG))]
17778   "TARGET_USE_FANCY_MATH_387
17779    && flag_unsafe_math_optimizations
17780    && !(reload_completed || reload_in_progress)"
17781   "#"
17782   "&& 1"
17783   [(const_int 0)]
17785   ix86_optimize_mode_switching[I387_CEIL] = 1;
17787   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17788   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17789   if (memory_operand (operands[0], VOIDmode))
17790     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17791                                      operands[2], operands[3]));
17792   else
17793     {
17794       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17795       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17796                                                  operands[2], operands[3],
17797                                                  operands[4]));
17798     }
17799   DONE;
17801   [(set_attr "type" "fistp")
17802    (set_attr "i387_cw" "ceil")
17803    (set_attr "mode" "<MODE>")])
17805 (define_insn "fistdi2_ceil"
17806   [(set (match_operand:DI 0 "memory_operand" "=m")
17807         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17808          UNSPEC_FIST_CEIL))
17809    (use (match_operand:HI 2 "memory_operand" "m"))
17810    (use (match_operand:HI 3 "memory_operand" "m"))
17811    (clobber (match_scratch:XF 4 "=&1f"))]
17812   "TARGET_USE_FANCY_MATH_387
17813    && flag_unsafe_math_optimizations"
17814   "* return output_fix_trunc (insn, operands, 0);"
17815   [(set_attr "type" "fistp")
17816    (set_attr "i387_cw" "ceil")
17817    (set_attr "mode" "DI")])
17819 (define_insn "fistdi2_ceil_with_temp"
17820   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17821         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17822          UNSPEC_FIST_CEIL))
17823    (use (match_operand:HI 2 "memory_operand" "m,m"))
17824    (use (match_operand:HI 3 "memory_operand" "m,m"))
17825    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17826    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17827   "TARGET_USE_FANCY_MATH_387
17828    && flag_unsafe_math_optimizations"
17829   "#"
17830   [(set_attr "type" "fistp")
17831    (set_attr "i387_cw" "ceil")
17832    (set_attr "mode" "DI")])
17834 (define_split
17835   [(set (match_operand:DI 0 "register_operand" "")
17836         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17837          UNSPEC_FIST_CEIL))
17838    (use (match_operand:HI 2 "memory_operand" ""))
17839    (use (match_operand:HI 3 "memory_operand" ""))
17840    (clobber (match_operand:DI 4 "memory_operand" ""))
17841    (clobber (match_scratch 5 ""))]
17842   "reload_completed"
17843   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17844               (use (match_dup 2))
17845               (use (match_dup 3))
17846               (clobber (match_dup 5))])
17847    (set (match_dup 0) (match_dup 4))]
17848   "")
17850 (define_split
17851   [(set (match_operand:DI 0 "memory_operand" "")
17852         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17853          UNSPEC_FIST_CEIL))
17854    (use (match_operand:HI 2 "memory_operand" ""))
17855    (use (match_operand:HI 3 "memory_operand" ""))
17856    (clobber (match_operand:DI 4 "memory_operand" ""))
17857    (clobber (match_scratch 5 ""))]
17858   "reload_completed"
17859   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17860               (use (match_dup 2))
17861               (use (match_dup 3))
17862               (clobber (match_dup 5))])]
17863   "")
17865 (define_insn "fist<mode>2_ceil"
17866   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17867         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17868          UNSPEC_FIST_CEIL))
17869    (use (match_operand:HI 2 "memory_operand" "m"))
17870    (use (match_operand:HI 3 "memory_operand" "m"))]
17871   "TARGET_USE_FANCY_MATH_387
17872    && flag_unsafe_math_optimizations"
17873   "* return output_fix_trunc (insn, operands, 0);"
17874   [(set_attr "type" "fistp")
17875    (set_attr "i387_cw" "ceil")
17876    (set_attr "mode" "<MODE>")])
17878 (define_insn "fist<mode>2_ceil_with_temp"
17879   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17880         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17881          UNSPEC_FIST_CEIL))
17882    (use (match_operand:HI 2 "memory_operand" "m,m"))
17883    (use (match_operand:HI 3 "memory_operand" "m,m"))
17884    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17885   "TARGET_USE_FANCY_MATH_387
17886    && flag_unsafe_math_optimizations"
17887   "#"
17888   [(set_attr "type" "fistp")
17889    (set_attr "i387_cw" "ceil")
17890    (set_attr "mode" "<MODE>")])
17892 (define_split
17893   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17894         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17895          UNSPEC_FIST_CEIL))
17896    (use (match_operand:HI 2 "memory_operand" ""))
17897    (use (match_operand:HI 3 "memory_operand" ""))
17898    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17899   "reload_completed"
17900   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17901                                   UNSPEC_FIST_CEIL))
17902               (use (match_dup 2))
17903               (use (match_dup 3))])
17904    (set (match_dup 0) (match_dup 4))]
17905   "")
17907 (define_split
17908   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17909         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17910          UNSPEC_FIST_CEIL))
17911    (use (match_operand:HI 2 "memory_operand" ""))
17912    (use (match_operand:HI 3 "memory_operand" ""))
17913    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17914   "reload_completed"
17915   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17916                                   UNSPEC_FIST_CEIL))
17917               (use (match_dup 2))
17918               (use (match_dup 3))])]
17919   "")
17921 (define_expand "lceilxf<mode>2"
17922   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17923                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17924                     UNSPEC_FIST_CEIL))
17925               (clobber (reg:CC FLAGS_REG))])]
17926   "TARGET_USE_FANCY_MATH_387
17927    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17928    && flag_unsafe_math_optimizations"
17929   "")
17931 (define_expand "lceil<mode>di2"
17932   [(match_operand:DI 0 "nonimmediate_operand" "")
17933    (match_operand:SSEMODEF 1 "register_operand" "")]
17934   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17935    && !flag_trapping_math"
17937   ix86_expand_lfloorceil (operand0, operand1, false);
17938   DONE;
17941 (define_expand "lceil<mode>si2"
17942   [(match_operand:SI 0 "nonimmediate_operand" "")
17943    (match_operand:SSEMODEF 1 "register_operand" "")]
17944   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17945    && !flag_trapping_math"
17947   ix86_expand_lfloorceil (operand0, operand1, false);
17948   DONE;
17951 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17952 (define_insn_and_split "frndintxf2_trunc"
17953   [(set (match_operand:XF 0 "register_operand" "=f")
17954         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17955          UNSPEC_FRNDINT_TRUNC))
17956    (clobber (reg:CC FLAGS_REG))]
17957   "TARGET_USE_FANCY_MATH_387
17958    && flag_unsafe_math_optimizations
17959    && !(reload_completed || reload_in_progress)"
17960   "#"
17961   "&& 1"
17962   [(const_int 0)]
17964   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17966   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17967   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17969   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17970                                         operands[2], operands[3]));
17971   DONE;
17973   [(set_attr "type" "frndint")
17974    (set_attr "i387_cw" "trunc")
17975    (set_attr "mode" "XF")])
17977 (define_insn "frndintxf2_trunc_i387"
17978   [(set (match_operand:XF 0 "register_operand" "=f")
17979         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17980          UNSPEC_FRNDINT_TRUNC))
17981    (use (match_operand:HI 2 "memory_operand" "m"))
17982    (use (match_operand:HI 3 "memory_operand" "m"))]
17983   "TARGET_USE_FANCY_MATH_387
17984    && flag_unsafe_math_optimizations"
17985   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17986   [(set_attr "type" "frndint")
17987    (set_attr "i387_cw" "trunc")
17988    (set_attr "mode" "XF")])
17990 (define_expand "btruncxf2"
17991   [(use (match_operand:XF 0 "register_operand" ""))
17992    (use (match_operand:XF 1 "register_operand" ""))]
17993   "TARGET_USE_FANCY_MATH_387
17994    && flag_unsafe_math_optimizations && !optimize_size"
17996   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17997   DONE;
18000 (define_expand "btruncdf2"
18001   [(use (match_operand:DF 0 "register_operand" ""))
18002    (use (match_operand:DF 1 "register_operand" ""))]
18003   "((TARGET_USE_FANCY_MATH_387
18004      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18005      && flag_unsafe_math_optimizations)
18006     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18007         && !flag_trapping_math))
18008    && !optimize_size"
18010   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18011       && !flag_trapping_math)
18012     {
18013       if (TARGET_64BIT)
18014         ix86_expand_trunc (operand0, operand1);
18015       else
18016         ix86_expand_truncdf_32 (operand0, operand1);
18017     }
18018   else
18019     {
18020       rtx op0 = gen_reg_rtx (XFmode);
18021       rtx op1 = gen_reg_rtx (XFmode);
18023       emit_insn (gen_extenddfxf2 (op1, operands[1]));
18024       emit_insn (gen_frndintxf2_trunc (op0, op1));
18026       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18027     }
18028   DONE;
18031 (define_expand "btruncsf2"
18032   [(use (match_operand:SF 0 "register_operand" ""))
18033    (use (match_operand:SF 1 "register_operand" ""))]
18034   "((TARGET_USE_FANCY_MATH_387
18035      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18036      && flag_unsafe_math_optimizations)
18037     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18038         && !flag_trapping_math))
18039    && !optimize_size"
18041   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18042       && !flag_trapping_math)
18043     ix86_expand_trunc (operand0, operand1);
18044   else
18045     {
18046       rtx op0 = gen_reg_rtx (XFmode);
18047       rtx op1 = gen_reg_rtx (XFmode);
18049       emit_insn (gen_extendsfxf2 (op1, operands[1]));
18050       emit_insn (gen_frndintxf2_trunc (op0, op1));
18052       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18053     }
18054   DONE;
18057 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18058 (define_insn_and_split "frndintxf2_mask_pm"
18059   [(set (match_operand:XF 0 "register_operand" "=f")
18060         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18061          UNSPEC_FRNDINT_MASK_PM))
18062    (clobber (reg:CC FLAGS_REG))]
18063   "TARGET_USE_FANCY_MATH_387
18064    && flag_unsafe_math_optimizations
18065    && !(reload_completed || reload_in_progress)"
18066   "#"
18067   "&& 1"
18068   [(const_int 0)]
18070   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18072   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18073   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18075   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18076                                           operands[2], operands[3]));
18077   DONE;
18079   [(set_attr "type" "frndint")
18080    (set_attr "i387_cw" "mask_pm")
18081    (set_attr "mode" "XF")])
18083 (define_insn "frndintxf2_mask_pm_i387"
18084   [(set (match_operand:XF 0 "register_operand" "=f")
18085         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18086          UNSPEC_FRNDINT_MASK_PM))
18087    (use (match_operand:HI 2 "memory_operand" "m"))
18088    (use (match_operand:HI 3 "memory_operand" "m"))]
18089   "TARGET_USE_FANCY_MATH_387
18090    && flag_unsafe_math_optimizations"
18091   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18092   [(set_attr "type" "frndint")
18093    (set_attr "i387_cw" "mask_pm")
18094    (set_attr "mode" "XF")])
18096 (define_expand "nearbyintxf2"
18097   [(use (match_operand:XF 0 "register_operand" ""))
18098    (use (match_operand:XF 1 "register_operand" ""))]
18099   "TARGET_USE_FANCY_MATH_387
18100    && flag_unsafe_math_optimizations"
18102   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18104   DONE;
18107 (define_expand "nearbyintdf2"
18108   [(use (match_operand:DF 0 "register_operand" ""))
18109    (use (match_operand:DF 1 "register_operand" ""))]
18110   "TARGET_USE_FANCY_MATH_387
18111    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18112    && flag_unsafe_math_optimizations"
18114   rtx op0 = gen_reg_rtx (XFmode);
18115   rtx op1 = gen_reg_rtx (XFmode);
18117   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18118   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18120   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18121   DONE;
18124 (define_expand "nearbyintsf2"
18125   [(use (match_operand:SF 0 "register_operand" ""))
18126    (use (match_operand:SF 1 "register_operand" ""))]
18127   "TARGET_USE_FANCY_MATH_387
18128    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18129    && flag_unsafe_math_optimizations"
18131   rtx op0 = gen_reg_rtx (XFmode);
18132   rtx op1 = gen_reg_rtx (XFmode);
18134   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18135   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18137   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18138   DONE;
18142 ;; Block operation instructions
18144 (define_insn "cld"
18145  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18146  ""
18147  "cld"
18148   [(set_attr "type" "cld")])
18150 (define_expand "movmemsi"
18151   [(use (match_operand:BLK 0 "memory_operand" ""))
18152    (use (match_operand:BLK 1 "memory_operand" ""))
18153    (use (match_operand:SI 2 "nonmemory_operand" ""))
18154    (use (match_operand:SI 3 "const_int_operand" ""))]
18155   ""
18157  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18158                          operands[3], constm1_rtx))
18159    DONE;
18160  else
18161    FAIL;
18164 (define_expand "movmemdi"
18165   [(use (match_operand:BLK 0 "memory_operand" ""))
18166    (use (match_operand:BLK 1 "memory_operand" ""))
18167    (use (match_operand:DI 2 "nonmemory_operand" ""))
18168    (use (match_operand:DI 3 "const_int_operand" ""))]
18169   "TARGET_64BIT"
18171  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18172                          operands[3], constm1_rtx))
18173    DONE;
18174  else
18175    FAIL;
18178 ;; Most CPUs don't like single string operations
18179 ;; Handle this case here to simplify previous expander.
18181 (define_expand "strmov"
18182   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18183    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18184    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18185               (clobber (reg:CC FLAGS_REG))])
18186    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18187               (clobber (reg:CC FLAGS_REG))])]
18188   ""
18190   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18192   /* If .md ever supports :P for Pmode, these can be directly
18193      in the pattern above.  */
18194   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18195   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18197   if (TARGET_SINGLE_STRINGOP || optimize_size)
18198     {
18199       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18200                                       operands[2], operands[3],
18201                                       operands[5], operands[6]));
18202       DONE;
18203     }
18205   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18208 (define_expand "strmov_singleop"
18209   [(parallel [(set (match_operand 1 "memory_operand" "")
18210                    (match_operand 3 "memory_operand" ""))
18211               (set (match_operand 0 "register_operand" "")
18212                    (match_operand 4 "" ""))
18213               (set (match_operand 2 "register_operand" "")
18214                    (match_operand 5 "" ""))
18215               (use (reg:SI DIRFLAG_REG))])]
18216   "TARGET_SINGLE_STRINGOP || optimize_size"
18217   "")
18219 (define_insn "*strmovdi_rex_1"
18220   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18221         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18222    (set (match_operand:DI 0 "register_operand" "=D")
18223         (plus:DI (match_dup 2)
18224                  (const_int 8)))
18225    (set (match_operand:DI 1 "register_operand" "=S")
18226         (plus:DI (match_dup 3)
18227                  (const_int 8)))
18228    (use (reg:SI DIRFLAG_REG))]
18229   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18230   "movsq"
18231   [(set_attr "type" "str")
18232    (set_attr "mode" "DI")
18233    (set_attr "memory" "both")])
18235 (define_insn "*strmovsi_1"
18236   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18237         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18238    (set (match_operand:SI 0 "register_operand" "=D")
18239         (plus:SI (match_dup 2)
18240                  (const_int 4)))
18241    (set (match_operand:SI 1 "register_operand" "=S")
18242         (plus:SI (match_dup 3)
18243                  (const_int 4)))
18244    (use (reg:SI DIRFLAG_REG))]
18245   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18246   "{movsl|movsd}"
18247   [(set_attr "type" "str")
18248    (set_attr "mode" "SI")
18249    (set_attr "memory" "both")])
18251 (define_insn "*strmovsi_rex_1"
18252   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18253         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18254    (set (match_operand:DI 0 "register_operand" "=D")
18255         (plus:DI (match_dup 2)
18256                  (const_int 4)))
18257    (set (match_operand:DI 1 "register_operand" "=S")
18258         (plus:DI (match_dup 3)
18259                  (const_int 4)))
18260    (use (reg:SI DIRFLAG_REG))]
18261   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18262   "{movsl|movsd}"
18263   [(set_attr "type" "str")
18264    (set_attr "mode" "SI")
18265    (set_attr "memory" "both")])
18267 (define_insn "*strmovhi_1"
18268   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18269         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18270    (set (match_operand:SI 0 "register_operand" "=D")
18271         (plus:SI (match_dup 2)
18272                  (const_int 2)))
18273    (set (match_operand:SI 1 "register_operand" "=S")
18274         (plus:SI (match_dup 3)
18275                  (const_int 2)))
18276    (use (reg:SI DIRFLAG_REG))]
18277   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18278   "movsw"
18279   [(set_attr "type" "str")
18280    (set_attr "memory" "both")
18281    (set_attr "mode" "HI")])
18283 (define_insn "*strmovhi_rex_1"
18284   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18285         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18286    (set (match_operand:DI 0 "register_operand" "=D")
18287         (plus:DI (match_dup 2)
18288                  (const_int 2)))
18289    (set (match_operand:DI 1 "register_operand" "=S")
18290         (plus:DI (match_dup 3)
18291                  (const_int 2)))
18292    (use (reg:SI DIRFLAG_REG))]
18293   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18294   "movsw"
18295   [(set_attr "type" "str")
18296    (set_attr "memory" "both")
18297    (set_attr "mode" "HI")])
18299 (define_insn "*strmovqi_1"
18300   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18301         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18302    (set (match_operand:SI 0 "register_operand" "=D")
18303         (plus:SI (match_dup 2)
18304                  (const_int 1)))
18305    (set (match_operand:SI 1 "register_operand" "=S")
18306         (plus:SI (match_dup 3)
18307                  (const_int 1)))
18308    (use (reg:SI DIRFLAG_REG))]
18309   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18310   "movsb"
18311   [(set_attr "type" "str")
18312    (set_attr "memory" "both")
18313    (set_attr "mode" "QI")])
18315 (define_insn "*strmovqi_rex_1"
18316   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18317         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18318    (set (match_operand:DI 0 "register_operand" "=D")
18319         (plus:DI (match_dup 2)
18320                  (const_int 1)))
18321    (set (match_operand:DI 1 "register_operand" "=S")
18322         (plus:DI (match_dup 3)
18323                  (const_int 1)))
18324    (use (reg:SI DIRFLAG_REG))]
18325   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18326   "movsb"
18327   [(set_attr "type" "str")
18328    (set_attr "memory" "both")
18329    (set_attr "mode" "QI")])
18331 (define_expand "rep_mov"
18332   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18333               (set (match_operand 0 "register_operand" "")
18334                    (match_operand 5 "" ""))
18335               (set (match_operand 2 "register_operand" "")
18336                    (match_operand 6 "" ""))
18337               (set (match_operand 1 "memory_operand" "")
18338                    (match_operand 3 "memory_operand" ""))
18339               (use (match_dup 4))
18340               (use (reg:SI DIRFLAG_REG))])]
18341   ""
18342   "")
18344 (define_insn "*rep_movdi_rex64"
18345   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18346    (set (match_operand:DI 0 "register_operand" "=D")
18347         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18348                             (const_int 3))
18349                  (match_operand:DI 3 "register_operand" "0")))
18350    (set (match_operand:DI 1 "register_operand" "=S")
18351         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18352                  (match_operand:DI 4 "register_operand" "1")))
18353    (set (mem:BLK (match_dup 3))
18354         (mem:BLK (match_dup 4)))
18355    (use (match_dup 5))
18356    (use (reg:SI DIRFLAG_REG))]
18357   "TARGET_64BIT"
18358   "{rep\;movsq|rep movsq}"
18359   [(set_attr "type" "str")
18360    (set_attr "prefix_rep" "1")
18361    (set_attr "memory" "both")
18362    (set_attr "mode" "DI")])
18364 (define_insn "*rep_movsi"
18365   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18366    (set (match_operand:SI 0 "register_operand" "=D")
18367         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18368                             (const_int 2))
18369                  (match_operand:SI 3 "register_operand" "0")))
18370    (set (match_operand:SI 1 "register_operand" "=S")
18371         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18372                  (match_operand:SI 4 "register_operand" "1")))
18373    (set (mem:BLK (match_dup 3))
18374         (mem:BLK (match_dup 4)))
18375    (use (match_dup 5))
18376    (use (reg:SI DIRFLAG_REG))]
18377   "!TARGET_64BIT"
18378   "{rep\;movsl|rep movsd}"
18379   [(set_attr "type" "str")
18380    (set_attr "prefix_rep" "1")
18381    (set_attr "memory" "both")
18382    (set_attr "mode" "SI")])
18384 (define_insn "*rep_movsi_rex64"
18385   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18386    (set (match_operand:DI 0 "register_operand" "=D")
18387         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18388                             (const_int 2))
18389                  (match_operand:DI 3 "register_operand" "0")))
18390    (set (match_operand:DI 1 "register_operand" "=S")
18391         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18392                  (match_operand:DI 4 "register_operand" "1")))
18393    (set (mem:BLK (match_dup 3))
18394         (mem:BLK (match_dup 4)))
18395    (use (match_dup 5))
18396    (use (reg:SI DIRFLAG_REG))]
18397   "TARGET_64BIT"
18398   "{rep\;movsl|rep movsd}"
18399   [(set_attr "type" "str")
18400    (set_attr "prefix_rep" "1")
18401    (set_attr "memory" "both")
18402    (set_attr "mode" "SI")])
18404 (define_insn "*rep_movqi"
18405   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18406    (set (match_operand:SI 0 "register_operand" "=D")
18407         (plus:SI (match_operand:SI 3 "register_operand" "0")
18408                  (match_operand:SI 5 "register_operand" "2")))
18409    (set (match_operand:SI 1 "register_operand" "=S")
18410         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18411    (set (mem:BLK (match_dup 3))
18412         (mem:BLK (match_dup 4)))
18413    (use (match_dup 5))
18414    (use (reg:SI DIRFLAG_REG))]
18415   "!TARGET_64BIT"
18416   "{rep\;movsb|rep movsb}"
18417   [(set_attr "type" "str")
18418    (set_attr "prefix_rep" "1")
18419    (set_attr "memory" "both")
18420    (set_attr "mode" "SI")])
18422 (define_insn "*rep_movqi_rex64"
18423   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18424    (set (match_operand:DI 0 "register_operand" "=D")
18425         (plus:DI (match_operand:DI 3 "register_operand" "0")
18426                  (match_operand:DI 5 "register_operand" "2")))
18427    (set (match_operand:DI 1 "register_operand" "=S")
18428         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18429    (set (mem:BLK (match_dup 3))
18430         (mem:BLK (match_dup 4)))
18431    (use (match_dup 5))
18432    (use (reg:SI DIRFLAG_REG))]
18433   "TARGET_64BIT"
18434   "{rep\;movsb|rep movsb}"
18435   [(set_attr "type" "str")
18436    (set_attr "prefix_rep" "1")
18437    (set_attr "memory" "both")
18438    (set_attr "mode" "SI")])
18440 (define_expand "setmemsi"
18441    [(use (match_operand:BLK 0 "memory_operand" ""))
18442     (use (match_operand:SI 1 "nonmemory_operand" ""))
18443     (use (match_operand 2 "const_int_operand" ""))
18444     (use (match_operand 3 "const_int_operand" ""))]
18445   ""
18447  if (ix86_expand_setmem (operands[0], operands[1],
18448                          operands[2], operands[3],
18449                          operands[3], constm1_rtx))
18450    DONE;
18451  else
18452    FAIL;
18455 (define_expand "setmemdi"
18456    [(use (match_operand:BLK 0 "memory_operand" ""))
18457     (use (match_operand:DI 1 "nonmemory_operand" ""))
18458     (use (match_operand 2 "const_int_operand" ""))
18459     (use (match_operand 3 "const_int_operand" ""))
18460     (use (match_operand 4 "const_int_operand" ""))
18461     (use (match_operand 5 "const_int_operand" ""))]
18462   "TARGET_64BIT"
18464  if (ix86_expand_setmem (operands[0], operands[1],
18465                          operands[2], operands[3],
18466                          operands[3], constm1_rtx))
18467    DONE;
18468  else
18469    FAIL;
18472 ;; Most CPUs don't like single string operations
18473 ;; Handle this case here to simplify previous expander.
18475 (define_expand "strset"
18476   [(set (match_operand 1 "memory_operand" "")
18477         (match_operand 2 "register_operand" ""))
18478    (parallel [(set (match_operand 0 "register_operand" "")
18479                    (match_dup 3))
18480               (clobber (reg:CC FLAGS_REG))])]
18481   ""
18483   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18484     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18486   /* If .md ever supports :P for Pmode, this can be directly
18487      in the pattern above.  */
18488   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18489                               GEN_INT (GET_MODE_SIZE (GET_MODE
18490                                                       (operands[2]))));
18491   if (TARGET_SINGLE_STRINGOP || optimize_size)
18492     {
18493       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18494                                       operands[3]));
18495       DONE;
18496     }
18499 (define_expand "strset_singleop"
18500   [(parallel [(set (match_operand 1 "memory_operand" "")
18501                    (match_operand 2 "register_operand" ""))
18502               (set (match_operand 0 "register_operand" "")
18503                    (match_operand 3 "" ""))
18504               (use (reg:SI DIRFLAG_REG))])]
18505   "TARGET_SINGLE_STRINGOP || optimize_size"
18506   "")
18508 (define_insn "*strsetdi_rex_1"
18509   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18510         (match_operand:DI 2 "register_operand" "a"))
18511    (set (match_operand:DI 0 "register_operand" "=D")
18512         (plus:DI (match_dup 1)
18513                  (const_int 8)))
18514    (use (reg:SI DIRFLAG_REG))]
18515   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18516   "stosq"
18517   [(set_attr "type" "str")
18518    (set_attr "memory" "store")
18519    (set_attr "mode" "DI")])
18521 (define_insn "*strsetsi_1"
18522   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18523         (match_operand:SI 2 "register_operand" "a"))
18524    (set (match_operand:SI 0 "register_operand" "=D")
18525         (plus:SI (match_dup 1)
18526                  (const_int 4)))
18527    (use (reg:SI DIRFLAG_REG))]
18528   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18529   "{stosl|stosd}"
18530   [(set_attr "type" "str")
18531    (set_attr "memory" "store")
18532    (set_attr "mode" "SI")])
18534 (define_insn "*strsetsi_rex_1"
18535   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18536         (match_operand:SI 2 "register_operand" "a"))
18537    (set (match_operand:DI 0 "register_operand" "=D")
18538         (plus:DI (match_dup 1)
18539                  (const_int 4)))
18540    (use (reg:SI DIRFLAG_REG))]
18541   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18542   "{stosl|stosd}"
18543   [(set_attr "type" "str")
18544    (set_attr "memory" "store")
18545    (set_attr "mode" "SI")])
18547 (define_insn "*strsethi_1"
18548   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18549         (match_operand:HI 2 "register_operand" "a"))
18550    (set (match_operand:SI 0 "register_operand" "=D")
18551         (plus:SI (match_dup 1)
18552                  (const_int 2)))
18553    (use (reg:SI DIRFLAG_REG))]
18554   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18555   "stosw"
18556   [(set_attr "type" "str")
18557    (set_attr "memory" "store")
18558    (set_attr "mode" "HI")])
18560 (define_insn "*strsethi_rex_1"
18561   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18562         (match_operand:HI 2 "register_operand" "a"))
18563    (set (match_operand:DI 0 "register_operand" "=D")
18564         (plus:DI (match_dup 1)
18565                  (const_int 2)))
18566    (use (reg:SI DIRFLAG_REG))]
18567   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18568   "stosw"
18569   [(set_attr "type" "str")
18570    (set_attr "memory" "store")
18571    (set_attr "mode" "HI")])
18573 (define_insn "*strsetqi_1"
18574   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18575         (match_operand:QI 2 "register_operand" "a"))
18576    (set (match_operand:SI 0 "register_operand" "=D")
18577         (plus:SI (match_dup 1)
18578                  (const_int 1)))
18579    (use (reg:SI DIRFLAG_REG))]
18580   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18581   "stosb"
18582   [(set_attr "type" "str")
18583    (set_attr "memory" "store")
18584    (set_attr "mode" "QI")])
18586 (define_insn "*strsetqi_rex_1"
18587   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18588         (match_operand:QI 2 "register_operand" "a"))
18589    (set (match_operand:DI 0 "register_operand" "=D")
18590         (plus:DI (match_dup 1)
18591                  (const_int 1)))
18592    (use (reg:SI DIRFLAG_REG))]
18593   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18594   "stosb"
18595   [(set_attr "type" "str")
18596    (set_attr "memory" "store")
18597    (set_attr "mode" "QI")])
18599 (define_expand "rep_stos"
18600   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18601               (set (match_operand 0 "register_operand" "")
18602                    (match_operand 4 "" ""))
18603               (set (match_operand 2 "memory_operand" "") (const_int 0))
18604               (use (match_operand 3 "register_operand" ""))
18605               (use (match_dup 1))
18606               (use (reg:SI DIRFLAG_REG))])]
18607   ""
18608   "")
18610 (define_insn "*rep_stosdi_rex64"
18611   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18612    (set (match_operand:DI 0 "register_operand" "=D")
18613         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18614                             (const_int 3))
18615                  (match_operand:DI 3 "register_operand" "0")))
18616    (set (mem:BLK (match_dup 3))
18617         (const_int 0))
18618    (use (match_operand:DI 2 "register_operand" "a"))
18619    (use (match_dup 4))
18620    (use (reg:SI DIRFLAG_REG))]
18621   "TARGET_64BIT"
18622   "{rep\;stosq|rep stosq}"
18623   [(set_attr "type" "str")
18624    (set_attr "prefix_rep" "1")
18625    (set_attr "memory" "store")
18626    (set_attr "mode" "DI")])
18628 (define_insn "*rep_stossi"
18629   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18630    (set (match_operand:SI 0 "register_operand" "=D")
18631         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18632                             (const_int 2))
18633                  (match_operand:SI 3 "register_operand" "0")))
18634    (set (mem:BLK (match_dup 3))
18635         (const_int 0))
18636    (use (match_operand:SI 2 "register_operand" "a"))
18637    (use (match_dup 4))
18638    (use (reg:SI DIRFLAG_REG))]
18639   "!TARGET_64BIT"
18640   "{rep\;stosl|rep stosd}"
18641   [(set_attr "type" "str")
18642    (set_attr "prefix_rep" "1")
18643    (set_attr "memory" "store")
18644    (set_attr "mode" "SI")])
18646 (define_insn "*rep_stossi_rex64"
18647   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18648    (set (match_operand:DI 0 "register_operand" "=D")
18649         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18650                             (const_int 2))
18651                  (match_operand:DI 3 "register_operand" "0")))
18652    (set (mem:BLK (match_dup 3))
18653         (const_int 0))
18654    (use (match_operand:SI 2 "register_operand" "a"))
18655    (use (match_dup 4))
18656    (use (reg:SI DIRFLAG_REG))]
18657   "TARGET_64BIT"
18658   "{rep\;stosl|rep stosd}"
18659   [(set_attr "type" "str")
18660    (set_attr "prefix_rep" "1")
18661    (set_attr "memory" "store")
18662    (set_attr "mode" "SI")])
18664 (define_insn "*rep_stosqi"
18665   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18666    (set (match_operand:SI 0 "register_operand" "=D")
18667         (plus:SI (match_operand:SI 3 "register_operand" "0")
18668                  (match_operand:SI 4 "register_operand" "1")))
18669    (set (mem:BLK (match_dup 3))
18670         (const_int 0))
18671    (use (match_operand:QI 2 "register_operand" "a"))
18672    (use (match_dup 4))
18673    (use (reg:SI DIRFLAG_REG))]
18674   "!TARGET_64BIT"
18675   "{rep\;stosb|rep stosb}"
18676   [(set_attr "type" "str")
18677    (set_attr "prefix_rep" "1")
18678    (set_attr "memory" "store")
18679    (set_attr "mode" "QI")])
18681 (define_insn "*rep_stosqi_rex64"
18682   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18683    (set (match_operand:DI 0 "register_operand" "=D")
18684         (plus:DI (match_operand:DI 3 "register_operand" "0")
18685                  (match_operand:DI 4 "register_operand" "1")))
18686    (set (mem:BLK (match_dup 3))
18687         (const_int 0))
18688    (use (match_operand:QI 2 "register_operand" "a"))
18689    (use (match_dup 4))
18690    (use (reg:SI DIRFLAG_REG))]
18691   "TARGET_64BIT"
18692   "{rep\;stosb|rep stosb}"
18693   [(set_attr "type" "str")
18694    (set_attr "prefix_rep" "1")
18695    (set_attr "memory" "store")
18696    (set_attr "mode" "QI")])
18698 (define_expand "cmpstrnsi"
18699   [(set (match_operand:SI 0 "register_operand" "")
18700         (compare:SI (match_operand:BLK 1 "general_operand" "")
18701                     (match_operand:BLK 2 "general_operand" "")))
18702    (use (match_operand 3 "general_operand" ""))
18703    (use (match_operand 4 "immediate_operand" ""))]
18704   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18706   rtx addr1, addr2, out, outlow, count, countreg, align;
18708   /* Can't use this if the user has appropriated esi or edi.  */
18709   if (global_regs[4] || global_regs[5])
18710     FAIL;
18712   out = operands[0];
18713   if (GET_CODE (out) != REG)
18714     out = gen_reg_rtx (SImode);
18716   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18717   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18718   if (addr1 != XEXP (operands[1], 0))
18719     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18720   if (addr2 != XEXP (operands[2], 0))
18721     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18723   count = operands[3];
18724   countreg = ix86_zero_extend_to_Pmode (count);
18726   /* %%% Iff we are testing strict equality, we can use known alignment
18727      to good advantage.  This may be possible with combine, particularly
18728      once cc0 is dead.  */
18729   align = operands[4];
18731   emit_insn (gen_cld ());
18732   if (GET_CODE (count) == CONST_INT)
18733     {
18734       if (INTVAL (count) == 0)
18735         {
18736           emit_move_insn (operands[0], const0_rtx);
18737           DONE;
18738         }
18739       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18740                                      operands[1], operands[2]));
18741     }
18742   else
18743     {
18744       if (TARGET_64BIT)
18745         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18746       else
18747         emit_insn (gen_cmpsi_1 (countreg, countreg));
18748       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18749                                   operands[1], operands[2]));
18750     }
18752   outlow = gen_lowpart (QImode, out);
18753   emit_insn (gen_cmpintqi (outlow));
18754   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18756   if (operands[0] != out)
18757     emit_move_insn (operands[0], out);
18759   DONE;
18762 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18764 (define_expand "cmpintqi"
18765   [(set (match_dup 1)
18766         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18767    (set (match_dup 2)
18768         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18769    (parallel [(set (match_operand:QI 0 "register_operand" "")
18770                    (minus:QI (match_dup 1)
18771                              (match_dup 2)))
18772               (clobber (reg:CC FLAGS_REG))])]
18773   ""
18774   "operands[1] = gen_reg_rtx (QImode);
18775    operands[2] = gen_reg_rtx (QImode);")
18777 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18778 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18780 (define_expand "cmpstrnqi_nz_1"
18781   [(parallel [(set (reg:CC FLAGS_REG)
18782                    (compare:CC (match_operand 4 "memory_operand" "")
18783                                (match_operand 5 "memory_operand" "")))
18784               (use (match_operand 2 "register_operand" ""))
18785               (use (match_operand:SI 3 "immediate_operand" ""))
18786               (use (reg:SI DIRFLAG_REG))
18787               (clobber (match_operand 0 "register_operand" ""))
18788               (clobber (match_operand 1 "register_operand" ""))
18789               (clobber (match_dup 2))])]
18790   ""
18791   "")
18793 (define_insn "*cmpstrnqi_nz_1"
18794   [(set (reg:CC FLAGS_REG)
18795         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18796                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18797    (use (match_operand:SI 6 "register_operand" "2"))
18798    (use (match_operand:SI 3 "immediate_operand" "i"))
18799    (use (reg:SI DIRFLAG_REG))
18800    (clobber (match_operand:SI 0 "register_operand" "=S"))
18801    (clobber (match_operand:SI 1 "register_operand" "=D"))
18802    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18803   "!TARGET_64BIT"
18804   "repz{\;| }cmpsb"
18805   [(set_attr "type" "str")
18806    (set_attr "mode" "QI")
18807    (set_attr "prefix_rep" "1")])
18809 (define_insn "*cmpstrnqi_nz_rex_1"
18810   [(set (reg:CC FLAGS_REG)
18811         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18812                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18813    (use (match_operand:DI 6 "register_operand" "2"))
18814    (use (match_operand:SI 3 "immediate_operand" "i"))
18815    (use (reg:SI DIRFLAG_REG))
18816    (clobber (match_operand:DI 0 "register_operand" "=S"))
18817    (clobber (match_operand:DI 1 "register_operand" "=D"))
18818    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18819   "TARGET_64BIT"
18820   "repz{\;| }cmpsb"
18821   [(set_attr "type" "str")
18822    (set_attr "mode" "QI")
18823    (set_attr "prefix_rep" "1")])
18825 ;; The same, but the count is not known to not be zero.
18827 (define_expand "cmpstrnqi_1"
18828   [(parallel [(set (reg:CC FLAGS_REG)
18829                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18830                                      (const_int 0))
18831                   (compare:CC (match_operand 4 "memory_operand" "")
18832                               (match_operand 5 "memory_operand" ""))
18833                   (const_int 0)))
18834               (use (match_operand:SI 3 "immediate_operand" ""))
18835               (use (reg:CC FLAGS_REG))
18836               (use (reg:SI DIRFLAG_REG))
18837               (clobber (match_operand 0 "register_operand" ""))
18838               (clobber (match_operand 1 "register_operand" ""))
18839               (clobber (match_dup 2))])]
18840   ""
18841   "")
18843 (define_insn "*cmpstrnqi_1"
18844   [(set (reg:CC FLAGS_REG)
18845         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18846                              (const_int 0))
18847           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18848                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18849           (const_int 0)))
18850    (use (match_operand:SI 3 "immediate_operand" "i"))
18851    (use (reg:CC FLAGS_REG))
18852    (use (reg:SI DIRFLAG_REG))
18853    (clobber (match_operand:SI 0 "register_operand" "=S"))
18854    (clobber (match_operand:SI 1 "register_operand" "=D"))
18855    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18856   "!TARGET_64BIT"
18857   "repz{\;| }cmpsb"
18858   [(set_attr "type" "str")
18859    (set_attr "mode" "QI")
18860    (set_attr "prefix_rep" "1")])
18862 (define_insn "*cmpstrnqi_rex_1"
18863   [(set (reg:CC FLAGS_REG)
18864         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18865                              (const_int 0))
18866           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18867                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18868           (const_int 0)))
18869    (use (match_operand:SI 3 "immediate_operand" "i"))
18870    (use (reg:CC FLAGS_REG))
18871    (use (reg:SI DIRFLAG_REG))
18872    (clobber (match_operand:DI 0 "register_operand" "=S"))
18873    (clobber (match_operand:DI 1 "register_operand" "=D"))
18874    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18875   "TARGET_64BIT"
18876   "repz{\;| }cmpsb"
18877   [(set_attr "type" "str")
18878    (set_attr "mode" "QI")
18879    (set_attr "prefix_rep" "1")])
18881 (define_expand "strlensi"
18882   [(set (match_operand:SI 0 "register_operand" "")
18883         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18884                     (match_operand:QI 2 "immediate_operand" "")
18885                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18886   ""
18888  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18889    DONE;
18890  else
18891    FAIL;
18894 (define_expand "strlendi"
18895   [(set (match_operand:DI 0 "register_operand" "")
18896         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18897                     (match_operand:QI 2 "immediate_operand" "")
18898                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18899   ""
18901  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18902    DONE;
18903  else
18904    FAIL;
18907 (define_expand "strlenqi_1"
18908   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18909               (use (reg:SI DIRFLAG_REG))
18910               (clobber (match_operand 1 "register_operand" ""))
18911               (clobber (reg:CC FLAGS_REG))])]
18912   ""
18913   "")
18915 (define_insn "*strlenqi_1"
18916   [(set (match_operand:SI 0 "register_operand" "=&c")
18917         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18918                     (match_operand:QI 2 "register_operand" "a")
18919                     (match_operand:SI 3 "immediate_operand" "i")
18920                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18921    (use (reg:SI DIRFLAG_REG))
18922    (clobber (match_operand:SI 1 "register_operand" "=D"))
18923    (clobber (reg:CC FLAGS_REG))]
18924   "!TARGET_64BIT"
18925   "repnz{\;| }scasb"
18926   [(set_attr "type" "str")
18927    (set_attr "mode" "QI")
18928    (set_attr "prefix_rep" "1")])
18930 (define_insn "*strlenqi_rex_1"
18931   [(set (match_operand:DI 0 "register_operand" "=&c")
18932         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18933                     (match_operand:QI 2 "register_operand" "a")
18934                     (match_operand:DI 3 "immediate_operand" "i")
18935                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18936    (use (reg:SI DIRFLAG_REG))
18937    (clobber (match_operand:DI 1 "register_operand" "=D"))
18938    (clobber (reg:CC FLAGS_REG))]
18939   "TARGET_64BIT"
18940   "repnz{\;| }scasb"
18941   [(set_attr "type" "str")
18942    (set_attr "mode" "QI")
18943    (set_attr "prefix_rep" "1")])
18945 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18946 ;; handled in combine, but it is not currently up to the task.
18947 ;; When used for their truth value, the cmpstrn* expanders generate
18948 ;; code like this:
18950 ;;   repz cmpsb
18951 ;;   seta       %al
18952 ;;   setb       %dl
18953 ;;   cmpb       %al, %dl
18954 ;;   jcc        label
18956 ;; The intermediate three instructions are unnecessary.
18958 ;; This one handles cmpstrn*_nz_1...
18959 (define_peephole2
18960   [(parallel[
18961      (set (reg:CC FLAGS_REG)
18962           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18963                       (mem:BLK (match_operand 5 "register_operand" ""))))
18964      (use (match_operand 6 "register_operand" ""))
18965      (use (match_operand:SI 3 "immediate_operand" ""))
18966      (use (reg:SI DIRFLAG_REG))
18967      (clobber (match_operand 0 "register_operand" ""))
18968      (clobber (match_operand 1 "register_operand" ""))
18969      (clobber (match_operand 2 "register_operand" ""))])
18970    (set (match_operand:QI 7 "register_operand" "")
18971         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18972    (set (match_operand:QI 8 "register_operand" "")
18973         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18974    (set (reg FLAGS_REG)
18975         (compare (match_dup 7) (match_dup 8)))
18976   ]
18977   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18978   [(parallel[
18979      (set (reg:CC FLAGS_REG)
18980           (compare:CC (mem:BLK (match_dup 4))
18981                       (mem:BLK (match_dup 5))))
18982      (use (match_dup 6))
18983      (use (match_dup 3))
18984      (use (reg:SI DIRFLAG_REG))
18985      (clobber (match_dup 0))
18986      (clobber (match_dup 1))
18987      (clobber (match_dup 2))])]
18988   "")
18990 ;; ...and this one handles cmpstrn*_1.
18991 (define_peephole2
18992   [(parallel[
18993      (set (reg:CC FLAGS_REG)
18994           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18995                                (const_int 0))
18996             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18997                         (mem:BLK (match_operand 5 "register_operand" "")))
18998             (const_int 0)))
18999      (use (match_operand:SI 3 "immediate_operand" ""))
19000      (use (reg:CC FLAGS_REG))
19001      (use (reg:SI DIRFLAG_REG))
19002      (clobber (match_operand 0 "register_operand" ""))
19003      (clobber (match_operand 1 "register_operand" ""))
19004      (clobber (match_operand 2 "register_operand" ""))])
19005    (set (match_operand:QI 7 "register_operand" "")
19006         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19007    (set (match_operand:QI 8 "register_operand" "")
19008         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19009    (set (reg FLAGS_REG)
19010         (compare (match_dup 7) (match_dup 8)))
19011   ]
19012   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19013   [(parallel[
19014      (set (reg:CC FLAGS_REG)
19015           (if_then_else:CC (ne (match_dup 6)
19016                                (const_int 0))
19017             (compare:CC (mem:BLK (match_dup 4))
19018                         (mem:BLK (match_dup 5)))
19019             (const_int 0)))
19020      (use (match_dup 3))
19021      (use (reg:CC FLAGS_REG))
19022      (use (reg:SI DIRFLAG_REG))
19023      (clobber (match_dup 0))
19024      (clobber (match_dup 1))
19025      (clobber (match_dup 2))])]
19026   "")
19030 ;; Conditional move instructions.
19032 (define_expand "movdicc"
19033   [(set (match_operand:DI 0 "register_operand" "")
19034         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19035                          (match_operand:DI 2 "general_operand" "")
19036                          (match_operand:DI 3 "general_operand" "")))]
19037   "TARGET_64BIT"
19038   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19040 (define_insn "x86_movdicc_0_m1_rex64"
19041   [(set (match_operand:DI 0 "register_operand" "=r")
19042         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19043           (const_int -1)
19044           (const_int 0)))
19045    (clobber (reg:CC FLAGS_REG))]
19046   "TARGET_64BIT"
19047   "sbb{q}\t%0, %0"
19048   ; Since we don't have the proper number of operands for an alu insn,
19049   ; fill in all the blanks.
19050   [(set_attr "type" "alu")
19051    (set_attr "pent_pair" "pu")
19052    (set_attr "memory" "none")
19053    (set_attr "imm_disp" "false")
19054    (set_attr "mode" "DI")
19055    (set_attr "length_immediate" "0")])
19057 (define_insn "*movdicc_c_rex64"
19058   [(set (match_operand:DI 0 "register_operand" "=r,r")
19059         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19060                                 [(reg FLAGS_REG) (const_int 0)])
19061                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19062                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19063   "TARGET_64BIT && TARGET_CMOVE
19064    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19065   "@
19066    cmov%O2%C1\t{%2, %0|%0, %2}
19067    cmov%O2%c1\t{%3, %0|%0, %3}"
19068   [(set_attr "type" "icmov")
19069    (set_attr "mode" "DI")])
19071 (define_expand "movsicc"
19072   [(set (match_operand:SI 0 "register_operand" "")
19073         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19074                          (match_operand:SI 2 "general_operand" "")
19075                          (match_operand:SI 3 "general_operand" "")))]
19076   ""
19077   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19079 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19080 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19081 ;; So just document what we're doing explicitly.
19083 (define_insn "x86_movsicc_0_m1"
19084   [(set (match_operand:SI 0 "register_operand" "=r")
19085         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19086           (const_int -1)
19087           (const_int 0)))
19088    (clobber (reg:CC FLAGS_REG))]
19089   ""
19090   "sbb{l}\t%0, %0"
19091   ; Since we don't have the proper number of operands for an alu insn,
19092   ; fill in all the blanks.
19093   [(set_attr "type" "alu")
19094    (set_attr "pent_pair" "pu")
19095    (set_attr "memory" "none")
19096    (set_attr "imm_disp" "false")
19097    (set_attr "mode" "SI")
19098    (set_attr "length_immediate" "0")])
19100 (define_insn "*movsicc_noc"
19101   [(set (match_operand:SI 0 "register_operand" "=r,r")
19102         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19103                                 [(reg FLAGS_REG) (const_int 0)])
19104                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19105                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19106   "TARGET_CMOVE
19107    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19108   "@
19109    cmov%O2%C1\t{%2, %0|%0, %2}
19110    cmov%O2%c1\t{%3, %0|%0, %3}"
19111   [(set_attr "type" "icmov")
19112    (set_attr "mode" "SI")])
19114 (define_expand "movhicc"
19115   [(set (match_operand:HI 0 "register_operand" "")
19116         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19117                          (match_operand:HI 2 "general_operand" "")
19118                          (match_operand:HI 3 "general_operand" "")))]
19119   "TARGET_HIMODE_MATH"
19120   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19122 (define_insn "*movhicc_noc"
19123   [(set (match_operand:HI 0 "register_operand" "=r,r")
19124         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19125                                 [(reg FLAGS_REG) (const_int 0)])
19126                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19127                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19128   "TARGET_CMOVE
19129    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19130   "@
19131    cmov%O2%C1\t{%2, %0|%0, %2}
19132    cmov%O2%c1\t{%3, %0|%0, %3}"
19133   [(set_attr "type" "icmov")
19134    (set_attr "mode" "HI")])
19136 (define_expand "movqicc"
19137   [(set (match_operand:QI 0 "register_operand" "")
19138         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19139                          (match_operand:QI 2 "general_operand" "")
19140                          (match_operand:QI 3 "general_operand" "")))]
19141   "TARGET_QIMODE_MATH"
19142   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19144 (define_insn_and_split "*movqicc_noc"
19145   [(set (match_operand:QI 0 "register_operand" "=r,r")
19146         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19147                                 [(match_operand 4 "flags_reg_operand" "")
19148                                  (const_int 0)])
19149                       (match_operand:QI 2 "register_operand" "r,0")
19150                       (match_operand:QI 3 "register_operand" "0,r")))]
19151   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19152   "#"
19153   "&& reload_completed"
19154   [(set (match_dup 0)
19155         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19156                       (match_dup 2)
19157                       (match_dup 3)))]
19158   "operands[0] = gen_lowpart (SImode, operands[0]);
19159    operands[2] = gen_lowpart (SImode, operands[2]);
19160    operands[3] = gen_lowpart (SImode, operands[3]);"
19161   [(set_attr "type" "icmov")
19162    (set_attr "mode" "SI")])
19164 (define_expand "movsfcc"
19165   [(set (match_operand:SF 0 "register_operand" "")
19166         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19167                          (match_operand:SF 2 "register_operand" "")
19168                          (match_operand:SF 3 "register_operand" "")))]
19169   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19170   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19172 (define_insn "*movsfcc_1_387"
19173   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19174         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19175                                 [(reg FLAGS_REG) (const_int 0)])
19176                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19177                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19178   "TARGET_80387 && TARGET_CMOVE
19179    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19180   "@
19181    fcmov%F1\t{%2, %0|%0, %2}
19182    fcmov%f1\t{%3, %0|%0, %3}
19183    cmov%O2%C1\t{%2, %0|%0, %2}
19184    cmov%O2%c1\t{%3, %0|%0, %3}"
19185   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19186    (set_attr "mode" "SF,SF,SI,SI")])
19188 (define_expand "movdfcc"
19189   [(set (match_operand:DF 0 "register_operand" "")
19190         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19191                          (match_operand:DF 2 "register_operand" "")
19192                          (match_operand:DF 3 "register_operand" "")))]
19193   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19194   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19196 (define_insn "*movdfcc_1"
19197   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19198         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19199                                 [(reg FLAGS_REG) (const_int 0)])
19200                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19201                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19202   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19203    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19204   "@
19205    fcmov%F1\t{%2, %0|%0, %2}
19206    fcmov%f1\t{%3, %0|%0, %3}
19207    #
19208    #"
19209   [(set_attr "type" "fcmov,fcmov,multi,multi")
19210    (set_attr "mode" "DF")])
19212 (define_insn "*movdfcc_1_rex64"
19213   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19214         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19215                                 [(reg FLAGS_REG) (const_int 0)])
19216                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19217                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19218   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19219    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19220   "@
19221    fcmov%F1\t{%2, %0|%0, %2}
19222    fcmov%f1\t{%3, %0|%0, %3}
19223    cmov%O2%C1\t{%2, %0|%0, %2}
19224    cmov%O2%c1\t{%3, %0|%0, %3}"
19225   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19226    (set_attr "mode" "DF")])
19228 (define_split
19229   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19230         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19231                                 [(match_operand 4 "flags_reg_operand" "")
19232                                  (const_int 0)])
19233                       (match_operand:DF 2 "nonimmediate_operand" "")
19234                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19235   "!TARGET_64BIT && reload_completed"
19236   [(set (match_dup 2)
19237         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19238                       (match_dup 5)
19239                       (match_dup 7)))
19240    (set (match_dup 3)
19241         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19242                       (match_dup 6)
19243                       (match_dup 8)))]
19244   "split_di (operands+2, 1, operands+5, operands+6);
19245    split_di (operands+3, 1, operands+7, operands+8);
19246    split_di (operands, 1, operands+2, operands+3);")
19248 (define_expand "movxfcc"
19249   [(set (match_operand:XF 0 "register_operand" "")
19250         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19251                          (match_operand:XF 2 "register_operand" "")
19252                          (match_operand:XF 3 "register_operand" "")))]
19253   "TARGET_80387 && TARGET_CMOVE"
19254   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19256 (define_insn "*movxfcc_1"
19257   [(set (match_operand:XF 0 "register_operand" "=f,f")
19258         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19259                                 [(reg FLAGS_REG) (const_int 0)])
19260                       (match_operand:XF 2 "register_operand" "f,0")
19261                       (match_operand:XF 3 "register_operand" "0,f")))]
19262   "TARGET_80387 && TARGET_CMOVE"
19263   "@
19264    fcmov%F1\t{%2, %0|%0, %2}
19265    fcmov%f1\t{%3, %0|%0, %3}"
19266   [(set_attr "type" "fcmov")
19267    (set_attr "mode" "XF")])
19269 ;; These versions of the min/max patterns are intentionally ignorant of
19270 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19271 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19272 ;; are undefined in this condition, we're certain this is correct.
19274 (define_insn "sminsf3"
19275   [(set (match_operand:SF 0 "register_operand" "=x")
19276         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19277                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19278   "TARGET_SSE_MATH"
19279   "minss\t{%2, %0|%0, %2}"
19280   [(set_attr "type" "sseadd")
19281    (set_attr "mode" "SF")])
19283 (define_insn "smaxsf3"
19284   [(set (match_operand:SF 0 "register_operand" "=x")
19285         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19286                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19287   "TARGET_SSE_MATH"
19288   "maxss\t{%2, %0|%0, %2}"
19289   [(set_attr "type" "sseadd")
19290    (set_attr "mode" "SF")])
19292 (define_insn "smindf3"
19293   [(set (match_operand:DF 0 "register_operand" "=x")
19294         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19295                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19296   "TARGET_SSE2 && TARGET_SSE_MATH"
19297   "minsd\t{%2, %0|%0, %2}"
19298   [(set_attr "type" "sseadd")
19299    (set_attr "mode" "DF")])
19301 (define_insn "smaxdf3"
19302   [(set (match_operand:DF 0 "register_operand" "=x")
19303         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19304                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19305   "TARGET_SSE2 && TARGET_SSE_MATH"
19306   "maxsd\t{%2, %0|%0, %2}"
19307   [(set_attr "type" "sseadd")
19308    (set_attr "mode" "DF")])
19310 ;; These versions of the min/max patterns implement exactly the operations
19311 ;;   min = (op1 < op2 ? op1 : op2)
19312 ;;   max = (!(op1 < op2) ? op1 : op2)
19313 ;; Their operands are not commutative, and thus they may be used in the
19314 ;; presence of -0.0 and NaN.
19316 (define_insn "*ieee_sminsf3"
19317   [(set (match_operand:SF 0 "register_operand" "=x")
19318         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19319                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19320                    UNSPEC_IEEE_MIN))]
19321   "TARGET_SSE_MATH"
19322   "minss\t{%2, %0|%0, %2}"
19323   [(set_attr "type" "sseadd")
19324    (set_attr "mode" "SF")])
19326 (define_insn "*ieee_smaxsf3"
19327   [(set (match_operand:SF 0 "register_operand" "=x")
19328         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19329                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19330                    UNSPEC_IEEE_MAX))]
19331   "TARGET_SSE_MATH"
19332   "maxss\t{%2, %0|%0, %2}"
19333   [(set_attr "type" "sseadd")
19334    (set_attr "mode" "SF")])
19336 (define_insn "*ieee_smindf3"
19337   [(set (match_operand:DF 0 "register_operand" "=x")
19338         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19339                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19340                    UNSPEC_IEEE_MIN))]
19341   "TARGET_SSE2 && TARGET_SSE_MATH"
19342   "minsd\t{%2, %0|%0, %2}"
19343   [(set_attr "type" "sseadd")
19344    (set_attr "mode" "DF")])
19346 (define_insn "*ieee_smaxdf3"
19347   [(set (match_operand:DF 0 "register_operand" "=x")
19348         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19349                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19350                    UNSPEC_IEEE_MAX))]
19351   "TARGET_SSE2 && TARGET_SSE_MATH"
19352   "maxsd\t{%2, %0|%0, %2}"
19353   [(set_attr "type" "sseadd")
19354    (set_attr "mode" "DF")])
19356 ;; Make two stack loads independent:
19357 ;;   fld aa              fld aa
19358 ;;   fld %st(0)     ->   fld bb
19359 ;;   fmul bb             fmul %st(1), %st
19361 ;; Actually we only match the last two instructions for simplicity.
19362 (define_peephole2
19363   [(set (match_operand 0 "fp_register_operand" "")
19364         (match_operand 1 "fp_register_operand" ""))
19365    (set (match_dup 0)
19366         (match_operator 2 "binary_fp_operator"
19367            [(match_dup 0)
19368             (match_operand 3 "memory_operand" "")]))]
19369   "REGNO (operands[0]) != REGNO (operands[1])"
19370   [(set (match_dup 0) (match_dup 3))
19371    (set (match_dup 0) (match_dup 4))]
19373   ;; The % modifier is not operational anymore in peephole2's, so we have to
19374   ;; swap the operands manually in the case of addition and multiplication.
19375   "if (COMMUTATIVE_ARITH_P (operands[2]))
19376      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19377                                  operands[0], operands[1]);
19378    else
19379      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19380                                  operands[1], operands[0]);")
19382 ;; Conditional addition patterns
19383 (define_expand "addqicc"
19384   [(match_operand:QI 0 "register_operand" "")
19385    (match_operand 1 "comparison_operator" "")
19386    (match_operand:QI 2 "register_operand" "")
19387    (match_operand:QI 3 "const_int_operand" "")]
19388   ""
19389   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19391 (define_expand "addhicc"
19392   [(match_operand:HI 0 "register_operand" "")
19393    (match_operand 1 "comparison_operator" "")
19394    (match_operand:HI 2 "register_operand" "")
19395    (match_operand:HI 3 "const_int_operand" "")]
19396   ""
19397   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19399 (define_expand "addsicc"
19400   [(match_operand:SI 0 "register_operand" "")
19401    (match_operand 1 "comparison_operator" "")
19402    (match_operand:SI 2 "register_operand" "")
19403    (match_operand:SI 3 "const_int_operand" "")]
19404   ""
19405   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19407 (define_expand "adddicc"
19408   [(match_operand:DI 0 "register_operand" "")
19409    (match_operand 1 "comparison_operator" "")
19410    (match_operand:DI 2 "register_operand" "")
19411    (match_operand:DI 3 "const_int_operand" "")]
19412   "TARGET_64BIT"
19413   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19416 ;; Misc patterns (?)
19418 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19419 ;; Otherwise there will be nothing to keep
19421 ;; [(set (reg ebp) (reg esp))]
19422 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19423 ;;  (clobber (eflags)]
19424 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19426 ;; in proper program order.
19427 (define_insn "pro_epilogue_adjust_stack_1"
19428   [(set (match_operand:SI 0 "register_operand" "=r,r")
19429         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19430                  (match_operand:SI 2 "immediate_operand" "i,i")))
19431    (clobber (reg:CC FLAGS_REG))
19432    (clobber (mem:BLK (scratch)))]
19433   "!TARGET_64BIT"
19435   switch (get_attr_type (insn))
19436     {
19437     case TYPE_IMOV:
19438       return "mov{l}\t{%1, %0|%0, %1}";
19440     case TYPE_ALU:
19441       if (GET_CODE (operands[2]) == CONST_INT
19442           && (INTVAL (operands[2]) == 128
19443               || (INTVAL (operands[2]) < 0
19444                   && INTVAL (operands[2]) != -128)))
19445         {
19446           operands[2] = GEN_INT (-INTVAL (operands[2]));
19447           return "sub{l}\t{%2, %0|%0, %2}";
19448         }
19449       return "add{l}\t{%2, %0|%0, %2}";
19451     case TYPE_LEA:
19452       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19453       return "lea{l}\t{%a2, %0|%0, %a2}";
19455     default:
19456       gcc_unreachable ();
19457     }
19459   [(set (attr "type")
19460         (cond [(eq_attr "alternative" "0")
19461                  (const_string "alu")
19462                (match_operand:SI 2 "const0_operand" "")
19463                  (const_string "imov")
19464               ]
19465               (const_string "lea")))
19466    (set_attr "mode" "SI")])
19468 (define_insn "pro_epilogue_adjust_stack_rex64"
19469   [(set (match_operand:DI 0 "register_operand" "=r,r")
19470         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19471                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19472    (clobber (reg:CC FLAGS_REG))
19473    (clobber (mem:BLK (scratch)))]
19474   "TARGET_64BIT"
19476   switch (get_attr_type (insn))
19477     {
19478     case TYPE_IMOV:
19479       return "mov{q}\t{%1, %0|%0, %1}";
19481     case TYPE_ALU:
19482       if (GET_CODE (operands[2]) == CONST_INT
19483           /* Avoid overflows.  */
19484           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19485           && (INTVAL (operands[2]) == 128
19486               || (INTVAL (operands[2]) < 0
19487                   && INTVAL (operands[2]) != -128)))
19488         {
19489           operands[2] = GEN_INT (-INTVAL (operands[2]));
19490           return "sub{q}\t{%2, %0|%0, %2}";
19491         }
19492       return "add{q}\t{%2, %0|%0, %2}";
19494     case TYPE_LEA:
19495       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19496       return "lea{q}\t{%a2, %0|%0, %a2}";
19498     default:
19499       gcc_unreachable ();
19500     }
19502   [(set (attr "type")
19503         (cond [(eq_attr "alternative" "0")
19504                  (const_string "alu")
19505                (match_operand:DI 2 "const0_operand" "")
19506                  (const_string "imov")
19507               ]
19508               (const_string "lea")))
19509    (set_attr "mode" "DI")])
19511 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19512   [(set (match_operand:DI 0 "register_operand" "=r,r")
19513         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19514                  (match_operand:DI 3 "immediate_operand" "i,i")))
19515    (use (match_operand:DI 2 "register_operand" "r,r"))
19516    (clobber (reg:CC FLAGS_REG))
19517    (clobber (mem:BLK (scratch)))]
19518   "TARGET_64BIT"
19520   switch (get_attr_type (insn))
19521     {
19522     case TYPE_ALU:
19523       return "add{q}\t{%2, %0|%0, %2}";
19525     case TYPE_LEA:
19526       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19527       return "lea{q}\t{%a2, %0|%0, %a2}";
19529     default:
19530       gcc_unreachable ();
19531     }
19533   [(set_attr "type" "alu,lea")
19534    (set_attr "mode" "DI")])
19536 (define_expand "allocate_stack_worker"
19537   [(match_operand:SI 0 "register_operand" "")]
19538   "TARGET_STACK_PROBE"
19540   if (reload_completed)
19541     {
19542       if (TARGET_64BIT)
19543         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19544       else
19545         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19546     }
19547   else
19548     {
19549       if (TARGET_64BIT)
19550         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19551       else
19552         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19553     }
19554   DONE;
19557 (define_insn "allocate_stack_worker_1"
19558   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19559     UNSPECV_STACK_PROBE)
19560    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19561    (clobber (match_scratch:SI 1 "=0"))
19562    (clobber (reg:CC FLAGS_REG))]
19563   "!TARGET_64BIT && TARGET_STACK_PROBE"
19564   "call\t__alloca"
19565   [(set_attr "type" "multi")
19566    (set_attr "length" "5")])
19568 (define_expand "allocate_stack_worker_postreload"
19569   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19570                                     UNSPECV_STACK_PROBE)
19571               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19572               (clobber (match_dup 0))
19573               (clobber (reg:CC FLAGS_REG))])]
19574   ""
19575   "")
19577 (define_insn "allocate_stack_worker_rex64"
19578   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19579     UNSPECV_STACK_PROBE)
19580    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19581    (clobber (match_scratch:DI 1 "=0"))
19582    (clobber (reg:CC FLAGS_REG))]
19583   "TARGET_64BIT && TARGET_STACK_PROBE"
19584   "call\t__alloca"
19585   [(set_attr "type" "multi")
19586    (set_attr "length" "5")])
19588 (define_expand "allocate_stack_worker_rex64_postreload"
19589   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19590                                     UNSPECV_STACK_PROBE)
19591               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19592               (clobber (match_dup 0))
19593               (clobber (reg:CC FLAGS_REG))])]
19594   ""
19595   "")
19597 (define_expand "allocate_stack"
19598   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19599                    (minus:SI (reg:SI SP_REG)
19600                              (match_operand:SI 1 "general_operand" "")))
19601               (clobber (reg:CC FLAGS_REG))])
19602    (parallel [(set (reg:SI SP_REG)
19603                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19604               (clobber (reg:CC FLAGS_REG))])]
19605   "TARGET_STACK_PROBE"
19607 #ifdef CHECK_STACK_LIMIT
19608   if (GET_CODE (operands[1]) == CONST_INT
19609       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19610     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19611                            operands[1]));
19612   else
19613 #endif
19614     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19615                                                             operands[1])));
19617   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19618   DONE;
19621 (define_expand "builtin_setjmp_receiver"
19622   [(label_ref (match_operand 0 "" ""))]
19623   "!TARGET_64BIT && flag_pic"
19625   if (TARGET_MACHO)
19626     {
19627       rtx xops[3];
19628       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19629       rtx label_rtx = gen_label_rtx ();
19630       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19631       xops[0] = xops[1] = picreg;
19632       xops[2] = gen_rtx_CONST (SImode,
19633                   gen_rtx_MINUS (SImode,
19634                     gen_rtx_LABEL_REF (SImode, label_rtx),
19635                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19636       ix86_expand_binary_operator (MINUS, SImode, xops);
19637     }
19638   else
19639     emit_insn (gen_set_got (pic_offset_table_rtx));
19640   DONE;
19643 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19645 (define_split
19646   [(set (match_operand 0 "register_operand" "")
19647         (match_operator 3 "promotable_binary_operator"
19648            [(match_operand 1 "register_operand" "")
19649             (match_operand 2 "aligned_operand" "")]))
19650    (clobber (reg:CC FLAGS_REG))]
19651   "! TARGET_PARTIAL_REG_STALL && reload_completed
19652    && ((GET_MODE (operands[0]) == HImode
19653         && ((!optimize_size && !TARGET_FAST_PREFIX)
19654             /* ??? next two lines just !satisfies_constraint_K (...) */
19655             || GET_CODE (operands[2]) != CONST_INT
19656             || satisfies_constraint_K (operands[2])))
19657        || (GET_MODE (operands[0]) == QImode
19658            && (TARGET_PROMOTE_QImode || optimize_size)))"
19659   [(parallel [(set (match_dup 0)
19660                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19661               (clobber (reg:CC FLAGS_REG))])]
19662   "operands[0] = gen_lowpart (SImode, operands[0]);
19663    operands[1] = gen_lowpart (SImode, operands[1]);
19664    if (GET_CODE (operands[3]) != ASHIFT)
19665      operands[2] = gen_lowpart (SImode, operands[2]);
19666    PUT_MODE (operands[3], SImode);")
19668 ; Promote the QImode tests, as i386 has encoding of the AND
19669 ; instruction with 32-bit sign-extended immediate and thus the
19670 ; instruction size is unchanged, except in the %eax case for
19671 ; which it is increased by one byte, hence the ! optimize_size.
19672 (define_split
19673   [(set (match_operand 0 "flags_reg_operand" "")
19674         (match_operator 2 "compare_operator"
19675           [(and (match_operand 3 "aligned_operand" "")
19676                 (match_operand 4 "const_int_operand" ""))
19677            (const_int 0)]))
19678    (set (match_operand 1 "register_operand" "")
19679         (and (match_dup 3) (match_dup 4)))]
19680   "! TARGET_PARTIAL_REG_STALL && reload_completed
19681    /* Ensure that the operand will remain sign-extended immediate.  */
19682    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19683    && ! optimize_size
19684    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19685        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19686   [(parallel [(set (match_dup 0)
19687                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19688                                     (const_int 0)]))
19689               (set (match_dup 1)
19690                    (and:SI (match_dup 3) (match_dup 4)))])]
19692   operands[4]
19693     = gen_int_mode (INTVAL (operands[4])
19694                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19695   operands[1] = gen_lowpart (SImode, operands[1]);
19696   operands[3] = gen_lowpart (SImode, operands[3]);
19699 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19700 ; the TEST instruction with 32-bit sign-extended immediate and thus
19701 ; the instruction size would at least double, which is not what we
19702 ; want even with ! optimize_size.
19703 (define_split
19704   [(set (match_operand 0 "flags_reg_operand" "")
19705         (match_operator 1 "compare_operator"
19706           [(and (match_operand:HI 2 "aligned_operand" "")
19707                 (match_operand:HI 3 "const_int_operand" ""))
19708            (const_int 0)]))]
19709   "! TARGET_PARTIAL_REG_STALL && reload_completed
19710    /* Ensure that the operand will remain sign-extended immediate.  */
19711    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19712    && ! TARGET_FAST_PREFIX
19713    && ! optimize_size"
19714   [(set (match_dup 0)
19715         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19716                          (const_int 0)]))]
19718   operands[3]
19719     = gen_int_mode (INTVAL (operands[3])
19720                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19721   operands[2] = gen_lowpart (SImode, operands[2]);
19724 (define_split
19725   [(set (match_operand 0 "register_operand" "")
19726         (neg (match_operand 1 "register_operand" "")))
19727    (clobber (reg:CC FLAGS_REG))]
19728   "! TARGET_PARTIAL_REG_STALL && reload_completed
19729    && (GET_MODE (operands[0]) == HImode
19730        || (GET_MODE (operands[0]) == QImode
19731            && (TARGET_PROMOTE_QImode || optimize_size)))"
19732   [(parallel [(set (match_dup 0)
19733                    (neg:SI (match_dup 1)))
19734               (clobber (reg:CC FLAGS_REG))])]
19735   "operands[0] = gen_lowpart (SImode, operands[0]);
19736    operands[1] = gen_lowpart (SImode, operands[1]);")
19738 (define_split
19739   [(set (match_operand 0 "register_operand" "")
19740         (not (match_operand 1 "register_operand" "")))]
19741   "! TARGET_PARTIAL_REG_STALL && reload_completed
19742    && (GET_MODE (operands[0]) == HImode
19743        || (GET_MODE (operands[0]) == QImode
19744            && (TARGET_PROMOTE_QImode || optimize_size)))"
19745   [(set (match_dup 0)
19746         (not:SI (match_dup 1)))]
19747   "operands[0] = gen_lowpart (SImode, operands[0]);
19748    operands[1] = gen_lowpart (SImode, operands[1]);")
19750 (define_split
19751   [(set (match_operand 0 "register_operand" "")
19752         (if_then_else (match_operator 1 "comparison_operator"
19753                                 [(reg FLAGS_REG) (const_int 0)])
19754                       (match_operand 2 "register_operand" "")
19755                       (match_operand 3 "register_operand" "")))]
19756   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19757    && (GET_MODE (operands[0]) == HImode
19758        || (GET_MODE (operands[0]) == QImode
19759            && (TARGET_PROMOTE_QImode || optimize_size)))"
19760   [(set (match_dup 0)
19761         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19762   "operands[0] = gen_lowpart (SImode, operands[0]);
19763    operands[2] = gen_lowpart (SImode, operands[2]);
19764    operands[3] = gen_lowpart (SImode, operands[3]);")
19767 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19768 ;; transform a complex memory operation into two memory to register operations.
19770 ;; Don't push memory operands
19771 (define_peephole2
19772   [(set (match_operand:SI 0 "push_operand" "")
19773         (match_operand:SI 1 "memory_operand" ""))
19774    (match_scratch:SI 2 "r")]
19775   "!optimize_size && !TARGET_PUSH_MEMORY
19776    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19777   [(set (match_dup 2) (match_dup 1))
19778    (set (match_dup 0) (match_dup 2))]
19779   "")
19781 (define_peephole2
19782   [(set (match_operand:DI 0 "push_operand" "")
19783         (match_operand:DI 1 "memory_operand" ""))
19784    (match_scratch:DI 2 "r")]
19785   "!optimize_size && !TARGET_PUSH_MEMORY
19786    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19787   [(set (match_dup 2) (match_dup 1))
19788    (set (match_dup 0) (match_dup 2))]
19789   "")
19791 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19792 ;; SImode pushes.
19793 (define_peephole2
19794   [(set (match_operand:SF 0 "push_operand" "")
19795         (match_operand:SF 1 "memory_operand" ""))
19796    (match_scratch:SF 2 "r")]
19797   "!optimize_size && !TARGET_PUSH_MEMORY
19798    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19799   [(set (match_dup 2) (match_dup 1))
19800    (set (match_dup 0) (match_dup 2))]
19801   "")
19803 (define_peephole2
19804   [(set (match_operand:HI 0 "push_operand" "")
19805         (match_operand:HI 1 "memory_operand" ""))
19806    (match_scratch:HI 2 "r")]
19807   "!optimize_size && !TARGET_PUSH_MEMORY
19808    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19809   [(set (match_dup 2) (match_dup 1))
19810    (set (match_dup 0) (match_dup 2))]
19811   "")
19813 (define_peephole2
19814   [(set (match_operand:QI 0 "push_operand" "")
19815         (match_operand:QI 1 "memory_operand" ""))
19816    (match_scratch:QI 2 "q")]
19817   "!optimize_size && !TARGET_PUSH_MEMORY
19818    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19819   [(set (match_dup 2) (match_dup 1))
19820    (set (match_dup 0) (match_dup 2))]
19821   "")
19823 ;; Don't move an immediate directly to memory when the instruction
19824 ;; gets too big.
19825 (define_peephole2
19826   [(match_scratch:SI 1 "r")
19827    (set (match_operand:SI 0 "memory_operand" "")
19828         (const_int 0))]
19829   "! optimize_size
19830    && ! TARGET_USE_MOV0
19831    && TARGET_SPLIT_LONG_MOVES
19832    && get_attr_length (insn) >= ix86_cost->large_insn
19833    && peep2_regno_dead_p (0, FLAGS_REG)"
19834   [(parallel [(set (match_dup 1) (const_int 0))
19835               (clobber (reg:CC FLAGS_REG))])
19836    (set (match_dup 0) (match_dup 1))]
19837   "")
19839 (define_peephole2
19840   [(match_scratch:HI 1 "r")
19841    (set (match_operand:HI 0 "memory_operand" "")
19842         (const_int 0))]
19843   "! optimize_size
19844    && ! TARGET_USE_MOV0
19845    && TARGET_SPLIT_LONG_MOVES
19846    && get_attr_length (insn) >= ix86_cost->large_insn
19847    && peep2_regno_dead_p (0, FLAGS_REG)"
19848   [(parallel [(set (match_dup 2) (const_int 0))
19849               (clobber (reg:CC FLAGS_REG))])
19850    (set (match_dup 0) (match_dup 1))]
19851   "operands[2] = gen_lowpart (SImode, operands[1]);")
19853 (define_peephole2
19854   [(match_scratch:QI 1 "q")
19855    (set (match_operand:QI 0 "memory_operand" "")
19856         (const_int 0))]
19857   "! optimize_size
19858    && ! TARGET_USE_MOV0
19859    && TARGET_SPLIT_LONG_MOVES
19860    && get_attr_length (insn) >= ix86_cost->large_insn
19861    && peep2_regno_dead_p (0, FLAGS_REG)"
19862   [(parallel [(set (match_dup 2) (const_int 0))
19863               (clobber (reg:CC FLAGS_REG))])
19864    (set (match_dup 0) (match_dup 1))]
19865   "operands[2] = gen_lowpart (SImode, operands[1]);")
19867 (define_peephole2
19868   [(match_scratch:SI 2 "r")
19869    (set (match_operand:SI 0 "memory_operand" "")
19870         (match_operand:SI 1 "immediate_operand" ""))]
19871   "! optimize_size
19872    && get_attr_length (insn) >= ix86_cost->large_insn
19873    && TARGET_SPLIT_LONG_MOVES"
19874   [(set (match_dup 2) (match_dup 1))
19875    (set (match_dup 0) (match_dup 2))]
19876   "")
19878 (define_peephole2
19879   [(match_scratch:HI 2 "r")
19880    (set (match_operand:HI 0 "memory_operand" "")
19881         (match_operand:HI 1 "immediate_operand" ""))]
19882   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19883   && TARGET_SPLIT_LONG_MOVES"
19884   [(set (match_dup 2) (match_dup 1))
19885    (set (match_dup 0) (match_dup 2))]
19886   "")
19888 (define_peephole2
19889   [(match_scratch:QI 2 "q")
19890    (set (match_operand:QI 0 "memory_operand" "")
19891         (match_operand:QI 1 "immediate_operand" ""))]
19892   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19893   && TARGET_SPLIT_LONG_MOVES"
19894   [(set (match_dup 2) (match_dup 1))
19895    (set (match_dup 0) (match_dup 2))]
19896   "")
19898 ;; Don't compare memory with zero, load and use a test instead.
19899 (define_peephole2
19900   [(set (match_operand 0 "flags_reg_operand" "")
19901         (match_operator 1 "compare_operator"
19902           [(match_operand:SI 2 "memory_operand" "")
19903            (const_int 0)]))
19904    (match_scratch:SI 3 "r")]
19905   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19906   [(set (match_dup 3) (match_dup 2))
19907    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19908   "")
19910 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19911 ;; Don't split NOTs with a displacement operand, because resulting XOR
19912 ;; will not be pairable anyway.
19914 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19915 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19916 ;; so this split helps here as well.
19918 ;; Note: Can't do this as a regular split because we can't get proper
19919 ;; lifetime information then.
19921 (define_peephole2
19922   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19923         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19924   "!optimize_size
19925    && peep2_regno_dead_p (0, FLAGS_REG)
19926    && ((TARGET_PENTIUM
19927         && (GET_CODE (operands[0]) != MEM
19928             || !memory_displacement_operand (operands[0], SImode)))
19929        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19930   [(parallel [(set (match_dup 0)
19931                    (xor:SI (match_dup 1) (const_int -1)))
19932               (clobber (reg:CC FLAGS_REG))])]
19933   "")
19935 (define_peephole2
19936   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19937         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19938   "!optimize_size
19939    && peep2_regno_dead_p (0, FLAGS_REG)
19940    && ((TARGET_PENTIUM
19941         && (GET_CODE (operands[0]) != MEM
19942             || !memory_displacement_operand (operands[0], HImode)))
19943        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19944   [(parallel [(set (match_dup 0)
19945                    (xor:HI (match_dup 1) (const_int -1)))
19946               (clobber (reg:CC FLAGS_REG))])]
19947   "")
19949 (define_peephole2
19950   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19951         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19952   "!optimize_size
19953    && peep2_regno_dead_p (0, FLAGS_REG)
19954    && ((TARGET_PENTIUM
19955         && (GET_CODE (operands[0]) != MEM
19956             || !memory_displacement_operand (operands[0], QImode)))
19957        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19958   [(parallel [(set (match_dup 0)
19959                    (xor:QI (match_dup 1) (const_int -1)))
19960               (clobber (reg:CC FLAGS_REG))])]
19961   "")
19963 ;; Non pairable "test imm, reg" instructions can be translated to
19964 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19965 ;; byte opcode instead of two, have a short form for byte operands),
19966 ;; so do it for other CPUs as well.  Given that the value was dead,
19967 ;; this should not create any new dependencies.  Pass on the sub-word
19968 ;; versions if we're concerned about partial register stalls.
19970 (define_peephole2
19971   [(set (match_operand 0 "flags_reg_operand" "")
19972         (match_operator 1 "compare_operator"
19973           [(and:SI (match_operand:SI 2 "register_operand" "")
19974                    (match_operand:SI 3 "immediate_operand" ""))
19975            (const_int 0)]))]
19976   "ix86_match_ccmode (insn, CCNOmode)
19977    && (true_regnum (operands[2]) != 0
19978        || satisfies_constraint_K (operands[3]))
19979    && peep2_reg_dead_p (1, operands[2])"
19980   [(parallel
19981      [(set (match_dup 0)
19982            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19983                             (const_int 0)]))
19984       (set (match_dup 2)
19985            (and:SI (match_dup 2) (match_dup 3)))])]
19986   "")
19988 ;; We don't need to handle HImode case, because it will be promoted to SImode
19989 ;; on ! TARGET_PARTIAL_REG_STALL
19991 (define_peephole2
19992   [(set (match_operand 0 "flags_reg_operand" "")
19993         (match_operator 1 "compare_operator"
19994           [(and:QI (match_operand:QI 2 "register_operand" "")
19995                    (match_operand:QI 3 "immediate_operand" ""))
19996            (const_int 0)]))]
19997   "! TARGET_PARTIAL_REG_STALL
19998    && ix86_match_ccmode (insn, CCNOmode)
19999    && true_regnum (operands[2]) != 0
20000    && peep2_reg_dead_p (1, operands[2])"
20001   [(parallel
20002      [(set (match_dup 0)
20003            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20004                             (const_int 0)]))
20005       (set (match_dup 2)
20006            (and:QI (match_dup 2) (match_dup 3)))])]
20007   "")
20009 (define_peephole2
20010   [(set (match_operand 0 "flags_reg_operand" "")
20011         (match_operator 1 "compare_operator"
20012           [(and:SI
20013              (zero_extract:SI
20014                (match_operand 2 "ext_register_operand" "")
20015                (const_int 8)
20016                (const_int 8))
20017              (match_operand 3 "const_int_operand" ""))
20018            (const_int 0)]))]
20019   "! TARGET_PARTIAL_REG_STALL
20020    && ix86_match_ccmode (insn, CCNOmode)
20021    && true_regnum (operands[2]) != 0
20022    && peep2_reg_dead_p (1, operands[2])"
20023   [(parallel [(set (match_dup 0)
20024                    (match_op_dup 1
20025                      [(and:SI
20026                         (zero_extract:SI
20027                           (match_dup 2)
20028                           (const_int 8)
20029                           (const_int 8))
20030                         (match_dup 3))
20031                       (const_int 0)]))
20032               (set (zero_extract:SI (match_dup 2)
20033                                     (const_int 8)
20034                                     (const_int 8))
20035                    (and:SI
20036                      (zero_extract:SI
20037                        (match_dup 2)
20038                        (const_int 8)
20039                        (const_int 8))
20040                      (match_dup 3)))])]
20041   "")
20043 ;; Don't do logical operations with memory inputs.
20044 (define_peephole2
20045   [(match_scratch:SI 2 "r")
20046    (parallel [(set (match_operand:SI 0 "register_operand" "")
20047                    (match_operator:SI 3 "arith_or_logical_operator"
20048                      [(match_dup 0)
20049                       (match_operand:SI 1 "memory_operand" "")]))
20050               (clobber (reg:CC FLAGS_REG))])]
20051   "! optimize_size && ! TARGET_READ_MODIFY"
20052   [(set (match_dup 2) (match_dup 1))
20053    (parallel [(set (match_dup 0)
20054                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20055               (clobber (reg:CC FLAGS_REG))])]
20056   "")
20058 (define_peephole2
20059   [(match_scratch:SI 2 "r")
20060    (parallel [(set (match_operand:SI 0 "register_operand" "")
20061                    (match_operator:SI 3 "arith_or_logical_operator"
20062                      [(match_operand:SI 1 "memory_operand" "")
20063                       (match_dup 0)]))
20064               (clobber (reg:CC FLAGS_REG))])]
20065   "! optimize_size && ! TARGET_READ_MODIFY"
20066   [(set (match_dup 2) (match_dup 1))
20067    (parallel [(set (match_dup 0)
20068                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20069               (clobber (reg:CC FLAGS_REG))])]
20070   "")
20072 ; Don't do logical operations with memory outputs
20074 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20075 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20076 ; the same decoder scheduling characteristics as the original.
20078 (define_peephole2
20079   [(match_scratch:SI 2 "r")
20080    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20081                    (match_operator:SI 3 "arith_or_logical_operator"
20082                      [(match_dup 0)
20083                       (match_operand:SI 1 "nonmemory_operand" "")]))
20084               (clobber (reg:CC FLAGS_REG))])]
20085   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20086   [(set (match_dup 2) (match_dup 0))
20087    (parallel [(set (match_dup 2)
20088                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20089               (clobber (reg:CC FLAGS_REG))])
20090    (set (match_dup 0) (match_dup 2))]
20091   "")
20093 (define_peephole2
20094   [(match_scratch:SI 2 "r")
20095    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20096                    (match_operator:SI 3 "arith_or_logical_operator"
20097                      [(match_operand:SI 1 "nonmemory_operand" "")
20098                       (match_dup 0)]))
20099               (clobber (reg:CC FLAGS_REG))])]
20100   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20101   [(set (match_dup 2) (match_dup 0))
20102    (parallel [(set (match_dup 2)
20103                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20104               (clobber (reg:CC FLAGS_REG))])
20105    (set (match_dup 0) (match_dup 2))]
20106   "")
20108 ;; Attempt to always use XOR for zeroing registers.
20109 (define_peephole2
20110   [(set (match_operand 0 "register_operand" "")
20111         (match_operand 1 "const0_operand" ""))]
20112   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20113    && (! TARGET_USE_MOV0 || optimize_size)
20114    && GENERAL_REG_P (operands[0])
20115    && peep2_regno_dead_p (0, FLAGS_REG)"
20116   [(parallel [(set (match_dup 0) (const_int 0))
20117               (clobber (reg:CC FLAGS_REG))])]
20119   operands[0] = gen_lowpart (word_mode, operands[0]);
20122 (define_peephole2
20123   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20124         (const_int 0))]
20125   "(GET_MODE (operands[0]) == QImode
20126     || GET_MODE (operands[0]) == HImode)
20127    && (! TARGET_USE_MOV0 || optimize_size)
20128    && peep2_regno_dead_p (0, FLAGS_REG)"
20129   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20130               (clobber (reg:CC FLAGS_REG))])])
20132 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20133 (define_peephole2
20134   [(set (match_operand 0 "register_operand" "")
20135         (const_int -1))]
20136   "(GET_MODE (operands[0]) == HImode
20137     || GET_MODE (operands[0]) == SImode
20138     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20139    && (optimize_size || TARGET_PENTIUM)
20140    && peep2_regno_dead_p (0, FLAGS_REG)"
20141   [(parallel [(set (match_dup 0) (const_int -1))
20142               (clobber (reg:CC FLAGS_REG))])]
20143   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20144                               operands[0]);")
20146 ;; Attempt to convert simple leas to adds. These can be created by
20147 ;; move expanders.
20148 (define_peephole2
20149   [(set (match_operand:SI 0 "register_operand" "")
20150         (plus:SI (match_dup 0)
20151                  (match_operand:SI 1 "nonmemory_operand" "")))]
20152   "peep2_regno_dead_p (0, FLAGS_REG)"
20153   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20154               (clobber (reg:CC FLAGS_REG))])]
20155   "")
20157 (define_peephole2
20158   [(set (match_operand:SI 0 "register_operand" "")
20159         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20160                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20161   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20162   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20163               (clobber (reg:CC FLAGS_REG))])]
20164   "operands[2] = gen_lowpart (SImode, operands[2]);")
20166 (define_peephole2
20167   [(set (match_operand:DI 0 "register_operand" "")
20168         (plus:DI (match_dup 0)
20169                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20170   "peep2_regno_dead_p (0, FLAGS_REG)"
20171   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20172               (clobber (reg:CC FLAGS_REG))])]
20173   "")
20175 (define_peephole2
20176   [(set (match_operand:SI 0 "register_operand" "")
20177         (mult:SI (match_dup 0)
20178                  (match_operand:SI 1 "const_int_operand" "")))]
20179   "exact_log2 (INTVAL (operands[1])) >= 0
20180    && peep2_regno_dead_p (0, FLAGS_REG)"
20181   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20182               (clobber (reg:CC FLAGS_REG))])]
20183   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20185 (define_peephole2
20186   [(set (match_operand:DI 0 "register_operand" "")
20187         (mult:DI (match_dup 0)
20188                  (match_operand:DI 1 "const_int_operand" "")))]
20189   "exact_log2 (INTVAL (operands[1])) >= 0
20190    && peep2_regno_dead_p (0, FLAGS_REG)"
20191   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20192               (clobber (reg:CC FLAGS_REG))])]
20193   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20195 (define_peephole2
20196   [(set (match_operand:SI 0 "register_operand" "")
20197         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20198                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20199   "exact_log2 (INTVAL (operands[2])) >= 0
20200    && REGNO (operands[0]) == REGNO (operands[1])
20201    && peep2_regno_dead_p (0, FLAGS_REG)"
20202   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20203               (clobber (reg:CC FLAGS_REG))])]
20204   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20206 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20207 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20208 ;; many CPUs it is also faster, since special hardware to avoid esp
20209 ;; dependencies is present.
20211 ;; While some of these conversions may be done using splitters, we use peepholes
20212 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20214 ;; Convert prologue esp subtractions to push.
20215 ;; We need register to push.  In order to keep verify_flow_info happy we have
20216 ;; two choices
20217 ;; - use scratch and clobber it in order to avoid dependencies
20218 ;; - use already live register
20219 ;; We can't use the second way right now, since there is no reliable way how to
20220 ;; verify that given register is live.  First choice will also most likely in
20221 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20222 ;; call clobbered registers are dead.  We may want to use base pointer as an
20223 ;; alternative when no register is available later.
20225 (define_peephole2
20226   [(match_scratch:SI 0 "r")
20227    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20228               (clobber (reg:CC FLAGS_REG))
20229               (clobber (mem:BLK (scratch)))])]
20230   "optimize_size || !TARGET_SUB_ESP_4"
20231   [(clobber (match_dup 0))
20232    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20233               (clobber (mem:BLK (scratch)))])])
20235 (define_peephole2
20236   [(match_scratch:SI 0 "r")
20237    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20238               (clobber (reg:CC FLAGS_REG))
20239               (clobber (mem:BLK (scratch)))])]
20240   "optimize_size || !TARGET_SUB_ESP_8"
20241   [(clobber (match_dup 0))
20242    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20243    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20244               (clobber (mem:BLK (scratch)))])])
20246 ;; Convert esp subtractions to push.
20247 (define_peephole2
20248   [(match_scratch:SI 0 "r")
20249    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20250               (clobber (reg:CC FLAGS_REG))])]
20251   "optimize_size || !TARGET_SUB_ESP_4"
20252   [(clobber (match_dup 0))
20253    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20255 (define_peephole2
20256   [(match_scratch:SI 0 "r")
20257    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20258               (clobber (reg:CC FLAGS_REG))])]
20259   "optimize_size || !TARGET_SUB_ESP_8"
20260   [(clobber (match_dup 0))
20261    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20262    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20264 ;; Convert epilogue deallocator to pop.
20265 (define_peephole2
20266   [(match_scratch:SI 0 "r")
20267    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20268               (clobber (reg:CC FLAGS_REG))
20269               (clobber (mem:BLK (scratch)))])]
20270   "optimize_size || !TARGET_ADD_ESP_4"
20271   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20272               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20273               (clobber (mem:BLK (scratch)))])]
20274   "")
20276 ;; Two pops case is tricky, since pop causes dependency on destination register.
20277 ;; We use two registers if available.
20278 (define_peephole2
20279   [(match_scratch:SI 0 "r")
20280    (match_scratch:SI 1 "r")
20281    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20282               (clobber (reg:CC FLAGS_REG))
20283               (clobber (mem:BLK (scratch)))])]
20284   "optimize_size || !TARGET_ADD_ESP_8"
20285   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20286               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20287               (clobber (mem:BLK (scratch)))])
20288    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20289               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20290   "")
20292 (define_peephole2
20293   [(match_scratch:SI 0 "r")
20294    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20295               (clobber (reg:CC FLAGS_REG))
20296               (clobber (mem:BLK (scratch)))])]
20297   "optimize_size"
20298   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20299               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20300               (clobber (mem:BLK (scratch)))])
20301    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20302               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20303   "")
20305 ;; Convert esp additions to pop.
20306 (define_peephole2
20307   [(match_scratch:SI 0 "r")
20308    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20309               (clobber (reg:CC FLAGS_REG))])]
20310   ""
20311   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20312               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20313   "")
20315 ;; Two pops case is tricky, since pop causes dependency on destination register.
20316 ;; We use two registers if available.
20317 (define_peephole2
20318   [(match_scratch:SI 0 "r")
20319    (match_scratch:SI 1 "r")
20320    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20321               (clobber (reg:CC FLAGS_REG))])]
20322   ""
20323   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20324               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20325    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20326               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20327   "")
20329 (define_peephole2
20330   [(match_scratch:SI 0 "r")
20331    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20332               (clobber (reg:CC FLAGS_REG))])]
20333   "optimize_size"
20334   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20335               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20336    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20337               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20338   "")
20340 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20341 ;; required and register dies.  Similarly for 128 to plus -128.
20342 (define_peephole2
20343   [(set (match_operand 0 "flags_reg_operand" "")
20344         (match_operator 1 "compare_operator"
20345           [(match_operand 2 "register_operand" "")
20346            (match_operand 3 "const_int_operand" "")]))]
20347   "(INTVAL (operands[3]) == -1
20348     || INTVAL (operands[3]) == 1
20349     || INTVAL (operands[3]) == 128)
20350    && ix86_match_ccmode (insn, CCGCmode)
20351    && peep2_reg_dead_p (1, operands[2])"
20352   [(parallel [(set (match_dup 0)
20353                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20354               (clobber (match_dup 2))])]
20355   "")
20357 (define_peephole2
20358   [(match_scratch:DI 0 "r")
20359    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20360               (clobber (reg:CC FLAGS_REG))
20361               (clobber (mem:BLK (scratch)))])]
20362   "optimize_size || !TARGET_SUB_ESP_4"
20363   [(clobber (match_dup 0))
20364    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20365               (clobber (mem:BLK (scratch)))])])
20367 (define_peephole2
20368   [(match_scratch:DI 0 "r")
20369    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20370               (clobber (reg:CC FLAGS_REG))
20371               (clobber (mem:BLK (scratch)))])]
20372   "optimize_size || !TARGET_SUB_ESP_8"
20373   [(clobber (match_dup 0))
20374    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20375    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20376               (clobber (mem:BLK (scratch)))])])
20378 ;; Convert esp subtractions to push.
20379 (define_peephole2
20380   [(match_scratch:DI 0 "r")
20381    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20382               (clobber (reg:CC FLAGS_REG))])]
20383   "optimize_size || !TARGET_SUB_ESP_4"
20384   [(clobber (match_dup 0))
20385    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20387 (define_peephole2
20388   [(match_scratch:DI 0 "r")
20389    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20390               (clobber (reg:CC FLAGS_REG))])]
20391   "optimize_size || !TARGET_SUB_ESP_8"
20392   [(clobber (match_dup 0))
20393    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20394    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20396 ;; Convert epilogue deallocator to pop.
20397 (define_peephole2
20398   [(match_scratch:DI 0 "r")
20399    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20400               (clobber (reg:CC FLAGS_REG))
20401               (clobber (mem:BLK (scratch)))])]
20402   "optimize_size || !TARGET_ADD_ESP_4"
20403   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20404               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20405               (clobber (mem:BLK (scratch)))])]
20406   "")
20408 ;; Two pops case is tricky, since pop causes dependency on destination register.
20409 ;; We use two registers if available.
20410 (define_peephole2
20411   [(match_scratch:DI 0 "r")
20412    (match_scratch:DI 1 "r")
20413    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20414               (clobber (reg:CC FLAGS_REG))
20415               (clobber (mem:BLK (scratch)))])]
20416   "optimize_size || !TARGET_ADD_ESP_8"
20417   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20418               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20419               (clobber (mem:BLK (scratch)))])
20420    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20421               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20422   "")
20424 (define_peephole2
20425   [(match_scratch:DI 0 "r")
20426    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20427               (clobber (reg:CC FLAGS_REG))
20428               (clobber (mem:BLK (scratch)))])]
20429   "optimize_size"
20430   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20431               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20432               (clobber (mem:BLK (scratch)))])
20433    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20434               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20435   "")
20437 ;; Convert esp additions to pop.
20438 (define_peephole2
20439   [(match_scratch:DI 0 "r")
20440    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20441               (clobber (reg:CC FLAGS_REG))])]
20442   ""
20443   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20444               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20445   "")
20447 ;; Two pops case is tricky, since pop causes dependency on destination register.
20448 ;; We use two registers if available.
20449 (define_peephole2
20450   [(match_scratch:DI 0 "r")
20451    (match_scratch:DI 1 "r")
20452    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20453               (clobber (reg:CC FLAGS_REG))])]
20454   ""
20455   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20456               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20457    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20458               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20459   "")
20461 (define_peephole2
20462   [(match_scratch:DI 0 "r")
20463    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20464               (clobber (reg:CC FLAGS_REG))])]
20465   "optimize_size"
20466   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20467               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20468    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20469               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20470   "")
20472 ;; Convert imul by three, five and nine into lea
20473 (define_peephole2
20474   [(parallel
20475     [(set (match_operand:SI 0 "register_operand" "")
20476           (mult:SI (match_operand:SI 1 "register_operand" "")
20477                    (match_operand:SI 2 "const_int_operand" "")))
20478      (clobber (reg:CC FLAGS_REG))])]
20479   "INTVAL (operands[2]) == 3
20480    || INTVAL (operands[2]) == 5
20481    || INTVAL (operands[2]) == 9"
20482   [(set (match_dup 0)
20483         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20484                  (match_dup 1)))]
20485   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20487 (define_peephole2
20488   [(parallel
20489     [(set (match_operand:SI 0 "register_operand" "")
20490           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20491                    (match_operand:SI 2 "const_int_operand" "")))
20492      (clobber (reg:CC FLAGS_REG))])]
20493   "!optimize_size
20494    && (INTVAL (operands[2]) == 3
20495        || INTVAL (operands[2]) == 5
20496        || INTVAL (operands[2]) == 9)"
20497   [(set (match_dup 0) (match_dup 1))
20498    (set (match_dup 0)
20499         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20500                  (match_dup 0)))]
20501   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20503 (define_peephole2
20504   [(parallel
20505     [(set (match_operand:DI 0 "register_operand" "")
20506           (mult:DI (match_operand:DI 1 "register_operand" "")
20507                    (match_operand:DI 2 "const_int_operand" "")))
20508      (clobber (reg:CC FLAGS_REG))])]
20509   "TARGET_64BIT
20510    && (INTVAL (operands[2]) == 3
20511        || INTVAL (operands[2]) == 5
20512        || INTVAL (operands[2]) == 9)"
20513   [(set (match_dup 0)
20514         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20515                  (match_dup 1)))]
20516   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20518 (define_peephole2
20519   [(parallel
20520     [(set (match_operand:DI 0 "register_operand" "")
20521           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20522                    (match_operand:DI 2 "const_int_operand" "")))
20523      (clobber (reg:CC FLAGS_REG))])]
20524   "TARGET_64BIT
20525    && !optimize_size
20526    && (INTVAL (operands[2]) == 3
20527        || INTVAL (operands[2]) == 5
20528        || INTVAL (operands[2]) == 9)"
20529   [(set (match_dup 0) (match_dup 1))
20530    (set (match_dup 0)
20531         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20532                  (match_dup 0)))]
20533   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20535 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20536 ;; imul $32bit_imm, reg, reg is direct decoded.
20537 (define_peephole2
20538   [(match_scratch:DI 3 "r")
20539    (parallel [(set (match_operand:DI 0 "register_operand" "")
20540                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20541                             (match_operand:DI 2 "immediate_operand" "")))
20542               (clobber (reg:CC FLAGS_REG))])]
20543   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20544    && !satisfies_constraint_K (operands[2])"
20545   [(set (match_dup 3) (match_dup 1))
20546    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20547               (clobber (reg:CC FLAGS_REG))])]
20550 (define_peephole2
20551   [(match_scratch:SI 3 "r")
20552    (parallel [(set (match_operand:SI 0 "register_operand" "")
20553                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20554                             (match_operand:SI 2 "immediate_operand" "")))
20555               (clobber (reg:CC FLAGS_REG))])]
20556   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20557    && !satisfies_constraint_K (operands[2])"
20558   [(set (match_dup 3) (match_dup 1))
20559    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20560               (clobber (reg:CC FLAGS_REG))])]
20563 (define_peephole2
20564   [(match_scratch:SI 3 "r")
20565    (parallel [(set (match_operand:DI 0 "register_operand" "")
20566                    (zero_extend:DI
20567                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20568                               (match_operand:SI 2 "immediate_operand" ""))))
20569               (clobber (reg:CC FLAGS_REG))])]
20570   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20571    && !satisfies_constraint_K (operands[2])"
20572   [(set (match_dup 3) (match_dup 1))
20573    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20574               (clobber (reg:CC FLAGS_REG))])]
20577 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20578 ;; Convert it into imul reg, reg
20579 ;; It would be better to force assembler to encode instruction using long
20580 ;; immediate, but there is apparently no way to do so.
20581 (define_peephole2
20582   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20583                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20584                             (match_operand:DI 2 "const_int_operand" "")))
20585               (clobber (reg:CC FLAGS_REG))])
20586    (match_scratch:DI 3 "r")]
20587   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20588    && satisfies_constraint_K (operands[2])"
20589   [(set (match_dup 3) (match_dup 2))
20590    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20591               (clobber (reg:CC FLAGS_REG))])]
20593   if (!rtx_equal_p (operands[0], operands[1]))
20594     emit_move_insn (operands[0], operands[1]);
20597 (define_peephole2
20598   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20599                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20600                             (match_operand:SI 2 "const_int_operand" "")))
20601               (clobber (reg:CC FLAGS_REG))])
20602    (match_scratch:SI 3 "r")]
20603   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20604    && satisfies_constraint_K (operands[2])"
20605   [(set (match_dup 3) (match_dup 2))
20606    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20607               (clobber (reg:CC FLAGS_REG))])]
20609   if (!rtx_equal_p (operands[0], operands[1]))
20610     emit_move_insn (operands[0], operands[1]);
20613 (define_peephole2
20614   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20615                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20616                             (match_operand:HI 2 "immediate_operand" "")))
20617               (clobber (reg:CC FLAGS_REG))])
20618    (match_scratch:HI 3 "r")]
20619   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20620   [(set (match_dup 3) (match_dup 2))
20621    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20622               (clobber (reg:CC FLAGS_REG))])]
20624   if (!rtx_equal_p (operands[0], operands[1]))
20625     emit_move_insn (operands[0], operands[1]);
20628 ;; After splitting up read-modify operations, array accesses with memory
20629 ;; operands might end up in form:
20630 ;;  sall    $2, %eax
20631 ;;  movl    4(%esp), %edx
20632 ;;  addl    %edx, %eax
20633 ;; instead of pre-splitting:
20634 ;;  sall    $2, %eax
20635 ;;  addl    4(%esp), %eax
20636 ;; Turn it into:
20637 ;;  movl    4(%esp), %edx
20638 ;;  leal    (%edx,%eax,4), %eax
20640 (define_peephole2
20641   [(parallel [(set (match_operand 0 "register_operand" "")
20642                    (ashift (match_operand 1 "register_operand" "")
20643                            (match_operand 2 "const_int_operand" "")))
20644                (clobber (reg:CC FLAGS_REG))])
20645    (set (match_operand 3 "register_operand")
20646         (match_operand 4 "x86_64_general_operand" ""))
20647    (parallel [(set (match_operand 5 "register_operand" "")
20648                    (plus (match_operand 6 "register_operand" "")
20649                          (match_operand 7 "register_operand" "")))
20650                    (clobber (reg:CC FLAGS_REG))])]
20651   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20652    /* Validate MODE for lea.  */
20653    && ((!TARGET_PARTIAL_REG_STALL
20654         && (GET_MODE (operands[0]) == QImode
20655             || GET_MODE (operands[0]) == HImode))
20656        || GET_MODE (operands[0]) == SImode
20657        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20658    /* We reorder load and the shift.  */
20659    && !rtx_equal_p (operands[1], operands[3])
20660    && !reg_overlap_mentioned_p (operands[0], operands[4])
20661    /* Last PLUS must consist of operand 0 and 3.  */
20662    && !rtx_equal_p (operands[0], operands[3])
20663    && (rtx_equal_p (operands[3], operands[6])
20664        || rtx_equal_p (operands[3], operands[7]))
20665    && (rtx_equal_p (operands[0], operands[6])
20666        || rtx_equal_p (operands[0], operands[7]))
20667    /* The intermediate operand 0 must die or be same as output.  */
20668    && (rtx_equal_p (operands[0], operands[5])
20669        || peep2_reg_dead_p (3, operands[0]))"
20670   [(set (match_dup 3) (match_dup 4))
20671    (set (match_dup 0) (match_dup 1))]
20673   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20674   int scale = 1 << INTVAL (operands[2]);
20675   rtx index = gen_lowpart (Pmode, operands[1]);
20676   rtx base = gen_lowpart (Pmode, operands[3]);
20677   rtx dest = gen_lowpart (mode, operands[5]);
20679   operands[1] = gen_rtx_PLUS (Pmode, base,
20680                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20681   if (mode != Pmode)
20682     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20683   operands[0] = dest;
20686 ;; Call-value patterns last so that the wildcard operand does not
20687 ;; disrupt insn-recog's switch tables.
20689 (define_insn "*call_value_pop_0"
20690   [(set (match_operand 0 "" "")
20691         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20692               (match_operand:SI 2 "" "")))
20693    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20694                             (match_operand:SI 3 "immediate_operand" "")))]
20695   "!TARGET_64BIT"
20697   if (SIBLING_CALL_P (insn))
20698     return "jmp\t%P1";
20699   else
20700     return "call\t%P1";
20702   [(set_attr "type" "callv")])
20704 (define_insn "*call_value_pop_1"
20705   [(set (match_operand 0 "" "")
20706         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20707               (match_operand:SI 2 "" "")))
20708    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20709                             (match_operand:SI 3 "immediate_operand" "i")))]
20710   "!TARGET_64BIT"
20712   if (constant_call_address_operand (operands[1], Pmode))
20713     {
20714       if (SIBLING_CALL_P (insn))
20715         return "jmp\t%P1";
20716       else
20717         return "call\t%P1";
20718     }
20719   if (SIBLING_CALL_P (insn))
20720     return "jmp\t%A1";
20721   else
20722     return "call\t%A1";
20724   [(set_attr "type" "callv")])
20726 (define_insn "*call_value_0"
20727   [(set (match_operand 0 "" "")
20728         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20729               (match_operand:SI 2 "" "")))]
20730   "!TARGET_64BIT"
20732   if (SIBLING_CALL_P (insn))
20733     return "jmp\t%P1";
20734   else
20735     return "call\t%P1";
20737   [(set_attr "type" "callv")])
20739 (define_insn "*call_value_0_rex64"
20740   [(set (match_operand 0 "" "")
20741         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20742               (match_operand:DI 2 "const_int_operand" "")))]
20743   "TARGET_64BIT"
20745   if (SIBLING_CALL_P (insn))
20746     return "jmp\t%P1";
20747   else
20748     return "call\t%P1";
20750   [(set_attr "type" "callv")])
20752 (define_insn "*call_value_1"
20753   [(set (match_operand 0 "" "")
20754         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20755               (match_operand:SI 2 "" "")))]
20756   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20758   if (constant_call_address_operand (operands[1], Pmode))
20759     return "call\t%P1";
20760   return "call\t%A1";
20762   [(set_attr "type" "callv")])
20764 (define_insn "*sibcall_value_1"
20765   [(set (match_operand 0 "" "")
20766         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20767               (match_operand:SI 2 "" "")))]
20768   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20770   if (constant_call_address_operand (operands[1], Pmode))
20771     return "jmp\t%P1";
20772   return "jmp\t%A1";
20774   [(set_attr "type" "callv")])
20776 (define_insn "*call_value_1_rex64"
20777   [(set (match_operand 0 "" "")
20778         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20779               (match_operand:DI 2 "" "")))]
20780   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20782   if (constant_call_address_operand (operands[1], Pmode))
20783     return "call\t%P1";
20784   return "call\t%A1";
20786   [(set_attr "type" "callv")])
20788 (define_insn "*sibcall_value_1_rex64"
20789   [(set (match_operand 0 "" "")
20790         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20791               (match_operand:DI 2 "" "")))]
20792   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20793   "jmp\t%P1"
20794   [(set_attr "type" "callv")])
20796 (define_insn "*sibcall_value_1_rex64_v"
20797   [(set (match_operand 0 "" "")
20798         (call (mem:QI (reg:DI R11_REG))
20799               (match_operand:DI 1 "" "")))]
20800   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20801   "jmp\t*%%r11"
20802   [(set_attr "type" "callv")])
20804 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20805 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20806 ;; caught for use by garbage collectors and the like.  Using an insn that
20807 ;; maps to SIGILL makes it more likely the program will rightfully die.
20808 ;; Keeping with tradition, "6" is in honor of #UD.
20809 (define_insn "trap"
20810   [(trap_if (const_int 1) (const_int 6))]
20811   ""
20812   { return ASM_SHORT "0x0b0f"; }
20813   [(set_attr "length" "2")])
20815 (define_expand "sse_prologue_save"
20816   [(parallel [(set (match_operand:BLK 0 "" "")
20817                    (unspec:BLK [(reg:DI 22)
20818                                 (reg:DI 23)
20819                                 (reg:DI 24)
20820                                 (reg:DI 25)
20821                                 (reg:DI 26)
20822                                 (reg:DI 27)
20823                                 (reg:DI 28)
20824                                 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20825               (use (match_operand:DI 1 "register_operand" ""))
20826               (use (match_operand:DI 2 "immediate_operand" ""))
20827               (use (label_ref:DI (match_operand 3 "" "")))])]
20828   "TARGET_64BIT"
20829   "")
20831 (define_insn "*sse_prologue_save_insn"
20832   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20833                           (match_operand:DI 4 "const_int_operand" "n")))
20834         (unspec:BLK [(reg:DI 22)
20835                      (reg:DI 23)
20836                      (reg:DI 24)
20837                      (reg:DI 25)
20838                      (reg:DI 26)
20839                      (reg:DI 27)
20840                      (reg:DI 28)
20841                      (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20842    (use (match_operand:DI 1 "register_operand" "r"))
20843    (use (match_operand:DI 2 "const_int_operand" "i"))
20844    (use (label_ref:DI (match_operand 3 "" "X")))]
20845   "TARGET_64BIT
20846    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20847    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20848   "*
20850   int i;
20851   operands[0] = gen_rtx_MEM (Pmode,
20852                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20853   output_asm_insn (\"jmp\\t%A1\", operands);
20854   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20855     {
20856       operands[4] = adjust_address (operands[0], DImode, i*16);
20857       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20858       PUT_MODE (operands[4], TImode);
20859       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20860         output_asm_insn (\"rex\", operands);
20861       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20862     }
20863   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20864                              CODE_LABEL_NUMBER (operands[3]));
20865   RET;
20867   "
20868   [(set_attr "type" "other")
20869    (set_attr "length_immediate" "0")
20870    (set_attr "length_address" "0")
20871    (set_attr "length" "135")
20872    (set_attr "memory" "store")
20873    (set_attr "modrm" "0")
20874    (set_attr "mode" "DI")])
20876 (define_expand "prefetch"
20877   [(prefetch (match_operand 0 "address_operand" "")
20878              (match_operand:SI 1 "const_int_operand" "")
20879              (match_operand:SI 2 "const_int_operand" ""))]
20880   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20882   int rw = INTVAL (operands[1]);
20883   int locality = INTVAL (operands[2]);
20885   gcc_assert (rw == 0 || rw == 1);
20886   gcc_assert (locality >= 0 && locality <= 3);
20887   gcc_assert (GET_MODE (operands[0]) == Pmode
20888               || GET_MODE (operands[0]) == VOIDmode);
20890   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20891      supported by SSE counterpart or the SSE prefetch is not available
20892      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20893      of locality.  */
20894   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20895     operands[2] = GEN_INT (3);
20896   else
20897     operands[1] = const0_rtx;
20900 (define_insn "*prefetch_sse"
20901   [(prefetch (match_operand:SI 0 "address_operand" "p")
20902              (const_int 0)
20903              (match_operand:SI 1 "const_int_operand" ""))]
20904   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20906   static const char * const patterns[4] = {
20907    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20908   };
20910   int locality = INTVAL (operands[1]);
20911   gcc_assert (locality >= 0 && locality <= 3);
20913   return patterns[locality];
20915   [(set_attr "type" "sse")
20916    (set_attr "memory" "none")])
20918 (define_insn "*prefetch_sse_rex"
20919   [(prefetch (match_operand:DI 0 "address_operand" "p")
20920              (const_int 0)
20921              (match_operand:SI 1 "const_int_operand" ""))]
20922   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20924   static const char * const patterns[4] = {
20925    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20926   };
20928   int locality = INTVAL (operands[1]);
20929   gcc_assert (locality >= 0 && locality <= 3);
20931   return patterns[locality];
20933   [(set_attr "type" "sse")
20934    (set_attr "memory" "none")])
20936 (define_insn "*prefetch_3dnow"
20937   [(prefetch (match_operand:SI 0 "address_operand" "p")
20938              (match_operand:SI 1 "const_int_operand" "n")
20939              (const_int 3))]
20940   "TARGET_3DNOW && !TARGET_64BIT"
20942   if (INTVAL (operands[1]) == 0)
20943     return "prefetch\t%a0";
20944   else
20945     return "prefetchw\t%a0";
20947   [(set_attr "type" "mmx")
20948    (set_attr "memory" "none")])
20950 (define_insn "*prefetch_3dnow_rex"
20951   [(prefetch (match_operand:DI 0 "address_operand" "p")
20952              (match_operand:SI 1 "const_int_operand" "n")
20953              (const_int 3))]
20954   "TARGET_3DNOW && TARGET_64BIT"
20956   if (INTVAL (operands[1]) == 0)
20957     return "prefetch\t%a0";
20958   else
20959     return "prefetchw\t%a0";
20961   [(set_attr "type" "mmx")
20962    (set_attr "memory" "none")])
20964 (define_expand "stack_protect_set"
20965   [(match_operand 0 "memory_operand" "")
20966    (match_operand 1 "memory_operand" "")]
20967   ""
20969 #ifdef TARGET_THREAD_SSP_OFFSET
20970   if (TARGET_64BIT)
20971     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20972                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20973   else
20974     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20975                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20976 #else
20977   if (TARGET_64BIT)
20978     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20979   else
20980     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20981 #endif
20982   DONE;
20985 (define_insn "stack_protect_set_si"
20986   [(set (match_operand:SI 0 "memory_operand" "=m")
20987         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20988    (set (match_scratch:SI 2 "=&r") (const_int 0))
20989    (clobber (reg:CC FLAGS_REG))]
20990   ""
20991   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20992   [(set_attr "type" "multi")])
20994 (define_insn "stack_protect_set_di"
20995   [(set (match_operand:DI 0 "memory_operand" "=m")
20996         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20997    (set (match_scratch:DI 2 "=&r") (const_int 0))
20998    (clobber (reg:CC FLAGS_REG))]
20999   "TARGET_64BIT"
21000   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21001   [(set_attr "type" "multi")])
21003 (define_insn "stack_tls_protect_set_si"
21004   [(set (match_operand:SI 0 "memory_operand" "=m")
21005         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21006    (set (match_scratch:SI 2 "=&r") (const_int 0))
21007    (clobber (reg:CC FLAGS_REG))]
21008   ""
21009   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21010   [(set_attr "type" "multi")])
21012 (define_insn "stack_tls_protect_set_di"
21013   [(set (match_operand:DI 0 "memory_operand" "=m")
21014         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21015    (set (match_scratch:DI 2 "=&r") (const_int 0))
21016    (clobber (reg:CC FLAGS_REG))]
21017   "TARGET_64BIT"
21018   {
21019      /* The kernel uses a different segment register for performance reasons; a
21020         system call would not have to trash the userspace segment register,
21021         which would be expensive */
21022      if (ix86_cmodel != CM_KERNEL)
21023         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21024      else
21025         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21026   }
21027   [(set_attr "type" "multi")])
21029 (define_expand "stack_protect_test"
21030   [(match_operand 0 "memory_operand" "")
21031    (match_operand 1 "memory_operand" "")
21032    (match_operand 2 "" "")]
21033   ""
21035   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21036   ix86_compare_op0 = operands[0];
21037   ix86_compare_op1 = operands[1];
21038   ix86_compare_emitted = flags;
21040 #ifdef TARGET_THREAD_SSP_OFFSET
21041   if (TARGET_64BIT)
21042     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21043                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21044   else
21045     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21046                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21047 #else
21048   if (TARGET_64BIT)
21049     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21050   else
21051     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21052 #endif
21053   emit_jump_insn (gen_beq (operands[2]));
21054   DONE;
21057 (define_insn "stack_protect_test_si"
21058   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21059         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21060                      (match_operand:SI 2 "memory_operand" "m")]
21061                     UNSPEC_SP_TEST))
21062    (clobber (match_scratch:SI 3 "=&r"))]
21063   ""
21064   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21065   [(set_attr "type" "multi")])
21067 (define_insn "stack_protect_test_di"
21068   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21069         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21070                      (match_operand:DI 2 "memory_operand" "m")]
21071                     UNSPEC_SP_TEST))
21072    (clobber (match_scratch:DI 3 "=&r"))]
21073   "TARGET_64BIT"
21074   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21075   [(set_attr "type" "multi")])
21077 (define_insn "stack_tls_protect_test_si"
21078   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21079         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21080                      (match_operand:SI 2 "const_int_operand" "i")]
21081                     UNSPEC_SP_TLS_TEST))
21082    (clobber (match_scratch:SI 3 "=r"))]
21083   ""
21084   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21085   [(set_attr "type" "multi")])
21087 (define_insn "stack_tls_protect_test_di"
21088   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21089         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21090                      (match_operand:DI 2 "const_int_operand" "i")]
21091                     UNSPEC_SP_TLS_TEST))
21092    (clobber (match_scratch:DI 3 "=r"))]
21093   "TARGET_64BIT"
21094   {
21095      /* The kernel uses a different segment register for performance reasons; a
21096         system call would not have to trash the userspace segment register,
21097         which would be expensive */
21098      if (ix86_cmodel != CM_KERNEL)
21099         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21100      else
21101         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21102   }
21103   [(set_attr "type" "multi")])
21105 (include "mmx.md")
21106 (include "sse.md")
21107 (include "sync.md")