Update FSF address.
[official-gcc.git] / gcc / config / i386 / i386.md
blob46fe51e5662928ebbb7a1200d635f84593c64d29
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
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)
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_FNSTSW               21)
78    (UNSPEC_SAHF                 22)
79    (UNSPEC_FSTCW                23)
80    (UNSPEC_ADD_CARRY            24)
81    (UNSPEC_FLDCW                25)
82    (UNSPEC_REP                  26)
83    (UNSPEC_EH_RETURN            27)
85    ; For SSE/MMX support:
86    (UNSPEC_FIX_NOTRUNC          30)
87    (UNSPEC_MASKMOV              31)
88    (UNSPEC_MOVMSK               32)
89    (UNSPEC_MOVNT                33)
90    (UNSPEC_MOVU                 34)
91    (UNSPEC_RCP                  35)
92    (UNSPEC_RSQRT                36)
93    (UNSPEC_SFENCE               37)
94    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
95    (UNSPEC_PFRCP                39)
96    (UNSPEC_PFRCPIT1             40)
97    (UNSPEC_PFRCPIT2             41)
98    (UNSPEC_PFRSQRT              42)
99    (UNSPEC_PFRSQIT1             43)
100    (UNSPEC_MFENCE               44)
101    (UNSPEC_LFENCE               45)
102    (UNSPEC_PSADBW               46)
103    (UNSPEC_LDQQU                47)
105    ; Generic math support
106    (UNSPEC_COPYSIGN             50)
107    (UNSPEC_IEEE_MIN             51)     ; not commutative
108    (UNSPEC_IEEE_MAX             52)     ; not commutative
110    ; x87 Floating point
111    (UNSPEC_SIN                  60)
112    (UNSPEC_COS                  61)
113    (UNSPEC_FPATAN               62)
114    (UNSPEC_FYL2X                63)
115    (UNSPEC_FYL2XP1              64)
116    (UNSPEC_FRNDINT              65)
117    (UNSPEC_FIST                 66)
118    (UNSPEC_F2XM1                67)
120    ; x87 Rounding
121    (UNSPEC_FRNDINT_FLOOR        70)
122    (UNSPEC_FRNDINT_CEIL         71)
123    (UNSPEC_FRNDINT_TRUNC        72)
124    (UNSPEC_FRNDINT_MASK_PM      73)
125    (UNSPEC_FIST_FLOOR           74)
126    (UNSPEC_FIST_CEIL            75)
128    ; x87 Double output FP
129    (UNSPEC_SINCOS_COS           80)
130    (UNSPEC_SINCOS_SIN           81)
131    (UNSPEC_TAN_ONE              82)
132    (UNSPEC_TAN_TAN              83)
133    (UNSPEC_XTRACT_FRACT         84)
134    (UNSPEC_XTRACT_EXP           85)
135    (UNSPEC_FSCALE_FRACT         86)
136    (UNSPEC_FSCALE_EXP           87)
137    (UNSPEC_FPREM_F              88)
138    (UNSPEC_FPREM_U              89)
139    (UNSPEC_FPREM1_F             90)
140    (UNSPEC_FPREM1_U             91)
141   ])
143 (define_constants
144   [(UNSPECV_BLOCKAGE            0)
145    (UNSPECV_STACK_PROBE         1)
146    (UNSPECV_EMMS                2)
147    (UNSPECV_LDMXCSR             3)
148    (UNSPECV_STMXCSR             4)
149    (UNSPECV_FEMMS               5)
150    (UNSPECV_CLFLUSH             6)
151    (UNSPECV_ALIGN               7)
152    (UNSPECV_MONITOR             8)
153    (UNSPECV_MWAIT               9)
154    (UNSPECV_CMPXCHG_1           10)
155    (UNSPECV_CMPXCHG_2           11)
156    (UNSPECV_XCHG                12)
157    (UNSPECV_LOCK                13)
158   ])
160 ;; Registers by name.
161 (define_constants
162   [(BP_REG                       6)
163    (SP_REG                       7)
164    (FLAGS_REG                   17)
165    (FPSR_REG                    18)
166    (DIRFLAG_REG                 19)
167   ])
169 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
170 ;; from i386.c.
172 ;; In C guard expressions, put expressions which may be compile-time
173 ;; constants first.  This allows for better optimization.  For
174 ;; example, write "TARGET_64BIT && reload_completed", not
175 ;; "reload_completed && TARGET_64BIT".
178 ;; Processor type.  This attribute must exactly match the processor_type
179 ;; enumeration in i386.h.
180 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
181   (const (symbol_ref "ix86_tune")))
183 ;; A basic instruction type.  Refinements due to arguments to be
184 ;; provided in other attributes.
185 (define_attr "type"
186   "other,multi,
187    alu,alu1,negnot,imov,imovx,lea,
188    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
189    icmp,test,ibr,setcc,icmov,
190    push,pop,call,callv,leave,
191    str,cld,
192    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
193    sselog,sselog1,sseiadd,sseishft,sseimul,
194    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
195    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
196   (const_string "other"))
198 ;; Main data type used by the insn
199 (define_attr "mode"
200   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
201   (const_string "unknown"))
203 ;; The CPU unit operations uses.
204 (define_attr "unit" "integer,i387,sse,mmx,unknown"
205   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
206            (const_string "i387")
207          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
208                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
209            (const_string "sse")
210          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
211            (const_string "mmx")
212          (eq_attr "type" "other")
213            (const_string "unknown")]
214          (const_string "integer")))
216 ;; The (bounding maximum) length of an instruction immediate.
217 (define_attr "length_immediate" ""
218   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
219            (const_int 0)
220          (eq_attr "unit" "i387,sse,mmx")
221            (const_int 0)
222          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
223                           imul,icmp,push,pop")
224            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
225          (eq_attr "type" "imov,test")
226            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
227          (eq_attr "type" "call")
228            (if_then_else (match_operand 0 "constant_call_address_operand" "")
229              (const_int 4)
230              (const_int 0))
231          (eq_attr "type" "callv")
232            (if_then_else (match_operand 1 "constant_call_address_operand" "")
233              (const_int 4)
234              (const_int 0))
235          ;; We don't know the size before shorten_branches.  Expect
236          ;; the instruction to fit for better scheduling.
237          (eq_attr "type" "ibr")
238            (const_int 1)
239          ]
240          (symbol_ref "/* Update immediate_length and other attributes! */
241                       gcc_unreachable (),1")))
243 ;; The (bounding maximum) length of an instruction address.
244 (define_attr "length_address" ""
245   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
246            (const_int 0)
247          (and (eq_attr "type" "call")
248               (match_operand 0 "constant_call_address_operand" ""))
249              (const_int 0)
250          (and (eq_attr "type" "callv")
251               (match_operand 1 "constant_call_address_operand" ""))
252              (const_int 0)
253          ]
254          (symbol_ref "ix86_attr_length_address_default (insn)")))
256 ;; Set when length prefix is used.
257 (define_attr "prefix_data16" ""
258   (if_then_else (ior (eq_attr "mode" "HI")
259                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
260     (const_int 1)
261     (const_int 0)))
263 ;; Set when string REP prefix is used.
264 (define_attr "prefix_rep" "" 
265   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
266     (const_int 1)
267     (const_int 0)))
269 ;; Set when 0f opcode prefix is used.
270 (define_attr "prefix_0f" ""
271   (if_then_else 
272     (ior (eq_attr "type" "imovx,setcc,icmov")
273          (eq_attr "unit" "sse,mmx"))
274     (const_int 1)
275     (const_int 0)))
277 ;; Set when REX opcode prefix is used.
278 (define_attr "prefix_rex" ""
279   (cond [(and (eq_attr "mode" "DI")
280               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
281            (const_int 1)
282          (and (eq_attr "mode" "QI")
283               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
284                   (const_int 0)))
285            (const_int 1)
286          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
287              (const_int 0))
288            (const_int 1)
289         ]
290         (const_int 0)))
292 ;; Set when modrm byte is used.
293 (define_attr "modrm" ""
294   (cond [(eq_attr "type" "str,cld,leave")
295            (const_int 0)
296          (eq_attr "unit" "i387")
297            (const_int 0)
298          (and (eq_attr "type" "incdec")
299               (ior (match_operand:SI 1 "register_operand" "")
300                    (match_operand:HI 1 "register_operand" "")))
301            (const_int 0)
302          (and (eq_attr "type" "push")
303               (not (match_operand 1 "memory_operand" "")))
304            (const_int 0)
305          (and (eq_attr "type" "pop")
306               (not (match_operand 0 "memory_operand" "")))
307            (const_int 0)
308          (and (eq_attr "type" "imov")
309               (and (match_operand 0 "register_operand" "")
310                    (match_operand 1 "immediate_operand" "")))
311            (const_int 0)
312          (and (eq_attr "type" "call")
313               (match_operand 0 "constant_call_address_operand" ""))
314              (const_int 0)
315          (and (eq_attr "type" "callv")
316               (match_operand 1 "constant_call_address_operand" ""))
317              (const_int 0)
318          ]
319          (const_int 1)))
321 ;; The (bounding maximum) length of an instruction in bytes.
322 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
323 ;; Later we may want to split them and compute proper length as for
324 ;; other insns.
325 (define_attr "length" ""
326   (cond [(eq_attr "type" "other,multi,fistp,frndint")
327            (const_int 16)
328          (eq_attr "type" "fcmp")
329            (const_int 4)
330          (eq_attr "unit" "i387")
331            (plus (const_int 2)
332                  (plus (attr "prefix_data16")
333                        (attr "length_address")))]
334          (plus (plus (attr "modrm")
335                      (plus (attr "prefix_0f")
336                            (plus (attr "prefix_rex")
337                                  (const_int 1))))
338                (plus (attr "prefix_rep")
339                      (plus (attr "prefix_data16")
340                            (plus (attr "length_immediate")
341                                  (attr "length_address")))))))
343 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
344 ;; `store' if there is a simple memory reference therein, or `unknown'
345 ;; if the instruction is complex.
347 (define_attr "memory" "none,load,store,both,unknown"
348   (cond [(eq_attr "type" "other,multi,str")
349            (const_string "unknown")
350          (eq_attr "type" "lea,fcmov,fpspc,cld")
351            (const_string "none")
352          (eq_attr "type" "fistp,leave")
353            (const_string "both")
354          (eq_attr "type" "frndint")
355            (const_string "load")
356          (eq_attr "type" "push")
357            (if_then_else (match_operand 1 "memory_operand" "")
358              (const_string "both")
359              (const_string "store"))
360          (eq_attr "type" "pop")
361            (if_then_else (match_operand 0 "memory_operand" "")
362              (const_string "both")
363              (const_string "load"))
364          (eq_attr "type" "setcc")
365            (if_then_else (match_operand 0 "memory_operand" "")
366              (const_string "store")
367              (const_string "none"))
368          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
369            (if_then_else (ior (match_operand 0 "memory_operand" "")
370                               (match_operand 1 "memory_operand" ""))
371              (const_string "load")
372              (const_string "none"))
373          (eq_attr "type" "ibr")
374            (if_then_else (match_operand 0 "memory_operand" "")
375              (const_string "load")
376              (const_string "none"))
377          (eq_attr "type" "call")
378            (if_then_else (match_operand 0 "constant_call_address_operand" "")
379              (const_string "none")
380              (const_string "load"))
381          (eq_attr "type" "callv")
382            (if_then_else (match_operand 1 "constant_call_address_operand" "")
383              (const_string "none")
384              (const_string "load"))
385          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
386               (match_operand 1 "memory_operand" ""))
387            (const_string "both")
388          (and (match_operand 0 "memory_operand" "")
389               (match_operand 1 "memory_operand" ""))
390            (const_string "both")
391          (match_operand 0 "memory_operand" "")
392            (const_string "store")
393          (match_operand 1 "memory_operand" "")
394            (const_string "load")
395          (and (eq_attr "type"
396                  "!alu1,negnot,ishift1,
397                    imov,imovx,icmp,test,
398                    fmov,fcmp,fsgn,
399                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
400                    mmx,mmxmov,mmxcmp,mmxcvt")
401               (match_operand 2 "memory_operand" ""))
402            (const_string "load")
403          (and (eq_attr "type" "icmov")
404               (match_operand 3 "memory_operand" ""))
405            (const_string "load")
406         ]
407         (const_string "none")))
409 ;; Indicates if an instruction has both an immediate and a displacement.
411 (define_attr "imm_disp" "false,true,unknown"
412   (cond [(eq_attr "type" "other,multi")
413            (const_string "unknown")
414          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
415               (and (match_operand 0 "memory_displacement_operand" "")
416                    (match_operand 1 "immediate_operand" "")))
417            (const_string "true")
418          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
419               (and (match_operand 0 "memory_displacement_operand" "")
420                    (match_operand 2 "immediate_operand" "")))
421            (const_string "true")
422         ]
423         (const_string "false")))
425 ;; Indicates if an FP operation has an integer source.
427 (define_attr "fp_int_src" "false,true"
428   (const_string "false"))
430 ;; Defines rounding mode of an FP operation.
432 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
433   (const_string "any"))
435 ;; Describe a user's asm statement.
436 (define_asm_attributes
437   [(set_attr "length" "128")
438    (set_attr "type" "multi")])
440 ;; All x87 floating point modes
441 (define_mode_macro X87MODEF [SF DF XF])
443 ;; All integer modes handled by x87 fisttp operator.
444 (define_mode_macro X87MODEI [HI SI DI])
446 ;; All integer modes handled by integer x87 operators.
447 (define_mode_macro X87MODEI12 [HI SI])
449 ;; All SSE floating point modes
450 (define_mode_macro SSEMODEF [SF DF])
452 ;; All integer modes handled by SSE cvtts?2si* operators.
453 (define_mode_macro SSEMODEI24 [SI DI])
456 ;; Scheduling descriptions
458 (include "pentium.md")
459 (include "ppro.md")
460 (include "k6.md")
461 (include "athlon.md")
464 ;; Operand and operator predicates
466 (include "predicates.md")
469 ;; Compare instructions.
471 ;; All compare insns have expanders that save the operands away without
472 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
473 ;; after the cmp) will actually emit the cmpM.
475 (define_expand "cmpdi"
476   [(set (reg:CC FLAGS_REG)
477         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
478                     (match_operand:DI 1 "x86_64_general_operand" "")))]
479   ""
481   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
482     operands[0] = force_reg (DImode, operands[0]);
483   ix86_compare_op0 = operands[0];
484   ix86_compare_op1 = operands[1];
485   DONE;
488 (define_expand "cmpsi"
489   [(set (reg:CC FLAGS_REG)
490         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
491                     (match_operand:SI 1 "general_operand" "")))]
492   ""
494   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
495     operands[0] = force_reg (SImode, operands[0]);
496   ix86_compare_op0 = operands[0];
497   ix86_compare_op1 = operands[1];
498   DONE;
501 (define_expand "cmphi"
502   [(set (reg:CC FLAGS_REG)
503         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
504                     (match_operand:HI 1 "general_operand" "")))]
505   ""
507   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
508     operands[0] = force_reg (HImode, operands[0]);
509   ix86_compare_op0 = operands[0];
510   ix86_compare_op1 = operands[1];
511   DONE;
514 (define_expand "cmpqi"
515   [(set (reg:CC FLAGS_REG)
516         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
517                     (match_operand:QI 1 "general_operand" "")))]
518   "TARGET_QIMODE_MATH"
520   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
521     operands[0] = force_reg (QImode, operands[0]);
522   ix86_compare_op0 = operands[0];
523   ix86_compare_op1 = operands[1];
524   DONE;
527 (define_insn "cmpdi_ccno_1_rex64"
528   [(set (reg FLAGS_REG)
529         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
530                  (match_operand:DI 1 "const0_operand" "n,n")))]
531   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
532   "@
533    test{q}\t{%0, %0|%0, %0}
534    cmp{q}\t{%1, %0|%0, %1}"
535   [(set_attr "type" "test,icmp")
536    (set_attr "length_immediate" "0,1")
537    (set_attr "mode" "DI")])
539 (define_insn "*cmpdi_minus_1_rex64"
540   [(set (reg FLAGS_REG)
541         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
542                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
543                  (const_int 0)))]
544   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
545   "cmp{q}\t{%1, %0|%0, %1}"
546   [(set_attr "type" "icmp")
547    (set_attr "mode" "DI")])
549 (define_expand "cmpdi_1_rex64"
550   [(set (reg:CC FLAGS_REG)
551         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
552                     (match_operand:DI 1 "general_operand" "")))]
553   "TARGET_64BIT"
554   "")
556 (define_insn "cmpdi_1_insn_rex64"
557   [(set (reg FLAGS_REG)
558         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
559                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
560   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
561   "cmp{q}\t{%1, %0|%0, %1}"
562   [(set_attr "type" "icmp")
563    (set_attr "mode" "DI")])
566 (define_insn "*cmpsi_ccno_1"
567   [(set (reg FLAGS_REG)
568         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
569                  (match_operand:SI 1 "const0_operand" "n,n")))]
570   "ix86_match_ccmode (insn, CCNOmode)"
571   "@
572    test{l}\t{%0, %0|%0, %0}
573    cmp{l}\t{%1, %0|%0, %1}"
574   [(set_attr "type" "test,icmp")
575    (set_attr "length_immediate" "0,1")
576    (set_attr "mode" "SI")])
578 (define_insn "*cmpsi_minus_1"
579   [(set (reg FLAGS_REG)
580         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
581                            (match_operand:SI 1 "general_operand" "ri,mr"))
582                  (const_int 0)))]
583   "ix86_match_ccmode (insn, CCGOCmode)"
584   "cmp{l}\t{%1, %0|%0, %1}"
585   [(set_attr "type" "icmp")
586    (set_attr "mode" "SI")])
588 (define_expand "cmpsi_1"
589   [(set (reg:CC FLAGS_REG)
590         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
591                     (match_operand:SI 1 "general_operand" "ri,mr")))]
592   ""
593   "")
595 (define_insn "*cmpsi_1_insn"
596   [(set (reg FLAGS_REG)
597         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
598                  (match_operand:SI 1 "general_operand" "ri,mr")))]
599   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
600     && ix86_match_ccmode (insn, CCmode)"
601   "cmp{l}\t{%1, %0|%0, %1}"
602   [(set_attr "type" "icmp")
603    (set_attr "mode" "SI")])
605 (define_insn "*cmphi_ccno_1"
606   [(set (reg FLAGS_REG)
607         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
608                  (match_operand:HI 1 "const0_operand" "n,n")))]
609   "ix86_match_ccmode (insn, CCNOmode)"
610   "@
611    test{w}\t{%0, %0|%0, %0}
612    cmp{w}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "test,icmp")
614    (set_attr "length_immediate" "0,1")
615    (set_attr "mode" "HI")])
617 (define_insn "*cmphi_minus_1"
618   [(set (reg FLAGS_REG)
619         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
620                            (match_operand:HI 1 "general_operand" "ri,mr"))
621                  (const_int 0)))]
622   "ix86_match_ccmode (insn, CCGOCmode)"
623   "cmp{w}\t{%1, %0|%0, %1}"
624   [(set_attr "type" "icmp")
625    (set_attr "mode" "HI")])
627 (define_insn "*cmphi_1"
628   [(set (reg FLAGS_REG)
629         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
630                  (match_operand:HI 1 "general_operand" "ri,mr")))]
631   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
632    && ix86_match_ccmode (insn, CCmode)"
633   "cmp{w}\t{%1, %0|%0, %1}"
634   [(set_attr "type" "icmp")
635    (set_attr "mode" "HI")])
637 (define_insn "*cmpqi_ccno_1"
638   [(set (reg FLAGS_REG)
639         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
640                  (match_operand:QI 1 "const0_operand" "n,n")))]
641   "ix86_match_ccmode (insn, CCNOmode)"
642   "@
643    test{b}\t{%0, %0|%0, %0}
644    cmp{b}\t{$0, %0|%0, 0}"
645   [(set_attr "type" "test,icmp")
646    (set_attr "length_immediate" "0,1")
647    (set_attr "mode" "QI")])
649 (define_insn "*cmpqi_1"
650   [(set (reg FLAGS_REG)
651         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
652                  (match_operand:QI 1 "general_operand" "qi,mq")))]
653   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
654     && ix86_match_ccmode (insn, CCmode)"
655   "cmp{b}\t{%1, %0|%0, %1}"
656   [(set_attr "type" "icmp")
657    (set_attr "mode" "QI")])
659 (define_insn "*cmpqi_minus_1"
660   [(set (reg FLAGS_REG)
661         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
662                            (match_operand:QI 1 "general_operand" "qi,mq"))
663                  (const_int 0)))]
664   "ix86_match_ccmode (insn, CCGOCmode)"
665   "cmp{b}\t{%1, %0|%0, %1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
669 (define_insn "*cmpqi_ext_1"
670   [(set (reg FLAGS_REG)
671         (compare
672           (match_operand:QI 0 "general_operand" "Qm")
673           (subreg:QI
674             (zero_extract:SI
675               (match_operand 1 "ext_register_operand" "Q")
676               (const_int 8)
677               (const_int 8)) 0)))]
678   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%h1, %0|%0, %h1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
683 (define_insn "*cmpqi_ext_1_rex64"
684   [(set (reg FLAGS_REG)
685         (compare
686           (match_operand:QI 0 "register_operand" "Q")
687           (subreg:QI
688             (zero_extract:SI
689               (match_operand 1 "ext_register_operand" "Q")
690               (const_int 8)
691               (const_int 8)) 0)))]
692   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
693   "cmp{b}\t{%h1, %0|%0, %h1}"
694   [(set_attr "type" "icmp")
695    (set_attr "mode" "QI")])
697 (define_insn "*cmpqi_ext_2"
698   [(set (reg FLAGS_REG)
699         (compare
700           (subreg:QI
701             (zero_extract:SI
702               (match_operand 0 "ext_register_operand" "Q")
703               (const_int 8)
704               (const_int 8)) 0)
705           (match_operand:QI 1 "const0_operand" "n")))]
706   "ix86_match_ccmode (insn, CCNOmode)"
707   "test{b}\t%h0, %h0"
708   [(set_attr "type" "test")
709    (set_attr "length_immediate" "0")
710    (set_attr "mode" "QI")])
712 (define_expand "cmpqi_ext_3"
713   [(set (reg:CC FLAGS_REG)
714         (compare:CC
715           (subreg:QI
716             (zero_extract:SI
717               (match_operand 0 "ext_register_operand" "")
718               (const_int 8)
719               (const_int 8)) 0)
720           (match_operand:QI 1 "general_operand" "")))]
721   ""
722   "")
724 (define_insn "cmpqi_ext_3_insn"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "general_operand" "Qmn")))]
733   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734   "cmp{b}\t{%1, %h0|%h0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "QI")])
738 (define_insn "cmpqi_ext_3_insn_rex64"
739   [(set (reg FLAGS_REG)
740         (compare
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)
746           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
747   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
748   "cmp{b}\t{%1, %h0|%h0, %1}"
749   [(set_attr "type" "icmp")
750    (set_attr "mode" "QI")])
752 (define_insn "*cmpqi_ext_4"
753   [(set (reg FLAGS_REG)
754         (compare
755           (subreg:QI
756             (zero_extract:SI
757               (match_operand 0 "ext_register_operand" "Q")
758               (const_int 8)
759               (const_int 8)) 0)
760           (subreg:QI
761             (zero_extract:SI
762               (match_operand 1 "ext_register_operand" "Q")
763               (const_int 8)
764               (const_int 8)) 0)))]
765   "ix86_match_ccmode (insn, CCmode)"
766   "cmp{b}\t{%h1, %h0|%h0, %h1}"
767   [(set_attr "type" "icmp")
768    (set_attr "mode" "QI")])
770 ;; These implement float point compares.
771 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
772 ;; which would allow mix and match FP modes on the compares.  Which is what
773 ;; the old patterns did, but with many more of them.
775 (define_expand "cmpxf"
776   [(set (reg:CC FLAGS_REG)
777         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
778                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
779   "TARGET_80387"
781   ix86_compare_op0 = operands[0];
782   ix86_compare_op1 = operands[1];
783   DONE;
786 (define_expand "cmpdf"
787   [(set (reg:CC FLAGS_REG)
788         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
789                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
790   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
792   ix86_compare_op0 = operands[0];
793   ix86_compare_op1 = operands[1];
794   DONE;
797 (define_expand "cmpsf"
798   [(set (reg:CC FLAGS_REG)
799         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
800                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
801   "TARGET_80387 || TARGET_SSE_MATH"
803   ix86_compare_op0 = operands[0];
804   ix86_compare_op1 = operands[1];
805   DONE;
808 ;; FP compares, step 1:
809 ;; Set the FP condition codes.
811 ;; CCFPmode     compare with exceptions
812 ;; CCFPUmode    compare with no exceptions
814 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
815 ;; used to manage the reg stack popping would not be preserved.
817 (define_insn "*cmpfp_0"
818   [(set (match_operand:HI 0 "register_operand" "=a")
819         (unspec:HI
820           [(compare:CCFP
821              (match_operand 1 "register_operand" "f")
822              (match_operand 2 "const0_operand" "X"))]
823         UNSPEC_FNSTSW))]
824   "TARGET_80387
825    && FLOAT_MODE_P (GET_MODE (operands[1]))
826    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
827   "* return output_fp_compare (insn, operands, 0, 0);"
828   [(set_attr "type" "multi")
829    (set_attr "unit" "i387")
830    (set (attr "mode")
831      (cond [(match_operand:SF 1 "" "")
832               (const_string "SF")
833             (match_operand:DF 1 "" "")
834               (const_string "DF")
835            ]
836            (const_string "XF")))])
838 (define_insn "*cmpfp_sf"
839   [(set (match_operand:HI 0 "register_operand" "=a")
840         (unspec:HI
841           [(compare:CCFP
842              (match_operand:SF 1 "register_operand" "f")
843              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
844           UNSPEC_FNSTSW))]
845   "TARGET_80387"
846   "* return output_fp_compare (insn, operands, 0, 0);"
847   [(set_attr "type" "multi")
848    (set_attr "unit" "i387")
849    (set_attr "mode" "SF")])
851 (define_insn "*cmpfp_df"
852   [(set (match_operand:HI 0 "register_operand" "=a")
853         (unspec:HI
854           [(compare:CCFP
855              (match_operand:DF 1 "register_operand" "f")
856              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857           UNSPEC_FNSTSW))]
858   "TARGET_80387"
859   "* return output_fp_compare (insn, operands, 0, 0);"
860   [(set_attr "type" "multi")
861    (set_attr "unit" "i387")
862    (set_attr "mode" "DF")])
864 (define_insn "*cmpfp_xf"
865   [(set (match_operand:HI 0 "register_operand" "=a")
866         (unspec:HI
867           [(compare:CCFP
868              (match_operand:XF 1 "register_operand" "f")
869              (match_operand:XF 2 "register_operand" "f"))]
870           UNSPEC_FNSTSW))]
871   "TARGET_80387"
872   "* return output_fp_compare (insn, operands, 0, 0);"
873   [(set_attr "type" "multi")
874    (set_attr "unit" "i387")
875    (set_attr "mode" "XF")])
877 (define_insn "*cmpfp_u"
878   [(set (match_operand:HI 0 "register_operand" "=a")
879         (unspec:HI
880           [(compare:CCFPU
881              (match_operand 1 "register_operand" "f")
882              (match_operand 2 "register_operand" "f"))]
883           UNSPEC_FNSTSW))]
884   "TARGET_80387
885    && FLOAT_MODE_P (GET_MODE (operands[1]))
886    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
887   "* return output_fp_compare (insn, operands, 0, 1);"
888   [(set_attr "type" "multi")
889    (set_attr "unit" "i387")
890    (set (attr "mode")
891      (cond [(match_operand:SF 1 "" "")
892               (const_string "SF")
893             (match_operand:DF 1 "" "")
894               (const_string "DF")
895            ]
896            (const_string "XF")))])
898 (define_insn "*cmpfp_<mode>"
899   [(set (match_operand:HI 0 "register_operand" "=a")
900         (unspec:HI
901           [(compare:CCFP
902              (match_operand 1 "register_operand" "f")
903              (match_operator 3 "float_operator"
904                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
905           UNSPEC_FNSTSW))]
906   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
907    && FLOAT_MODE_P (GET_MODE (operands[1]))
908    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
909   "* return output_fp_compare (insn, operands, 0, 0);"
910   [(set_attr "type" "multi")
911    (set_attr "unit" "i387")
912    (set_attr "fp_int_src" "true")
913    (set_attr "mode" "<MODE>")])
915 ;; FP compares, step 2
916 ;; Move the fpsw to ax.
918 (define_insn "x86_fnstsw_1"
919   [(set (match_operand:HI 0 "register_operand" "=a")
920         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
921   "TARGET_80387"
922   "fnstsw\t%0"
923   [(set_attr "length" "2")
924    (set_attr "mode" "SI")
925    (set_attr "unit" "i387")])
927 ;; FP compares, step 3
928 ;; Get ax into flags, general case.
930 (define_insn "x86_sahf_1"
931   [(set (reg:CC FLAGS_REG)
932         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
933   "!TARGET_64BIT"
934   "sahf"
935   [(set_attr "length" "1")
936    (set_attr "athlon_decode" "vector")
937    (set_attr "mode" "SI")])
939 ;; Pentium Pro can do steps 1 through 3 in one go.
941 (define_insn "*cmpfp_i_mixed"
942   [(set (reg:CCFP FLAGS_REG)
943         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
944                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
945   "TARGET_MIX_SSE_I387
946    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
947    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
948   "* return output_fp_compare (insn, operands, 1, 0);"
949   [(set_attr "type" "fcmp,ssecomi")
950    (set (attr "mode")
951      (if_then_else (match_operand:SF 1 "" "")
952         (const_string "SF")
953         (const_string "DF")))
954    (set_attr "athlon_decode" "vector")])
956 (define_insn "*cmpfp_i_sse"
957   [(set (reg:CCFP FLAGS_REG)
958         (compare:CCFP (match_operand 0 "register_operand" "x")
959                       (match_operand 1 "nonimmediate_operand" "xm")))]
960   "TARGET_SSE_MATH
961    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963   "* return output_fp_compare (insn, operands, 1, 0);"
964   [(set_attr "type" "ssecomi")
965    (set (attr "mode")
966      (if_then_else (match_operand:SF 1 "" "")
967         (const_string "SF")
968         (const_string "DF")))
969    (set_attr "athlon_decode" "vector")])
971 (define_insn "*cmpfp_i_i387"
972   [(set (reg:CCFP FLAGS_REG)
973         (compare:CCFP (match_operand 0 "register_operand" "f")
974                       (match_operand 1 "register_operand" "f")))]
975   "TARGET_80387 && TARGET_CMOVE
976    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
977    && FLOAT_MODE_P (GET_MODE (operands[0]))
978    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
979   "* return output_fp_compare (insn, operands, 1, 0);"
980   [(set_attr "type" "fcmp")
981    (set (attr "mode")
982      (cond [(match_operand:SF 1 "" "")
983               (const_string "SF")
984             (match_operand:DF 1 "" "")
985               (const_string "DF")
986            ]
987            (const_string "XF")))
988    (set_attr "athlon_decode" "vector")])
990 (define_insn "*cmpfp_iu_mixed"
991   [(set (reg:CCFPU FLAGS_REG)
992         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
993                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
994   "TARGET_MIX_SSE_I387
995    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
996    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
997   "* return output_fp_compare (insn, operands, 1, 1);"
998   [(set_attr "type" "fcmp,ssecomi")
999    (set (attr "mode")
1000      (if_then_else (match_operand:SF 1 "" "")
1001         (const_string "SF")
1002         (const_string "DF")))
1003    (set_attr "athlon_decode" "vector")])
1005 (define_insn "*cmpfp_iu_sse"
1006   [(set (reg:CCFPU FLAGS_REG)
1007         (compare:CCFPU (match_operand 0 "register_operand" "x")
1008                        (match_operand 1 "nonimmediate_operand" "xm")))]
1009   "TARGET_SSE_MATH
1010    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1011    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1012   "* return output_fp_compare (insn, operands, 1, 1);"
1013   [(set_attr "type" "ssecomi")
1014    (set (attr "mode")
1015      (if_then_else (match_operand:SF 1 "" "")
1016         (const_string "SF")
1017         (const_string "DF")))
1018    (set_attr "athlon_decode" "vector")])
1020 (define_insn "*cmpfp_iu_387"
1021   [(set (reg:CCFPU FLAGS_REG)
1022         (compare:CCFPU (match_operand 0 "register_operand" "f")
1023                        (match_operand 1 "register_operand" "f")))]
1024   "TARGET_80387 && TARGET_CMOVE
1025    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1026    && FLOAT_MODE_P (GET_MODE (operands[0]))
1027    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1028   "* return output_fp_compare (insn, operands, 1, 1);"
1029   [(set_attr "type" "fcmp")
1030    (set (attr "mode")
1031      (cond [(match_operand:SF 1 "" "")
1032               (const_string "SF")
1033             (match_operand:DF 1 "" "")
1034               (const_string "DF")
1035            ]
1036            (const_string "XF")))
1037    (set_attr "athlon_decode" "vector")])
1039 ;; Move instructions.
1041 ;; General case of fullword move.
1043 (define_expand "movsi"
1044   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1045         (match_operand:SI 1 "general_operand" ""))]
1046   ""
1047   "ix86_expand_move (SImode, operands); DONE;")
1049 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1050 ;; general_operand.
1052 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1053 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1054 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1055 ;; targets without our curiosities, and it is just as easy to represent
1056 ;; this differently.
1058 (define_insn "*pushsi2"
1059   [(set (match_operand:SI 0 "push_operand" "=<")
1060         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1061   "!TARGET_64BIT"
1062   "push{l}\t%1"
1063   [(set_attr "type" "push")
1064    (set_attr "mode" "SI")])
1066 ;; For 64BIT abi we always round up to 8 bytes.
1067 (define_insn "*pushsi2_rex64"
1068   [(set (match_operand:SI 0 "push_operand" "=X")
1069         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1070   "TARGET_64BIT"
1071   "push{q}\t%q1"
1072   [(set_attr "type" "push")
1073    (set_attr "mode" "SI")])
1075 (define_insn "*pushsi2_prologue"
1076   [(set (match_operand:SI 0 "push_operand" "=<")
1077         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1078    (clobber (mem:BLK (scratch)))]
1079   "!TARGET_64BIT"
1080   "push{l}\t%1"
1081   [(set_attr "type" "push")
1082    (set_attr "mode" "SI")])
1084 (define_insn "*popsi1_epilogue"
1085   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1086         (mem:SI (reg:SI SP_REG)))
1087    (set (reg:SI SP_REG)
1088         (plus:SI (reg:SI SP_REG) (const_int 4)))
1089    (clobber (mem:BLK (scratch)))]
1090   "!TARGET_64BIT"
1091   "pop{l}\t%0"
1092   [(set_attr "type" "pop")
1093    (set_attr "mode" "SI")])
1095 (define_insn "popsi1"
1096   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1097         (mem:SI (reg:SI SP_REG)))
1098    (set (reg:SI SP_REG)
1099         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1100   "!TARGET_64BIT"
1101   "pop{l}\t%0"
1102   [(set_attr "type" "pop")
1103    (set_attr "mode" "SI")])
1105 (define_insn "*movsi_xor"
1106   [(set (match_operand:SI 0 "register_operand" "=r")
1107         (match_operand:SI 1 "const0_operand" "i"))
1108    (clobber (reg:CC FLAGS_REG))]
1109   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1110   "xor{l}\t{%0, %0|%0, %0}"
1111   [(set_attr "type" "alu1")
1112    (set_attr "mode" "SI")
1113    (set_attr "length_immediate" "0")])
1115 (define_insn "*movsi_or"
1116   [(set (match_operand:SI 0 "register_operand" "=r")
1117         (match_operand:SI 1 "immediate_operand" "i"))
1118    (clobber (reg:CC FLAGS_REG))]
1119   "reload_completed
1120    && operands[1] == constm1_rtx
1121    && (TARGET_PENTIUM || optimize_size)"
1123   operands[1] = constm1_rtx;
1124   return "or{l}\t{%1, %0|%0, %1}";
1126   [(set_attr "type" "alu1")
1127    (set_attr "mode" "SI")
1128    (set_attr "length_immediate" "1")])
1130 (define_insn "*movsi_1"
1131   [(set (match_operand:SI 0 "nonimmediate_operand"
1132                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1133         (match_operand:SI 1 "general_operand"
1134                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1135   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1137   switch (get_attr_type (insn))
1138     {
1139     case TYPE_SSELOG1:
1140       if (get_attr_mode (insn) == MODE_TI)
1141         return "pxor\t%0, %0";
1142       return "xorps\t%0, %0";
1144     case TYPE_SSEMOV:
1145       switch (get_attr_mode (insn))
1146         {
1147         case MODE_TI:
1148           return "movdqa\t{%1, %0|%0, %1}";
1149         case MODE_V4SF:
1150           return "movaps\t{%1, %0|%0, %1}";
1151         case MODE_SI:
1152           return "movd\t{%1, %0|%0, %1}";
1153         case MODE_SF:
1154           return "movss\t{%1, %0|%0, %1}";
1155         default:
1156           gcc_unreachable ();
1157         }
1159     case TYPE_MMXADD:
1160       return "pxor\t%0, %0";
1162     case TYPE_MMXMOV:
1163       if (get_attr_mode (insn) == MODE_DI)
1164         return "movq\t{%1, %0|%0, %1}";
1165       return "movd\t{%1, %0|%0, %1}";
1167     case TYPE_LEA:
1168       return "lea{l}\t{%1, %0|%0, %1}";
1170     default:
1171       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1172       return "mov{l}\t{%1, %0|%0, %1}";
1173     }
1175   [(set (attr "type")
1176      (cond [(eq_attr "alternative" "2")
1177               (const_string "mmx")
1178             (eq_attr "alternative" "3,4,5")
1179               (const_string "mmxmov")
1180             (eq_attr "alternative" "6")
1181               (const_string "sselog1")
1182             (eq_attr "alternative" "7,8,9,10,11")
1183               (const_string "ssemov")
1184             (and (ne (symbol_ref "flag_pic") (const_int 0))
1185                  (match_operand:SI 1 "symbolic_operand" ""))
1186               (const_string "lea")
1187            ]
1188            (const_string "imov")))
1189    (set (attr "mode")
1190      (cond [(eq_attr "alternative" "2,3")
1191               (const_string "DI")
1192             (eq_attr "alternative" "6,7")
1193               (if_then_else
1194                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1195                 (const_string "V4SF")
1196                 (const_string "TI"))
1197             (and (eq_attr "alternative" "8,9,10,11")
1198                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1199               (const_string "SF")
1200            ]
1201            (const_string "SI")))])
1203 ;; Stores and loads of ax to arbitrary constant address.
1204 ;; We fake an second form of instruction to force reload to load address
1205 ;; into register when rax is not available
1206 (define_insn "*movabssi_1_rex64"
1207   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1208         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1209   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1210   "@
1211    movabs{l}\t{%1, %P0|%P0, %1}
1212    mov{l}\t{%1, %a0|%a0, %1}"
1213   [(set_attr "type" "imov")
1214    (set_attr "modrm" "0,*")
1215    (set_attr "length_address" "8,0")
1216    (set_attr "length_immediate" "0,*")
1217    (set_attr "memory" "store")
1218    (set_attr "mode" "SI")])
1220 (define_insn "*movabssi_2_rex64"
1221   [(set (match_operand:SI 0 "register_operand" "=a,r")
1222         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1223   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1224   "@
1225    movabs{l}\t{%P1, %0|%0, %P1}
1226    mov{l}\t{%a1, %0|%0, %a1}"
1227   [(set_attr "type" "imov")
1228    (set_attr "modrm" "0,*")
1229    (set_attr "length_address" "8,0")
1230    (set_attr "length_immediate" "0")
1231    (set_attr "memory" "load")
1232    (set_attr "mode" "SI")])
1234 (define_insn "*swapsi"
1235   [(set (match_operand:SI 0 "register_operand" "+r")
1236         (match_operand:SI 1 "register_operand" "+r"))
1237    (set (match_dup 1)
1238         (match_dup 0))]
1239   ""
1240   "xchg{l}\t%1, %0"
1241   [(set_attr "type" "imov")
1242    (set_attr "mode" "SI")
1243    (set_attr "pent_pair" "np")
1244    (set_attr "athlon_decode" "vector")])
1246 (define_expand "movhi"
1247   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1248         (match_operand:HI 1 "general_operand" ""))]
1249   ""
1250   "ix86_expand_move (HImode, operands); DONE;")
1252 (define_insn "*pushhi2"
1253   [(set (match_operand:HI 0 "push_operand" "=<,<")
1254         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1255   "!TARGET_64BIT"
1256   "@
1257    push{w}\t{|WORD PTR }%1
1258    push{w}\t%1"
1259   [(set_attr "type" "push")
1260    (set_attr "mode" "HI")])
1262 ;; For 64BIT abi we always round up to 8 bytes.
1263 (define_insn "*pushhi2_rex64"
1264   [(set (match_operand:HI 0 "push_operand" "=X")
1265         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1266   "TARGET_64BIT"
1267   "push{q}\t%q1"
1268   [(set_attr "type" "push")
1269    (set_attr "mode" "QI")])
1271 (define_insn "*movhi_1"
1272   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1273         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1274   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1276   switch (get_attr_type (insn))
1277     {
1278     case TYPE_IMOVX:
1279       /* movzwl is faster than movw on p2 due to partial word stalls,
1280          though not as fast as an aligned movl.  */
1281       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1282     default:
1283       if (get_attr_mode (insn) == MODE_SI)
1284         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1285       else
1286         return "mov{w}\t{%1, %0|%0, %1}";
1287     }
1289   [(set (attr "type")
1290      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1291               (const_string "imov")
1292             (and (eq_attr "alternative" "0")
1293                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1294                           (const_int 0))
1295                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1296                           (const_int 0))))
1297               (const_string "imov")
1298             (and (eq_attr "alternative" "1,2")
1299                  (match_operand:HI 1 "aligned_operand" ""))
1300               (const_string "imov")
1301             (and (ne (symbol_ref "TARGET_MOVX")
1302                      (const_int 0))
1303                  (eq_attr "alternative" "0,2"))
1304               (const_string "imovx")
1305            ]
1306            (const_string "imov")))
1307     (set (attr "mode")
1308       (cond [(eq_attr "type" "imovx")
1309                (const_string "SI")
1310              (and (eq_attr "alternative" "1,2")
1311                   (match_operand:HI 1 "aligned_operand" ""))
1312                (const_string "SI")
1313              (and (eq_attr "alternative" "0")
1314                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315                            (const_int 0))
1316                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1317                            (const_int 0))))
1318                (const_string "SI")
1319             ]
1320             (const_string "HI")))])
1322 ;; Stores and loads of ax to arbitrary constant address.
1323 ;; We fake an second form of instruction to force reload to load address
1324 ;; into register when rax is not available
1325 (define_insn "*movabshi_1_rex64"
1326   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1327         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1328   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1329   "@
1330    movabs{w}\t{%1, %P0|%P0, %1}
1331    mov{w}\t{%1, %a0|%a0, %1}"
1332   [(set_attr "type" "imov")
1333    (set_attr "modrm" "0,*")
1334    (set_attr "length_address" "8,0")
1335    (set_attr "length_immediate" "0,*")
1336    (set_attr "memory" "store")
1337    (set_attr "mode" "HI")])
1339 (define_insn "*movabshi_2_rex64"
1340   [(set (match_operand:HI 0 "register_operand" "=a,r")
1341         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1342   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1343   "@
1344    movabs{w}\t{%P1, %0|%0, %P1}
1345    mov{w}\t{%a1, %0|%0, %a1}"
1346   [(set_attr "type" "imov")
1347    (set_attr "modrm" "0,*")
1348    (set_attr "length_address" "8,0")
1349    (set_attr "length_immediate" "0")
1350    (set_attr "memory" "load")
1351    (set_attr "mode" "HI")])
1353 (define_insn "*swaphi_1"
1354   [(set (match_operand:HI 0 "register_operand" "+r")
1355         (match_operand:HI 1 "register_operand" "+r"))
1356    (set (match_dup 1)
1357         (match_dup 0))]
1358   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1359   "xchg{l}\t%k1, %k0"
1360   [(set_attr "type" "imov")
1361    (set_attr "mode" "SI")
1362    (set_attr "pent_pair" "np")
1363    (set_attr "athlon_decode" "vector")])
1365 (define_insn "*swaphi_2"
1366   [(set (match_operand:HI 0 "register_operand" "+r")
1367         (match_operand:HI 1 "register_operand" "+r"))
1368    (set (match_dup 1)
1369         (match_dup 0))]
1370   "TARGET_PARTIAL_REG_STALL"
1371   "xchg{w}\t%1, %0"
1372   [(set_attr "type" "imov")
1373    (set_attr "mode" "HI")
1374    (set_attr "pent_pair" "np")
1375    (set_attr "athlon_decode" "vector")])
1377 (define_expand "movstricthi"
1378   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1379         (match_operand:HI 1 "general_operand" ""))]
1380   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1382   /* Don't generate memory->memory moves, go through a register */
1383   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1384     operands[1] = force_reg (HImode, operands[1]);
1387 (define_insn "*movstricthi_1"
1388   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1389         (match_operand:HI 1 "general_operand" "rn,m"))]
1390   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1391    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1392   "mov{w}\t{%1, %0|%0, %1}"
1393   [(set_attr "type" "imov")
1394    (set_attr "mode" "HI")])
1396 (define_insn "*movstricthi_xor"
1397   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1398         (match_operand:HI 1 "const0_operand" "i"))
1399    (clobber (reg:CC FLAGS_REG))]
1400   "reload_completed
1401    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1402   "xor{w}\t{%0, %0|%0, %0}"
1403   [(set_attr "type" "alu1")
1404    (set_attr "mode" "HI")
1405    (set_attr "length_immediate" "0")])
1407 (define_expand "movqi"
1408   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1409         (match_operand:QI 1 "general_operand" ""))]
1410   ""
1411   "ix86_expand_move (QImode, operands); DONE;")
1413 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1414 ;; "push a byte".  But actually we use pushw, which has the effect
1415 ;; of rounding the amount pushed up to a halfword.
1417 (define_insn "*pushqi2"
1418   [(set (match_operand:QI 0 "push_operand" "=X,X")
1419         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1420   "!TARGET_64BIT"
1421   "@
1422    push{w}\t{|word ptr }%1
1423    push{w}\t%w1"
1424   [(set_attr "type" "push")
1425    (set_attr "mode" "HI")])
1427 ;; For 64BIT abi we always round up to 8 bytes.
1428 (define_insn "*pushqi2_rex64"
1429   [(set (match_operand:QI 0 "push_operand" "=X")
1430         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1431   "TARGET_64BIT"
1432   "push{q}\t%q1"
1433   [(set_attr "type" "push")
1434    (set_attr "mode" "QI")])
1436 ;; Situation is quite tricky about when to choose full sized (SImode) move
1437 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1438 ;; partial register dependency machines (such as AMD Athlon), where QImode
1439 ;; moves issue extra dependency and for partial register stalls machines
1440 ;; that don't use QImode patterns (and QImode move cause stall on the next
1441 ;; instruction).
1443 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1444 ;; register stall machines with, where we use QImode instructions, since
1445 ;; partial register stall can be caused there.  Then we use movzx.
1446 (define_insn "*movqi_1"
1447   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1448         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,m ,qn"))]
1449   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1451   switch (get_attr_type (insn))
1452     {
1453     case TYPE_IMOVX:
1454       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1455       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1456     default:
1457       if (get_attr_mode (insn) == MODE_SI)
1458         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1459       else
1460         return "mov{b}\t{%1, %0|%0, %1}";
1461     }
1463   [(set (attr "type")
1464      (cond [(eq_attr "alternative" "5")
1465               (const_string "imovx")
1466             (ne (symbol_ref "optimize_size") (const_int 0))
1467               (const_string "imov")
1468             (and (eq_attr "alternative" "3")
1469                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1470                           (const_int 0))
1471                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1472                           (const_int 0))))
1473               (const_string "imov")
1474             (eq_attr "alternative" "3")
1475               (const_string "imovx")
1476             (and (ne (symbol_ref "TARGET_MOVX")
1477                      (const_int 0))
1478                  (eq_attr "alternative" "2"))
1479               (const_string "imovx")
1480            ]
1481            (const_string "imov")))
1482    (set (attr "mode")
1483       (cond [(eq_attr "alternative" "3,4,5")
1484                (const_string "SI")
1485              (eq_attr "alternative" "6")
1486                (const_string "QI")
1487              (eq_attr "type" "imovx")
1488                (const_string "SI")
1489              (and (eq_attr "type" "imov")
1490                   (and (eq_attr "alternative" "0,1")
1491                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1492                            (const_int 0))))
1493                (const_string "SI")
1494              ;; Avoid partial register stalls when not using QImode arithmetic
1495              (and (eq_attr "type" "imov")
1496                   (and (eq_attr "alternative" "0,1")
1497                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1498                                 (const_int 0))
1499                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1500                                 (const_int 0)))))
1501                (const_string "SI")
1502            ]
1503            (const_string "QI")))])
1505 (define_expand "reload_outqi"
1506   [(parallel [(match_operand:QI 0 "" "=m")
1507               (match_operand:QI 1 "register_operand" "r")
1508               (match_operand:QI 2 "register_operand" "=&q")])]
1509   ""
1511   rtx op0, op1, op2;
1512   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1514   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1515   if (! q_regs_operand (op1, QImode))
1516     {
1517       emit_insn (gen_movqi (op2, op1));
1518       op1 = op2;
1519     }
1520   emit_insn (gen_movqi (op0, op1));
1521   DONE;
1524 (define_insn "*swapqi_1"
1525   [(set (match_operand:QI 0 "register_operand" "+r")
1526         (match_operand:QI 1 "register_operand" "+r"))
1527    (set (match_dup 1)
1528         (match_dup 0))]
1529   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1530   "xchg{l}\t%k1, %k0"
1531   [(set_attr "type" "imov")
1532    (set_attr "mode" "SI")
1533    (set_attr "pent_pair" "np")
1534    (set_attr "athlon_decode" "vector")])
1536 (define_insn "*swapqi_2"
1537   [(set (match_operand:QI 0 "register_operand" "+q")
1538         (match_operand:QI 1 "register_operand" "+q"))
1539    (set (match_dup 1)
1540         (match_dup 0))]
1541   "TARGET_PARTIAL_REG_STALL"
1542   "xchg{b}\t%1, %0"
1543   [(set_attr "type" "imov")
1544    (set_attr "mode" "QI")
1545    (set_attr "pent_pair" "np")
1546    (set_attr "athlon_decode" "vector")])
1548 (define_expand "movstrictqi"
1549   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1550         (match_operand:QI 1 "general_operand" ""))]
1551   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1553   /* Don't generate memory->memory moves, go through a register.  */
1554   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1555     operands[1] = force_reg (QImode, operands[1]);
1558 (define_insn "*movstrictqi_1"
1559   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1560         (match_operand:QI 1 "general_operand" "*qn,m"))]
1561   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1562    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1563   "mov{b}\t{%1, %0|%0, %1}"
1564   [(set_attr "type" "imov")
1565    (set_attr "mode" "QI")])
1567 (define_insn "*movstrictqi_xor"
1568   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1569         (match_operand:QI 1 "const0_operand" "i"))
1570    (clobber (reg:CC FLAGS_REG))]
1571   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1572   "xor{b}\t{%0, %0|%0, %0}"
1573   [(set_attr "type" "alu1")
1574    (set_attr "mode" "QI")
1575    (set_attr "length_immediate" "0")])
1577 (define_insn "*movsi_extv_1"
1578   [(set (match_operand:SI 0 "register_operand" "=R")
1579         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1580                          (const_int 8)
1581                          (const_int 8)))]
1582   ""
1583   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1584   [(set_attr "type" "imovx")
1585    (set_attr "mode" "SI")])
1587 (define_insn "*movhi_extv_1"
1588   [(set (match_operand:HI 0 "register_operand" "=R")
1589         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1590                          (const_int 8)
1591                          (const_int 8)))]
1592   ""
1593   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1594   [(set_attr "type" "imovx")
1595    (set_attr "mode" "SI")])
1597 (define_insn "*movqi_extv_1"
1598   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1599         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1600                          (const_int 8)
1601                          (const_int 8)))]
1602   "!TARGET_64BIT"
1604   switch (get_attr_type (insn))
1605     {
1606     case TYPE_IMOVX:
1607       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1608     default:
1609       return "mov{b}\t{%h1, %0|%0, %h1}";
1610     }
1612   [(set (attr "type")
1613      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1614                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1615                              (ne (symbol_ref "TARGET_MOVX")
1616                                  (const_int 0))))
1617         (const_string "imovx")
1618         (const_string "imov")))
1619    (set (attr "mode")
1620      (if_then_else (eq_attr "type" "imovx")
1621         (const_string "SI")
1622         (const_string "QI")))])
1624 (define_insn "*movqi_extv_1_rex64"
1625   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1626         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1627                          (const_int 8)
1628                          (const_int 8)))]
1629   "TARGET_64BIT"
1631   switch (get_attr_type (insn))
1632     {
1633     case TYPE_IMOVX:
1634       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1635     default:
1636       return "mov{b}\t{%h1, %0|%0, %h1}";
1637     }
1639   [(set (attr "type")
1640      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1641                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1642                              (ne (symbol_ref "TARGET_MOVX")
1643                                  (const_int 0))))
1644         (const_string "imovx")
1645         (const_string "imov")))
1646    (set (attr "mode")
1647      (if_then_else (eq_attr "type" "imovx")
1648         (const_string "SI")
1649         (const_string "QI")))])
1651 ;; Stores and loads of ax to arbitrary constant address.
1652 ;; We fake an second form of instruction to force reload to load address
1653 ;; into register when rax is not available
1654 (define_insn "*movabsqi_1_rex64"
1655   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1656         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1657   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1658   "@
1659    movabs{b}\t{%1, %P0|%P0, %1}
1660    mov{b}\t{%1, %a0|%a0, %1}"
1661   [(set_attr "type" "imov")
1662    (set_attr "modrm" "0,*")
1663    (set_attr "length_address" "8,0")
1664    (set_attr "length_immediate" "0,*")
1665    (set_attr "memory" "store")
1666    (set_attr "mode" "QI")])
1668 (define_insn "*movabsqi_2_rex64"
1669   [(set (match_operand:QI 0 "register_operand" "=a,r")
1670         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1671   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1672   "@
1673    movabs{b}\t{%P1, %0|%0, %P1}
1674    mov{b}\t{%a1, %0|%0, %a1}"
1675   [(set_attr "type" "imov")
1676    (set_attr "modrm" "0,*")
1677    (set_attr "length_address" "8,0")
1678    (set_attr "length_immediate" "0")
1679    (set_attr "memory" "load")
1680    (set_attr "mode" "QI")])
1682 (define_insn "*movsi_extzv_1"
1683   [(set (match_operand:SI 0 "register_operand" "=R")
1684         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1685                          (const_int 8)
1686                          (const_int 8)))]
1687   ""
1688   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1689   [(set_attr "type" "imovx")
1690    (set_attr "mode" "SI")])
1692 (define_insn "*movqi_extzv_2"
1693   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1694         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1695                                     (const_int 8)
1696                                     (const_int 8)) 0))]
1697   "!TARGET_64BIT"
1699   switch (get_attr_type (insn))
1700     {
1701     case TYPE_IMOVX:
1702       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1703     default:
1704       return "mov{b}\t{%h1, %0|%0, %h1}";
1705     }
1707   [(set (attr "type")
1708      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1709                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1710                              (ne (symbol_ref "TARGET_MOVX")
1711                                  (const_int 0))))
1712         (const_string "imovx")
1713         (const_string "imov")))
1714    (set (attr "mode")
1715      (if_then_else (eq_attr "type" "imovx")
1716         (const_string "SI")
1717         (const_string "QI")))])
1719 (define_insn "*movqi_extzv_2_rex64"
1720   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1721         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1722                                     (const_int 8)
1723                                     (const_int 8)) 0))]
1724   "TARGET_64BIT"
1726   switch (get_attr_type (insn))
1727     {
1728     case TYPE_IMOVX:
1729       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1730     default:
1731       return "mov{b}\t{%h1, %0|%0, %h1}";
1732     }
1734   [(set (attr "type")
1735      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1736                         (ne (symbol_ref "TARGET_MOVX")
1737                             (const_int 0)))
1738         (const_string "imovx")
1739         (const_string "imov")))
1740    (set (attr "mode")
1741      (if_then_else (eq_attr "type" "imovx")
1742         (const_string "SI")
1743         (const_string "QI")))])
1745 (define_insn "movsi_insv_1"
1746   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1747                          (const_int 8)
1748                          (const_int 8))
1749         (match_operand:SI 1 "general_operand" "Qmn"))]
1750   "!TARGET_64BIT"
1751   "mov{b}\t{%b1, %h0|%h0, %b1}"
1752   [(set_attr "type" "imov")
1753    (set_attr "mode" "QI")])
1755 (define_insn "movdi_insv_1_rex64"
1756   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1757                          (const_int 8)
1758                          (const_int 8))
1759         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1760   "TARGET_64BIT"
1761   "mov{b}\t{%b1, %h0|%h0, %b1}"
1762   [(set_attr "type" "imov")
1763    (set_attr "mode" "QI")])
1765 (define_insn "*movqi_insv_2"
1766   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1767                          (const_int 8)
1768                          (const_int 8))
1769         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1770                      (const_int 8)))]
1771   ""
1772   "mov{b}\t{%h1, %h0|%h0, %h1}"
1773   [(set_attr "type" "imov")
1774    (set_attr "mode" "QI")])
1776 (define_expand "movdi"
1777   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1778         (match_operand:DI 1 "general_operand" ""))]
1779   ""
1780   "ix86_expand_move (DImode, operands); DONE;")
1782 (define_insn "*pushdi"
1783   [(set (match_operand:DI 0 "push_operand" "=<")
1784         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1785   "!TARGET_64BIT"
1786   "#")
1788 (define_insn "*pushdi2_rex64"
1789   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1790         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1791   "TARGET_64BIT"
1792   "@
1793    push{q}\t%1
1794    #"
1795   [(set_attr "type" "push,multi")
1796    (set_attr "mode" "DI")])
1798 ;; Convert impossible pushes of immediate to existing instructions.
1799 ;; First try to get scratch register and go through it.  In case this
1800 ;; fails, push sign extended lower part first and then overwrite
1801 ;; upper part by 32bit move.
1802 (define_peephole2
1803   [(match_scratch:DI 2 "r")
1804    (set (match_operand:DI 0 "push_operand" "")
1805         (match_operand:DI 1 "immediate_operand" ""))]
1806   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1807    && !x86_64_immediate_operand (operands[1], DImode)"
1808   [(set (match_dup 2) (match_dup 1))
1809    (set (match_dup 0) (match_dup 2))]
1810   "")
1812 ;; We need to define this as both peepholer and splitter for case
1813 ;; peephole2 pass is not run.
1814 ;; "&& 1" is needed to keep it from matching the previous pattern.
1815 (define_peephole2
1816   [(set (match_operand:DI 0 "push_operand" "")
1817         (match_operand:DI 1 "immediate_operand" ""))]
1818   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1819    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1820   [(set (match_dup 0) (match_dup 1))
1821    (set (match_dup 2) (match_dup 3))]
1822   "split_di (operands + 1, 1, operands + 2, operands + 3);
1823    operands[1] = gen_lowpart (DImode, operands[2]);
1824    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1825                                                     GEN_INT (4)));
1826   ")
1828 (define_split
1829   [(set (match_operand:DI 0 "push_operand" "")
1830         (match_operand:DI 1 "immediate_operand" ""))]
1831   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1832    && !symbolic_operand (operands[1], DImode)
1833    && !x86_64_immediate_operand (operands[1], DImode)"
1834   [(set (match_dup 0) (match_dup 1))
1835    (set (match_dup 2) (match_dup 3))]
1836   "split_di (operands + 1, 1, operands + 2, operands + 3);
1837    operands[1] = gen_lowpart (DImode, operands[2]);
1838    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1839                                                     GEN_INT (4)));
1840   ")
1842 (define_insn "*pushdi2_prologue_rex64"
1843   [(set (match_operand:DI 0 "push_operand" "=<")
1844         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1845    (clobber (mem:BLK (scratch)))]
1846   "TARGET_64BIT"
1847   "push{q}\t%1"
1848   [(set_attr "type" "push")
1849    (set_attr "mode" "DI")])
1851 (define_insn "*popdi1_epilogue_rex64"
1852   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1853         (mem:DI (reg:DI SP_REG)))
1854    (set (reg:DI SP_REG)
1855         (plus:DI (reg:DI SP_REG) (const_int 8)))
1856    (clobber (mem:BLK (scratch)))]
1857   "TARGET_64BIT"
1858   "pop{q}\t%0"
1859   [(set_attr "type" "pop")
1860    (set_attr "mode" "DI")])
1862 (define_insn "popdi1"
1863   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1864         (mem:DI (reg:DI SP_REG)))
1865    (set (reg:DI SP_REG)
1866         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1867   "TARGET_64BIT"
1868   "pop{q}\t%0"
1869   [(set_attr "type" "pop")
1870    (set_attr "mode" "DI")])
1872 (define_insn "*movdi_xor_rex64"
1873   [(set (match_operand:DI 0 "register_operand" "=r")
1874         (match_operand:DI 1 "const0_operand" "i"))
1875    (clobber (reg:CC FLAGS_REG))]
1876   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1877    && reload_completed"
1878   "xor{l}\t{%k0, %k0|%k0, %k0}"
1879   [(set_attr "type" "alu1")
1880    (set_attr "mode" "SI")
1881    (set_attr "length_immediate" "0")])
1883 (define_insn "*movdi_or_rex64"
1884   [(set (match_operand:DI 0 "register_operand" "=r")
1885         (match_operand:DI 1 "const_int_operand" "i"))
1886    (clobber (reg:CC FLAGS_REG))]
1887   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1888    && reload_completed
1889    && operands[1] == constm1_rtx"
1891   operands[1] = constm1_rtx;
1892   return "or{q}\t{%1, %0|%0, %1}";
1894   [(set_attr "type" "alu1")
1895    (set_attr "mode" "DI")
1896    (set_attr "length_immediate" "1")])
1898 (define_insn "*movdi_2"
1899   [(set (match_operand:DI 0 "nonimmediate_operand"
1900                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1901         (match_operand:DI 1 "general_operand"
1902                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1903   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1904   "@
1905    #
1906    #
1907    pxor\t%0, %0
1908    movq\t{%1, %0|%0, %1}
1909    movq\t{%1, %0|%0, %1}
1910    pxor\t%0, %0
1911    movq\t{%1, %0|%0, %1}
1912    movdqa\t{%1, %0|%0, %1}
1913    movq\t{%1, %0|%0, %1}
1914    xorps\t%0, %0
1915    movlps\t{%1, %0|%0, %1}
1916    movaps\t{%1, %0|%0, %1}
1917    movlps\t{%1, %0|%0, %1}"
1918   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1919    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1921 (define_split
1922   [(set (match_operand:DI 0 "push_operand" "")
1923         (match_operand:DI 1 "general_operand" ""))]
1924   "!TARGET_64BIT && reload_completed
1925    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1926   [(const_int 0)]
1927   "ix86_split_long_move (operands); DONE;")
1929 ;; %%% This multiword shite has got to go.
1930 (define_split
1931   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1932         (match_operand:DI 1 "general_operand" ""))]
1933   "!TARGET_64BIT && reload_completed
1934    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1935    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1936   [(const_int 0)]
1937   "ix86_split_long_move (operands); DONE;")
1939 (define_insn "*movdi_1_rex64"
1940   [(set (match_operand:DI 0 "nonimmediate_operand"
1941                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1942         (match_operand:DI 1 "general_operand"
1943                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1944   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1946   switch (get_attr_type (insn))
1947     {
1948     case TYPE_SSECVT:
1949       if (which_alternative == 13)
1950         return "movq2dq\t{%1, %0|%0, %1}";
1951       else
1952         return "movdq2q\t{%1, %0|%0, %1}";
1953     case TYPE_SSEMOV:
1954       if (get_attr_mode (insn) == MODE_TI)
1955           return "movdqa\t{%1, %0|%0, %1}";
1956       /* FALLTHRU */
1957     case TYPE_MMXMOV:
1958       /* Moves from and into integer register is done using movd opcode with
1959          REX prefix.  */
1960       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1961           return "movd\t{%1, %0|%0, %1}";
1962       return "movq\t{%1, %0|%0, %1}";
1963     case TYPE_SSELOG1:
1964     case TYPE_MMXADD:
1965       return "pxor\t%0, %0";
1966     case TYPE_MULTI:
1967       return "#";
1968     case TYPE_LEA:
1969       return "lea{q}\t{%a1, %0|%0, %a1}";
1970     default:
1971       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1972       if (get_attr_mode (insn) == MODE_SI)
1973         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1974       else if (which_alternative == 2)
1975         return "movabs{q}\t{%1, %0|%0, %1}";
1976       else
1977         return "mov{q}\t{%1, %0|%0, %1}";
1978     }
1980   [(set (attr "type")
1981      (cond [(eq_attr "alternative" "5")
1982               (const_string "mmx")
1983             (eq_attr "alternative" "6,7,8")
1984               (const_string "mmxmov")
1985             (eq_attr "alternative" "9")
1986               (const_string "sselog1")
1987             (eq_attr "alternative" "10,11,12")
1988               (const_string "ssemov")
1989             (eq_attr "alternative" "13,14")
1990               (const_string "ssecvt")
1991             (eq_attr "alternative" "4")
1992               (const_string "multi")
1993             (and (ne (symbol_ref "flag_pic") (const_int 0))
1994                  (match_operand:DI 1 "symbolic_operand" ""))
1995               (const_string "lea")
1996            ]
1997            (const_string "imov")))
1998    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
1999    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2000    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2002 ;; Stores and loads of ax to arbitrary constant address.
2003 ;; We fake an second form of instruction to force reload to load address
2004 ;; into register when rax is not available
2005 (define_insn "*movabsdi_1_rex64"
2006   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2007         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2008   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2009   "@
2010    movabs{q}\t{%1, %P0|%P0, %1}
2011    mov{q}\t{%1, %a0|%a0, %1}"
2012   [(set_attr "type" "imov")
2013    (set_attr "modrm" "0,*")
2014    (set_attr "length_address" "8,0")
2015    (set_attr "length_immediate" "0,*")
2016    (set_attr "memory" "store")
2017    (set_attr "mode" "DI")])
2019 (define_insn "*movabsdi_2_rex64"
2020   [(set (match_operand:DI 0 "register_operand" "=a,r")
2021         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2022   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2023   "@
2024    movabs{q}\t{%P1, %0|%0, %P1}
2025    mov{q}\t{%a1, %0|%0, %a1}"
2026   [(set_attr "type" "imov")
2027    (set_attr "modrm" "0,*")
2028    (set_attr "length_address" "8,0")
2029    (set_attr "length_immediate" "0")
2030    (set_attr "memory" "load")
2031    (set_attr "mode" "DI")])
2033 ;; Convert impossible stores of immediate to existing instructions.
2034 ;; First try to get scratch register and go through it.  In case this
2035 ;; fails, move by 32bit parts.
2036 (define_peephole2
2037   [(match_scratch:DI 2 "r")
2038    (set (match_operand:DI 0 "memory_operand" "")
2039         (match_operand:DI 1 "immediate_operand" ""))]
2040   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2041    && !x86_64_immediate_operand (operands[1], DImode)"
2042   [(set (match_dup 2) (match_dup 1))
2043    (set (match_dup 0) (match_dup 2))]
2044   "")
2046 ;; We need to define this as both peepholer and splitter for case
2047 ;; peephole2 pass is not run.
2048 ;; "&& 1" is needed to keep it from matching the previous pattern.
2049 (define_peephole2
2050   [(set (match_operand:DI 0 "memory_operand" "")
2051         (match_operand:DI 1 "immediate_operand" ""))]
2052   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2053    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2054   [(set (match_dup 2) (match_dup 3))
2055    (set (match_dup 4) (match_dup 5))]
2056   "split_di (operands, 2, operands + 2, operands + 4);")
2058 (define_split
2059   [(set (match_operand:DI 0 "memory_operand" "")
2060         (match_operand:DI 1 "immediate_operand" ""))]
2061   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2062    && !symbolic_operand (operands[1], DImode)
2063    && !x86_64_immediate_operand (operands[1], DImode)"
2064   [(set (match_dup 2) (match_dup 3))
2065    (set (match_dup 4) (match_dup 5))]
2066   "split_di (operands, 2, operands + 2, operands + 4);")
2068 (define_insn "*swapdi_rex64"
2069   [(set (match_operand:DI 0 "register_operand" "+r")
2070         (match_operand:DI 1 "register_operand" "+r"))
2071    (set (match_dup 1)
2072         (match_dup 0))]
2073   "TARGET_64BIT"
2074   "xchg{q}\t%1, %0"
2075   [(set_attr "type" "imov")
2076    (set_attr "mode" "DI")
2077    (set_attr "pent_pair" "np")
2078    (set_attr "athlon_decode" "vector")])
2080 (define_expand "movti"
2081   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2082         (match_operand:TI 1 "nonimmediate_operand" ""))]
2083   "TARGET_SSE || TARGET_64BIT"
2085   if (TARGET_64BIT)
2086     ix86_expand_move (TImode, operands);
2087   else
2088     ix86_expand_vector_move (TImode, operands);
2089   DONE;
2092 (define_insn "*movti_internal"
2093   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2094         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2095   "TARGET_SSE && !TARGET_64BIT
2096    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2098   switch (which_alternative)
2099     {
2100     case 0:
2101       if (get_attr_mode (insn) == MODE_V4SF)
2102         return "xorps\t%0, %0";
2103       else
2104         return "pxor\t%0, %0";
2105     case 1:
2106     case 2:
2107       if (get_attr_mode (insn) == MODE_V4SF)
2108         return "movaps\t{%1, %0|%0, %1}";
2109       else
2110         return "movdqa\t{%1, %0|%0, %1}";
2111     default:
2112       gcc_unreachable ();
2113     }
2115   [(set_attr "type" "ssemov,ssemov,ssemov")
2116    (set (attr "mode")
2117         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2118                  (const_string "V4SF")
2120                (eq_attr "alternative" "0,1")
2121                  (if_then_else
2122                    (ne (symbol_ref "optimize_size")
2123                        (const_int 0))
2124                    (const_string "V4SF")
2125                    (const_string "TI"))
2126                (eq_attr "alternative" "2")
2127                  (if_then_else
2128                    (ne (symbol_ref "optimize_size")
2129                        (const_int 0))
2130                    (const_string "V4SF")
2131                    (const_string "TI"))]
2132                (const_string "TI")))])
2134 (define_insn "*movti_rex64"
2135   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2136         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2137   "TARGET_64BIT
2138    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2140   switch (which_alternative)
2141     {
2142     case 0:
2143     case 1:
2144       return "#";
2145     case 2:
2146       if (get_attr_mode (insn) == MODE_V4SF)
2147         return "xorps\t%0, %0";
2148       else
2149         return "pxor\t%0, %0";
2150     case 3:
2151     case 4:
2152       if (get_attr_mode (insn) == MODE_V4SF)
2153         return "movaps\t{%1, %0|%0, %1}";
2154       else
2155         return "movdqa\t{%1, %0|%0, %1}";
2156     default:
2157       gcc_unreachable ();
2158     }
2160   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2161    (set (attr "mode")
2162         (cond [(eq_attr "alternative" "2,3")
2163                  (if_then_else
2164                    (ne (symbol_ref "optimize_size")
2165                        (const_int 0))
2166                    (const_string "V4SF")
2167                    (const_string "TI"))
2168                (eq_attr "alternative" "4")
2169                  (if_then_else
2170                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2171                             (const_int 0))
2172                         (ne (symbol_ref "optimize_size")
2173                             (const_int 0)))
2174                    (const_string "V4SF")
2175                    (const_string "TI"))]
2176                (const_string "DI")))])
2178 (define_split
2179   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2180         (match_operand:TI 1 "general_operand" ""))]
2181   "reload_completed && !SSE_REG_P (operands[0])
2182    && !SSE_REG_P (operands[1])"
2183   [(const_int 0)]
2184   "ix86_split_long_move (operands); DONE;")
2186 (define_expand "movsf"
2187   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2188         (match_operand:SF 1 "general_operand" ""))]
2189   ""
2190   "ix86_expand_move (SFmode, operands); DONE;")
2192 (define_insn "*pushsf"
2193   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2194         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2195   "!TARGET_64BIT"
2197   /* Anything else should be already split before reg-stack.  */
2198   gcc_assert (which_alternative == 1);
2199   return "push{l}\t%1";
2201   [(set_attr "type" "multi,push,multi")
2202    (set_attr "unit" "i387,*,*")
2203    (set_attr "mode" "SF,SI,SF")])
2205 (define_insn "*pushsf_rex64"
2206   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2207         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2208   "TARGET_64BIT"
2210   /* Anything else should be already split before reg-stack.  */
2211   gcc_assert (which_alternative == 1);
2212   return "push{q}\t%q1";
2214   [(set_attr "type" "multi,push,multi")
2215    (set_attr "unit" "i387,*,*")
2216    (set_attr "mode" "SF,DI,SF")])
2218 (define_split
2219   [(set (match_operand:SF 0 "push_operand" "")
2220         (match_operand:SF 1 "memory_operand" ""))]
2221   "reload_completed
2222    && GET_CODE (operands[1]) == MEM
2223    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2224    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2225   [(set (match_dup 0)
2226         (match_dup 1))]
2227   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2230 ;; %%% Kill this when call knows how to work this out.
2231 (define_split
2232   [(set (match_operand:SF 0 "push_operand" "")
2233         (match_operand:SF 1 "any_fp_register_operand" ""))]
2234   "!TARGET_64BIT"
2235   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2236    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2238 (define_split
2239   [(set (match_operand:SF 0 "push_operand" "")
2240         (match_operand:SF 1 "any_fp_register_operand" ""))]
2241   "TARGET_64BIT"
2242   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2243    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2245 (define_insn "*movsf_1"
2246   [(set (match_operand:SF 0 "nonimmediate_operand"
2247           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2248         (match_operand:SF 1 "general_operand"
2249           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2250   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2251    && (reload_in_progress || reload_completed
2252        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2253        || GET_CODE (operands[1]) != CONST_DOUBLE
2254        || memory_operand (operands[0], SFmode))" 
2256   switch (which_alternative)
2257     {
2258     case 0:
2259       return output_387_reg_move (insn, operands);
2261     case 1:
2262       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2263         return "fstp%z0\t%y0";
2264       else
2265         return "fst%z0\t%y0";
2267     case 2:
2268       return standard_80387_constant_opcode (operands[1]);
2270     case 3:
2271     case 4:
2272       return "mov{l}\t{%1, %0|%0, %1}";
2273     case 5:
2274       if (get_attr_mode (insn) == MODE_TI)
2275         return "pxor\t%0, %0";
2276       else
2277         return "xorps\t%0, %0";
2278     case 6:
2279       if (get_attr_mode (insn) == MODE_V4SF)
2280         return "movaps\t{%1, %0|%0, %1}";
2281       else
2282         return "movss\t{%1, %0|%0, %1}";
2283     case 7:
2284     case 8:
2285       return "movss\t{%1, %0|%0, %1}";
2287     case 9:
2288     case 10:
2289       return "movd\t{%1, %0|%0, %1}";
2291     case 11:
2292       return "movq\t{%1, %0|%0, %1}";
2294     default:
2295       gcc_unreachable ();
2296     }
2298   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2299    (set (attr "mode")
2300         (cond [(eq_attr "alternative" "3,4,9,10")
2301                  (const_string "SI")
2302                (eq_attr "alternative" "5")
2303                  (if_then_else
2304                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2305                                  (const_int 0))
2306                              (ne (symbol_ref "TARGET_SSE2")
2307                                  (const_int 0)))
2308                         (eq (symbol_ref "optimize_size")
2309                             (const_int 0)))
2310                    (const_string "TI")
2311                    (const_string "V4SF"))
2312                /* For architectures resolving dependencies on
2313                   whole SSE registers use APS move to break dependency
2314                   chains, otherwise use short move to avoid extra work. 
2316                   Do the same for architectures resolving dependencies on
2317                   the parts.  While in DF mode it is better to always handle
2318                   just register parts, the SF mode is different due to lack
2319                   of instructions to load just part of the register.  It is
2320                   better to maintain the whole registers in single format
2321                   to avoid problems on using packed logical operations.  */
2322                (eq_attr "alternative" "6")
2323                  (if_then_else
2324                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2325                             (const_int 0))
2326                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2327                             (const_int 0)))
2328                    (const_string "V4SF")
2329                    (const_string "SF"))
2330                (eq_attr "alternative" "11")
2331                  (const_string "DI")]
2332                (const_string "SF")))])
2334 (define_insn "*swapsf"
2335   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2336         (match_operand:SF 1 "fp_register_operand" "+f"))
2337    (set (match_dup 1)
2338         (match_dup 0))]
2339   "reload_completed || TARGET_80387"
2341   if (STACK_TOP_P (operands[0]))
2342     return "fxch\t%1";
2343   else
2344     return "fxch\t%0";
2346   [(set_attr "type" "fxch")
2347    (set_attr "mode" "SF")])
2349 (define_expand "movdf"
2350   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2351         (match_operand:DF 1 "general_operand" ""))]
2352   ""
2353   "ix86_expand_move (DFmode, operands); DONE;")
2355 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2356 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2357 ;; On the average, pushdf using integers can be still shorter.  Allow this
2358 ;; pattern for optimize_size too.
2360 (define_insn "*pushdf_nointeger"
2361   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2362         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2363   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2365   /* This insn should be already split before reg-stack.  */
2366   gcc_unreachable ();
2368   [(set_attr "type" "multi")
2369    (set_attr "unit" "i387,*,*,*")
2370    (set_attr "mode" "DF,SI,SI,DF")])
2372 (define_insn "*pushdf_integer"
2373   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2374         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2375   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2377   /* This insn should be already split before reg-stack.  */
2378   gcc_unreachable ();
2380   [(set_attr "type" "multi")
2381    (set_attr "unit" "i387,*,*")
2382    (set_attr "mode" "DF,SI,DF")])
2384 ;; %%% Kill this when call knows how to work this out.
2385 (define_split
2386   [(set (match_operand:DF 0 "push_operand" "")
2387         (match_operand:DF 1 "any_fp_register_operand" ""))]
2388   "!TARGET_64BIT && reload_completed"
2389   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2390    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2391   "")
2393 (define_split
2394   [(set (match_operand:DF 0 "push_operand" "")
2395         (match_operand:DF 1 "any_fp_register_operand" ""))]
2396   "TARGET_64BIT && reload_completed"
2397   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2398    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2399   "")
2401 (define_split
2402   [(set (match_operand:DF 0 "push_operand" "")
2403         (match_operand:DF 1 "general_operand" ""))]
2404   "reload_completed"
2405   [(const_int 0)]
2406   "ix86_split_long_move (operands); DONE;")
2408 ;; Moving is usually shorter when only FP registers are used. This separate
2409 ;; movdf pattern avoids the use of integer registers for FP operations
2410 ;; when optimizing for size.
2412 (define_insn "*movdf_nointeger"
2413   [(set (match_operand:DF 0 "nonimmediate_operand"
2414                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2415         (match_operand:DF 1 "general_operand"
2416                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2417   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2418    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2419    && (reload_in_progress || reload_completed
2420        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2421        || GET_CODE (operands[1]) != CONST_DOUBLE
2422        || memory_operand (operands[0], DFmode))" 
2424   switch (which_alternative)
2425     {
2426     case 0:
2427       return output_387_reg_move (insn, operands);
2429     case 1:
2430       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2431         return "fstp%z0\t%y0";
2432       else
2433         return "fst%z0\t%y0";
2435     case 2:
2436       return standard_80387_constant_opcode (operands[1]);
2438     case 3:
2439     case 4:
2440       return "#";
2441     case 5:
2442       switch (get_attr_mode (insn))
2443         {
2444         case MODE_V4SF:
2445           return "xorps\t%0, %0";
2446         case MODE_V2DF:
2447           return "xorpd\t%0, %0";
2448         case MODE_TI:
2449           return "pxor\t%0, %0";
2450         default:
2451           gcc_unreachable ();
2452         }
2453     case 6:
2454     case 7:
2455     case 8:
2456       switch (get_attr_mode (insn))
2457         {
2458         case MODE_V4SF:
2459           return "movaps\t{%1, %0|%0, %1}";
2460         case MODE_V2DF:
2461           return "movapd\t{%1, %0|%0, %1}";
2462         case MODE_TI:
2463           return "movdqa\t{%1, %0|%0, %1}";
2464         case MODE_DI:
2465           return "movq\t{%1, %0|%0, %1}";
2466         case MODE_DF:
2467           return "movsd\t{%1, %0|%0, %1}";
2468         case MODE_V1DF:
2469           return "movlpd\t{%1, %0|%0, %1}";
2470         case MODE_V2SF:
2471           return "movlps\t{%1, %0|%0, %1}";
2472         default:
2473           gcc_unreachable ();
2474         }
2476     default:
2477       gcc_unreachable ();
2478     }
2480   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2481    (set (attr "mode")
2482         (cond [(eq_attr "alternative" "0,1,2")
2483                  (const_string "DF")
2484                (eq_attr "alternative" "3,4")
2485                  (const_string "SI")
2487                /* For SSE1, we have many fewer alternatives.  */
2488                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2489                  (cond [(eq_attr "alternative" "5,6")
2490                           (const_string "V4SF")
2491                        ]
2492                    (const_string "V2SF"))
2494                /* xorps is one byte shorter.  */
2495                (eq_attr "alternative" "5")
2496                  (cond [(ne (symbol_ref "optimize_size")
2497                             (const_int 0))
2498                           (const_string "V4SF")
2499                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2500                             (const_int 0))
2501                           (const_string "TI")
2502                        ]
2503                        (const_string "V2DF"))
2505                /* For architectures resolving dependencies on
2506                   whole SSE registers use APD move to break dependency
2507                   chains, otherwise use short move to avoid extra work.
2509                   movaps encodes one byte shorter.  */
2510                (eq_attr "alternative" "6")
2511                  (cond
2512                    [(ne (symbol_ref "optimize_size")
2513                         (const_int 0))
2514                       (const_string "V4SF")
2515                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2516                         (const_int 0))
2517                       (const_string "V2DF")
2518                    ]
2519                    (const_string "DF"))
2520                /* For architectures resolving dependencies on register
2521                   parts we may avoid extra work to zero out upper part
2522                   of register.  */
2523                (eq_attr "alternative" "7")
2524                  (if_then_else
2525                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2526                        (const_int 0))
2527                    (const_string "V1DF")
2528                    (const_string "DF"))
2529               ]
2530               (const_string "DF")))])
2532 (define_insn "*movdf_integer"
2533   [(set (match_operand:DF 0 "nonimmediate_operand"
2534                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2535         (match_operand:DF 1 "general_operand"
2536                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2537   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2538    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2539    && (reload_in_progress || reload_completed
2540        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2541        || GET_CODE (operands[1]) != CONST_DOUBLE
2542        || memory_operand (operands[0], DFmode))" 
2544   switch (which_alternative)
2545     {
2546     case 0:
2547       return output_387_reg_move (insn, operands);
2549     case 1:
2550       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2551         return "fstp%z0\t%y0";
2552       else
2553         return "fst%z0\t%y0";
2555     case 2:
2556       return standard_80387_constant_opcode (operands[1]);
2558     case 3:
2559     case 4:
2560       return "#";
2562     case 5:
2563       switch (get_attr_mode (insn))
2564         {
2565         case MODE_V4SF:
2566           return "xorps\t%0, %0";
2567         case MODE_V2DF:
2568           return "xorpd\t%0, %0";
2569         case MODE_TI:
2570           return "pxor\t%0, %0";
2571         default:
2572           gcc_unreachable ();
2573         }
2574     case 6:
2575     case 7:
2576     case 8:
2577       switch (get_attr_mode (insn))
2578         {
2579         case MODE_V4SF:
2580           return "movaps\t{%1, %0|%0, %1}";
2581         case MODE_V2DF:
2582           return "movapd\t{%1, %0|%0, %1}";
2583         case MODE_TI:
2584           return "movdqa\t{%1, %0|%0, %1}";
2585         case MODE_DI:
2586           return "movq\t{%1, %0|%0, %1}";
2587         case MODE_DF:
2588           return "movsd\t{%1, %0|%0, %1}";
2589         case MODE_V1DF:
2590           return "movlpd\t{%1, %0|%0, %1}";
2591         case MODE_V2SF:
2592           return "movlps\t{%1, %0|%0, %1}";
2593         default:
2594           gcc_unreachable ();
2595         }
2597     default:
2598       gcc_unreachable();
2599     }
2601   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2602    (set (attr "mode")
2603         (cond [(eq_attr "alternative" "0,1,2")
2604                  (const_string "DF")
2605                (eq_attr "alternative" "3,4")
2606                  (const_string "SI")
2608                /* For SSE1, we have many fewer alternatives.  */
2609                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2610                  (cond [(eq_attr "alternative" "5,6")
2611                           (const_string "V4SF")
2612                        ]
2613                    (const_string "V2SF"))
2615                /* xorps is one byte shorter.  */
2616                (eq_attr "alternative" "5")
2617                  (cond [(ne (symbol_ref "optimize_size")
2618                             (const_int 0))
2619                           (const_string "V4SF")
2620                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2621                             (const_int 0))
2622                           (const_string "TI")
2623                        ]
2624                        (const_string "V2DF"))
2626                /* For architectures resolving dependencies on
2627                   whole SSE registers use APD move to break dependency
2628                   chains, otherwise use short move to avoid extra work.
2630                   movaps encodes one byte shorter.  */
2631                (eq_attr "alternative" "6")
2632                  (cond
2633                    [(ne (symbol_ref "optimize_size")
2634                         (const_int 0))
2635                       (const_string "V4SF")
2636                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2637                         (const_int 0))
2638                       (const_string "V2DF")
2639                    ]
2640                    (const_string "DF"))
2641                /* For architectures resolving dependencies on register
2642                   parts we may avoid extra work to zero out upper part
2643                   of register.  */
2644                (eq_attr "alternative" "7")
2645                  (if_then_else
2646                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2647                        (const_int 0))
2648                    (const_string "V1DF")
2649                    (const_string "DF"))
2650               ]
2651               (const_string "DF")))])
2653 (define_split
2654   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2655         (match_operand:DF 1 "general_operand" ""))]
2656   "reload_completed
2657    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2658    && ! (ANY_FP_REG_P (operands[0]) || 
2659          (GET_CODE (operands[0]) == SUBREG
2660           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2661    && ! (ANY_FP_REG_P (operands[1]) || 
2662          (GET_CODE (operands[1]) == SUBREG
2663           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2664   [(const_int 0)]
2665   "ix86_split_long_move (operands); DONE;")
2667 (define_insn "*swapdf"
2668   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2669         (match_operand:DF 1 "fp_register_operand" "+f"))
2670    (set (match_dup 1)
2671         (match_dup 0))]
2672   "reload_completed || TARGET_80387"
2674   if (STACK_TOP_P (operands[0]))
2675     return "fxch\t%1";
2676   else
2677     return "fxch\t%0";
2679   [(set_attr "type" "fxch")
2680    (set_attr "mode" "DF")])
2682 (define_expand "movxf"
2683   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2684         (match_operand:XF 1 "general_operand" ""))]
2685   ""
2686   "ix86_expand_move (XFmode, operands); DONE;")
2688 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2689 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2690 ;; Pushing using integer instructions is longer except for constants
2691 ;; and direct memory references.
2692 ;; (assuming that any given constant is pushed only once, but this ought to be
2693 ;;  handled elsewhere).
2695 (define_insn "*pushxf_nointeger"
2696   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2697         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2698   "optimize_size"
2700   /* This insn should be already split before reg-stack.  */
2701   gcc_unreachable ();
2703   [(set_attr "type" "multi")
2704    (set_attr "unit" "i387,*,*")
2705    (set_attr "mode" "XF,SI,SI")])
2707 (define_insn "*pushxf_integer"
2708   [(set (match_operand:XF 0 "push_operand" "=<,<")
2709         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2710   "!optimize_size"
2712   /* This insn should be already split before reg-stack.  */
2713   gcc_unreachable ();
2715   [(set_attr "type" "multi")
2716    (set_attr "unit" "i387,*")
2717    (set_attr "mode" "XF,SI")])
2719 (define_split
2720   [(set (match_operand 0 "push_operand" "")
2721         (match_operand 1 "general_operand" ""))]
2722   "reload_completed
2723    && (GET_MODE (operands[0]) == XFmode
2724        || GET_MODE (operands[0]) == DFmode)
2725    && !ANY_FP_REG_P (operands[1])"
2726   [(const_int 0)]
2727   "ix86_split_long_move (operands); DONE;")
2729 (define_split
2730   [(set (match_operand:XF 0 "push_operand" "")
2731         (match_operand:XF 1 "any_fp_register_operand" ""))]
2732   "!TARGET_64BIT"
2733   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2734    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2735   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2737 (define_split
2738   [(set (match_operand:XF 0 "push_operand" "")
2739         (match_operand:XF 1 "any_fp_register_operand" ""))]
2740   "TARGET_64BIT"
2741   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2742    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2743   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2745 ;; Do not use integer registers when optimizing for size
2746 (define_insn "*movxf_nointeger"
2747   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2748         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2749   "optimize_size
2750    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2751    && (reload_in_progress || reload_completed
2752        || GET_CODE (operands[1]) != CONST_DOUBLE
2753        || memory_operand (operands[0], XFmode))" 
2755   switch (which_alternative)
2756     {
2757     case 0:
2758       return output_387_reg_move (insn, operands);
2760     case 1:
2761       /* There is no non-popping store to memory for XFmode.  So if
2762          we need one, follow the store with a load.  */
2763       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2764         return "fstp%z0\t%y0\;fld%z0\t%y0";
2765       else
2766         return "fstp%z0\t%y0";
2768     case 2:
2769       return standard_80387_constant_opcode (operands[1]);
2771     case 3: case 4:
2772       return "#";
2773     default:
2774       gcc_unreachable ();
2775     }
2777   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2778    (set_attr "mode" "XF,XF,XF,SI,SI")])
2780 (define_insn "*movxf_integer"
2781   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2782         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2783   "!optimize_size
2784    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2785    && (reload_in_progress || reload_completed
2786        || GET_CODE (operands[1]) != CONST_DOUBLE
2787        || memory_operand (operands[0], XFmode))" 
2789   switch (which_alternative)
2790     {
2791     case 0:
2792       return output_387_reg_move (insn, operands);
2794     case 1:
2795       /* There is no non-popping store to memory for XFmode.  So if
2796          we need one, follow the store with a load.  */
2797       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2798         return "fstp%z0\t%y0\;fld%z0\t%y0";
2799       else
2800         return "fstp%z0\t%y0";
2802     case 2:
2803       return standard_80387_constant_opcode (operands[1]);
2805     case 3: case 4:
2806       return "#";
2808     default:
2809       gcc_unreachable ();
2810     }
2812   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2813    (set_attr "mode" "XF,XF,XF,SI,SI")])
2815 (define_split
2816   [(set (match_operand 0 "nonimmediate_operand" "")
2817         (match_operand 1 "general_operand" ""))]
2818   "reload_completed
2819    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2820    && GET_MODE (operands[0]) == XFmode
2821    && ! (ANY_FP_REG_P (operands[0]) || 
2822          (GET_CODE (operands[0]) == SUBREG
2823           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2824    && ! (ANY_FP_REG_P (operands[1]) || 
2825          (GET_CODE (operands[1]) == SUBREG
2826           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2827   [(const_int 0)]
2828   "ix86_split_long_move (operands); DONE;")
2830 (define_split
2831   [(set (match_operand 0 "register_operand" "")
2832         (match_operand 1 "memory_operand" ""))]
2833   "reload_completed
2834    && GET_CODE (operands[1]) == MEM
2835    && (GET_MODE (operands[0]) == XFmode
2836        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2837    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2838    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2839   [(set (match_dup 0) (match_dup 1))]
2841   rtx c = get_pool_constant (XEXP (operands[1], 0));
2842   rtx r = operands[0];
2844   if (GET_CODE (r) == SUBREG)
2845     r = SUBREG_REG (r);
2847   if (SSE_REG_P (r))
2848     {
2849       if (!standard_sse_constant_p (c))
2850         FAIL;
2851     }
2852   else if (FP_REG_P (r))
2853     {
2854       if (!standard_80387_constant_p (c))
2855         FAIL;
2856     }
2857   else if (MMX_REG_P (r))
2858     FAIL;
2860   operands[1] = c;
2863 (define_insn "swapxf"
2864   [(set (match_operand:XF 0 "register_operand" "+f")
2865         (match_operand:XF 1 "register_operand" "+f"))
2866    (set (match_dup 1)
2867         (match_dup 0))]
2868   "TARGET_80387"
2870   if (STACK_TOP_P (operands[0]))
2871     return "fxch\t%1";
2872   else
2873     return "fxch\t%0";
2875   [(set_attr "type" "fxch")
2876    (set_attr "mode" "XF")])
2878 (define_expand "movtf"
2879   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2880         (match_operand:TF 1 "nonimmediate_operand" ""))]
2881   "TARGET_64BIT"
2883   ix86_expand_move (TFmode, operands);
2884   DONE;
2887 (define_insn "*movtf_internal"
2888   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2889         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2890   "TARGET_64BIT
2891    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2893   switch (which_alternative)
2894     {
2895     case 0:
2896     case 1:
2897       return "#";
2898     case 2:
2899       if (get_attr_mode (insn) == MODE_V4SF)
2900         return "xorps\t%0, %0";
2901       else
2902         return "pxor\t%0, %0";
2903     case 3:
2904     case 4:
2905       if (get_attr_mode (insn) == MODE_V4SF)
2906         return "movaps\t{%1, %0|%0, %1}";
2907       else
2908         return "movdqa\t{%1, %0|%0, %1}";
2909     default:
2910       gcc_unreachable ();
2911     }
2913   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2914    (set (attr "mode")
2915         (cond [(eq_attr "alternative" "2,3")
2916                  (if_then_else
2917                    (ne (symbol_ref "optimize_size")
2918                        (const_int 0))
2919                    (const_string "V4SF")
2920                    (const_string "TI"))
2921                (eq_attr "alternative" "4")
2922                  (if_then_else
2923                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2924                             (const_int 0))
2925                         (ne (symbol_ref "optimize_size")
2926                             (const_int 0)))
2927                    (const_string "V4SF")
2928                    (const_string "TI"))]
2929                (const_string "DI")))])
2931 (define_split
2932   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2933         (match_operand:TF 1 "general_operand" ""))]
2934   "reload_completed && !SSE_REG_P (operands[0])
2935    && !SSE_REG_P (operands[1])"
2936   [(const_int 0)]
2937   "ix86_split_long_move (operands); DONE;")
2939 ;; Zero extension instructions
2941 (define_expand "zero_extendhisi2"
2942   [(set (match_operand:SI 0 "register_operand" "")
2943      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2944   ""
2946   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2947     {
2948       operands[1] = force_reg (HImode, operands[1]);
2949       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2950       DONE;
2951     }
2954 (define_insn "zero_extendhisi2_and"
2955   [(set (match_operand:SI 0 "register_operand" "=r")
2956      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2957    (clobber (reg:CC FLAGS_REG))]
2958   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2959   "#"
2960   [(set_attr "type" "alu1")
2961    (set_attr "mode" "SI")])
2963 (define_split
2964   [(set (match_operand:SI 0 "register_operand" "")
2965         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2966    (clobber (reg:CC FLAGS_REG))]
2967   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2968   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2969               (clobber (reg:CC FLAGS_REG))])]
2970   "")
2972 (define_insn "*zero_extendhisi2_movzwl"
2973   [(set (match_operand:SI 0 "register_operand" "=r")
2974      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2975   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2976   "movz{wl|x}\t{%1, %0|%0, %1}"
2977   [(set_attr "type" "imovx")
2978    (set_attr "mode" "SI")])
2980 (define_expand "zero_extendqihi2"
2981   [(parallel
2982     [(set (match_operand:HI 0 "register_operand" "")
2983        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2984      (clobber (reg:CC FLAGS_REG))])]
2985   ""
2986   "")
2988 (define_insn "*zero_extendqihi2_and"
2989   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2990      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2991    (clobber (reg:CC FLAGS_REG))]
2992   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2993   "#"
2994   [(set_attr "type" "alu1")
2995    (set_attr "mode" "HI")])
2997 (define_insn "*zero_extendqihi2_movzbw_and"
2998   [(set (match_operand:HI 0 "register_operand" "=r,r")
2999      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3000    (clobber (reg:CC FLAGS_REG))]
3001   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3002   "#"
3003   [(set_attr "type" "imovx,alu1")
3004    (set_attr "mode" "HI")])
3006 (define_insn "*zero_extendqihi2_movzbw"
3007   [(set (match_operand:HI 0 "register_operand" "=r")
3008      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3009   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3010   "movz{bw|x}\t{%1, %0|%0, %1}"
3011   [(set_attr "type" "imovx")
3012    (set_attr "mode" "HI")])
3014 ;; For the movzbw case strip only the clobber
3015 (define_split
3016   [(set (match_operand:HI 0 "register_operand" "")
3017         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3018    (clobber (reg:CC FLAGS_REG))]
3019   "reload_completed 
3020    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3021    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3022   [(set (match_operand:HI 0 "register_operand" "")
3023         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3025 ;; When source and destination does not overlap, clear destination
3026 ;; first and then do the movb
3027 (define_split
3028   [(set (match_operand:HI 0 "register_operand" "")
3029         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3030    (clobber (reg:CC FLAGS_REG))]
3031   "reload_completed
3032    && ANY_QI_REG_P (operands[0])
3033    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3034    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3035   [(set (match_dup 0) (const_int 0))
3036    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3037   "operands[2] = gen_lowpart (QImode, operands[0]);")
3039 ;; Rest is handled by single and.
3040 (define_split
3041   [(set (match_operand:HI 0 "register_operand" "")
3042         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3043    (clobber (reg:CC FLAGS_REG))]
3044   "reload_completed
3045    && true_regnum (operands[0]) == true_regnum (operands[1])"
3046   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3047               (clobber (reg:CC FLAGS_REG))])]
3048   "")
3050 (define_expand "zero_extendqisi2"
3051   [(parallel
3052     [(set (match_operand:SI 0 "register_operand" "")
3053        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3054      (clobber (reg:CC FLAGS_REG))])]
3055   ""
3056   "")
3058 (define_insn "*zero_extendqisi2_and"
3059   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3060      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3061    (clobber (reg:CC FLAGS_REG))]
3062   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3063   "#"
3064   [(set_attr "type" "alu1")
3065    (set_attr "mode" "SI")])
3067 (define_insn "*zero_extendqisi2_movzbw_and"
3068   [(set (match_operand:SI 0 "register_operand" "=r,r")
3069      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3070    (clobber (reg:CC FLAGS_REG))]
3071   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3072   "#"
3073   [(set_attr "type" "imovx,alu1")
3074    (set_attr "mode" "SI")])
3076 (define_insn "*zero_extendqisi2_movzbw"
3077   [(set (match_operand:SI 0 "register_operand" "=r")
3078      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3079   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3080   "movz{bl|x}\t{%1, %0|%0, %1}"
3081   [(set_attr "type" "imovx")
3082    (set_attr "mode" "SI")])
3084 ;; For the movzbl case strip only the clobber
3085 (define_split
3086   [(set (match_operand:SI 0 "register_operand" "")
3087         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3088    (clobber (reg:CC FLAGS_REG))]
3089   "reload_completed 
3090    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3091    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3092   [(set (match_dup 0)
3093         (zero_extend:SI (match_dup 1)))])
3095 ;; When source and destination does not overlap, clear destination
3096 ;; first and then do the movb
3097 (define_split
3098   [(set (match_operand:SI 0 "register_operand" "")
3099         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3100    (clobber (reg:CC FLAGS_REG))]
3101   "reload_completed
3102    && ANY_QI_REG_P (operands[0])
3103    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3104    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3105    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3106   [(set (match_dup 0) (const_int 0))
3107    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3108   "operands[2] = gen_lowpart (QImode, operands[0]);")
3110 ;; Rest is handled by single and.
3111 (define_split
3112   [(set (match_operand:SI 0 "register_operand" "")
3113         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3114    (clobber (reg:CC FLAGS_REG))]
3115   "reload_completed
3116    && true_regnum (operands[0]) == true_regnum (operands[1])"
3117   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3118               (clobber (reg:CC FLAGS_REG))])]
3119   "")
3121 ;; %%% Kill me once multi-word ops are sane.
3122 (define_expand "zero_extendsidi2"
3123   [(set (match_operand:DI 0 "register_operand" "=r")
3124      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3125   ""
3126   "if (!TARGET_64BIT)
3127      {
3128        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3129        DONE;
3130      }
3131   ")
3133 (define_insn "zero_extendsidi2_32"
3134   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3135         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3136    (clobber (reg:CC FLAGS_REG))]
3137   "!TARGET_64BIT"
3138   "@
3139    #
3140    #
3141    #
3142    movd\t{%1, %0|%0, %1}
3143    movd\t{%1, %0|%0, %1}"
3144   [(set_attr "mode" "SI,SI,SI,DI,TI")
3145    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3147 (define_insn "zero_extendsidi2_rex64"
3148   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3149      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3150   "TARGET_64BIT"
3151   "@
3152    mov\t{%k1, %k0|%k0, %k1}
3153    #
3154    movd\t{%1, %0|%0, %1}
3155    movd\t{%1, %0|%0, %1}"
3156   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3157    (set_attr "mode" "SI,DI,SI,SI")])
3159 (define_split
3160   [(set (match_operand:DI 0 "memory_operand" "")
3161      (zero_extend:DI (match_dup 0)))]
3162   "TARGET_64BIT"
3163   [(set (match_dup 4) (const_int 0))]
3164   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3166 (define_split 
3167   [(set (match_operand:DI 0 "register_operand" "")
3168         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3169    (clobber (reg:CC FLAGS_REG))]
3170   "!TARGET_64BIT && reload_completed
3171    && true_regnum (operands[0]) == true_regnum (operands[1])"
3172   [(set (match_dup 4) (const_int 0))]
3173   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3175 (define_split 
3176   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3177         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3178    (clobber (reg:CC FLAGS_REG))]
3179   "!TARGET_64BIT && reload_completed
3180    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3181   [(set (match_dup 3) (match_dup 1))
3182    (set (match_dup 4) (const_int 0))]
3183   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3185 (define_insn "zero_extendhidi2"
3186   [(set (match_operand:DI 0 "register_operand" "=r,r")
3187      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3188   "TARGET_64BIT"
3189   "@
3190    movz{wl|x}\t{%1, %k0|%k0, %1}
3191    movz{wq|x}\t{%1, %0|%0, %1}"
3192   [(set_attr "type" "imovx")
3193    (set_attr "mode" "SI,DI")])
3195 (define_insn "zero_extendqidi2"
3196   [(set (match_operand:DI 0 "register_operand" "=r,r")
3197      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3198   "TARGET_64BIT"
3199   "@
3200    movz{bl|x}\t{%1, %k0|%k0, %1}
3201    movz{bq|x}\t{%1, %0|%0, %1}"
3202   [(set_attr "type" "imovx")
3203    (set_attr "mode" "SI,DI")])
3205 ;; Sign extension instructions
3207 (define_expand "extendsidi2"
3208   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3209                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3210               (clobber (reg:CC FLAGS_REG))
3211               (clobber (match_scratch:SI 2 ""))])]
3212   ""
3214   if (TARGET_64BIT)
3215     {
3216       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3217       DONE;
3218     }
3221 (define_insn "*extendsidi2_1"
3222   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3223         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3224    (clobber (reg:CC FLAGS_REG))
3225    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3226   "!TARGET_64BIT"
3227   "#")
3229 (define_insn "extendsidi2_rex64"
3230   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3231         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3232   "TARGET_64BIT"
3233   "@
3234    {cltq|cdqe}
3235    movs{lq|x}\t{%1,%0|%0, %1}"
3236   [(set_attr "type" "imovx")
3237    (set_attr "mode" "DI")
3238    (set_attr "prefix_0f" "0")
3239    (set_attr "modrm" "0,1")])
3241 (define_insn "extendhidi2"
3242   [(set (match_operand:DI 0 "register_operand" "=r")
3243         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3244   "TARGET_64BIT"
3245   "movs{wq|x}\t{%1,%0|%0, %1}"
3246   [(set_attr "type" "imovx")
3247    (set_attr "mode" "DI")])
3249 (define_insn "extendqidi2"
3250   [(set (match_operand:DI 0 "register_operand" "=r")
3251         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3252   "TARGET_64BIT"
3253   "movs{bq|x}\t{%1,%0|%0, %1}"
3254    [(set_attr "type" "imovx")
3255     (set_attr "mode" "DI")])
3257 ;; Extend to memory case when source register does die.
3258 (define_split 
3259   [(set (match_operand:DI 0 "memory_operand" "")
3260         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3261    (clobber (reg:CC FLAGS_REG))
3262    (clobber (match_operand:SI 2 "register_operand" ""))]
3263   "(reload_completed
3264     && dead_or_set_p (insn, operands[1])
3265     && !reg_mentioned_p (operands[1], operands[0]))"
3266   [(set (match_dup 3) (match_dup 1))
3267    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3268               (clobber (reg:CC FLAGS_REG))])
3269    (set (match_dup 4) (match_dup 1))]
3270   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3272 ;; Extend to memory case when source register does not die.
3273 (define_split 
3274   [(set (match_operand:DI 0 "memory_operand" "")
3275         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3276    (clobber (reg:CC FLAGS_REG))
3277    (clobber (match_operand:SI 2 "register_operand" ""))]
3278   "reload_completed"
3279   [(const_int 0)]
3281   split_di (&operands[0], 1, &operands[3], &operands[4]);
3283   emit_move_insn (operands[3], operands[1]);
3285   /* Generate a cltd if possible and doing so it profitable.  */
3286   if (true_regnum (operands[1]) == 0
3287       && true_regnum (operands[2]) == 1
3288       && (optimize_size || TARGET_USE_CLTD))
3289     {
3290       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3291     }
3292   else
3293     {
3294       emit_move_insn (operands[2], operands[1]);
3295       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3296     }
3297   emit_move_insn (operands[4], operands[2]);
3298   DONE;
3301 ;; Extend to register case.  Optimize case where source and destination
3302 ;; registers match and cases where we can use cltd.
3303 (define_split 
3304   [(set (match_operand:DI 0 "register_operand" "")
3305         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3306    (clobber (reg:CC FLAGS_REG))
3307    (clobber (match_scratch:SI 2 ""))]
3308   "reload_completed"
3309   [(const_int 0)]
3311   split_di (&operands[0], 1, &operands[3], &operands[4]);
3313   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3314     emit_move_insn (operands[3], operands[1]);
3316   /* Generate a cltd if possible and doing so it profitable.  */
3317   if (true_regnum (operands[3]) == 0
3318       && (optimize_size || TARGET_USE_CLTD))
3319     {
3320       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3321       DONE;
3322     }
3324   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3325     emit_move_insn (operands[4], operands[1]);
3327   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3328   DONE;
3331 (define_insn "extendhisi2"
3332   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3333         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3334   ""
3336   switch (get_attr_prefix_0f (insn))
3337     {
3338     case 0:
3339       return "{cwtl|cwde}";
3340     default:
3341       return "movs{wl|x}\t{%1,%0|%0, %1}";
3342     }
3344   [(set_attr "type" "imovx")
3345    (set_attr "mode" "SI")
3346    (set (attr "prefix_0f")
3347      ;; movsx is short decodable while cwtl is vector decoded.
3348      (if_then_else (and (eq_attr "cpu" "!k6")
3349                         (eq_attr "alternative" "0"))
3350         (const_string "0")
3351         (const_string "1")))
3352    (set (attr "modrm")
3353      (if_then_else (eq_attr "prefix_0f" "0")
3354         (const_string "0")
3355         (const_string "1")))])
3357 (define_insn "*extendhisi2_zext"
3358   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3359         (zero_extend:DI
3360           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3361   "TARGET_64BIT"
3363   switch (get_attr_prefix_0f (insn))
3364     {
3365     case 0:
3366       return "{cwtl|cwde}";
3367     default:
3368       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3369     }
3371   [(set_attr "type" "imovx")
3372    (set_attr "mode" "SI")
3373    (set (attr "prefix_0f")
3374      ;; movsx is short decodable while cwtl is vector decoded.
3375      (if_then_else (and (eq_attr "cpu" "!k6")
3376                         (eq_attr "alternative" "0"))
3377         (const_string "0")
3378         (const_string "1")))
3379    (set (attr "modrm")
3380      (if_then_else (eq_attr "prefix_0f" "0")
3381         (const_string "0")
3382         (const_string "1")))])
3384 (define_insn "extendqihi2"
3385   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3386         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3387   ""
3389   switch (get_attr_prefix_0f (insn))
3390     {
3391     case 0:
3392       return "{cbtw|cbw}";
3393     default:
3394       return "movs{bw|x}\t{%1,%0|%0, %1}";
3395     }
3397   [(set_attr "type" "imovx")
3398    (set_attr "mode" "HI")
3399    (set (attr "prefix_0f")
3400      ;; movsx is short decodable while cwtl is vector decoded.
3401      (if_then_else (and (eq_attr "cpu" "!k6")
3402                         (eq_attr "alternative" "0"))
3403         (const_string "0")
3404         (const_string "1")))
3405    (set (attr "modrm")
3406      (if_then_else (eq_attr "prefix_0f" "0")
3407         (const_string "0")
3408         (const_string "1")))])
3410 (define_insn "extendqisi2"
3411   [(set (match_operand:SI 0 "register_operand" "=r")
3412         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3413   ""
3414   "movs{bl|x}\t{%1,%0|%0, %1}"
3415    [(set_attr "type" "imovx")
3416     (set_attr "mode" "SI")])
3418 (define_insn "*extendqisi2_zext"
3419   [(set (match_operand:DI 0 "register_operand" "=r")
3420         (zero_extend:DI
3421           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3422   "TARGET_64BIT"
3423   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3424    [(set_attr "type" "imovx")
3425     (set_attr "mode" "SI")])
3427 ;; Conversions between float and double.
3429 ;; These are all no-ops in the model used for the 80387.  So just
3430 ;; emit moves.
3432 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3433 (define_insn "*dummy_extendsfdf2"
3434   [(set (match_operand:DF 0 "push_operand" "=<")
3435         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3436   "0"
3437   "#")
3439 (define_split
3440   [(set (match_operand:DF 0 "push_operand" "")
3441         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3442   "!TARGET_64BIT"
3443   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3444    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3446 (define_split
3447   [(set (match_operand:DF 0 "push_operand" "")
3448         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3449   "TARGET_64BIT"
3450   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3451    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3453 (define_insn "*dummy_extendsfxf2"
3454   [(set (match_operand:XF 0 "push_operand" "=<")
3455         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3456   "0"
3457   "#")
3459 (define_split
3460   [(set (match_operand:XF 0 "push_operand" "")
3461         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3462   ""
3463   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3464    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3465   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3467 (define_split
3468   [(set (match_operand:XF 0 "push_operand" "")
3469         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3470   "TARGET_64BIT"
3471   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3472    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3473   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3475 (define_split
3476   [(set (match_operand:XF 0 "push_operand" "")
3477         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3478   ""
3479   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3480    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3481   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3483 (define_split
3484   [(set (match_operand:XF 0 "push_operand" "")
3485         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3486   "TARGET_64BIT"
3487   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3488    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3489   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3491 (define_expand "extendsfdf2"
3492   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3493         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3494   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3496   /* ??? Needed for compress_float_constant since all fp constants
3497      are LEGITIMATE_CONSTANT_P.  */
3498   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3499     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3500   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3501     operands[1] = force_reg (SFmode, operands[1]);
3504 (define_insn "*extendsfdf2_mixed"
3505   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3506         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3507   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3508    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3510   switch (which_alternative)
3511     {
3512     case 0:
3513       return output_387_reg_move (insn, operands);
3515     case 1:
3516       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3517         return "fstp%z0\t%y0";
3518       else
3519         return "fst%z0\t%y0";
3521     case 2:
3522       return "cvtss2sd\t{%1, %0|%0, %1}";
3524     default:
3525       gcc_unreachable ();
3526     }
3528   [(set_attr "type" "fmov,fmov,ssecvt")
3529    (set_attr "mode" "SF,XF,DF")])
3531 (define_insn "*extendsfdf2_sse"
3532   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3533         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3534   "TARGET_SSE2 && TARGET_SSE_MATH
3535    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3536   "cvtss2sd\t{%1, %0|%0, %1}"
3537   [(set_attr "type" "ssecvt")
3538    (set_attr "mode" "DF")])
3540 (define_insn "*extendsfdf2_i387"
3541   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3542         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3543   "TARGET_80387
3544    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3546   switch (which_alternative)
3547     {
3548     case 0:
3549       return output_387_reg_move (insn, operands);
3551     case 1:
3552       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3553         return "fstp%z0\t%y0";
3554       else
3555         return "fst%z0\t%y0";
3557     default:
3558       gcc_unreachable ();
3559     }
3561   [(set_attr "type" "fmov")
3562    (set_attr "mode" "SF,XF")])
3564 (define_expand "extendsfxf2"
3565   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3566         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3567   "TARGET_80387"
3569   /* ??? Needed for compress_float_constant since all fp constants
3570      are LEGITIMATE_CONSTANT_P.  */
3571   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3572     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3573   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3574     operands[1] = force_reg (SFmode, operands[1]);
3577 (define_insn "*extendsfxf2_i387"
3578   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3579         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3580   "TARGET_80387
3581    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3583   switch (which_alternative)
3584     {
3585     case 0:
3586       return output_387_reg_move (insn, operands);
3588     case 1:
3589       /* There is no non-popping store to memory for XFmode.  So if
3590          we need one, follow the store with a load.  */
3591       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3592         return "fstp%z0\t%y0";
3593       else
3594         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3596     default:
3597       gcc_unreachable ();
3598     }
3600   [(set_attr "type" "fmov")
3601    (set_attr "mode" "SF,XF")])
3603 (define_expand "extenddfxf2"
3604   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3605         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3606   "TARGET_80387"
3608   /* ??? Needed for compress_float_constant since all fp constants
3609      are LEGITIMATE_CONSTANT_P.  */
3610   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3611     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3612   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3613     operands[1] = force_reg (DFmode, operands[1]);
3616 (define_insn "*extenddfxf2_i387"
3617   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3618         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3619   "TARGET_80387
3620    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3622   switch (which_alternative)
3623     {
3624     case 0:
3625       return output_387_reg_move (insn, operands);
3627     case 1:
3628       /* There is no non-popping store to memory for XFmode.  So if
3629          we need one, follow the store with a load.  */
3630       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3631         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3632       else
3633         return "fstp%z0\t%y0";
3635     default:
3636       gcc_unreachable ();
3637     }
3639   [(set_attr "type" "fmov")
3640    (set_attr "mode" "DF,XF")])
3642 ;; %%% This seems bad bad news.
3643 ;; This cannot output into an f-reg because there is no way to be sure
3644 ;; of truncating in that case.  Otherwise this is just like a simple move
3645 ;; insn.  So we pretend we can output to a reg in order to get better
3646 ;; register preferencing, but we really use a stack slot.
3648 ;; Conversion from DFmode to SFmode.
3650 (define_expand "truncdfsf2"
3651   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3652         (float_truncate:SF
3653           (match_operand:DF 1 "nonimmediate_operand" "")))]
3654   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3656   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3657     operands[1] = force_reg (DFmode, operands[1]);
3659   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3660     ;
3661   else if (flag_unsafe_math_optimizations)
3662     ;
3663   else
3664     {
3665       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3666       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3667       DONE;
3668     }
3671 (define_expand "truncdfsf2_with_temp"
3672   [(parallel [(set (match_operand:SF 0 "" "")
3673                    (float_truncate:SF (match_operand:DF 1 "" "")))
3674               (clobber (match_operand:SF 2 "" ""))])]
3675   "")
3677 (define_insn "*truncdfsf_fast_mixed"
3678   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3679         (float_truncate:SF
3680           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3681   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3683   switch (which_alternative)
3684     {
3685     case 0:
3686       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3687         return "fstp%z0\t%y0";
3688       else
3689         return "fst%z0\t%y0";
3690     case 1:
3691       return output_387_reg_move (insn, operands);
3692     case 2:
3693       return "cvtsd2ss\t{%1, %0|%0, %1}";
3694     default:
3695       gcc_unreachable ();
3696     }
3698   [(set_attr "type" "fmov,fmov,ssecvt")
3699    (set_attr "mode" "SF")])
3701 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3702 ;; because nothing we do here is unsafe.
3703 (define_insn "*truncdfsf_fast_sse"
3704   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3705         (float_truncate:SF
3706           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3707   "TARGET_SSE2 && TARGET_SSE_MATH"
3708   "cvtsd2ss\t{%1, %0|%0, %1}"
3709   [(set_attr "type" "ssecvt")
3710    (set_attr "mode" "SF")])
3712 (define_insn "*truncdfsf_fast_i387"
3713   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3714         (float_truncate:SF
3715           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3716   "TARGET_80387 && flag_unsafe_math_optimizations"
3717   "* return output_387_reg_move (insn, operands);"
3718   [(set_attr "type" "fmov")
3719    (set_attr "mode" "SF")])
3721 (define_insn "*truncdfsf_mixed"
3722   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3723         (float_truncate:SF
3724           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3725    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3726   "TARGET_MIX_SSE_I387"
3728   switch (which_alternative)
3729     {
3730     case 0:
3731       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3732         return "fstp%z0\t%y0";
3733       else
3734         return "fst%z0\t%y0";
3735     case 1:
3736       return "#";
3737     case 2:
3738       return "cvtsd2ss\t{%1, %0|%0, %1}";
3739     default:
3740       gcc_unreachable ();
3741     }
3743   [(set_attr "type" "fmov,multi,ssecvt")
3744    (set_attr "unit" "*,i387,*")
3745    (set_attr "mode" "SF")])
3747 (define_insn "*truncdfsf_i387"
3748   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3749         (float_truncate:SF
3750           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3751    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3752   "TARGET_80387"
3754   switch (which_alternative)
3755     {
3756     case 0:
3757       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3758         return "fstp%z0\t%y0";
3759       else
3760         return "fst%z0\t%y0";
3761     case 1:
3762       return "#";
3763     default:
3764       gcc_unreachable ();
3765     }
3767   [(set_attr "type" "fmov,multi")
3768    (set_attr "unit" "*,i387")
3769    (set_attr "mode" "SF")])
3771 (define_insn "*truncdfsf2_i387_1"
3772   [(set (match_operand:SF 0 "memory_operand" "=m")
3773         (float_truncate:SF
3774           (match_operand:DF 1 "register_operand" "f")))]
3775   "TARGET_80387
3776    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3777    && !TARGET_MIX_SSE_I387"
3779   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3780     return "fstp%z0\t%y0";
3781   else
3782     return "fst%z0\t%y0";
3784   [(set_attr "type" "fmov")
3785    (set_attr "mode" "SF")])
3787 (define_split
3788   [(set (match_operand:SF 0 "register_operand" "")
3789         (float_truncate:SF
3790          (match_operand:DF 1 "fp_register_operand" "")))
3791    (clobber (match_operand 2 "" ""))]
3792   "reload_completed"
3793   [(set (match_dup 2) (match_dup 1))
3794    (set (match_dup 0) (match_dup 2))]
3796   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3799 ;; Conversion from XFmode to SFmode.
3801 (define_expand "truncxfsf2"
3802   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3803                    (float_truncate:SF
3804                     (match_operand:XF 1 "register_operand" "")))
3805               (clobber (match_dup 2))])]
3806   "TARGET_80387"
3808   if (flag_unsafe_math_optimizations)
3809     {
3810       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3811       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3812       if (reg != operands[0])
3813         emit_move_insn (operands[0], reg);
3814       DONE;
3815     }
3816   else
3817     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3820 (define_insn "*truncxfsf2_mixed"
3821   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3822         (float_truncate:SF
3823          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3824    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3825   "TARGET_MIX_SSE_I387"
3827   gcc_assert (!which_alternative);
3828   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3829     return "fstp%z0\t%y0";
3830   else
3831     return "fst%z0\t%y0";
3833   [(set_attr "type" "fmov,multi,multi,multi")
3834    (set_attr "unit" "*,i387,i387,i387")
3835    (set_attr "mode" "SF")])
3837 (define_insn "truncxfsf2_i387_noop"
3838   [(set (match_operand:SF 0 "register_operand" "=f")
3839         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3840   "TARGET_80387 && flag_unsafe_math_optimizations"
3842   return output_387_reg_move (insn, operands);
3844   [(set_attr "type" "fmov")
3845    (set_attr "mode" "SF")])
3847 (define_insn "*truncxfsf2_i387"
3848   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3849         (float_truncate:SF
3850          (match_operand:XF 1 "register_operand" "f,f,f")))
3851    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3852   "TARGET_80387"
3854   gcc_assert (!which_alternative);
3855   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3856     return "fstp%z0\t%y0";
3857    else
3858      return "fst%z0\t%y0";
3860   [(set_attr "type" "fmov,multi,multi")
3861    (set_attr "unit" "*,i387,i387")
3862    (set_attr "mode" "SF")])
3864 (define_insn "*truncxfsf2_i387_1"
3865   [(set (match_operand:SF 0 "memory_operand" "=m")
3866         (float_truncate:SF
3867          (match_operand:XF 1 "register_operand" "f")))]
3868   "TARGET_80387"
3870   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3871     return "fstp%z0\t%y0";
3872   else
3873     return "fst%z0\t%y0";
3875   [(set_attr "type" "fmov")
3876    (set_attr "mode" "SF")])
3878 (define_split
3879   [(set (match_operand:SF 0 "register_operand" "")
3880         (float_truncate:SF
3881          (match_operand:XF 1 "register_operand" "")))
3882    (clobber (match_operand:SF 2 "memory_operand" ""))]
3883   "TARGET_80387 && reload_completed"
3884   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3885    (set (match_dup 0) (match_dup 2))]
3886   "")
3888 (define_split
3889   [(set (match_operand:SF 0 "memory_operand" "")
3890         (float_truncate:SF
3891          (match_operand:XF 1 "register_operand" "")))
3892    (clobber (match_operand:SF 2 "memory_operand" ""))]
3893   "TARGET_80387"
3894   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3895   "")
3897 ;; Conversion from XFmode to DFmode.
3899 (define_expand "truncxfdf2"
3900   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3901                    (float_truncate:DF
3902                     (match_operand:XF 1 "register_operand" "")))
3903               (clobber (match_dup 2))])]
3904   "TARGET_80387"
3906   if (flag_unsafe_math_optimizations)
3907     {
3908       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3909       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3910       if (reg != operands[0])
3911         emit_move_insn (operands[0], reg);
3912       DONE;
3913     }
3914   else
3915     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3918 (define_insn "*truncxfdf2_mixed"
3919   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3920         (float_truncate:DF
3921          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3922    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3923   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3925   gcc_assert (!which_alternative);
3926   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3927     return "fstp%z0\t%y0";
3928   else
3929     return "fst%z0\t%y0";
3931   [(set_attr "type" "fmov,multi,multi,multi")
3932    (set_attr "unit" "*,i387,i387,i387")
3933    (set_attr "mode" "DF")])
3935 (define_insn "truncxfdf2_i387_noop"
3936   [(set (match_operand:DF 0 "register_operand" "=f")
3937         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3938   "TARGET_80387 && flag_unsafe_math_optimizations"
3940   return output_387_reg_move (insn, operands);
3942   [(set_attr "type" "fmov")
3943    (set_attr "mode" "DF")])
3945 (define_insn "*truncxfdf2_i387"
3946   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3947         (float_truncate:DF
3948          (match_operand:XF 1 "register_operand" "f,f,f")))
3949    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3950   "TARGET_80387"
3952   gcc_assert (!which_alternative);
3953   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3954     return "fstp%z0\t%y0";
3955   else
3956     return "fst%z0\t%y0";
3958   [(set_attr "type" "fmov,multi,multi")
3959    (set_attr "unit" "*,i387,i387")
3960    (set_attr "mode" "DF")])
3962 (define_insn "*truncxfdf2_i387_1"
3963   [(set (match_operand:DF 0 "memory_operand" "=m")
3964         (float_truncate:DF
3965           (match_operand:XF 1 "register_operand" "f")))]
3966   "TARGET_80387"
3968   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3969     return "fstp%z0\t%y0";
3970   else
3971     return "fst%z0\t%y0";
3973   [(set_attr "type" "fmov")
3974    (set_attr "mode" "DF")])
3976 (define_split
3977   [(set (match_operand:DF 0 "register_operand" "")
3978         (float_truncate:DF
3979          (match_operand:XF 1 "register_operand" "")))
3980    (clobber (match_operand:DF 2 "memory_operand" ""))]
3981   "TARGET_80387 && reload_completed"
3982   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3983    (set (match_dup 0) (match_dup 2))]
3984   "")
3986 (define_split
3987   [(set (match_operand:DF 0 "memory_operand" "")
3988         (float_truncate:DF
3989          (match_operand:XF 1 "register_operand" "")))
3990    (clobber (match_operand:DF 2 "memory_operand" ""))]
3991   "TARGET_80387"
3992   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3993   "")
3995 ;; Signed conversion to DImode.
3997 (define_expand "fix_truncxfdi2"
3998   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3999                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4000               (clobber (reg:CC FLAGS_REG))])]
4001   "TARGET_80387"
4003   if (TARGET_FISTTP)
4004    {
4005      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4006      DONE;
4007    }
4010 (define_expand "fix_trunc<mode>di2"
4011   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4012                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4013               (clobber (reg:CC FLAGS_REG))])]
4014   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4016   if (TARGET_FISTTP
4017       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4018    {
4019      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4020      DONE;
4021    }
4022   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4023    {
4024      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4025      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4026      if (out != operands[0])
4027         emit_move_insn (operands[0], out);
4028      DONE;
4029    }
4032 ;; Signed conversion to SImode.
4034 (define_expand "fix_truncxfsi2"
4035   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4036                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4037               (clobber (reg:CC FLAGS_REG))])]
4038   "TARGET_80387"
4040   if (TARGET_FISTTP)
4041    {
4042      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4043      DONE;
4044    }
4047 (define_expand "fix_trunc<mode>si2"
4048   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4049                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4050               (clobber (reg:CC FLAGS_REG))])]
4051   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4053   if (TARGET_FISTTP
4054       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4055    {
4056      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4057      DONE;
4058    }
4059   if (SSE_FLOAT_MODE_P (<MODE>mode))
4060    {
4061      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4062      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4063      if (out != operands[0])
4064         emit_move_insn (operands[0], out);
4065      DONE;
4066    }
4069 ;; Signed conversion to HImode.
4071 (define_expand "fix_trunc<mode>hi2"
4072   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4073                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4074               (clobber (reg:CC FLAGS_REG))])]
4075   "TARGET_80387
4076    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4078   if (TARGET_FISTTP)
4079    {
4080      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4081      DONE;
4082    }
4085 ;; When SSE is available, it is always faster to use it!
4086 (define_insn "fix_truncsfdi_sse"
4087   [(set (match_operand:DI 0 "register_operand" "=r,r")
4088         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4089   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4090   "cvttss2si{q}\t{%1, %0|%0, %1}"
4091   [(set_attr "type" "sseicvt")
4092    (set_attr "mode" "SF")
4093    (set_attr "athlon_decode" "double,vector")])
4095 (define_insn "fix_truncdfdi_sse"
4096   [(set (match_operand:DI 0 "register_operand" "=r,r")
4097         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4098   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4099   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4100   [(set_attr "type" "sseicvt")
4101    (set_attr "mode" "DF")
4102    (set_attr "athlon_decode" "double,vector")])
4104 (define_insn "fix_truncsfsi_sse"
4105   [(set (match_operand:SI 0 "register_operand" "=r,r")
4106         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4107   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4108   "cvttss2si\t{%1, %0|%0, %1}"
4109   [(set_attr "type" "sseicvt")
4110    (set_attr "mode" "DF")
4111    (set_attr "athlon_decode" "double,vector")])
4113 (define_insn "fix_truncdfsi_sse"
4114   [(set (match_operand:SI 0 "register_operand" "=r,r")
4115         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4116   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4117   "cvttsd2si\t{%1, %0|%0, %1}"
4118   [(set_attr "type" "sseicvt")
4119    (set_attr "mode" "DF")
4120    (set_attr "athlon_decode" "double,vector")])
4122 ;; Avoid vector decoded forms of the instruction.
4123 (define_peephole2
4124   [(match_scratch:DF 2 "Y")
4125    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4126         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4127   "TARGET_K8 && !optimize_size"
4128   [(set (match_dup 2) (match_dup 1))
4129    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4130   "")
4132 (define_peephole2
4133   [(match_scratch:SF 2 "x")
4134    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4135         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4136   "TARGET_K8 && !optimize_size"
4137   [(set (match_dup 2) (match_dup 1))
4138    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4139   "")
4141 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4142   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4143         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4144   "TARGET_80387 && TARGET_FISTTP
4145    && FLOAT_MODE_P (GET_MODE (operands[1]))
4146    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4147          && (TARGET_64BIT || <MODE>mode != DImode))
4148         && TARGET_SSE_MATH)
4149    && !(reload_completed || reload_in_progress)"
4150   "#"
4151   "&& 1"
4152   [(const_int 0)]
4154   if (memory_operand (operands[0], VOIDmode))
4155     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4156   else
4157     {
4158       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4159       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4160                                                             operands[1],
4161                                                             operands[2]));
4162     }
4163   DONE;
4165   [(set_attr "type" "fisttp")
4166    (set_attr "mode" "<MODE>")])
4168 (define_insn "fix_trunc<mode>_i387_fisttp"
4169   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4170         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4171    (clobber (match_scratch:XF 2 "=&1f"))]
4172   "TARGET_80387 && TARGET_FISTTP
4173    && FLOAT_MODE_P (GET_MODE (operands[1]))
4174    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4175          && (TARGET_64BIT || <MODE>mode != DImode))
4176         && TARGET_SSE_MATH)"
4177   "* return output_fix_trunc (insn, operands, 1);"
4178   [(set_attr "type" "fisttp")
4179    (set_attr "mode" "<MODE>")])
4181 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4182   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4183         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4184    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4185    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4186   "TARGET_80387 && TARGET_FISTTP
4187    && FLOAT_MODE_P (GET_MODE (operands[1]))
4188    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4189         && (TARGET_64BIT || <MODE>mode != DImode))
4190         && TARGET_SSE_MATH)"
4191   "#"
4192   [(set_attr "type" "fisttp")
4193    (set_attr "mode" "<MODE>")])
4195 (define_split
4196   [(set (match_operand:X87MODEI 0 "register_operand" "")
4197         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4198    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4199    (clobber (match_scratch 3 ""))]
4200   "reload_completed"
4201   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4202               (clobber (match_dup 3))])
4203    (set (match_dup 0) (match_dup 2))]
4204   "")
4206 (define_split
4207   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4208         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4209    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4210    (clobber (match_scratch 3 ""))]
4211   "reload_completed"
4212   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4213               (clobber (match_dup 3))])]
4214   "")
4216 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4217 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4218 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4219 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4220 ;; function in i386.c.
4221 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4222   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4223         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4224    (clobber (reg:CC FLAGS_REG))]
4225   "TARGET_80387 && !TARGET_FISTTP
4226    && FLOAT_MODE_P (GET_MODE (operands[1]))
4227    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4228          && (TARGET_64BIT || <MODE>mode != DImode))
4229    && !(reload_completed || reload_in_progress)"
4230   "#"
4231   "&& 1"
4232   [(const_int 0)]
4234   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4236   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4237   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4238   if (memory_operand (operands[0], VOIDmode))
4239     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4240                                          operands[2], operands[3]));
4241   else
4242     {
4243       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4244       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4245                                                      operands[2], operands[3],
4246                                                      operands[4]));
4247     }
4248   DONE;
4250   [(set_attr "type" "fistp")
4251    (set_attr "i387_cw" "trunc")
4252    (set_attr "mode" "<MODE>")])
4254 (define_insn "fix_truncdi_i387"
4255   [(set (match_operand:DI 0 "memory_operand" "=m")
4256         (fix:DI (match_operand 1 "register_operand" "f")))
4257    (use (match_operand:HI 2 "memory_operand" "m"))
4258    (use (match_operand:HI 3 "memory_operand" "m"))
4259    (clobber (match_scratch:XF 4 "=&1f"))]
4260   "TARGET_80387 && !TARGET_FISTTP
4261    && FLOAT_MODE_P (GET_MODE (operands[1]))
4262    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4263   "* return output_fix_trunc (insn, operands, 0);"
4264   [(set_attr "type" "fistp")
4265    (set_attr "i387_cw" "trunc")
4266    (set_attr "mode" "DI")])
4268 (define_insn "fix_truncdi_i387_with_temp"
4269   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4270         (fix:DI (match_operand 1 "register_operand" "f,f")))
4271    (use (match_operand:HI 2 "memory_operand" "m,m"))
4272    (use (match_operand:HI 3 "memory_operand" "m,m"))
4273    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4274    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4275   "TARGET_80387 && !TARGET_FISTTP
4276    && FLOAT_MODE_P (GET_MODE (operands[1]))
4277    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4278   "#"
4279   [(set_attr "type" "fistp")
4280    (set_attr "i387_cw" "trunc")
4281    (set_attr "mode" "DI")])
4283 (define_split 
4284   [(set (match_operand:DI 0 "register_operand" "")
4285         (fix:DI (match_operand 1 "register_operand" "")))
4286    (use (match_operand:HI 2 "memory_operand" ""))
4287    (use (match_operand:HI 3 "memory_operand" ""))
4288    (clobber (match_operand:DI 4 "memory_operand" ""))
4289    (clobber (match_scratch 5 ""))]
4290   "reload_completed"
4291   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4292               (use (match_dup 2))
4293               (use (match_dup 3))
4294               (clobber (match_dup 5))])
4295    (set (match_dup 0) (match_dup 4))]
4296   "")
4298 (define_split 
4299   [(set (match_operand:DI 0 "memory_operand" "")
4300         (fix:DI (match_operand 1 "register_operand" "")))
4301    (use (match_operand:HI 2 "memory_operand" ""))
4302    (use (match_operand:HI 3 "memory_operand" ""))
4303    (clobber (match_operand:DI 4 "memory_operand" ""))
4304    (clobber (match_scratch 5 ""))]
4305   "reload_completed"
4306   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4307               (use (match_dup 2))
4308               (use (match_dup 3))
4309               (clobber (match_dup 5))])]
4310   "")
4312 (define_insn "fix_trunc<mode>_i387"
4313   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4314         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4315    (use (match_operand:HI 2 "memory_operand" "m"))
4316    (use (match_operand:HI 3 "memory_operand" "m"))]
4317   "TARGET_80387 && !TARGET_FISTTP
4318    && FLOAT_MODE_P (GET_MODE (operands[1]))
4319    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4320   "* return output_fix_trunc (insn, operands, 0);"
4321   [(set_attr "type" "fistp")
4322    (set_attr "i387_cw" "trunc")
4323    (set_attr "mode" "<MODE>")])
4325 (define_insn "fix_trunc<mode>_i387_with_temp"
4326   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4327         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4328    (use (match_operand:HI 2 "memory_operand" "m,m"))
4329    (use (match_operand:HI 3 "memory_operand" "m,m"))
4330    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4331   "TARGET_80387 && !TARGET_FISTTP
4332    && FLOAT_MODE_P (GET_MODE (operands[1]))
4333    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4334   "#"
4335   [(set_attr "type" "fistp")
4336    (set_attr "i387_cw" "trunc")
4337    (set_attr "mode" "<MODE>")])
4339 (define_split 
4340   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4341         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4342    (use (match_operand:HI 2 "memory_operand" ""))
4343    (use (match_operand:HI 3 "memory_operand" ""))
4344    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4345   "reload_completed"
4346   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4347               (use (match_dup 2))
4348               (use (match_dup 3))])
4349    (set (match_dup 0) (match_dup 4))]
4350   "")
4352 (define_split 
4353   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4354         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4355    (use (match_operand:HI 2 "memory_operand" ""))
4356    (use (match_operand:HI 3 "memory_operand" ""))
4357    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4358   "reload_completed"
4359   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4360               (use (match_dup 2))
4361               (use (match_dup 3))])]
4362   "")
4364 (define_insn "x86_fnstcw_1"
4365   [(set (match_operand:HI 0 "memory_operand" "=m")
4366         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4367   "TARGET_80387"
4368   "fnstcw\t%0"
4369   [(set_attr "length" "2")
4370    (set_attr "mode" "HI")
4371    (set_attr "unit" "i387")])
4373 (define_insn "x86_fldcw_1"
4374   [(set (reg:HI FPSR_REG)
4375         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4376   "TARGET_80387"
4377   "fldcw\t%0"
4378   [(set_attr "length" "2")
4379    (set_attr "mode" "HI")
4380    (set_attr "unit" "i387")
4381    (set_attr "athlon_decode" "vector")])
4383 ;; Conversion between fixed point and floating point.
4385 ;; Even though we only accept memory inputs, the backend _really_
4386 ;; wants to be able to do this between registers.
4388 (define_expand "floathisf2"
4389   [(set (match_operand:SF 0 "register_operand" "")
4390         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4391   "TARGET_80387 || TARGET_SSE_MATH"
4393   if (TARGET_SSE_MATH)
4394     {
4395       emit_insn (gen_floatsisf2 (operands[0],
4396                                  convert_to_mode (SImode, operands[1], 0)));
4397       DONE;
4398     }
4401 (define_insn "*floathisf2_i387"
4402   [(set (match_operand:SF 0 "register_operand" "=f,f")
4403         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4404   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4405   "@
4406    fild%z1\t%1
4407    #"
4408   [(set_attr "type" "fmov,multi")
4409    (set_attr "mode" "SF")
4410    (set_attr "unit" "*,i387")
4411    (set_attr "fp_int_src" "true")])
4413 (define_expand "floatsisf2"
4414   [(set (match_operand:SF 0 "register_operand" "")
4415         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4416   "TARGET_80387 || TARGET_SSE_MATH"
4417   "")
4419 (define_insn "*floatsisf2_mixed"
4420   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4421         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4422   "TARGET_MIX_SSE_I387"
4423   "@
4424    fild%z1\t%1
4425    #
4426    cvtsi2ss\t{%1, %0|%0, %1}
4427    cvtsi2ss\t{%1, %0|%0, %1}"
4428   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4429    (set_attr "mode" "SF")
4430    (set_attr "unit" "*,i387,*,*")
4431    (set_attr "athlon_decode" "*,*,vector,double")
4432    (set_attr "fp_int_src" "true")])
4434 (define_insn "*floatsisf2_sse"
4435   [(set (match_operand:SF 0 "register_operand" "=x,x")
4436         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4437   "TARGET_SSE_MATH"
4438   "cvtsi2ss\t{%1, %0|%0, %1}"
4439   [(set_attr "type" "sseicvt")
4440    (set_attr "mode" "SF")
4441    (set_attr "athlon_decode" "vector,double")
4442    (set_attr "fp_int_src" "true")])
4444 (define_insn "*floatsisf2_i387"
4445   [(set (match_operand:SF 0 "register_operand" "=f,f")
4446         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4447   "TARGET_80387"
4448   "@
4449    fild%z1\t%1
4450    #"
4451   [(set_attr "type" "fmov,multi")
4452    (set_attr "mode" "SF")
4453    (set_attr "unit" "*,i387")
4454    (set_attr "fp_int_src" "true")])
4456 (define_expand "floatdisf2"
4457   [(set (match_operand:SF 0 "register_operand" "")
4458         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4459   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4460   "")
4462 (define_insn "*floatdisf2_mixed"
4463   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4464         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4465   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4466   "@
4467    fild%z1\t%1
4468    #
4469    cvtsi2ss{q}\t{%1, %0|%0, %1}
4470    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4471   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4472    (set_attr "mode" "SF")
4473    (set_attr "unit" "*,i387,*,*")
4474    (set_attr "athlon_decode" "*,*,vector,double")
4475    (set_attr "fp_int_src" "true")])
4477 (define_insn "*floatdisf2_sse"
4478   [(set (match_operand:SF 0 "register_operand" "=x,x")
4479         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4480   "TARGET_64BIT && TARGET_SSE_MATH"
4481   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4482   [(set_attr "type" "sseicvt")
4483    (set_attr "mode" "SF")
4484    (set_attr "athlon_decode" "vector,double")
4485    (set_attr "fp_int_src" "true")])
4487 (define_insn "*floatdisf2_i387"
4488   [(set (match_operand:SF 0 "register_operand" "=f,f")
4489         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4490   "TARGET_80387"
4491   "@
4492    fild%z1\t%1
4493    #"
4494   [(set_attr "type" "fmov,multi")
4495    (set_attr "mode" "SF")
4496    (set_attr "unit" "*,i387")
4497    (set_attr "fp_int_src" "true")])
4499 (define_expand "floathidf2"
4500   [(set (match_operand:DF 0 "register_operand" "")
4501         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4502   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4504   if (TARGET_SSE2 && TARGET_SSE_MATH)
4505     {
4506       emit_insn (gen_floatsidf2 (operands[0],
4507                                  convert_to_mode (SImode, operands[1], 0)));
4508       DONE;
4509     }
4512 (define_insn "*floathidf2_i387"
4513   [(set (match_operand:DF 0 "register_operand" "=f,f")
4514         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4515   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4516   "@
4517    fild%z1\t%1
4518    #"
4519   [(set_attr "type" "fmov,multi")
4520    (set_attr "mode" "DF")
4521    (set_attr "unit" "*,i387")
4522    (set_attr "fp_int_src" "true")])
4524 (define_expand "floatsidf2"
4525   [(set (match_operand:DF 0 "register_operand" "")
4526         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4527   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4528   "")
4530 (define_insn "*floatsidf2_mixed"
4531   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4532         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4533   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4534   "@
4535    fild%z1\t%1
4536    #
4537    cvtsi2sd\t{%1, %0|%0, %1}
4538    cvtsi2sd\t{%1, %0|%0, %1}"
4539   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4540    (set_attr "mode" "DF")
4541    (set_attr "unit" "*,i387,*,*")
4542    (set_attr "athlon_decode" "*,*,double,direct")
4543    (set_attr "fp_int_src" "true")])
4545 (define_insn "*floatsidf2_sse"
4546   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4547         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4548   "TARGET_SSE2 && TARGET_SSE_MATH"
4549   "cvtsi2sd\t{%1, %0|%0, %1}"
4550   [(set_attr "type" "sseicvt")
4551    (set_attr "mode" "DF")
4552    (set_attr "athlon_decode" "double,direct")
4553    (set_attr "fp_int_src" "true")])
4555 (define_insn "*floatsidf2_i387"
4556   [(set (match_operand:DF 0 "register_operand" "=f,f")
4557         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4558   "TARGET_80387"
4559   "@
4560    fild%z1\t%1
4561    #"
4562   [(set_attr "type" "fmov,multi")
4563    (set_attr "mode" "DF")
4564    (set_attr "unit" "*,i387")
4565    (set_attr "fp_int_src" "true")])
4567 (define_expand "floatdidf2"
4568   [(set (match_operand:DF 0 "register_operand" "")
4569         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4570   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4571   "")
4573 (define_insn "*floatdidf2_mixed"
4574   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4575         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4576   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4577   "@
4578    fild%z1\t%1
4579    #
4580    cvtsi2sd{q}\t{%1, %0|%0, %1}
4581    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4582   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4583    (set_attr "mode" "DF")
4584    (set_attr "unit" "*,i387,*,*")
4585    (set_attr "athlon_decode" "*,*,double,direct")
4586    (set_attr "fp_int_src" "true")])
4588 (define_insn "*floatdidf2_sse"
4589   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4590         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4591   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4592   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4593   [(set_attr "type" "sseicvt")
4594    (set_attr "mode" "DF")
4595    (set_attr "athlon_decode" "double,direct")
4596    (set_attr "fp_int_src" "true")])
4598 (define_insn "*floatdidf2_i387"
4599   [(set (match_operand:DF 0 "register_operand" "=f,f")
4600         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4601   "TARGET_80387"
4602   "@
4603    fild%z1\t%1
4604    #"
4605   [(set_attr "type" "fmov,multi")
4606    (set_attr "mode" "DF")
4607    (set_attr "unit" "*,i387")
4608    (set_attr "fp_int_src" "true")])
4610 (define_insn "floathixf2"
4611   [(set (match_operand:XF 0 "register_operand" "=f,f")
4612         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4613   "TARGET_80387"
4614   "@
4615    fild%z1\t%1
4616    #"
4617   [(set_attr "type" "fmov,multi")
4618    (set_attr "mode" "XF")
4619    (set_attr "unit" "*,i387")
4620    (set_attr "fp_int_src" "true")])
4622 (define_insn "floatsixf2"
4623   [(set (match_operand:XF 0 "register_operand" "=f,f")
4624         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4625   "TARGET_80387"
4626   "@
4627    fild%z1\t%1
4628    #"
4629   [(set_attr "type" "fmov,multi")
4630    (set_attr "mode" "XF")
4631    (set_attr "unit" "*,i387")
4632    (set_attr "fp_int_src" "true")])
4634 (define_insn "floatdixf2"
4635   [(set (match_operand:XF 0 "register_operand" "=f,f")
4636         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4637   "TARGET_80387"
4638   "@
4639    fild%z1\t%1
4640    #"
4641   [(set_attr "type" "fmov,multi")
4642    (set_attr "mode" "XF")
4643    (set_attr "unit" "*,i387")
4644    (set_attr "fp_int_src" "true")])
4646 ;; %%% Kill these when reload knows how to do it.
4647 (define_split
4648   [(set (match_operand 0 "fp_register_operand" "")
4649         (float (match_operand 1 "register_operand" "")))]
4650   "reload_completed
4651    && TARGET_80387
4652    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4653   [(const_int 0)]
4655   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4656   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4657   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4658   ix86_free_from_memory (GET_MODE (operands[1]));
4659   DONE;
4662 (define_expand "floatunssisf2"
4663   [(use (match_operand:SF 0 "register_operand" ""))
4664    (use (match_operand:SI 1 "register_operand" ""))]
4665   "!TARGET_64BIT && TARGET_SSE_MATH"
4666   "x86_emit_floatuns (operands); DONE;")
4668 (define_expand "floatunsdisf2"
4669   [(use (match_operand:SF 0 "register_operand" ""))
4670    (use (match_operand:DI 1 "register_operand" ""))]
4671   "TARGET_64BIT && TARGET_SSE_MATH"
4672   "x86_emit_floatuns (operands); DONE;")
4674 (define_expand "floatunsdidf2"
4675   [(use (match_operand:DF 0 "register_operand" ""))
4676    (use (match_operand:DI 1 "register_operand" ""))]
4677   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4678   "x86_emit_floatuns (operands); DONE;")
4680 ;; SSE extract/set expanders
4683 ;; Add instructions
4685 ;; %%% splits for addsidi3
4686 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4687 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4688 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4690 (define_expand "adddi3"
4691   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4692         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4693                  (match_operand:DI 2 "x86_64_general_operand" "")))
4694    (clobber (reg:CC FLAGS_REG))]
4695   ""
4696   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4698 (define_insn "*adddi3_1"
4699   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4700         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4701                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4702    (clobber (reg:CC FLAGS_REG))]
4703   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4704   "#")
4706 (define_split
4707   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4708         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4709                  (match_operand:DI 2 "general_operand" "")))
4710    (clobber (reg:CC FLAGS_REG))]
4711   "!TARGET_64BIT && reload_completed"
4712   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4713                                           UNSPEC_ADD_CARRY))
4714               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4715    (parallel [(set (match_dup 3)
4716                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4717                                      (match_dup 4))
4718                             (match_dup 5)))
4719               (clobber (reg:CC FLAGS_REG))])]
4720   "split_di (operands+0, 1, operands+0, operands+3);
4721    split_di (operands+1, 1, operands+1, operands+4);
4722    split_di (operands+2, 1, operands+2, operands+5);")
4724 (define_insn "adddi3_carry_rex64"
4725   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4726           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4727                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4728                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4729    (clobber (reg:CC FLAGS_REG))]
4730   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4731   "adc{q}\t{%2, %0|%0, %2}"
4732   [(set_attr "type" "alu")
4733    (set_attr "pent_pair" "pu")
4734    (set_attr "mode" "DI")])
4736 (define_insn "*adddi3_cc_rex64"
4737   [(set (reg:CC FLAGS_REG)
4738         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4739                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4740                    UNSPEC_ADD_CARRY))
4741    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4742         (plus:DI (match_dup 1) (match_dup 2)))]
4743   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4744   "add{q}\t{%2, %0|%0, %2}"
4745   [(set_attr "type" "alu")
4746    (set_attr "mode" "DI")])
4748 (define_insn "addqi3_carry"
4749   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4750           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4751                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4752                    (match_operand:QI 2 "general_operand" "qi,qm")))
4753    (clobber (reg:CC FLAGS_REG))]
4754   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4755   "adc{b}\t{%2, %0|%0, %2}"
4756   [(set_attr "type" "alu")
4757    (set_attr "pent_pair" "pu")
4758    (set_attr "mode" "QI")])
4760 (define_insn "addhi3_carry"
4761   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4762           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4763                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4764                    (match_operand:HI 2 "general_operand" "ri,rm")))
4765    (clobber (reg:CC FLAGS_REG))]
4766   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4767   "adc{w}\t{%2, %0|%0, %2}"
4768   [(set_attr "type" "alu")
4769    (set_attr "pent_pair" "pu")
4770    (set_attr "mode" "HI")])
4772 (define_insn "addsi3_carry"
4773   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4774           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4775                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4776                    (match_operand:SI 2 "general_operand" "ri,rm")))
4777    (clobber (reg:CC FLAGS_REG))]
4778   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4779   "adc{l}\t{%2, %0|%0, %2}"
4780   [(set_attr "type" "alu")
4781    (set_attr "pent_pair" "pu")
4782    (set_attr "mode" "SI")])
4784 (define_insn "*addsi3_carry_zext"
4785   [(set (match_operand:DI 0 "register_operand" "=r")
4786           (zero_extend:DI 
4787             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4788                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4789                      (match_operand:SI 2 "general_operand" "rim"))))
4790    (clobber (reg:CC FLAGS_REG))]
4791   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4792   "adc{l}\t{%2, %k0|%k0, %2}"
4793   [(set_attr "type" "alu")
4794    (set_attr "pent_pair" "pu")
4795    (set_attr "mode" "SI")])
4797 (define_insn "*addsi3_cc"
4798   [(set (reg:CC FLAGS_REG)
4799         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4800                     (match_operand:SI 2 "general_operand" "ri,rm")]
4801                    UNSPEC_ADD_CARRY))
4802    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4803         (plus:SI (match_dup 1) (match_dup 2)))]
4804   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4805   "add{l}\t{%2, %0|%0, %2}"
4806   [(set_attr "type" "alu")
4807    (set_attr "mode" "SI")])
4809 (define_insn "addqi3_cc"
4810   [(set (reg:CC FLAGS_REG)
4811         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4812                     (match_operand:QI 2 "general_operand" "qi,qm")]
4813                    UNSPEC_ADD_CARRY))
4814    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4815         (plus:QI (match_dup 1) (match_dup 2)))]
4816   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4817   "add{b}\t{%2, %0|%0, %2}"
4818   [(set_attr "type" "alu")
4819    (set_attr "mode" "QI")])
4821 (define_expand "addsi3"
4822   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4823                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4824                             (match_operand:SI 2 "general_operand" "")))
4825               (clobber (reg:CC FLAGS_REG))])]
4826   ""
4827   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4829 (define_insn "*lea_1"
4830   [(set (match_operand:SI 0 "register_operand" "=r")
4831         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4832   "!TARGET_64BIT"
4833   "lea{l}\t{%a1, %0|%0, %a1}"
4834   [(set_attr "type" "lea")
4835    (set_attr "mode" "SI")])
4837 (define_insn "*lea_1_rex64"
4838   [(set (match_operand:SI 0 "register_operand" "=r")
4839         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4840   "TARGET_64BIT"
4841   "lea{l}\t{%a1, %0|%0, %a1}"
4842   [(set_attr "type" "lea")
4843    (set_attr "mode" "SI")])
4845 (define_insn "*lea_1_zext"
4846   [(set (match_operand:DI 0 "register_operand" "=r")
4847         (zero_extend:DI
4848          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4849   "TARGET_64BIT"
4850   "lea{l}\t{%a1, %k0|%k0, %a1}"
4851   [(set_attr "type" "lea")
4852    (set_attr "mode" "SI")])
4854 (define_insn "*lea_2_rex64"
4855   [(set (match_operand:DI 0 "register_operand" "=r")
4856         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4857   "TARGET_64BIT"
4858   "lea{q}\t{%a1, %0|%0, %a1}"
4859   [(set_attr "type" "lea")
4860    (set_attr "mode" "DI")])
4862 ;; The lea patterns for non-Pmodes needs to be matched by several
4863 ;; insns converted to real lea by splitters.
4865 (define_insn_and_split "*lea_general_1"
4866   [(set (match_operand 0 "register_operand" "=r")
4867         (plus (plus (match_operand 1 "index_register_operand" "l")
4868                     (match_operand 2 "register_operand" "r"))
4869               (match_operand 3 "immediate_operand" "i")))]
4870   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4871     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4872    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4873    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4874    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4875    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4876        || GET_MODE (operands[3]) == VOIDmode)"
4877   "#"
4878   "&& reload_completed"
4879   [(const_int 0)]
4881   rtx pat;
4882   operands[0] = gen_lowpart (SImode, operands[0]);
4883   operands[1] = gen_lowpart (Pmode, operands[1]);
4884   operands[2] = gen_lowpart (Pmode, operands[2]);
4885   operands[3] = gen_lowpart (Pmode, operands[3]);
4886   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4887                       operands[3]);
4888   if (Pmode != SImode)
4889     pat = gen_rtx_SUBREG (SImode, pat, 0);
4890   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4891   DONE;
4893   [(set_attr "type" "lea")
4894    (set_attr "mode" "SI")])
4896 (define_insn_and_split "*lea_general_1_zext"
4897   [(set (match_operand:DI 0 "register_operand" "=r")
4898         (zero_extend:DI
4899           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4900                             (match_operand:SI 2 "register_operand" "r"))
4901                    (match_operand:SI 3 "immediate_operand" "i"))))]
4902   "TARGET_64BIT"
4903   "#"
4904   "&& reload_completed"
4905   [(set (match_dup 0)
4906         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4907                                                      (match_dup 2))
4908                                             (match_dup 3)) 0)))]
4910   operands[1] = gen_lowpart (Pmode, operands[1]);
4911   operands[2] = gen_lowpart (Pmode, operands[2]);
4912   operands[3] = gen_lowpart (Pmode, operands[3]);
4914   [(set_attr "type" "lea")
4915    (set_attr "mode" "SI")])
4917 (define_insn_and_split "*lea_general_2"
4918   [(set (match_operand 0 "register_operand" "=r")
4919         (plus (mult (match_operand 1 "index_register_operand" "l")
4920                     (match_operand 2 "const248_operand" "i"))
4921               (match_operand 3 "nonmemory_operand" "ri")))]
4922   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4923     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4924    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4925    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4926    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4927        || GET_MODE (operands[3]) == VOIDmode)"
4928   "#"
4929   "&& reload_completed"
4930   [(const_int 0)]
4932   rtx pat;
4933   operands[0] = gen_lowpart (SImode, operands[0]);
4934   operands[1] = gen_lowpart (Pmode, operands[1]);
4935   operands[3] = gen_lowpart (Pmode, operands[3]);
4936   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4937                       operands[3]);
4938   if (Pmode != SImode)
4939     pat = gen_rtx_SUBREG (SImode, pat, 0);
4940   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4941   DONE;
4943   [(set_attr "type" "lea")
4944    (set_attr "mode" "SI")])
4946 (define_insn_and_split "*lea_general_2_zext"
4947   [(set (match_operand:DI 0 "register_operand" "=r")
4948         (zero_extend:DI
4949           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
4950                             (match_operand:SI 2 "const248_operand" "n"))
4951                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4952   "TARGET_64BIT"
4953   "#"
4954   "&& reload_completed"
4955   [(set (match_dup 0)
4956         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4957                                                      (match_dup 2))
4958                                             (match_dup 3)) 0)))]
4960   operands[1] = gen_lowpart (Pmode, operands[1]);
4961   operands[3] = gen_lowpart (Pmode, operands[3]);
4963   [(set_attr "type" "lea")
4964    (set_attr "mode" "SI")])
4966 (define_insn_and_split "*lea_general_3"
4967   [(set (match_operand 0 "register_operand" "=r")
4968         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
4969                           (match_operand 2 "const248_operand" "i"))
4970                     (match_operand 3 "register_operand" "r"))
4971               (match_operand 4 "immediate_operand" "i")))]
4972   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4973     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4974    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4975    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4976    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4977   "#"
4978   "&& reload_completed"
4979   [(const_int 0)]
4981   rtx pat;
4982   operands[0] = gen_lowpart (SImode, operands[0]);
4983   operands[1] = gen_lowpart (Pmode, operands[1]);
4984   operands[3] = gen_lowpart (Pmode, operands[3]);
4985   operands[4] = gen_lowpart (Pmode, operands[4]);
4986   pat = gen_rtx_PLUS (Pmode,
4987                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
4988                                                          operands[2]),
4989                                     operands[3]),
4990                       operands[4]);
4991   if (Pmode != SImode)
4992     pat = gen_rtx_SUBREG (SImode, pat, 0);
4993   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4994   DONE;
4996   [(set_attr "type" "lea")
4997    (set_attr "mode" "SI")])
4999 (define_insn_and_split "*lea_general_3_zext"
5000   [(set (match_operand:DI 0 "register_operand" "=r")
5001         (zero_extend:DI
5002           (plus:SI (plus:SI (mult:SI
5003                               (match_operand:SI 1 "index_register_operand" "l")
5004                               (match_operand:SI 2 "const248_operand" "n"))
5005                             (match_operand:SI 3 "register_operand" "r"))
5006                    (match_operand:SI 4 "immediate_operand" "i"))))]
5007   "TARGET_64BIT"
5008   "#"
5009   "&& reload_completed"
5010   [(set (match_dup 0)
5011         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5012                                                               (match_dup 2))
5013                                                      (match_dup 3))
5014                                             (match_dup 4)) 0)))]
5016   operands[1] = gen_lowpart (Pmode, operands[1]);
5017   operands[3] = gen_lowpart (Pmode, operands[3]);
5018   operands[4] = gen_lowpart (Pmode, operands[4]);
5020   [(set_attr "type" "lea")
5021    (set_attr "mode" "SI")])
5023 (define_insn "*adddi_1_rex64"
5024   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5025         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5026                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5027    (clobber (reg:CC FLAGS_REG))]
5028   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5030   switch (get_attr_type (insn))
5031     {
5032     case TYPE_LEA:
5033       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5034       return "lea{q}\t{%a2, %0|%0, %a2}";
5036     case TYPE_INCDEC:
5037       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5038       if (operands[2] == const1_rtx)
5039         return "inc{q}\t%0";
5040       else
5041         {
5042           gcc_assert (operands[2] == constm1_rtx);
5043           return "dec{q}\t%0";
5044         }
5046     default:
5047       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5049       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5050          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5051       if (GET_CODE (operands[2]) == CONST_INT
5052           /* Avoid overflows.  */
5053           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5054           && (INTVAL (operands[2]) == 128
5055               || (INTVAL (operands[2]) < 0
5056                   && INTVAL (operands[2]) != -128)))
5057         {
5058           operands[2] = GEN_INT (-INTVAL (operands[2]));
5059           return "sub{q}\t{%2, %0|%0, %2}";
5060         }
5061       return "add{q}\t{%2, %0|%0, %2}";
5062     }
5064   [(set (attr "type")
5065      (cond [(eq_attr "alternative" "2")
5066               (const_string "lea")
5067             ; Current assemblers are broken and do not allow @GOTOFF in
5068             ; ought but a memory context.
5069             (match_operand:DI 2 "pic_symbolic_operand" "")
5070               (const_string "lea")
5071             (match_operand:DI 2 "incdec_operand" "")
5072               (const_string "incdec")
5073            ]
5074            (const_string "alu")))
5075    (set_attr "mode" "DI")])
5077 ;; Convert lea to the lea pattern to avoid flags dependency.
5078 (define_split
5079   [(set (match_operand:DI 0 "register_operand" "")
5080         (plus:DI (match_operand:DI 1 "register_operand" "")
5081                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5082    (clobber (reg:CC FLAGS_REG))]
5083   "TARGET_64BIT && reload_completed
5084    && true_regnum (operands[0]) != true_regnum (operands[1])"
5085   [(set (match_dup 0)
5086         (plus:DI (match_dup 1)
5087                  (match_dup 2)))]
5088   "")
5090 (define_insn "*adddi_2_rex64"
5091   [(set (reg FLAGS_REG)
5092         (compare
5093           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5094                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5095           (const_int 0)))                       
5096    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5097         (plus:DI (match_dup 1) (match_dup 2)))]
5098   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5099    && ix86_binary_operator_ok (PLUS, DImode, operands)
5100    /* Current assemblers are broken and do not allow @GOTOFF in
5101       ought but a memory context.  */
5102    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5104   switch (get_attr_type (insn))
5105     {
5106     case TYPE_INCDEC:
5107       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5108       if (operands[2] == const1_rtx)
5109         return "inc{q}\t%0";
5110       else
5111         {
5112           gcc_assert (operands[2] == constm1_rtx);
5113           return "dec{q}\t%0";
5114         }
5116     default:
5117       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5118       /* ???? We ought to handle there the 32bit case too
5119          - do we need new constraint?  */
5120       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5121          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5122       if (GET_CODE (operands[2]) == CONST_INT
5123           /* Avoid overflows.  */
5124           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5125           && (INTVAL (operands[2]) == 128
5126               || (INTVAL (operands[2]) < 0
5127                   && INTVAL (operands[2]) != -128)))
5128         {
5129           operands[2] = GEN_INT (-INTVAL (operands[2]));
5130           return "sub{q}\t{%2, %0|%0, %2}";
5131         }
5132       return "add{q}\t{%2, %0|%0, %2}";
5133     }
5135   [(set (attr "type")
5136      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5137         (const_string "incdec")
5138         (const_string "alu")))
5139    (set_attr "mode" "DI")])
5141 (define_insn "*adddi_3_rex64"
5142   [(set (reg FLAGS_REG)
5143         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5144                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5145    (clobber (match_scratch:DI 0 "=r"))]
5146   "TARGET_64BIT
5147    && ix86_match_ccmode (insn, CCZmode)
5148    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5149    /* Current assemblers are broken and do not allow @GOTOFF in
5150       ought but a memory context.  */
5151    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5153   switch (get_attr_type (insn))
5154     {
5155     case TYPE_INCDEC:
5156       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5157       if (operands[2] == const1_rtx)
5158         return "inc{q}\t%0";
5159       else
5160         {
5161           gcc_assert (operands[2] == constm1_rtx);
5162           return "dec{q}\t%0";
5163         }
5165     default:
5166       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5167       /* ???? We ought to handle there the 32bit case too
5168          - do we need new constraint?  */
5169       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5170          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5171       if (GET_CODE (operands[2]) == CONST_INT
5172           /* Avoid overflows.  */
5173           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5174           && (INTVAL (operands[2]) == 128
5175               || (INTVAL (operands[2]) < 0
5176                   && INTVAL (operands[2]) != -128)))
5177         {
5178           operands[2] = GEN_INT (-INTVAL (operands[2]));
5179           return "sub{q}\t{%2, %0|%0, %2}";
5180         }
5181       return "add{q}\t{%2, %0|%0, %2}";
5182     }
5184   [(set (attr "type")
5185      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5186         (const_string "incdec")
5187         (const_string "alu")))
5188    (set_attr "mode" "DI")])
5190 ; For comparisons against 1, -1 and 128, we may generate better code
5191 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5192 ; is matched then.  We can't accept general immediate, because for
5193 ; case of overflows,  the result is messed up.
5194 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5195 ; when negated.
5196 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5197 ; only for comparisons not depending on it.
5198 (define_insn "*adddi_4_rex64"
5199   [(set (reg FLAGS_REG)
5200         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5201                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5202    (clobber (match_scratch:DI 0 "=rm"))]
5203   "TARGET_64BIT
5204    &&  ix86_match_ccmode (insn, CCGCmode)"
5206   switch (get_attr_type (insn))
5207     {
5208     case TYPE_INCDEC:
5209       if (operands[2] == constm1_rtx)
5210         return "inc{q}\t%0";
5211       else
5212         {
5213           gcc_assert (operands[2] == const1_rtx);
5214           return "dec{q}\t%0";
5215         }
5217     default:
5218       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5219       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5220          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5221       if ((INTVAL (operands[2]) == -128
5222            || (INTVAL (operands[2]) > 0
5223                && INTVAL (operands[2]) != 128))
5224           /* Avoid overflows.  */
5225           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5226         return "sub{q}\t{%2, %0|%0, %2}";
5227       operands[2] = GEN_INT (-INTVAL (operands[2]));
5228       return "add{q}\t{%2, %0|%0, %2}";
5229     }
5231   [(set (attr "type")
5232      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5233         (const_string "incdec")
5234         (const_string "alu")))
5235    (set_attr "mode" "DI")])
5237 (define_insn "*adddi_5_rex64"
5238   [(set (reg FLAGS_REG)
5239         (compare
5240           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5241                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5242           (const_int 0)))                       
5243    (clobber (match_scratch:DI 0 "=r"))]
5244   "TARGET_64BIT
5245    && ix86_match_ccmode (insn, CCGOCmode)
5246    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5247    /* Current assemblers are broken and do not allow @GOTOFF in
5248       ought but a memory context.  */
5249    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5251   switch (get_attr_type (insn))
5252     {
5253     case TYPE_INCDEC:
5254       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5255       if (operands[2] == const1_rtx)
5256         return "inc{q}\t%0";
5257       else
5258         {
5259           gcc_assert (operands[2] == constm1_rtx);
5260           return "dec{q}\t%0";
5261         }
5263     default:
5264       gcc_assert (rtx_equal_p (operands[0], operands[1]));
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")])
5287 (define_insn "*addsi_1"
5288   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5289         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5290                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5291    (clobber (reg:CC FLAGS_REG))]
5292   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5294   switch (get_attr_type (insn))
5295     {
5296     case TYPE_LEA:
5297       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5298       return "lea{l}\t{%a2, %0|%0, %a2}";
5300     case TYPE_INCDEC:
5301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5302       if (operands[2] == const1_rtx)
5303         return "inc{l}\t%0";
5304       else
5305         {
5306           gcc_assert (operands[2] == constm1_rtx);
5307           return "dec{l}\t%0";
5308         }
5310     default:
5311       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5313       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5314          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5315       if (GET_CODE (operands[2]) == CONST_INT
5316           && (INTVAL (operands[2]) == 128
5317               || (INTVAL (operands[2]) < 0
5318                   && INTVAL (operands[2]) != -128)))
5319         {
5320           operands[2] = GEN_INT (-INTVAL (operands[2]));
5321           return "sub{l}\t{%2, %0|%0, %2}";
5322         }
5323       return "add{l}\t{%2, %0|%0, %2}";
5324     }
5326   [(set (attr "type")
5327      (cond [(eq_attr "alternative" "2")
5328               (const_string "lea")
5329             ; Current assemblers are broken and do not allow @GOTOFF in
5330             ; ought but a memory context.
5331             (match_operand:SI 2 "pic_symbolic_operand" "")
5332               (const_string "lea")
5333             (match_operand:SI 2 "incdec_operand" "")
5334               (const_string "incdec")
5335            ]
5336            (const_string "alu")))
5337    (set_attr "mode" "SI")])
5339 ;; Convert lea to the lea pattern to avoid flags dependency.
5340 (define_split
5341   [(set (match_operand 0 "register_operand" "")
5342         (plus (match_operand 1 "register_operand" "")
5343               (match_operand 2 "nonmemory_operand" "")))
5344    (clobber (reg:CC FLAGS_REG))]
5345   "reload_completed
5346    && true_regnum (operands[0]) != true_regnum (operands[1])"
5347   [(const_int 0)]
5349   rtx pat;
5350   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5351      may confuse gen_lowpart.  */
5352   if (GET_MODE (operands[0]) != Pmode)
5353     {
5354       operands[1] = gen_lowpart (Pmode, operands[1]);
5355       operands[2] = gen_lowpart (Pmode, operands[2]);
5356     }
5357   operands[0] = gen_lowpart (SImode, operands[0]);
5358   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5359   if (Pmode != SImode)
5360     pat = gen_rtx_SUBREG (SImode, pat, 0);
5361   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5362   DONE;
5365 ;; It may seem that nonimmediate operand is proper one for operand 1.
5366 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5367 ;; we take care in ix86_binary_operator_ok to not allow two memory
5368 ;; operands so proper swapping will be done in reload.  This allow
5369 ;; patterns constructed from addsi_1 to match.
5370 (define_insn "addsi_1_zext"
5371   [(set (match_operand:DI 0 "register_operand" "=r,r")
5372         (zero_extend:DI
5373           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5374                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5375    (clobber (reg:CC FLAGS_REG))]
5376   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5378   switch (get_attr_type (insn))
5379     {
5380     case TYPE_LEA:
5381       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5382       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5384     case TYPE_INCDEC:
5385       if (operands[2] == const1_rtx)
5386         return "inc{l}\t%k0";
5387       else
5388         {
5389           gcc_assert (operands[2] == constm1_rtx);
5390           return "dec{l}\t%k0";
5391         }
5393     default:
5394       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5395          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5396       if (GET_CODE (operands[2]) == CONST_INT
5397           && (INTVAL (operands[2]) == 128
5398               || (INTVAL (operands[2]) < 0
5399                   && INTVAL (operands[2]) != -128)))
5400         {
5401           operands[2] = GEN_INT (-INTVAL (operands[2]));
5402           return "sub{l}\t{%2, %k0|%k0, %2}";
5403         }
5404       return "add{l}\t{%2, %k0|%k0, %2}";
5405     }
5407   [(set (attr "type")
5408      (cond [(eq_attr "alternative" "1")
5409               (const_string "lea")
5410             ; Current assemblers are broken and do not allow @GOTOFF in
5411             ; ought but a memory context.
5412             (match_operand:SI 2 "pic_symbolic_operand" "")
5413               (const_string "lea")
5414             (match_operand:SI 2 "incdec_operand" "")
5415               (const_string "incdec")
5416            ]
5417            (const_string "alu")))
5418    (set_attr "mode" "SI")])
5420 ;; Convert lea to the lea pattern to avoid flags dependency.
5421 (define_split
5422   [(set (match_operand:DI 0 "register_operand" "")
5423         (zero_extend:DI
5424           (plus:SI (match_operand:SI 1 "register_operand" "")
5425                    (match_operand:SI 2 "nonmemory_operand" ""))))
5426    (clobber (reg:CC FLAGS_REG))]
5427   "TARGET_64BIT && reload_completed
5428    && true_regnum (operands[0]) != true_regnum (operands[1])"
5429   [(set (match_dup 0)
5430         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5432   operands[1] = gen_lowpart (Pmode, operands[1]);
5433   operands[2] = gen_lowpart (Pmode, operands[2]);
5436 (define_insn "*addsi_2"
5437   [(set (reg FLAGS_REG)
5438         (compare
5439           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5440                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5441           (const_int 0)))                       
5442    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5443         (plus:SI (match_dup 1) (match_dup 2)))]
5444   "ix86_match_ccmode (insn, CCGOCmode)
5445    && ix86_binary_operator_ok (PLUS, SImode, operands)
5446    /* Current assemblers are broken and do not allow @GOTOFF in
5447       ought but a memory context.  */
5448    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5450   switch (get_attr_type (insn))
5451     {
5452     case TYPE_INCDEC:
5453       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5454       if (operands[2] == const1_rtx)
5455         return "inc{l}\t%0";
5456       else
5457         {
5458           gcc_assert (operands[2] == constm1_rtx);
5459           return "dec{l}\t%0";
5460         }
5462     default:
5463       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5464       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5465          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5466       if (GET_CODE (operands[2]) == CONST_INT
5467           && (INTVAL (operands[2]) == 128
5468               || (INTVAL (operands[2]) < 0
5469                   && INTVAL (operands[2]) != -128)))
5470         {
5471           operands[2] = GEN_INT (-INTVAL (operands[2]));
5472           return "sub{l}\t{%2, %0|%0, %2}";
5473         }
5474       return "add{l}\t{%2, %0|%0, %2}";
5475     }
5477   [(set (attr "type")
5478      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5479         (const_string "incdec")
5480         (const_string "alu")))
5481    (set_attr "mode" "SI")])
5483 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5484 (define_insn "*addsi_2_zext"
5485   [(set (reg FLAGS_REG)
5486         (compare
5487           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5488                    (match_operand:SI 2 "general_operand" "rmni"))
5489           (const_int 0)))                       
5490    (set (match_operand:DI 0 "register_operand" "=r")
5491         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5492   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5493    && ix86_binary_operator_ok (PLUS, SImode, operands)
5494    /* Current assemblers are broken and do not allow @GOTOFF in
5495       ought but a memory context.  */
5496    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5498   switch (get_attr_type (insn))
5499     {
5500     case TYPE_INCDEC:
5501       if (operands[2] == const1_rtx)
5502         return "inc{l}\t%k0";
5503       else
5504         {
5505           gcc_assert (operands[2] == constm1_rtx);
5506           return "dec{l}\t%k0";
5507         }
5509     default:
5510       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5511          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5512       if (GET_CODE (operands[2]) == CONST_INT
5513           && (INTVAL (operands[2]) == 128
5514               || (INTVAL (operands[2]) < 0
5515                   && INTVAL (operands[2]) != -128)))
5516         {
5517           operands[2] = GEN_INT (-INTVAL (operands[2]));
5518           return "sub{l}\t{%2, %k0|%k0, %2}";
5519         }
5520       return "add{l}\t{%2, %k0|%k0, %2}";
5521     }
5523   [(set (attr "type")
5524      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5525         (const_string "incdec")
5526         (const_string "alu")))
5527    (set_attr "mode" "SI")])
5529 (define_insn "*addsi_3"
5530   [(set (reg FLAGS_REG)
5531         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5532                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5533    (clobber (match_scratch:SI 0 "=r"))]
5534   "ix86_match_ccmode (insn, CCZmode)
5535    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5536    /* Current assemblers are broken and do not allow @GOTOFF in
5537       ought but a memory context.  */
5538    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5540   switch (get_attr_type (insn))
5541     {
5542     case TYPE_INCDEC:
5543       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5544       if (operands[2] == const1_rtx)
5545         return "inc{l}\t%0";
5546       else
5547         {
5548           gcc_assert (operands[2] == constm1_rtx);
5549           return "dec{l}\t%0";
5550         }
5552     default:
5553       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5554       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5555          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5556       if (GET_CODE (operands[2]) == CONST_INT
5557           && (INTVAL (operands[2]) == 128
5558               || (INTVAL (operands[2]) < 0
5559                   && INTVAL (operands[2]) != -128)))
5560         {
5561           operands[2] = GEN_INT (-INTVAL (operands[2]));
5562           return "sub{l}\t{%2, %0|%0, %2}";
5563         }
5564       return "add{l}\t{%2, %0|%0, %2}";
5565     }
5567   [(set (attr "type")
5568      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5569         (const_string "incdec")
5570         (const_string "alu")))
5571    (set_attr "mode" "SI")])
5573 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5574 (define_insn "*addsi_3_zext"
5575   [(set (reg FLAGS_REG)
5576         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5577                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5578    (set (match_operand:DI 0 "register_operand" "=r")
5579         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5580   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5581    && ix86_binary_operator_ok (PLUS, SImode, operands)
5582    /* Current assemblers are broken and do not allow @GOTOFF in
5583       ought but a memory context.  */
5584    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5586   switch (get_attr_type (insn))
5587     {
5588     case TYPE_INCDEC:
5589       if (operands[2] == const1_rtx)
5590         return "inc{l}\t%k0";
5591       else
5592         {
5593           gcc_assert (operands[2] == constm1_rtx);
5594           return "dec{l}\t%k0";
5595         }
5597     default:
5598       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5599          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5600       if (GET_CODE (operands[2]) == CONST_INT
5601           && (INTVAL (operands[2]) == 128
5602               || (INTVAL (operands[2]) < 0
5603                   && INTVAL (operands[2]) != -128)))
5604         {
5605           operands[2] = GEN_INT (-INTVAL (operands[2]));
5606           return "sub{l}\t{%2, %k0|%k0, %2}";
5607         }
5608       return "add{l}\t{%2, %k0|%k0, %2}";
5609     }
5611   [(set (attr "type")
5612      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5613         (const_string "incdec")
5614         (const_string "alu")))
5615    (set_attr "mode" "SI")])
5617 ; For comparisons against 1, -1 and 128, we may generate better code
5618 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5619 ; is matched then.  We can't accept general immediate, because for
5620 ; case of overflows,  the result is messed up.
5621 ; This pattern also don't hold of 0x80000000, since the value overflows
5622 ; when negated.
5623 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5624 ; only for comparisons not depending on it.
5625 (define_insn "*addsi_4"
5626   [(set (reg FLAGS_REG)
5627         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5628                  (match_operand:SI 2 "const_int_operand" "n")))
5629    (clobber (match_scratch:SI 0 "=rm"))]
5630   "ix86_match_ccmode (insn, CCGCmode)
5631    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5633   switch (get_attr_type (insn))
5634     {
5635     case TYPE_INCDEC:
5636       if (operands[2] == constm1_rtx)
5637         return "inc{l}\t%0";
5638       else
5639         {
5640           gcc_assert (operands[2] == const1_rtx);
5641           return "dec{l}\t%0";
5642         }
5644     default:
5645       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5646       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5647          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5648       if ((INTVAL (operands[2]) == -128
5649            || (INTVAL (operands[2]) > 0
5650                && INTVAL (operands[2]) != 128)))
5651         return "sub{l}\t{%2, %0|%0, %2}";
5652       operands[2] = GEN_INT (-INTVAL (operands[2]));
5653       return "add{l}\t{%2, %0|%0, %2}";
5654     }
5656   [(set (attr "type")
5657      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5658         (const_string "incdec")
5659         (const_string "alu")))
5660    (set_attr "mode" "SI")])
5662 (define_insn "*addsi_5"
5663   [(set (reg FLAGS_REG)
5664         (compare
5665           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5666                    (match_operand:SI 2 "general_operand" "rmni"))
5667           (const_int 0)))                       
5668    (clobber (match_scratch:SI 0 "=r"))]
5669   "ix86_match_ccmode (insn, CCGOCmode)
5670    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5671    /* Current assemblers are broken and do not allow @GOTOFF in
5672       ought but a memory context.  */
5673    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5675   switch (get_attr_type (insn))
5676     {
5677     case TYPE_INCDEC:
5678       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5679       if (operands[2] == const1_rtx)
5680         return "inc{l}\t%0";
5681       else
5682         {
5683           gcc_assert (operands[2] == constm1_rtx);
5684           return "dec{l}\t%0";
5685         }
5687     default:
5688       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5690          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5691       if (GET_CODE (operands[2]) == CONST_INT
5692           && (INTVAL (operands[2]) == 128
5693               || (INTVAL (operands[2]) < 0
5694                   && INTVAL (operands[2]) != -128)))
5695         {
5696           operands[2] = GEN_INT (-INTVAL (operands[2]));
5697           return "sub{l}\t{%2, %0|%0, %2}";
5698         }
5699       return "add{l}\t{%2, %0|%0, %2}";
5700     }
5702   [(set (attr "type")
5703      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5704         (const_string "incdec")
5705         (const_string "alu")))
5706    (set_attr "mode" "SI")])
5708 (define_expand "addhi3"
5709   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5710                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5711                             (match_operand:HI 2 "general_operand" "")))
5712               (clobber (reg:CC FLAGS_REG))])]
5713   "TARGET_HIMODE_MATH"
5714   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5716 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5717 ;; type optimizations enabled by define-splits.  This is not important
5718 ;; for PII, and in fact harmful because of partial register stalls.
5720 (define_insn "*addhi_1_lea"
5721   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5722         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5723                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5724    (clobber (reg:CC FLAGS_REG))]
5725   "!TARGET_PARTIAL_REG_STALL
5726    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5728   switch (get_attr_type (insn))
5729     {
5730     case TYPE_LEA:
5731       return "#";
5732     case TYPE_INCDEC:
5733       if (operands[2] == const1_rtx)
5734         return "inc{w}\t%0";
5735       else
5736         {
5737           gcc_assert (operands[2] == constm1_rtx);
5738           return "dec{w}\t%0";
5739         }
5741     default:
5742       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5743          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5744       if (GET_CODE (operands[2]) == CONST_INT
5745           && (INTVAL (operands[2]) == 128
5746               || (INTVAL (operands[2]) < 0
5747                   && INTVAL (operands[2]) != -128)))
5748         {
5749           operands[2] = GEN_INT (-INTVAL (operands[2]));
5750           return "sub{w}\t{%2, %0|%0, %2}";
5751         }
5752       return "add{w}\t{%2, %0|%0, %2}";
5753     }
5755   [(set (attr "type")
5756      (if_then_else (eq_attr "alternative" "2")
5757         (const_string "lea")
5758         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5759            (const_string "incdec")
5760            (const_string "alu"))))
5761    (set_attr "mode" "HI,HI,SI")])
5763 (define_insn "*addhi_1"
5764   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5765         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5766                  (match_operand:HI 2 "general_operand" "ri,rm")))
5767    (clobber (reg:CC FLAGS_REG))]
5768   "TARGET_PARTIAL_REG_STALL
5769    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5771   switch (get_attr_type (insn))
5772     {
5773     case TYPE_INCDEC:
5774       if (operands[2] == const1_rtx)
5775         return "inc{w}\t%0";
5776       else
5777         {
5778           gcc_assert (operands[2] == constm1_rtx);
5779           return "dec{w}\t%0";
5780         }
5782     default:
5783       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5784          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5785       if (GET_CODE (operands[2]) == CONST_INT
5786           && (INTVAL (operands[2]) == 128
5787               || (INTVAL (operands[2]) < 0
5788                   && INTVAL (operands[2]) != -128)))
5789         {
5790           operands[2] = GEN_INT (-INTVAL (operands[2]));
5791           return "sub{w}\t{%2, %0|%0, %2}";
5792         }
5793       return "add{w}\t{%2, %0|%0, %2}";
5794     }
5796   [(set (attr "type")
5797      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5798         (const_string "incdec")
5799         (const_string "alu")))
5800    (set_attr "mode" "HI")])
5802 (define_insn "*addhi_2"
5803   [(set (reg FLAGS_REG)
5804         (compare
5805           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5806                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5807           (const_int 0)))                       
5808    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5809         (plus:HI (match_dup 1) (match_dup 2)))]
5810   "ix86_match_ccmode (insn, CCGOCmode)
5811    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5813   switch (get_attr_type (insn))
5814     {
5815     case TYPE_INCDEC:
5816       if (operands[2] == const1_rtx)
5817         return "inc{w}\t%0";
5818       else
5819         {
5820           gcc_assert (operands[2] == constm1_rtx);
5821           return "dec{w}\t%0";
5822         }
5824     default:
5825       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5826          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5827       if (GET_CODE (operands[2]) == CONST_INT
5828           && (INTVAL (operands[2]) == 128
5829               || (INTVAL (operands[2]) < 0
5830                   && INTVAL (operands[2]) != -128)))
5831         {
5832           operands[2] = GEN_INT (-INTVAL (operands[2]));
5833           return "sub{w}\t{%2, %0|%0, %2}";
5834         }
5835       return "add{w}\t{%2, %0|%0, %2}";
5836     }
5838   [(set (attr "type")
5839      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5840         (const_string "incdec")
5841         (const_string "alu")))
5842    (set_attr "mode" "HI")])
5844 (define_insn "*addhi_3"
5845   [(set (reg FLAGS_REG)
5846         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5847                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5848    (clobber (match_scratch:HI 0 "=r"))]
5849   "ix86_match_ccmode (insn, CCZmode)
5850    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5852   switch (get_attr_type (insn))
5853     {
5854     case TYPE_INCDEC:
5855       if (operands[2] == const1_rtx)
5856         return "inc{w}\t%0";
5857       else
5858         {
5859           gcc_assert (operands[2] == constm1_rtx);
5860           return "dec{w}\t%0";
5861         }
5863     default:
5864       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5865          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5866       if (GET_CODE (operands[2]) == CONST_INT
5867           && (INTVAL (operands[2]) == 128
5868               || (INTVAL (operands[2]) < 0
5869                   && INTVAL (operands[2]) != -128)))
5870         {
5871           operands[2] = GEN_INT (-INTVAL (operands[2]));
5872           return "sub{w}\t{%2, %0|%0, %2}";
5873         }
5874       return "add{w}\t{%2, %0|%0, %2}";
5875     }
5877   [(set (attr "type")
5878      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5879         (const_string "incdec")
5880         (const_string "alu")))
5881    (set_attr "mode" "HI")])
5883 ; See comments above addsi_4 for details.
5884 (define_insn "*addhi_4"
5885   [(set (reg FLAGS_REG)
5886         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5887                  (match_operand:HI 2 "const_int_operand" "n")))
5888    (clobber (match_scratch:HI 0 "=rm"))]
5889   "ix86_match_ccmode (insn, CCGCmode)
5890    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5892   switch (get_attr_type (insn))
5893     {
5894     case TYPE_INCDEC:
5895       if (operands[2] == constm1_rtx)
5896         return "inc{w}\t%0";
5897       else
5898         {
5899           gcc_assert (operands[2] == const1_rtx);
5900           return "dec{w}\t%0";
5901         }
5903     default:
5904       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5905       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5906          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5907       if ((INTVAL (operands[2]) == -128
5908            || (INTVAL (operands[2]) > 0
5909                && INTVAL (operands[2]) != 128)))
5910         return "sub{w}\t{%2, %0|%0, %2}";
5911       operands[2] = GEN_INT (-INTVAL (operands[2]));
5912       return "add{w}\t{%2, %0|%0, %2}";
5913     }
5915   [(set (attr "type")
5916      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5917         (const_string "incdec")
5918         (const_string "alu")))
5919    (set_attr "mode" "SI")])
5922 (define_insn "*addhi_5"
5923   [(set (reg FLAGS_REG)
5924         (compare
5925           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5926                    (match_operand:HI 2 "general_operand" "rmni"))
5927           (const_int 0)))                       
5928    (clobber (match_scratch:HI 0 "=r"))]
5929   "ix86_match_ccmode (insn, CCGOCmode)
5930    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5932   switch (get_attr_type (insn))
5933     {
5934     case TYPE_INCDEC:
5935       if (operands[2] == const1_rtx)
5936         return "inc{w}\t%0";
5937       else
5938         {
5939           gcc_assert (operands[2] == constm1_rtx);
5940           return "dec{w}\t%0";
5941         }
5943     default:
5944       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5945          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5946       if (GET_CODE (operands[2]) == CONST_INT
5947           && (INTVAL (operands[2]) == 128
5948               || (INTVAL (operands[2]) < 0
5949                   && INTVAL (operands[2]) != -128)))
5950         {
5951           operands[2] = GEN_INT (-INTVAL (operands[2]));
5952           return "sub{w}\t{%2, %0|%0, %2}";
5953         }
5954       return "add{w}\t{%2, %0|%0, %2}";
5955     }
5957   [(set (attr "type")
5958      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5959         (const_string "incdec")
5960         (const_string "alu")))
5961    (set_attr "mode" "HI")])
5963 (define_expand "addqi3"
5964   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5965                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5966                             (match_operand:QI 2 "general_operand" "")))
5967               (clobber (reg:CC FLAGS_REG))])]
5968   "TARGET_QIMODE_MATH"
5969   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5971 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5972 (define_insn "*addqi_1_lea"
5973   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5974         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5975                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
5976    (clobber (reg:CC FLAGS_REG))]
5977   "!TARGET_PARTIAL_REG_STALL
5978    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5980   int widen = (which_alternative == 2);
5981   switch (get_attr_type (insn))
5982     {
5983     case TYPE_LEA:
5984       return "#";
5985     case TYPE_INCDEC:
5986       if (operands[2] == const1_rtx)
5987         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5988       else
5989         {
5990           gcc_assert (operands[2] == constm1_rtx);
5991           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5992         }
5994     default:
5995       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5996          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5997       if (GET_CODE (operands[2]) == CONST_INT
5998           && (INTVAL (operands[2]) == 128
5999               || (INTVAL (operands[2]) < 0
6000                   && INTVAL (operands[2]) != -128)))
6001         {
6002           operands[2] = GEN_INT (-INTVAL (operands[2]));
6003           if (widen)
6004             return "sub{l}\t{%2, %k0|%k0, %2}";
6005           else
6006             return "sub{b}\t{%2, %0|%0, %2}";
6007         }
6008       if (widen)
6009         return "add{l}\t{%k2, %k0|%k0, %k2}";
6010       else
6011         return "add{b}\t{%2, %0|%0, %2}";
6012     }
6014   [(set (attr "type")
6015      (if_then_else (eq_attr "alternative" "3")
6016         (const_string "lea")
6017         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6018            (const_string "incdec")
6019            (const_string "alu"))))
6020    (set_attr "mode" "QI,QI,SI,SI")])
6022 (define_insn "*addqi_1"
6023   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6024         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6025                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6026    (clobber (reg:CC FLAGS_REG))]
6027   "TARGET_PARTIAL_REG_STALL
6028    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6030   int widen = (which_alternative == 2);
6031   switch (get_attr_type (insn))
6032     {
6033     case TYPE_INCDEC:
6034       if (operands[2] == const1_rtx)
6035         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6036       else
6037         {
6038           gcc_assert (operands[2] == constm1_rtx);
6039           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6040         }
6042     default:
6043       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6044          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6045       if (GET_CODE (operands[2]) == CONST_INT
6046           && (INTVAL (operands[2]) == 128
6047               || (INTVAL (operands[2]) < 0
6048                   && INTVAL (operands[2]) != -128)))
6049         {
6050           operands[2] = GEN_INT (-INTVAL (operands[2]));
6051           if (widen)
6052             return "sub{l}\t{%2, %k0|%k0, %2}";
6053           else
6054             return "sub{b}\t{%2, %0|%0, %2}";
6055         }
6056       if (widen)
6057         return "add{l}\t{%k2, %k0|%k0, %k2}";
6058       else
6059         return "add{b}\t{%2, %0|%0, %2}";
6060     }
6062   [(set (attr "type")
6063      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6064         (const_string "incdec")
6065         (const_string "alu")))
6066    (set_attr "mode" "QI,QI,SI")])
6068 (define_insn "*addqi_1_slp"
6069   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6070         (plus:QI (match_dup 0)
6071                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6072    (clobber (reg:CC FLAGS_REG))]
6073   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6074    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6076   switch (get_attr_type (insn))
6077     {
6078     case TYPE_INCDEC:
6079       if (operands[1] == const1_rtx)
6080         return "inc{b}\t%0";
6081       else
6082         {
6083           gcc_assert (operands[1] == constm1_rtx);
6084           return "dec{b}\t%0";
6085         }
6087     default:
6088       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6089       if (GET_CODE (operands[1]) == CONST_INT
6090           && INTVAL (operands[1]) < 0)
6091         {
6092           operands[1] = GEN_INT (-INTVAL (operands[1]));
6093           return "sub{b}\t{%1, %0|%0, %1}";
6094         }
6095       return "add{b}\t{%1, %0|%0, %1}";
6096     }
6098   [(set (attr "type")
6099      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6100         (const_string "incdec")
6101         (const_string "alu1")))
6102    (set (attr "memory")
6103      (if_then_else (match_operand 1 "memory_operand" "")
6104         (const_string "load")
6105         (const_string "none")))
6106    (set_attr "mode" "QI")])
6108 (define_insn "*addqi_2"
6109   [(set (reg FLAGS_REG)
6110         (compare
6111           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6112                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6113           (const_int 0)))
6114    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6115         (plus:QI (match_dup 1) (match_dup 2)))]
6116   "ix86_match_ccmode (insn, CCGOCmode)
6117    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6119   switch (get_attr_type (insn))
6120     {
6121     case TYPE_INCDEC:
6122       if (operands[2] == const1_rtx)
6123         return "inc{b}\t%0";
6124       else
6125         {
6126           gcc_assert (operands[2] == constm1_rtx
6127                       || (GET_CODE (operands[2]) == CONST_INT
6128                           && INTVAL (operands[2]) == 255));
6129           return "dec{b}\t%0";
6130         }
6132     default:
6133       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6134       if (GET_CODE (operands[2]) == CONST_INT
6135           && INTVAL (operands[2]) < 0)
6136         {
6137           operands[2] = GEN_INT (-INTVAL (operands[2]));
6138           return "sub{b}\t{%2, %0|%0, %2}";
6139         }
6140       return "add{b}\t{%2, %0|%0, %2}";
6141     }
6143   [(set (attr "type")
6144      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6145         (const_string "incdec")
6146         (const_string "alu")))
6147    (set_attr "mode" "QI")])
6149 (define_insn "*addqi_3"
6150   [(set (reg FLAGS_REG)
6151         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6152                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6153    (clobber (match_scratch:QI 0 "=q"))]
6154   "ix86_match_ccmode (insn, CCZmode)
6155    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6157   switch (get_attr_type (insn))
6158     {
6159     case TYPE_INCDEC:
6160       if (operands[2] == const1_rtx)
6161         return "inc{b}\t%0";
6162       else
6163         {
6164           gcc_assert (operands[2] == constm1_rtx
6165                       || (GET_CODE (operands[2]) == CONST_INT
6166                           && INTVAL (operands[2]) == 255));
6167           return "dec{b}\t%0";
6168         }
6170     default:
6171       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6172       if (GET_CODE (operands[2]) == CONST_INT
6173           && INTVAL (operands[2]) < 0)
6174         {
6175           operands[2] = GEN_INT (-INTVAL (operands[2]));
6176           return "sub{b}\t{%2, %0|%0, %2}";
6177         }
6178       return "add{b}\t{%2, %0|%0, %2}";
6179     }
6181   [(set (attr "type")
6182      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6183         (const_string "incdec")
6184         (const_string "alu")))
6185    (set_attr "mode" "QI")])
6187 ; See comments above addsi_4 for details.
6188 (define_insn "*addqi_4"
6189   [(set (reg FLAGS_REG)
6190         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6191                  (match_operand:QI 2 "const_int_operand" "n")))
6192    (clobber (match_scratch:QI 0 "=qm"))]
6193   "ix86_match_ccmode (insn, CCGCmode)
6194    && (INTVAL (operands[2]) & 0xff) != 0x80"
6196   switch (get_attr_type (insn))
6197     {
6198     case TYPE_INCDEC:
6199       if (operands[2] == constm1_rtx
6200           || (GET_CODE (operands[2]) == CONST_INT
6201               && INTVAL (operands[2]) == 255))
6202         return "inc{b}\t%0";
6203       else
6204         {
6205           gcc_assert (operands[2] == const1_rtx);
6206           return "dec{b}\t%0";
6207         }
6209     default:
6210       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6211       if (INTVAL (operands[2]) < 0)
6212         {
6213           operands[2] = GEN_INT (-INTVAL (operands[2]));
6214           return "add{b}\t{%2, %0|%0, %2}";
6215         }
6216       return "sub{b}\t{%2, %0|%0, %2}";
6217     }
6219   [(set (attr "type")
6220      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6221         (const_string "incdec")
6222         (const_string "alu")))
6223    (set_attr "mode" "QI")])
6226 (define_insn "*addqi_5"
6227   [(set (reg FLAGS_REG)
6228         (compare
6229           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6230                    (match_operand:QI 2 "general_operand" "qmni"))
6231           (const_int 0)))
6232    (clobber (match_scratch:QI 0 "=q"))]
6233   "ix86_match_ccmode (insn, CCGOCmode)
6234    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6236   switch (get_attr_type (insn))
6237     {
6238     case TYPE_INCDEC:
6239       if (operands[2] == const1_rtx)
6240         return "inc{b}\t%0";
6241       else
6242         {
6243           gcc_assert (operands[2] == constm1_rtx
6244                       || (GET_CODE (operands[2]) == CONST_INT
6245                           && INTVAL (operands[2]) == 255));
6246           return "dec{b}\t%0";
6247         }
6249     default:
6250       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6251       if (GET_CODE (operands[2]) == CONST_INT
6252           && INTVAL (operands[2]) < 0)
6253         {
6254           operands[2] = GEN_INT (-INTVAL (operands[2]));
6255           return "sub{b}\t{%2, %0|%0, %2}";
6256         }
6257       return "add{b}\t{%2, %0|%0, %2}";
6258     }
6260   [(set (attr "type")
6261      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6262         (const_string "incdec")
6263         (const_string "alu")))
6264    (set_attr "mode" "QI")])
6267 (define_insn "addqi_ext_1"
6268   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6269                          (const_int 8)
6270                          (const_int 8))
6271         (plus:SI
6272           (zero_extract:SI
6273             (match_operand 1 "ext_register_operand" "0")
6274             (const_int 8)
6275             (const_int 8))
6276           (match_operand:QI 2 "general_operand" "Qmn")))
6277    (clobber (reg:CC FLAGS_REG))]
6278   "!TARGET_64BIT"
6280   switch (get_attr_type (insn))
6281     {
6282     case TYPE_INCDEC:
6283       if (operands[2] == const1_rtx)
6284         return "inc{b}\t%h0";
6285       else
6286         {
6287           gcc_assert (operands[2] == constm1_rtx
6288                       || (GET_CODE (operands[2]) == CONST_INT
6289                           && INTVAL (operands[2]) == 255));
6290           return "dec{b}\t%h0";
6291         }
6293     default:
6294       return "add{b}\t{%2, %h0|%h0, %2}";
6295     }
6297   [(set (attr "type")
6298      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6299         (const_string "incdec")
6300         (const_string "alu")))
6301    (set_attr "mode" "QI")])
6303 (define_insn "*addqi_ext_1_rex64"
6304   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6305                          (const_int 8)
6306                          (const_int 8))
6307         (plus:SI
6308           (zero_extract:SI
6309             (match_operand 1 "ext_register_operand" "0")
6310             (const_int 8)
6311             (const_int 8))
6312           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6313    (clobber (reg:CC FLAGS_REG))]
6314   "TARGET_64BIT"
6316   switch (get_attr_type (insn))
6317     {
6318     case TYPE_INCDEC:
6319       if (operands[2] == const1_rtx)
6320         return "inc{b}\t%h0";
6321       else
6322         {
6323           gcc_assert (operands[2] == constm1_rtx
6324                       || (GET_CODE (operands[2]) == CONST_INT
6325                           && INTVAL (operands[2]) == 255));
6326           return "dec{b}\t%h0";
6327         }
6329     default:
6330       return "add{b}\t{%2, %h0|%h0, %2}";
6331     }
6333   [(set (attr "type")
6334      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6335         (const_string "incdec")
6336         (const_string "alu")))
6337    (set_attr "mode" "QI")])
6339 (define_insn "*addqi_ext_2"
6340   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6341                          (const_int 8)
6342                          (const_int 8))
6343         (plus:SI
6344           (zero_extract:SI
6345             (match_operand 1 "ext_register_operand" "%0")
6346             (const_int 8)
6347             (const_int 8))
6348           (zero_extract:SI
6349             (match_operand 2 "ext_register_operand" "Q")
6350             (const_int 8)
6351             (const_int 8))))
6352    (clobber (reg:CC FLAGS_REG))]
6353   ""
6354   "add{b}\t{%h2, %h0|%h0, %h2}"
6355   [(set_attr "type" "alu")
6356    (set_attr "mode" "QI")])
6358 ;; The patterns that match these are at the end of this file.
6360 (define_expand "addxf3"
6361   [(set (match_operand:XF 0 "register_operand" "")
6362         (plus:XF (match_operand:XF 1 "register_operand" "")
6363                  (match_operand:XF 2 "register_operand" "")))]
6364   "TARGET_80387"
6365   "")
6367 (define_expand "adddf3"
6368   [(set (match_operand:DF 0 "register_operand" "")
6369         (plus:DF (match_operand:DF 1 "register_operand" "")
6370                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6371   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6372   "")
6374 (define_expand "addsf3"
6375   [(set (match_operand:SF 0 "register_operand" "")
6376         (plus:SF (match_operand:SF 1 "register_operand" "")
6377                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6378   "TARGET_80387 || TARGET_SSE_MATH"
6379   "")
6381 ;; Subtract instructions
6383 ;; %%% splits for subsidi3
6385 (define_expand "subdi3"
6386   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6387                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6388                              (match_operand:DI 2 "x86_64_general_operand" "")))
6389               (clobber (reg:CC FLAGS_REG))])]
6390   ""
6391   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6393 (define_insn "*subdi3_1"
6394   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6395         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6396                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6397    (clobber (reg:CC FLAGS_REG))]
6398   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6399   "#")
6401 (define_split
6402   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6403         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6404                   (match_operand:DI 2 "general_operand" "")))
6405    (clobber (reg:CC FLAGS_REG))]
6406   "!TARGET_64BIT && reload_completed"
6407   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6408               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6409    (parallel [(set (match_dup 3)
6410                    (minus:SI (match_dup 4)
6411                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6412                                       (match_dup 5))))
6413               (clobber (reg:CC FLAGS_REG))])]
6414   "split_di (operands+0, 1, operands+0, operands+3);
6415    split_di (operands+1, 1, operands+1, operands+4);
6416    split_di (operands+2, 1, operands+2, operands+5);")
6418 (define_insn "subdi3_carry_rex64"
6419   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6420           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6421             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6422                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6423    (clobber (reg:CC FLAGS_REG))]
6424   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6425   "sbb{q}\t{%2, %0|%0, %2}"
6426   [(set_attr "type" "alu")
6427    (set_attr "pent_pair" "pu")
6428    (set_attr "mode" "DI")])
6430 (define_insn "*subdi_1_rex64"
6431   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6432         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6433                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6434    (clobber (reg:CC FLAGS_REG))]
6435   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6436   "sub{q}\t{%2, %0|%0, %2}"
6437   [(set_attr "type" "alu")
6438    (set_attr "mode" "DI")])
6440 (define_insn "*subdi_2_rex64"
6441   [(set (reg FLAGS_REG)
6442         (compare
6443           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6444                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6445           (const_int 0)))
6446    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6447         (minus:DI (match_dup 1) (match_dup 2)))]
6448   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6449    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6450   "sub{q}\t{%2, %0|%0, %2}"
6451   [(set_attr "type" "alu")
6452    (set_attr "mode" "DI")])
6454 (define_insn "*subdi_3_rex63"
6455   [(set (reg FLAGS_REG)
6456         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6457                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6458    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6459         (minus:DI (match_dup 1) (match_dup 2)))]
6460   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6461    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6462   "sub{q}\t{%2, %0|%0, %2}"
6463   [(set_attr "type" "alu")
6464    (set_attr "mode" "DI")])
6466 (define_insn "subqi3_carry"
6467   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6468           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6469             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6470                (match_operand:QI 2 "general_operand" "qi,qm"))))
6471    (clobber (reg:CC FLAGS_REG))]
6472   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6473   "sbb{b}\t{%2, %0|%0, %2}"
6474   [(set_attr "type" "alu")
6475    (set_attr "pent_pair" "pu")
6476    (set_attr "mode" "QI")])
6478 (define_insn "subhi3_carry"
6479   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6480           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6481             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6482                (match_operand:HI 2 "general_operand" "ri,rm"))))
6483    (clobber (reg:CC FLAGS_REG))]
6484   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6485   "sbb{w}\t{%2, %0|%0, %2}"
6486   [(set_attr "type" "alu")
6487    (set_attr "pent_pair" "pu")
6488    (set_attr "mode" "HI")])
6490 (define_insn "subsi3_carry"
6491   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6492           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6493             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6494                (match_operand:SI 2 "general_operand" "ri,rm"))))
6495    (clobber (reg:CC FLAGS_REG))]
6496   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6497   "sbb{l}\t{%2, %0|%0, %2}"
6498   [(set_attr "type" "alu")
6499    (set_attr "pent_pair" "pu")
6500    (set_attr "mode" "SI")])
6502 (define_insn "subsi3_carry_zext"
6503   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6504           (zero_extend:DI
6505             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6506               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6507                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6508    (clobber (reg:CC FLAGS_REG))]
6509   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6510   "sbb{l}\t{%2, %k0|%k0, %2}"
6511   [(set_attr "type" "alu")
6512    (set_attr "pent_pair" "pu")
6513    (set_attr "mode" "SI")])
6515 (define_expand "subsi3"
6516   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6517                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6518                              (match_operand:SI 2 "general_operand" "")))
6519               (clobber (reg:CC FLAGS_REG))])]
6520   ""
6521   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6523 (define_insn "*subsi_1"
6524   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6525         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6526                   (match_operand:SI 2 "general_operand" "ri,rm")))
6527    (clobber (reg:CC FLAGS_REG))]
6528   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6529   "sub{l}\t{%2, %0|%0, %2}"
6530   [(set_attr "type" "alu")
6531    (set_attr "mode" "SI")])
6533 (define_insn "*subsi_1_zext"
6534   [(set (match_operand:DI 0 "register_operand" "=r")
6535         (zero_extend:DI
6536           (minus:SI (match_operand:SI 1 "register_operand" "0")
6537                     (match_operand:SI 2 "general_operand" "rim"))))
6538    (clobber (reg:CC FLAGS_REG))]
6539   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6540   "sub{l}\t{%2, %k0|%k0, %2}"
6541   [(set_attr "type" "alu")
6542    (set_attr "mode" "SI")])
6544 (define_insn "*subsi_2"
6545   [(set (reg FLAGS_REG)
6546         (compare
6547           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6548                     (match_operand:SI 2 "general_operand" "ri,rm"))
6549           (const_int 0)))
6550    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6551         (minus:SI (match_dup 1) (match_dup 2)))]
6552   "ix86_match_ccmode (insn, CCGOCmode)
6553    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554   "sub{l}\t{%2, %0|%0, %2}"
6555   [(set_attr "type" "alu")
6556    (set_attr "mode" "SI")])
6558 (define_insn "*subsi_2_zext"
6559   [(set (reg FLAGS_REG)
6560         (compare
6561           (minus:SI (match_operand:SI 1 "register_operand" "0")
6562                     (match_operand:SI 2 "general_operand" "rim"))
6563           (const_int 0)))
6564    (set (match_operand:DI 0 "register_operand" "=r")
6565         (zero_extend:DI
6566           (minus:SI (match_dup 1)
6567                     (match_dup 2))))]
6568   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6569    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6570   "sub{l}\t{%2, %k0|%k0, %2}"
6571   [(set_attr "type" "alu")
6572    (set_attr "mode" "SI")])
6574 (define_insn "*subsi_3"
6575   [(set (reg FLAGS_REG)
6576         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6577                  (match_operand:SI 2 "general_operand" "ri,rm")))
6578    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6579         (minus:SI (match_dup 1) (match_dup 2)))]
6580   "ix86_match_ccmode (insn, CCmode)
6581    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6582   "sub{l}\t{%2, %0|%0, %2}"
6583   [(set_attr "type" "alu")
6584    (set_attr "mode" "SI")])
6586 (define_insn "*subsi_3_zext"
6587   [(set (reg FLAGS_REG)
6588         (compare (match_operand:SI 1 "register_operand" "0")
6589                  (match_operand:SI 2 "general_operand" "rim")))
6590    (set (match_operand:DI 0 "register_operand" "=r")
6591         (zero_extend:DI
6592           (minus:SI (match_dup 1)
6593                     (match_dup 2))))]
6594   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6595    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6596   "sub{q}\t{%2, %0|%0, %2}"
6597   [(set_attr "type" "alu")
6598    (set_attr "mode" "DI")])
6600 (define_expand "subhi3"
6601   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6602                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6603                              (match_operand:HI 2 "general_operand" "")))
6604               (clobber (reg:CC FLAGS_REG))])]
6605   "TARGET_HIMODE_MATH"
6606   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6608 (define_insn "*subhi_1"
6609   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6610         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6611                   (match_operand:HI 2 "general_operand" "ri,rm")))
6612    (clobber (reg:CC FLAGS_REG))]
6613   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6614   "sub{w}\t{%2, %0|%0, %2}"
6615   [(set_attr "type" "alu")
6616    (set_attr "mode" "HI")])
6618 (define_insn "*subhi_2"
6619   [(set (reg FLAGS_REG)
6620         (compare
6621           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6622                     (match_operand:HI 2 "general_operand" "ri,rm"))
6623           (const_int 0)))
6624    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6625         (minus:HI (match_dup 1) (match_dup 2)))]
6626   "ix86_match_ccmode (insn, CCGOCmode)
6627    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6628   "sub{w}\t{%2, %0|%0, %2}"
6629   [(set_attr "type" "alu")
6630    (set_attr "mode" "HI")])
6632 (define_insn "*subhi_3"
6633   [(set (reg FLAGS_REG)
6634         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6635                  (match_operand:HI 2 "general_operand" "ri,rm")))
6636    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6637         (minus:HI (match_dup 1) (match_dup 2)))]
6638   "ix86_match_ccmode (insn, CCmode)
6639    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6640   "sub{w}\t{%2, %0|%0, %2}"
6641   [(set_attr "type" "alu")
6642    (set_attr "mode" "HI")])
6644 (define_expand "subqi3"
6645   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6646                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6647                              (match_operand:QI 2 "general_operand" "")))
6648               (clobber (reg:CC FLAGS_REG))])]
6649   "TARGET_QIMODE_MATH"
6650   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6652 (define_insn "*subqi_1"
6653   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6654         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6655                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6656    (clobber (reg:CC FLAGS_REG))]
6657   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6658   "sub{b}\t{%2, %0|%0, %2}"
6659   [(set_attr "type" "alu")
6660    (set_attr "mode" "QI")])
6662 (define_insn "*subqi_1_slp"
6663   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6664         (minus:QI (match_dup 0)
6665                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6666    (clobber (reg:CC FLAGS_REG))]
6667   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6668    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6669   "sub{b}\t{%1, %0|%0, %1}"
6670   [(set_attr "type" "alu1")
6671    (set_attr "mode" "QI")])
6673 (define_insn "*subqi_2"
6674   [(set (reg FLAGS_REG)
6675         (compare
6676           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6677                     (match_operand:QI 2 "general_operand" "qi,qm"))
6678           (const_int 0)))
6679    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6680         (minus:HI (match_dup 1) (match_dup 2)))]
6681   "ix86_match_ccmode (insn, CCGOCmode)
6682    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6683   "sub{b}\t{%2, %0|%0, %2}"
6684   [(set_attr "type" "alu")
6685    (set_attr "mode" "QI")])
6687 (define_insn "*subqi_3"
6688   [(set (reg FLAGS_REG)
6689         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6690                  (match_operand:QI 2 "general_operand" "qi,qm")))
6691    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6692         (minus:HI (match_dup 1) (match_dup 2)))]
6693   "ix86_match_ccmode (insn, CCmode)
6694    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6695   "sub{b}\t{%2, %0|%0, %2}"
6696   [(set_attr "type" "alu")
6697    (set_attr "mode" "QI")])
6699 ;; The patterns that match these are at the end of this file.
6701 (define_expand "subxf3"
6702   [(set (match_operand:XF 0 "register_operand" "")
6703         (minus:XF (match_operand:XF 1 "register_operand" "")
6704                   (match_operand:XF 2 "register_operand" "")))]
6705   "TARGET_80387"
6706   "")
6708 (define_expand "subdf3"
6709   [(set (match_operand:DF 0 "register_operand" "")
6710         (minus:DF (match_operand:DF 1 "register_operand" "")
6711                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6712   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6713   "")
6715 (define_expand "subsf3"
6716   [(set (match_operand:SF 0 "register_operand" "")
6717         (minus:SF (match_operand:SF 1 "register_operand" "")
6718                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6719   "TARGET_80387 || TARGET_SSE_MATH"
6720   "")
6722 ;; Multiply instructions
6724 (define_expand "muldi3"
6725   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6726                    (mult:DI (match_operand:DI 1 "register_operand" "")
6727                             (match_operand:DI 2 "x86_64_general_operand" "")))
6728               (clobber (reg:CC FLAGS_REG))])]
6729   "TARGET_64BIT"
6730   "")
6732 (define_insn "*muldi3_1_rex64"
6733   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6734         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6735                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6736    (clobber (reg:CC FLAGS_REG))]
6737   "TARGET_64BIT
6738    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6739   "@
6740    imul{q}\t{%2, %1, %0|%0, %1, %2}
6741    imul{q}\t{%2, %1, %0|%0, %1, %2}
6742    imul{q}\t{%2, %0|%0, %2}"
6743   [(set_attr "type" "imul")
6744    (set_attr "prefix_0f" "0,0,1")
6745    (set (attr "athlon_decode")
6746         (cond [(eq_attr "cpu" "athlon")
6747                   (const_string "vector")
6748                (eq_attr "alternative" "1")
6749                   (const_string "vector")
6750                (and (eq_attr "alternative" "2")
6751                     (match_operand 1 "memory_operand" ""))
6752                   (const_string "vector")]
6753               (const_string "direct")))
6754    (set_attr "mode" "DI")])
6756 (define_expand "mulsi3"
6757   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6758                    (mult:SI (match_operand:SI 1 "register_operand" "")
6759                             (match_operand:SI 2 "general_operand" "")))
6760               (clobber (reg:CC FLAGS_REG))])]
6761   ""
6762   "")
6764 (define_insn "*mulsi3_1"
6765   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6766         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6767                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6768    (clobber (reg:CC FLAGS_REG))]
6769   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6770   "@
6771    imul{l}\t{%2, %1, %0|%0, %1, %2}
6772    imul{l}\t{%2, %1, %0|%0, %1, %2}
6773    imul{l}\t{%2, %0|%0, %2}"
6774   [(set_attr "type" "imul")
6775    (set_attr "prefix_0f" "0,0,1")
6776    (set (attr "athlon_decode")
6777         (cond [(eq_attr "cpu" "athlon")
6778                   (const_string "vector")
6779                (eq_attr "alternative" "1")
6780                   (const_string "vector")
6781                (and (eq_attr "alternative" "2")
6782                     (match_operand 1 "memory_operand" ""))
6783                   (const_string "vector")]
6784               (const_string "direct")))
6785    (set_attr "mode" "SI")])
6787 (define_insn "*mulsi3_1_zext"
6788   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6789         (zero_extend:DI
6790           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6791                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6792    (clobber (reg:CC FLAGS_REG))]
6793   "TARGET_64BIT
6794    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6795   "@
6796    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6797    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6798    imul{l}\t{%2, %k0|%k0, %2}"
6799   [(set_attr "type" "imul")
6800    (set_attr "prefix_0f" "0,0,1")
6801    (set (attr "athlon_decode")
6802         (cond [(eq_attr "cpu" "athlon")
6803                   (const_string "vector")
6804                (eq_attr "alternative" "1")
6805                   (const_string "vector")
6806                (and (eq_attr "alternative" "2")
6807                     (match_operand 1 "memory_operand" ""))
6808                   (const_string "vector")]
6809               (const_string "direct")))
6810    (set_attr "mode" "SI")])
6812 (define_expand "mulhi3"
6813   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6814                    (mult:HI (match_operand:HI 1 "register_operand" "")
6815                             (match_operand:HI 2 "general_operand" "")))
6816               (clobber (reg:CC FLAGS_REG))])]
6817   "TARGET_HIMODE_MATH"
6818   "")
6820 (define_insn "*mulhi3_1"
6821   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6822         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6823                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6824    (clobber (reg:CC FLAGS_REG))]
6825   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6826   "@
6827    imul{w}\t{%2, %1, %0|%0, %1, %2}
6828    imul{w}\t{%2, %1, %0|%0, %1, %2}
6829    imul{w}\t{%2, %0|%0, %2}"
6830   [(set_attr "type" "imul")
6831    (set_attr "prefix_0f" "0,0,1")
6832    (set (attr "athlon_decode")
6833         (cond [(eq_attr "cpu" "athlon")
6834                   (const_string "vector")
6835                (eq_attr "alternative" "1,2")
6836                   (const_string "vector")]
6837               (const_string "direct")))
6838    (set_attr "mode" "HI")])
6840 (define_expand "mulqi3"
6841   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6842                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6843                             (match_operand:QI 2 "register_operand" "")))
6844               (clobber (reg:CC FLAGS_REG))])]
6845   "TARGET_QIMODE_MATH"
6846   "")
6848 (define_insn "*mulqi3_1"
6849   [(set (match_operand:QI 0 "register_operand" "=a")
6850         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6851                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6852    (clobber (reg:CC FLAGS_REG))]
6853   "TARGET_QIMODE_MATH
6854    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6855   "mul{b}\t%2"
6856   [(set_attr "type" "imul")
6857    (set_attr "length_immediate" "0")
6858    (set (attr "athlon_decode")
6859      (if_then_else (eq_attr "cpu" "athlon")
6860         (const_string "vector")
6861         (const_string "direct")))
6862    (set_attr "mode" "QI")])
6864 (define_expand "umulqihi3"
6865   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6866                    (mult:HI (zero_extend:HI
6867                               (match_operand:QI 1 "nonimmediate_operand" ""))
6868                             (zero_extend:HI
6869                               (match_operand:QI 2 "register_operand" ""))))
6870               (clobber (reg:CC FLAGS_REG))])]
6871   "TARGET_QIMODE_MATH"
6872   "")
6874 (define_insn "*umulqihi3_1"
6875   [(set (match_operand:HI 0 "register_operand" "=a")
6876         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6877                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6878    (clobber (reg:CC FLAGS_REG))]
6879   "TARGET_QIMODE_MATH
6880    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6881   "mul{b}\t%2"
6882   [(set_attr "type" "imul")
6883    (set_attr "length_immediate" "0")
6884    (set (attr "athlon_decode")
6885      (if_then_else (eq_attr "cpu" "athlon")
6886         (const_string "vector")
6887         (const_string "direct")))
6888    (set_attr "mode" "QI")])
6890 (define_expand "mulqihi3"
6891   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6892                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6893                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6894               (clobber (reg:CC FLAGS_REG))])]
6895   "TARGET_QIMODE_MATH"
6896   "")
6898 (define_insn "*mulqihi3_insn"
6899   [(set (match_operand:HI 0 "register_operand" "=a")
6900         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6901                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6902    (clobber (reg:CC FLAGS_REG))]
6903   "TARGET_QIMODE_MATH
6904    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6905   "imul{b}\t%2"
6906   [(set_attr "type" "imul")
6907    (set_attr "length_immediate" "0")
6908    (set (attr "athlon_decode")
6909      (if_then_else (eq_attr "cpu" "athlon")
6910         (const_string "vector")
6911         (const_string "direct")))
6912    (set_attr "mode" "QI")])
6914 (define_expand "umulditi3"
6915   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6916                    (mult:TI (zero_extend:TI
6917                               (match_operand:DI 1 "nonimmediate_operand" ""))
6918                             (zero_extend:TI
6919                               (match_operand:DI 2 "register_operand" ""))))
6920               (clobber (reg:CC FLAGS_REG))])]
6921   "TARGET_64BIT"
6922   "")
6924 (define_insn "*umulditi3_insn"
6925   [(set (match_operand:TI 0 "register_operand" "=A")
6926         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6927                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6928    (clobber (reg:CC FLAGS_REG))]
6929   "TARGET_64BIT
6930    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6931   "mul{q}\t%2"
6932   [(set_attr "type" "imul")
6933    (set_attr "length_immediate" "0")
6934    (set (attr "athlon_decode")
6935      (if_then_else (eq_attr "cpu" "athlon")
6936         (const_string "vector")
6937         (const_string "double")))
6938    (set_attr "mode" "DI")])
6940 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6941 (define_expand "umulsidi3"
6942   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6943                    (mult:DI (zero_extend:DI
6944                               (match_operand:SI 1 "nonimmediate_operand" ""))
6945                             (zero_extend:DI
6946                               (match_operand:SI 2 "register_operand" ""))))
6947               (clobber (reg:CC FLAGS_REG))])]
6948   "!TARGET_64BIT"
6949   "")
6951 (define_insn "*umulsidi3_insn"
6952   [(set (match_operand:DI 0 "register_operand" "=A")
6953         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6954                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6955    (clobber (reg:CC FLAGS_REG))]
6956   "!TARGET_64BIT
6957    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6958   "mul{l}\t%2"
6959   [(set_attr "type" "imul")
6960    (set_attr "length_immediate" "0")
6961    (set (attr "athlon_decode")
6962      (if_then_else (eq_attr "cpu" "athlon")
6963         (const_string "vector")
6964         (const_string "double")))
6965    (set_attr "mode" "SI")])
6967 (define_expand "mulditi3"
6968   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6969                    (mult:TI (sign_extend:TI
6970                               (match_operand:DI 1 "nonimmediate_operand" ""))
6971                             (sign_extend:TI
6972                               (match_operand:DI 2 "register_operand" ""))))
6973               (clobber (reg:CC FLAGS_REG))])]
6974   "TARGET_64BIT"
6975   "")
6977 (define_insn "*mulditi3_insn"
6978   [(set (match_operand:TI 0 "register_operand" "=A")
6979         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6980                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6981    (clobber (reg:CC FLAGS_REG))]
6982   "TARGET_64BIT
6983    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6984   "imul{q}\t%2"
6985   [(set_attr "type" "imul")
6986    (set_attr "length_immediate" "0")
6987    (set (attr "athlon_decode")
6988      (if_then_else (eq_attr "cpu" "athlon")
6989         (const_string "vector")
6990         (const_string "double")))
6991    (set_attr "mode" "DI")])
6993 (define_expand "mulsidi3"
6994   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6995                    (mult:DI (sign_extend:DI
6996                               (match_operand:SI 1 "nonimmediate_operand" ""))
6997                             (sign_extend:DI
6998                               (match_operand:SI 2 "register_operand" ""))))
6999               (clobber (reg:CC FLAGS_REG))])]
7000   "!TARGET_64BIT"
7001   "")
7003 (define_insn "*mulsidi3_insn"
7004   [(set (match_operand:DI 0 "register_operand" "=A")
7005         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7006                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7007    (clobber (reg:CC FLAGS_REG))]
7008   "!TARGET_64BIT
7009    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7010   "imul{l}\t%2"
7011   [(set_attr "type" "imul")
7012    (set_attr "length_immediate" "0")
7013    (set (attr "athlon_decode")
7014      (if_then_else (eq_attr "cpu" "athlon")
7015         (const_string "vector")
7016         (const_string "double")))
7017    (set_attr "mode" "SI")])
7019 (define_expand "umuldi3_highpart"
7020   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7021                    (truncate:DI
7022                      (lshiftrt:TI
7023                        (mult:TI (zero_extend:TI
7024                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7025                                 (zero_extend:TI
7026                                   (match_operand:DI 2 "register_operand" "")))
7027                        (const_int 64))))
7028               (clobber (match_scratch:DI 3 ""))
7029               (clobber (reg:CC FLAGS_REG))])]
7030   "TARGET_64BIT"
7031   "")
7033 (define_insn "*umuldi3_highpart_rex64"
7034   [(set (match_operand:DI 0 "register_operand" "=d")
7035         (truncate:DI
7036           (lshiftrt:TI
7037             (mult:TI (zero_extend:TI
7038                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7039                      (zero_extend:TI
7040                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7041             (const_int 64))))
7042    (clobber (match_scratch:DI 3 "=1"))
7043    (clobber (reg:CC FLAGS_REG))]
7044   "TARGET_64BIT
7045    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7046   "mul{q}\t%2"
7047   [(set_attr "type" "imul")
7048    (set_attr "length_immediate" "0")
7049    (set (attr "athlon_decode")
7050      (if_then_else (eq_attr "cpu" "athlon")
7051         (const_string "vector")
7052         (const_string "double")))
7053    (set_attr "mode" "DI")])
7055 (define_expand "umulsi3_highpart"
7056   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7057                    (truncate:SI
7058                      (lshiftrt:DI
7059                        (mult:DI (zero_extend:DI
7060                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7061                                 (zero_extend:DI
7062                                   (match_operand:SI 2 "register_operand" "")))
7063                        (const_int 32))))
7064               (clobber (match_scratch:SI 3 ""))
7065               (clobber (reg:CC FLAGS_REG))])]
7066   ""
7067   "")
7069 (define_insn "*umulsi3_highpart_insn"
7070   [(set (match_operand:SI 0 "register_operand" "=d")
7071         (truncate:SI
7072           (lshiftrt:DI
7073             (mult:DI (zero_extend:DI
7074                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7075                      (zero_extend:DI
7076                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7077             (const_int 32))))
7078    (clobber (match_scratch:SI 3 "=1"))
7079    (clobber (reg:CC FLAGS_REG))]
7080   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7081   "mul{l}\t%2"
7082   [(set_attr "type" "imul")
7083    (set_attr "length_immediate" "0")
7084    (set (attr "athlon_decode")
7085      (if_then_else (eq_attr "cpu" "athlon")
7086         (const_string "vector")
7087         (const_string "double")))
7088    (set_attr "mode" "SI")])
7090 (define_insn "*umulsi3_highpart_zext"
7091   [(set (match_operand:DI 0 "register_operand" "=d")
7092         (zero_extend:DI (truncate:SI
7093           (lshiftrt:DI
7094             (mult:DI (zero_extend:DI
7095                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7096                      (zero_extend:DI
7097                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7098             (const_int 32)))))
7099    (clobber (match_scratch:SI 3 "=1"))
7100    (clobber (reg:CC FLAGS_REG))]
7101   "TARGET_64BIT
7102    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7103   "mul{l}\t%2"
7104   [(set_attr "type" "imul")
7105    (set_attr "length_immediate" "0")
7106    (set (attr "athlon_decode")
7107      (if_then_else (eq_attr "cpu" "athlon")
7108         (const_string "vector")
7109         (const_string "double")))
7110    (set_attr "mode" "SI")])
7112 (define_expand "smuldi3_highpart"
7113   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7114                    (truncate:DI
7115                      (lshiftrt:TI
7116                        (mult:TI (sign_extend:TI
7117                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7118                                 (sign_extend:TI
7119                                   (match_operand:DI 2 "register_operand" "")))
7120                        (const_int 64))))
7121               (clobber (match_scratch:DI 3 ""))
7122               (clobber (reg:CC FLAGS_REG))])]
7123   "TARGET_64BIT"
7124   "")
7126 (define_insn "*smuldi3_highpart_rex64"
7127   [(set (match_operand:DI 0 "register_operand" "=d")
7128         (truncate:DI
7129           (lshiftrt:TI
7130             (mult:TI (sign_extend:TI
7131                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7132                      (sign_extend:TI
7133                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7134             (const_int 64))))
7135    (clobber (match_scratch:DI 3 "=1"))
7136    (clobber (reg:CC FLAGS_REG))]
7137   "TARGET_64BIT
7138    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7139   "imul{q}\t%2"
7140   [(set_attr "type" "imul")
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" "DI")])
7147 (define_expand "smulsi3_highpart"
7148   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7149                    (truncate:SI
7150                      (lshiftrt:DI
7151                        (mult:DI (sign_extend:DI
7152                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7153                                 (sign_extend:DI
7154                                   (match_operand:SI 2 "register_operand" "")))
7155                        (const_int 32))))
7156               (clobber (match_scratch:SI 3 ""))
7157               (clobber (reg:CC FLAGS_REG))])]
7158   ""
7159   "")
7161 (define_insn "*smulsi3_highpart_insn"
7162   [(set (match_operand:SI 0 "register_operand" "=d")
7163         (truncate:SI
7164           (lshiftrt:DI
7165             (mult:DI (sign_extend:DI
7166                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7167                      (sign_extend:DI
7168                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7169             (const_int 32))))
7170    (clobber (match_scratch:SI 3 "=1"))
7171    (clobber (reg:CC FLAGS_REG))]
7172   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7173   "imul{l}\t%2"
7174   [(set_attr "type" "imul")
7175    (set (attr "athlon_decode")
7176      (if_then_else (eq_attr "cpu" "athlon")
7177         (const_string "vector")
7178         (const_string "double")))
7179    (set_attr "mode" "SI")])
7181 (define_insn "*smulsi3_highpart_zext"
7182   [(set (match_operand:DI 0 "register_operand" "=d")
7183         (zero_extend:DI (truncate:SI
7184           (lshiftrt:DI
7185             (mult:DI (sign_extend:DI
7186                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7187                      (sign_extend:DI
7188                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7189             (const_int 32)))))
7190    (clobber (match_scratch:SI 3 "=1"))
7191    (clobber (reg:CC FLAGS_REG))]
7192   "TARGET_64BIT
7193    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7194   "imul{l}\t%2"
7195   [(set_attr "type" "imul")
7196    (set (attr "athlon_decode")
7197      (if_then_else (eq_attr "cpu" "athlon")
7198         (const_string "vector")
7199         (const_string "double")))
7200    (set_attr "mode" "SI")])
7202 ;; The patterns that match these are at the end of this file.
7204 (define_expand "mulxf3"
7205   [(set (match_operand:XF 0 "register_operand" "")
7206         (mult:XF (match_operand:XF 1 "register_operand" "")
7207                  (match_operand:XF 2 "register_operand" "")))]
7208   "TARGET_80387"
7209   "")
7211 (define_expand "muldf3"
7212   [(set (match_operand:DF 0 "register_operand" "")
7213         (mult:DF (match_operand:DF 1 "register_operand" "")
7214                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7215   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7216   "")
7218 (define_expand "mulsf3"
7219   [(set (match_operand:SF 0 "register_operand" "")
7220         (mult:SF (match_operand:SF 1 "register_operand" "")
7221                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7222   "TARGET_80387 || TARGET_SSE_MATH"
7223   "")
7225 ;; Divide instructions
7227 (define_insn "divqi3"
7228   [(set (match_operand:QI 0 "register_operand" "=a")
7229         (div:QI (match_operand:HI 1 "register_operand" "0")
7230                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7231    (clobber (reg:CC FLAGS_REG))]
7232   "TARGET_QIMODE_MATH"
7233   "idiv{b}\t%2"
7234   [(set_attr "type" "idiv")
7235    (set_attr "mode" "QI")])
7237 (define_insn "udivqi3"
7238   [(set (match_operand:QI 0 "register_operand" "=a")
7239         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7240                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7241    (clobber (reg:CC FLAGS_REG))]
7242   "TARGET_QIMODE_MATH"
7243   "div{b}\t%2"
7244   [(set_attr "type" "idiv")
7245    (set_attr "mode" "QI")])
7247 ;; The patterns that match these are at the end of this file.
7249 (define_expand "divxf3"
7250   [(set (match_operand:XF 0 "register_operand" "")
7251         (div:XF (match_operand:XF 1 "register_operand" "")
7252                 (match_operand:XF 2 "register_operand" "")))]
7253   "TARGET_80387"
7254   "")
7256 (define_expand "divdf3"
7257   [(set (match_operand:DF 0 "register_operand" "")
7258         (div:DF (match_operand:DF 1 "register_operand" "")
7259                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7260    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7261    "")
7263 (define_expand "divsf3"
7264   [(set (match_operand:SF 0 "register_operand" "")
7265         (div:SF (match_operand:SF 1 "register_operand" "")
7266                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7267   "TARGET_80387 || TARGET_SSE_MATH"
7268   "")
7270 ;; Remainder instructions.
7272 (define_expand "divmoddi4"
7273   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7274                    (div:DI (match_operand:DI 1 "register_operand" "")
7275                            (match_operand:DI 2 "nonimmediate_operand" "")))
7276               (set (match_operand:DI 3 "register_operand" "")
7277                    (mod:DI (match_dup 1) (match_dup 2)))
7278               (clobber (reg:CC FLAGS_REG))])]
7279   "TARGET_64BIT"
7280   "")
7282 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7283 ;; Penalize eax case slightly because it results in worse scheduling
7284 ;; of code.
7285 (define_insn "*divmoddi4_nocltd_rex64"
7286   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7287         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7288                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7289    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7290         (mod:DI (match_dup 2) (match_dup 3)))
7291    (clobber (reg:CC FLAGS_REG))]
7292   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7293   "#"
7294   [(set_attr "type" "multi")])
7296 (define_insn "*divmoddi4_cltd_rex64"
7297   [(set (match_operand:DI 0 "register_operand" "=a")
7298         (div:DI (match_operand:DI 2 "register_operand" "a")
7299                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7300    (set (match_operand:DI 1 "register_operand" "=&d")
7301         (mod:DI (match_dup 2) (match_dup 3)))
7302    (clobber (reg:CC FLAGS_REG))]
7303   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7304   "#"
7305   [(set_attr "type" "multi")])
7307 (define_insn "*divmoddi_noext_rex64"
7308   [(set (match_operand:DI 0 "register_operand" "=a")
7309         (div:DI (match_operand:DI 1 "register_operand" "0")
7310                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7311    (set (match_operand:DI 3 "register_operand" "=d")
7312         (mod:DI (match_dup 1) (match_dup 2)))
7313    (use (match_operand:DI 4 "register_operand" "3"))
7314    (clobber (reg:CC FLAGS_REG))]
7315   "TARGET_64BIT"
7316   "idiv{q}\t%2"
7317   [(set_attr "type" "idiv")
7318    (set_attr "mode" "DI")])
7320 (define_split
7321   [(set (match_operand:DI 0 "register_operand" "")
7322         (div:DI (match_operand:DI 1 "register_operand" "")
7323                 (match_operand:DI 2 "nonimmediate_operand" "")))
7324    (set (match_operand:DI 3 "register_operand" "")
7325         (mod:DI (match_dup 1) (match_dup 2)))
7326    (clobber (reg:CC FLAGS_REG))]
7327   "TARGET_64BIT && reload_completed"
7328   [(parallel [(set (match_dup 3)
7329                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7330               (clobber (reg:CC FLAGS_REG))])
7331    (parallel [(set (match_dup 0)
7332                    (div:DI (reg:DI 0) (match_dup 2)))
7333               (set (match_dup 3)
7334                    (mod:DI (reg:DI 0) (match_dup 2)))
7335               (use (match_dup 3))
7336               (clobber (reg:CC FLAGS_REG))])]
7338   /* Avoid use of cltd in favor of a mov+shift.  */
7339   if (!TARGET_USE_CLTD && !optimize_size)
7340     {
7341       if (true_regnum (operands[1]))
7342         emit_move_insn (operands[0], operands[1]);
7343       else
7344         emit_move_insn (operands[3], operands[1]);
7345       operands[4] = operands[3];
7346     }
7347   else
7348     {
7349       gcc_assert (!true_regnum (operands[1]));
7350       operands[4] = operands[1];
7351     }
7355 (define_expand "divmodsi4"
7356   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7357                    (div:SI (match_operand:SI 1 "register_operand" "")
7358                            (match_operand:SI 2 "nonimmediate_operand" "")))
7359               (set (match_operand:SI 3 "register_operand" "")
7360                    (mod:SI (match_dup 1) (match_dup 2)))
7361               (clobber (reg:CC FLAGS_REG))])]
7362   ""
7363   "")
7365 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7366 ;; Penalize eax case slightly because it results in worse scheduling
7367 ;; of code.
7368 (define_insn "*divmodsi4_nocltd"
7369   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7370         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7371                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7372    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7373         (mod:SI (match_dup 2) (match_dup 3)))
7374    (clobber (reg:CC FLAGS_REG))]
7375   "!optimize_size && !TARGET_USE_CLTD"
7376   "#"
7377   [(set_attr "type" "multi")])
7379 (define_insn "*divmodsi4_cltd"
7380   [(set (match_operand:SI 0 "register_operand" "=a")
7381         (div:SI (match_operand:SI 2 "register_operand" "a")
7382                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7383    (set (match_operand:SI 1 "register_operand" "=&d")
7384         (mod:SI (match_dup 2) (match_dup 3)))
7385    (clobber (reg:CC FLAGS_REG))]
7386   "optimize_size || TARGET_USE_CLTD"
7387   "#"
7388   [(set_attr "type" "multi")])
7390 (define_insn "*divmodsi_noext"
7391   [(set (match_operand:SI 0 "register_operand" "=a")
7392         (div:SI (match_operand:SI 1 "register_operand" "0")
7393                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7394    (set (match_operand:SI 3 "register_operand" "=d")
7395         (mod:SI (match_dup 1) (match_dup 2)))
7396    (use (match_operand:SI 4 "register_operand" "3"))
7397    (clobber (reg:CC FLAGS_REG))]
7398   ""
7399   "idiv{l}\t%2"
7400   [(set_attr "type" "idiv")
7401    (set_attr "mode" "SI")])
7403 (define_split
7404   [(set (match_operand:SI 0 "register_operand" "")
7405         (div:SI (match_operand:SI 1 "register_operand" "")
7406                 (match_operand:SI 2 "nonimmediate_operand" "")))
7407    (set (match_operand:SI 3 "register_operand" "")
7408         (mod:SI (match_dup 1) (match_dup 2)))
7409    (clobber (reg:CC FLAGS_REG))]
7410   "reload_completed"
7411   [(parallel [(set (match_dup 3)
7412                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7413               (clobber (reg:CC FLAGS_REG))])
7414    (parallel [(set (match_dup 0)
7415                    (div:SI (reg:SI 0) (match_dup 2)))
7416               (set (match_dup 3)
7417                    (mod:SI (reg:SI 0) (match_dup 2)))
7418               (use (match_dup 3))
7419               (clobber (reg:CC FLAGS_REG))])]
7421   /* Avoid use of cltd in favor of a mov+shift.  */
7422   if (!TARGET_USE_CLTD && !optimize_size)
7423     {
7424       if (true_regnum (operands[1]))
7425         emit_move_insn (operands[0], operands[1]);
7426       else
7427         emit_move_insn (operands[3], operands[1]);
7428       operands[4] = operands[3];
7429     }
7430   else
7431     {
7432       gcc_assert (!true_regnum (operands[1]));
7433       operands[4] = operands[1];
7434     }
7436 ;; %%% Split me.
7437 (define_insn "divmodhi4"
7438   [(set (match_operand:HI 0 "register_operand" "=a")
7439         (div:HI (match_operand:HI 1 "register_operand" "0")
7440                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7441    (set (match_operand:HI 3 "register_operand" "=&d")
7442         (mod:HI (match_dup 1) (match_dup 2)))
7443    (clobber (reg:CC FLAGS_REG))]
7444   "TARGET_HIMODE_MATH"
7445   "cwtd\;idiv{w}\t%2"
7446   [(set_attr "type" "multi")
7447    (set_attr "length_immediate" "0")
7448    (set_attr "mode" "SI")])
7450 (define_insn "udivmoddi4"
7451   [(set (match_operand:DI 0 "register_operand" "=a")
7452         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7453                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7454    (set (match_operand:DI 3 "register_operand" "=&d")
7455         (umod:DI (match_dup 1) (match_dup 2)))
7456    (clobber (reg:CC FLAGS_REG))]
7457   "TARGET_64BIT"
7458   "xor{q}\t%3, %3\;div{q}\t%2"
7459   [(set_attr "type" "multi")
7460    (set_attr "length_immediate" "0")
7461    (set_attr "mode" "DI")])
7463 (define_insn "*udivmoddi4_noext"
7464   [(set (match_operand:DI 0 "register_operand" "=a")
7465         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7466                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7467    (set (match_operand:DI 3 "register_operand" "=d")
7468         (umod:DI (match_dup 1) (match_dup 2)))
7469    (use (match_dup 3))
7470    (clobber (reg:CC FLAGS_REG))]
7471   "TARGET_64BIT"
7472   "div{q}\t%2"
7473   [(set_attr "type" "idiv")
7474    (set_attr "mode" "DI")])
7476 (define_split
7477   [(set (match_operand:DI 0 "register_operand" "")
7478         (udiv:DI (match_operand:DI 1 "register_operand" "")
7479                  (match_operand:DI 2 "nonimmediate_operand" "")))
7480    (set (match_operand:DI 3 "register_operand" "")
7481         (umod:DI (match_dup 1) (match_dup 2)))
7482    (clobber (reg:CC FLAGS_REG))]
7483   "TARGET_64BIT && reload_completed"
7484   [(set (match_dup 3) (const_int 0))
7485    (parallel [(set (match_dup 0)
7486                    (udiv:DI (match_dup 1) (match_dup 2)))
7487               (set (match_dup 3)
7488                    (umod:DI (match_dup 1) (match_dup 2)))
7489               (use (match_dup 3))
7490               (clobber (reg:CC FLAGS_REG))])]
7491   "")
7493 (define_insn "udivmodsi4"
7494   [(set (match_operand:SI 0 "register_operand" "=a")
7495         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7496                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7497    (set (match_operand:SI 3 "register_operand" "=&d")
7498         (umod:SI (match_dup 1) (match_dup 2)))
7499    (clobber (reg:CC FLAGS_REG))]
7500   ""
7501   "xor{l}\t%3, %3\;div{l}\t%2"
7502   [(set_attr "type" "multi")
7503    (set_attr "length_immediate" "0")
7504    (set_attr "mode" "SI")])
7506 (define_insn "*udivmodsi4_noext"
7507   [(set (match_operand:SI 0 "register_operand" "=a")
7508         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7509                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7510    (set (match_operand:SI 3 "register_operand" "=d")
7511         (umod:SI (match_dup 1) (match_dup 2)))
7512    (use (match_dup 3))
7513    (clobber (reg:CC FLAGS_REG))]
7514   ""
7515   "div{l}\t%2"
7516   [(set_attr "type" "idiv")
7517    (set_attr "mode" "SI")])
7519 (define_split
7520   [(set (match_operand:SI 0 "register_operand" "")
7521         (udiv:SI (match_operand:SI 1 "register_operand" "")
7522                  (match_operand:SI 2 "nonimmediate_operand" "")))
7523    (set (match_operand:SI 3 "register_operand" "")
7524         (umod:SI (match_dup 1) (match_dup 2)))
7525    (clobber (reg:CC FLAGS_REG))]
7526   "reload_completed"
7527   [(set (match_dup 3) (const_int 0))
7528    (parallel [(set (match_dup 0)
7529                    (udiv:SI (match_dup 1) (match_dup 2)))
7530               (set (match_dup 3)
7531                    (umod:SI (match_dup 1) (match_dup 2)))
7532               (use (match_dup 3))
7533               (clobber (reg:CC FLAGS_REG))])]
7534   "")
7536 (define_expand "udivmodhi4"
7537   [(set (match_dup 4) (const_int 0))
7538    (parallel [(set (match_operand:HI 0 "register_operand" "")
7539                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7540                             (match_operand:HI 2 "nonimmediate_operand" "")))
7541               (set (match_operand:HI 3 "register_operand" "")
7542                    (umod:HI (match_dup 1) (match_dup 2)))
7543               (use (match_dup 4))
7544               (clobber (reg:CC FLAGS_REG))])]
7545   "TARGET_HIMODE_MATH"
7546   "operands[4] = gen_reg_rtx (HImode);")
7548 (define_insn "*udivmodhi_noext"
7549   [(set (match_operand:HI 0 "register_operand" "=a")
7550         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7551                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7552    (set (match_operand:HI 3 "register_operand" "=d")
7553         (umod:HI (match_dup 1) (match_dup 2)))
7554    (use (match_operand:HI 4 "register_operand" "3"))
7555    (clobber (reg:CC FLAGS_REG))]
7556   ""
7557   "div{w}\t%2"
7558   [(set_attr "type" "idiv")
7559    (set_attr "mode" "HI")])
7561 ;; We cannot use div/idiv for double division, because it causes
7562 ;; "division by zero" on the overflow and that's not what we expect
7563 ;; from truncate.  Because true (non truncating) double division is
7564 ;; never generated, we can't create this insn anyway.
7566 ;(define_insn ""
7567 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7568 ;       (truncate:SI
7569 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7570 ;                  (zero_extend:DI
7571 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7572 ;   (set (match_operand:SI 3 "register_operand" "=d")
7573 ;       (truncate:SI
7574 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7575 ;   (clobber (reg:CC FLAGS_REG))]
7576 ;  ""
7577 ;  "div{l}\t{%2, %0|%0, %2}"
7578 ;  [(set_attr "type" "idiv")])
7580 ;;- Logical AND instructions
7582 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7583 ;; Note that this excludes ah.
7585 (define_insn "*testdi_1_rex64"
7586   [(set (reg FLAGS_REG)
7587         (compare
7588           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7589                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7590           (const_int 0)))]
7591   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7592    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7593   "@
7594    test{l}\t{%k1, %k0|%k0, %k1}
7595    test{l}\t{%k1, %k0|%k0, %k1}
7596    test{q}\t{%1, %0|%0, %1}
7597    test{q}\t{%1, %0|%0, %1}
7598    test{q}\t{%1, %0|%0, %1}"
7599   [(set_attr "type" "test")
7600    (set_attr "modrm" "0,1,0,1,1")
7601    (set_attr "mode" "SI,SI,DI,DI,DI")
7602    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7604 (define_insn "testsi_1"
7605   [(set (reg FLAGS_REG)
7606         (compare
7607           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7608                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7609           (const_int 0)))]
7610   "ix86_match_ccmode (insn, CCNOmode)
7611    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7612   "test{l}\t{%1, %0|%0, %1}"
7613   [(set_attr "type" "test")
7614    (set_attr "modrm" "0,1,1")
7615    (set_attr "mode" "SI")
7616    (set_attr "pent_pair" "uv,np,uv")])
7618 (define_expand "testsi_ccno_1"
7619   [(set (reg:CCNO FLAGS_REG)
7620         (compare:CCNO
7621           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7622                   (match_operand:SI 1 "nonmemory_operand" ""))
7623           (const_int 0)))]
7624   ""
7625   "")
7627 (define_insn "*testhi_1"
7628   [(set (reg FLAGS_REG)
7629         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7630                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7631                  (const_int 0)))]
7632   "ix86_match_ccmode (insn, CCNOmode)
7633    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7634   "test{w}\t{%1, %0|%0, %1}"
7635   [(set_attr "type" "test")
7636    (set_attr "modrm" "0,1,1")
7637    (set_attr "mode" "HI")
7638    (set_attr "pent_pair" "uv,np,uv")])
7640 (define_expand "testqi_ccz_1"
7641   [(set (reg:CCZ FLAGS_REG)
7642         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7643                              (match_operand:QI 1 "nonmemory_operand" ""))
7644                  (const_int 0)))]
7645   ""
7646   "")
7648 (define_insn "*testqi_1_maybe_si"
7649   [(set (reg FLAGS_REG)
7650         (compare
7651           (and:QI
7652             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7653             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7654           (const_int 0)))]
7655    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7656     && ix86_match_ccmode (insn,
7657                          GET_CODE (operands[1]) == CONST_INT
7658                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7660   if (which_alternative == 3)
7661     {
7662       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7663         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7664       return "test{l}\t{%1, %k0|%k0, %1}";
7665     }
7666   return "test{b}\t{%1, %0|%0, %1}";
7668   [(set_attr "type" "test")
7669    (set_attr "modrm" "0,1,1,1")
7670    (set_attr "mode" "QI,QI,QI,SI")
7671    (set_attr "pent_pair" "uv,np,uv,np")])
7673 (define_insn "*testqi_1"
7674   [(set (reg FLAGS_REG)
7675         (compare
7676           (and:QI
7677             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7678             (match_operand:QI 1 "general_operand" "n,n,qn"))
7679           (const_int 0)))]
7680   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7681    && ix86_match_ccmode (insn, CCNOmode)"
7682   "test{b}\t{%1, %0|%0, %1}"
7683   [(set_attr "type" "test")
7684    (set_attr "modrm" "0,1,1")
7685    (set_attr "mode" "QI")
7686    (set_attr "pent_pair" "uv,np,uv")])
7688 (define_expand "testqi_ext_ccno_0"
7689   [(set (reg:CCNO FLAGS_REG)
7690         (compare:CCNO
7691           (and:SI
7692             (zero_extract:SI
7693               (match_operand 0 "ext_register_operand" "")
7694               (const_int 8)
7695               (const_int 8))
7696             (match_operand 1 "const_int_operand" ""))
7697           (const_int 0)))]
7698   ""
7699   "")
7701 (define_insn "*testqi_ext_0"
7702   [(set (reg FLAGS_REG)
7703         (compare
7704           (and:SI
7705             (zero_extract:SI
7706               (match_operand 0 "ext_register_operand" "Q")
7707               (const_int 8)
7708               (const_int 8))
7709             (match_operand 1 "const_int_operand" "n"))
7710           (const_int 0)))]
7711   "ix86_match_ccmode (insn, CCNOmode)"
7712   "test{b}\t{%1, %h0|%h0, %1}"
7713   [(set_attr "type" "test")
7714    (set_attr "mode" "QI")
7715    (set_attr "length_immediate" "1")
7716    (set_attr "pent_pair" "np")])
7718 (define_insn "*testqi_ext_1"
7719   [(set (reg FLAGS_REG)
7720         (compare
7721           (and:SI
7722             (zero_extract:SI
7723               (match_operand 0 "ext_register_operand" "Q")
7724               (const_int 8)
7725               (const_int 8))
7726             (zero_extend:SI
7727               (match_operand:QI 1 "general_operand" "Qm")))
7728           (const_int 0)))]
7729   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7730    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7731   "test{b}\t{%1, %h0|%h0, %1}"
7732   [(set_attr "type" "test")
7733    (set_attr "mode" "QI")])
7735 (define_insn "*testqi_ext_1_rex64"
7736   [(set (reg FLAGS_REG)
7737         (compare
7738           (and:SI
7739             (zero_extract:SI
7740               (match_operand 0 "ext_register_operand" "Q")
7741               (const_int 8)
7742               (const_int 8))
7743             (zero_extend:SI
7744               (match_operand:QI 1 "register_operand" "Q")))
7745           (const_int 0)))]
7746   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7747   "test{b}\t{%1, %h0|%h0, %1}"
7748   [(set_attr "type" "test")
7749    (set_attr "mode" "QI")])
7751 (define_insn "*testqi_ext_2"
7752   [(set (reg FLAGS_REG)
7753         (compare
7754           (and:SI
7755             (zero_extract:SI
7756               (match_operand 0 "ext_register_operand" "Q")
7757               (const_int 8)
7758               (const_int 8))
7759             (zero_extract:SI
7760               (match_operand 1 "ext_register_operand" "Q")
7761               (const_int 8)
7762               (const_int 8)))
7763           (const_int 0)))]
7764   "ix86_match_ccmode (insn, CCNOmode)"
7765   "test{b}\t{%h1, %h0|%h0, %h1}"
7766   [(set_attr "type" "test")
7767    (set_attr "mode" "QI")])
7769 ;; Combine likes to form bit extractions for some tests.  Humor it.
7770 (define_insn "*testqi_ext_3"
7771   [(set (reg FLAGS_REG)
7772         (compare (zero_extract:SI
7773                    (match_operand 0 "nonimmediate_operand" "rm")
7774                    (match_operand:SI 1 "const_int_operand" "")
7775                    (match_operand:SI 2 "const_int_operand" ""))
7776                  (const_int 0)))]
7777   "ix86_match_ccmode (insn, CCNOmode)
7778    && (GET_MODE (operands[0]) == SImode
7779        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7780        || GET_MODE (operands[0]) == HImode
7781        || GET_MODE (operands[0]) == QImode)"
7782   "#")
7784 (define_insn "*testqi_ext_3_rex64"
7785   [(set (reg FLAGS_REG)
7786         (compare (zero_extract:DI
7787                    (match_operand 0 "nonimmediate_operand" "rm")
7788                    (match_operand:DI 1 "const_int_operand" "")
7789                    (match_operand:DI 2 "const_int_operand" ""))
7790                  (const_int 0)))]
7791   "TARGET_64BIT
7792    && ix86_match_ccmode (insn, CCNOmode)
7793    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7794    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7795    /* Ensure that resulting mask is zero or sign extended operand.  */
7796    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7797        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7798            && INTVAL (operands[1]) > 32))
7799    && (GET_MODE (operands[0]) == SImode
7800        || GET_MODE (operands[0]) == DImode
7801        || GET_MODE (operands[0]) == HImode
7802        || GET_MODE (operands[0]) == QImode)"
7803   "#")
7805 (define_split
7806   [(set (match_operand 0 "flags_reg_operand" "")
7807         (match_operator 1 "compare_operator"
7808           [(zero_extract
7809              (match_operand 2 "nonimmediate_operand" "")
7810              (match_operand 3 "const_int_operand" "")
7811              (match_operand 4 "const_int_operand" ""))
7812            (const_int 0)]))]
7813   "ix86_match_ccmode (insn, CCNOmode)"
7814   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7816   rtx val = operands[2];
7817   HOST_WIDE_INT len = INTVAL (operands[3]);
7818   HOST_WIDE_INT pos = INTVAL (operands[4]);
7819   HOST_WIDE_INT mask;
7820   enum machine_mode mode, submode;
7822   mode = GET_MODE (val);
7823   if (GET_CODE (val) == MEM)
7824     {
7825       /* ??? Combine likes to put non-volatile mem extractions in QImode
7826          no matter the size of the test.  So find a mode that works.  */
7827       if (! MEM_VOLATILE_P (val))
7828         {
7829           mode = smallest_mode_for_size (pos + len, MODE_INT);
7830           val = adjust_address (val, mode, 0);
7831         }
7832     }
7833   else if (GET_CODE (val) == SUBREG
7834            && (submode = GET_MODE (SUBREG_REG (val)),
7835                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7836            && pos + len <= GET_MODE_BITSIZE (submode))
7837     {
7838       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7839       mode = submode;
7840       val = SUBREG_REG (val);
7841     }
7842   else if (mode == HImode && pos + len <= 8)
7843     {
7844       /* Small HImode tests can be converted to QImode.  */
7845       mode = QImode;
7846       val = gen_lowpart (QImode, val);
7847     }
7849   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7850   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7852   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7855 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7856 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7857 ;; this is relatively important trick.
7858 ;; Do the conversion only post-reload to avoid limiting of the register class
7859 ;; to QI regs.
7860 (define_split
7861   [(set (match_operand 0 "flags_reg_operand" "")
7862         (match_operator 1 "compare_operator"
7863           [(and (match_operand 2 "register_operand" "")
7864                 (match_operand 3 "const_int_operand" ""))
7865            (const_int 0)]))]
7866    "reload_completed
7867     && QI_REG_P (operands[2])
7868     && GET_MODE (operands[2]) != QImode
7869     && ((ix86_match_ccmode (insn, CCZmode)
7870          && !(INTVAL (operands[3]) & ~(255 << 8)))
7871         || (ix86_match_ccmode (insn, CCNOmode)
7872             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7873   [(set (match_dup 0)
7874         (match_op_dup 1
7875           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7876                    (match_dup 3))
7877            (const_int 0)]))]
7878   "operands[2] = gen_lowpart (SImode, operands[2]);
7879    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7881 (define_split
7882   [(set (match_operand 0 "flags_reg_operand" "")
7883         (match_operator 1 "compare_operator"
7884           [(and (match_operand 2 "nonimmediate_operand" "")
7885                 (match_operand 3 "const_int_operand" ""))
7886            (const_int 0)]))]
7887    "reload_completed
7888     && GET_MODE (operands[2]) != QImode
7889     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7890     && ((ix86_match_ccmode (insn, CCZmode)
7891          && !(INTVAL (operands[3]) & ~255))
7892         || (ix86_match_ccmode (insn, CCNOmode)
7893             && !(INTVAL (operands[3]) & ~127)))"
7894   [(set (match_dup 0)
7895         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7896                          (const_int 0)]))]
7897   "operands[2] = gen_lowpart (QImode, operands[2]);
7898    operands[3] = gen_lowpart (QImode, operands[3]);")
7901 ;; %%% This used to optimize known byte-wide and operations to memory,
7902 ;; and sometimes to QImode registers.  If this is considered useful,
7903 ;; it should be done with splitters.
7905 (define_expand "anddi3"
7906   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7907         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7908                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7909    (clobber (reg:CC FLAGS_REG))]
7910   "TARGET_64BIT"
7911   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7913 (define_insn "*anddi_1_rex64"
7914   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7915         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7916                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7917    (clobber (reg:CC FLAGS_REG))]
7918   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7920   switch (get_attr_type (insn))
7921     {
7922     case TYPE_IMOVX:
7923       {
7924         enum machine_mode mode;
7926         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
7927         if (INTVAL (operands[2]) == 0xff)
7928           mode = QImode;
7929         else
7930           {
7931             gcc_assert (INTVAL (operands[2]) == 0xffff);
7932             mode = HImode;
7933           }
7934         
7935         operands[1] = gen_lowpart (mode, operands[1]);
7936         if (mode == QImode)
7937           return "movz{bq|x}\t{%1,%0|%0, %1}";
7938         else
7939           return "movz{wq|x}\t{%1,%0|%0, %1}";
7940       }
7942     default:
7943       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7944       if (get_attr_mode (insn) == MODE_SI)
7945         return "and{l}\t{%k2, %k0|%k0, %k2}";
7946       else
7947         return "and{q}\t{%2, %0|%0, %2}";
7948     }
7950   [(set_attr "type" "alu,alu,alu,imovx")
7951    (set_attr "length_immediate" "*,*,*,0")
7952    (set_attr "mode" "SI,DI,DI,DI")])
7954 (define_insn "*anddi_2"
7955   [(set (reg FLAGS_REG)
7956         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7957                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7958                  (const_int 0)))
7959    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7960         (and:DI (match_dup 1) (match_dup 2)))]
7961   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7962    && ix86_binary_operator_ok (AND, DImode, operands)"
7963   "@
7964    and{l}\t{%k2, %k0|%k0, %k2}
7965    and{q}\t{%2, %0|%0, %2}
7966    and{q}\t{%2, %0|%0, %2}"
7967   [(set_attr "type" "alu")
7968    (set_attr "mode" "SI,DI,DI")])
7970 (define_expand "andsi3"
7971   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7972         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7973                 (match_operand:SI 2 "general_operand" "")))
7974    (clobber (reg:CC FLAGS_REG))]
7975   ""
7976   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7978 (define_insn "*andsi_1"
7979   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7980         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7981                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7982    (clobber (reg:CC FLAGS_REG))]
7983   "ix86_binary_operator_ok (AND, SImode, operands)"
7985   switch (get_attr_type (insn))
7986     {
7987     case TYPE_IMOVX:
7988       {
7989         enum machine_mode mode;
7991         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
7992         if (INTVAL (operands[2]) == 0xff)
7993           mode = QImode;
7994         else
7995           {
7996             gcc_assert (INTVAL (operands[2]) == 0xffff);
7997             mode = HImode;
7998           }
7999         
8000         operands[1] = gen_lowpart (mode, operands[1]);
8001         if (mode == QImode)
8002           return "movz{bl|x}\t{%1,%0|%0, %1}";
8003         else
8004           return "movz{wl|x}\t{%1,%0|%0, %1}";
8005       }
8007     default:
8008       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8009       return "and{l}\t{%2, %0|%0, %2}";
8010     }
8012   [(set_attr "type" "alu,alu,imovx")
8013    (set_attr "length_immediate" "*,*,0")
8014    (set_attr "mode" "SI")])
8016 (define_split
8017   [(set (match_operand 0 "register_operand" "")
8018         (and (match_dup 0)
8019              (const_int -65536)))
8020    (clobber (reg:CC FLAGS_REG))]
8021   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8022   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8023   "operands[1] = gen_lowpart (HImode, operands[0]);")
8025 (define_split
8026   [(set (match_operand 0 "ext_register_operand" "")
8027         (and (match_dup 0)
8028              (const_int -256)))
8029    (clobber (reg:CC FLAGS_REG))]
8030   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8031   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8032   "operands[1] = gen_lowpart (QImode, operands[0]);")
8034 (define_split
8035   [(set (match_operand 0 "ext_register_operand" "")
8036         (and (match_dup 0)
8037              (const_int -65281)))
8038    (clobber (reg:CC FLAGS_REG))]
8039   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8040   [(parallel [(set (zero_extract:SI (match_dup 0)
8041                                     (const_int 8)
8042                                     (const_int 8))
8043                    (xor:SI 
8044                      (zero_extract:SI (match_dup 0)
8045                                       (const_int 8)
8046                                       (const_int 8))
8047                      (zero_extract:SI (match_dup 0)
8048                                       (const_int 8)
8049                                       (const_int 8))))
8050               (clobber (reg:CC FLAGS_REG))])]
8051   "operands[0] = gen_lowpart (SImode, operands[0]);")
8053 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8054 (define_insn "*andsi_1_zext"
8055   [(set (match_operand:DI 0 "register_operand" "=r")
8056         (zero_extend:DI
8057           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8058                   (match_operand:SI 2 "general_operand" "rim"))))
8059    (clobber (reg:CC FLAGS_REG))]
8060   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8061   "and{l}\t{%2, %k0|%k0, %2}"
8062   [(set_attr "type" "alu")
8063    (set_attr "mode" "SI")])
8065 (define_insn "*andsi_2"
8066   [(set (reg FLAGS_REG)
8067         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8068                          (match_operand:SI 2 "general_operand" "rim,ri"))
8069                  (const_int 0)))
8070    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8071         (and:SI (match_dup 1) (match_dup 2)))]
8072   "ix86_match_ccmode (insn, CCNOmode)
8073    && ix86_binary_operator_ok (AND, SImode, operands)"
8074   "and{l}\t{%2, %0|%0, %2}"
8075   [(set_attr "type" "alu")
8076    (set_attr "mode" "SI")])
8078 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8079 (define_insn "*andsi_2_zext"
8080   [(set (reg FLAGS_REG)
8081         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8082                          (match_operand:SI 2 "general_operand" "rim"))
8083                  (const_int 0)))
8084    (set (match_operand:DI 0 "register_operand" "=r")
8085         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8086   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8087    && ix86_binary_operator_ok (AND, SImode, operands)"
8088   "and{l}\t{%2, %k0|%k0, %2}"
8089   [(set_attr "type" "alu")
8090    (set_attr "mode" "SI")])
8092 (define_expand "andhi3"
8093   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8094         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8095                 (match_operand:HI 2 "general_operand" "")))
8096    (clobber (reg:CC FLAGS_REG))]
8097   "TARGET_HIMODE_MATH"
8098   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8100 (define_insn "*andhi_1"
8101   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8102         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8103                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8104    (clobber (reg:CC FLAGS_REG))]
8105   "ix86_binary_operator_ok (AND, HImode, operands)"
8107   switch (get_attr_type (insn))
8108     {
8109     case TYPE_IMOVX:
8110       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8111       gcc_assert (INTVAL (operands[2]) == 0xff);
8112       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8114     default:
8115       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8117       return "and{w}\t{%2, %0|%0, %2}";
8118     }
8120   [(set_attr "type" "alu,alu,imovx")
8121    (set_attr "length_immediate" "*,*,0")
8122    (set_attr "mode" "HI,HI,SI")])
8124 (define_insn "*andhi_2"
8125   [(set (reg FLAGS_REG)
8126         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8127                          (match_operand:HI 2 "general_operand" "rim,ri"))
8128                  (const_int 0)))
8129    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8130         (and:HI (match_dup 1) (match_dup 2)))]
8131   "ix86_match_ccmode (insn, CCNOmode)
8132    && ix86_binary_operator_ok (AND, HImode, operands)"
8133   "and{w}\t{%2, %0|%0, %2}"
8134   [(set_attr "type" "alu")
8135    (set_attr "mode" "HI")])
8137 (define_expand "andqi3"
8138   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8139         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8140                 (match_operand:QI 2 "general_operand" "")))
8141    (clobber (reg:CC FLAGS_REG))]
8142   "TARGET_QIMODE_MATH"
8143   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8145 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8146 (define_insn "*andqi_1"
8147   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8148         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8149                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8150    (clobber (reg:CC FLAGS_REG))]
8151   "ix86_binary_operator_ok (AND, QImode, operands)"
8152   "@
8153    and{b}\t{%2, %0|%0, %2}
8154    and{b}\t{%2, %0|%0, %2}
8155    and{l}\t{%k2, %k0|%k0, %k2}"
8156   [(set_attr "type" "alu")
8157    (set_attr "mode" "QI,QI,SI")])
8159 (define_insn "*andqi_1_slp"
8160   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8161         (and:QI (match_dup 0)
8162                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8163    (clobber (reg:CC FLAGS_REG))]
8164   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8165    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8166   "and{b}\t{%1, %0|%0, %1}"
8167   [(set_attr "type" "alu1")
8168    (set_attr "mode" "QI")])
8170 (define_insn "*andqi_2_maybe_si"
8171   [(set (reg FLAGS_REG)
8172         (compare (and:QI
8173                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8174                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8175                  (const_int 0)))
8176    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8177         (and:QI (match_dup 1) (match_dup 2)))]
8178   "ix86_binary_operator_ok (AND, QImode, operands)
8179    && ix86_match_ccmode (insn,
8180                          GET_CODE (operands[2]) == CONST_INT
8181                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8183   if (which_alternative == 2)
8184     {
8185       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8186         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8187       return "and{l}\t{%2, %k0|%k0, %2}";
8188     }
8189   return "and{b}\t{%2, %0|%0, %2}";
8191   [(set_attr "type" "alu")
8192    (set_attr "mode" "QI,QI,SI")])
8194 (define_insn "*andqi_2"
8195   [(set (reg FLAGS_REG)
8196         (compare (and:QI
8197                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8198                    (match_operand:QI 2 "general_operand" "qim,qi"))
8199                  (const_int 0)))
8200    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8201         (and:QI (match_dup 1) (match_dup 2)))]
8202   "ix86_match_ccmode (insn, CCNOmode)
8203    && ix86_binary_operator_ok (AND, QImode, operands)"
8204   "and{b}\t{%2, %0|%0, %2}"
8205   [(set_attr "type" "alu")
8206    (set_attr "mode" "QI")])
8208 (define_insn "*andqi_2_slp"
8209   [(set (reg FLAGS_REG)
8210         (compare (and:QI
8211                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8212                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8213                  (const_int 0)))
8214    (set (strict_low_part (match_dup 0))
8215         (and:QI (match_dup 0) (match_dup 1)))]
8216   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8217    && ix86_match_ccmode (insn, CCNOmode)
8218    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8219   "and{b}\t{%1, %0|%0, %1}"
8220   [(set_attr "type" "alu1")
8221    (set_attr "mode" "QI")])
8223 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8224 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8225 ;; for a QImode operand, which of course failed.
8227 (define_insn "andqi_ext_0"
8228   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8229                          (const_int 8)
8230                          (const_int 8))
8231         (and:SI 
8232           (zero_extract:SI
8233             (match_operand 1 "ext_register_operand" "0")
8234             (const_int 8)
8235             (const_int 8))
8236           (match_operand 2 "const_int_operand" "n")))
8237    (clobber (reg:CC FLAGS_REG))]
8238   ""
8239   "and{b}\t{%2, %h0|%h0, %2}"
8240   [(set_attr "type" "alu")
8241    (set_attr "length_immediate" "1")
8242    (set_attr "mode" "QI")])
8244 ;; Generated by peephole translating test to and.  This shows up
8245 ;; often in fp comparisons.
8247 (define_insn "*andqi_ext_0_cc"
8248   [(set (reg FLAGS_REG)
8249         (compare
8250           (and:SI
8251             (zero_extract:SI
8252               (match_operand 1 "ext_register_operand" "0")
8253               (const_int 8)
8254               (const_int 8))
8255             (match_operand 2 "const_int_operand" "n"))
8256           (const_int 0)))
8257    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8258                          (const_int 8)
8259                          (const_int 8))
8260         (and:SI 
8261           (zero_extract:SI
8262             (match_dup 1)
8263             (const_int 8)
8264             (const_int 8))
8265           (match_dup 2)))]
8266   "ix86_match_ccmode (insn, CCNOmode)"
8267   "and{b}\t{%2, %h0|%h0, %2}"
8268   [(set_attr "type" "alu")
8269    (set_attr "length_immediate" "1")
8270    (set_attr "mode" "QI")])
8272 (define_insn "*andqi_ext_1"
8273   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8274                          (const_int 8)
8275                          (const_int 8))
8276         (and:SI 
8277           (zero_extract:SI
8278             (match_operand 1 "ext_register_operand" "0")
8279             (const_int 8)
8280             (const_int 8))
8281           (zero_extend:SI
8282             (match_operand:QI 2 "general_operand" "Qm"))))
8283    (clobber (reg:CC FLAGS_REG))]
8284   "!TARGET_64BIT"
8285   "and{b}\t{%2, %h0|%h0, %2}"
8286   [(set_attr "type" "alu")
8287    (set_attr "length_immediate" "0")
8288    (set_attr "mode" "QI")])
8290 (define_insn "*andqi_ext_1_rex64"
8291   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8292                          (const_int 8)
8293                          (const_int 8))
8294         (and:SI 
8295           (zero_extract:SI
8296             (match_operand 1 "ext_register_operand" "0")
8297             (const_int 8)
8298             (const_int 8))
8299           (zero_extend:SI
8300             (match_operand 2 "ext_register_operand" "Q"))))
8301    (clobber (reg:CC FLAGS_REG))]
8302   "TARGET_64BIT"
8303   "and{b}\t{%2, %h0|%h0, %2}"
8304   [(set_attr "type" "alu")
8305    (set_attr "length_immediate" "0")
8306    (set_attr "mode" "QI")])
8308 (define_insn "*andqi_ext_2"
8309   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8310                          (const_int 8)
8311                          (const_int 8))
8312         (and:SI
8313           (zero_extract:SI
8314             (match_operand 1 "ext_register_operand" "%0")
8315             (const_int 8)
8316             (const_int 8))
8317           (zero_extract:SI
8318             (match_operand 2 "ext_register_operand" "Q")
8319             (const_int 8)
8320             (const_int 8))))
8321    (clobber (reg:CC FLAGS_REG))]
8322   ""
8323   "and{b}\t{%h2, %h0|%h0, %h2}"
8324   [(set_attr "type" "alu")
8325    (set_attr "length_immediate" "0")
8326    (set_attr "mode" "QI")])
8328 ;; Convert wide AND instructions with immediate operand to shorter QImode
8329 ;; equivalents when possible.
8330 ;; Don't do the splitting with memory operands, since it introduces risk
8331 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8332 ;; for size, but that can (should?) be handled by generic code instead.
8333 (define_split
8334   [(set (match_operand 0 "register_operand" "")
8335         (and (match_operand 1 "register_operand" "")
8336              (match_operand 2 "const_int_operand" "")))
8337    (clobber (reg:CC FLAGS_REG))]
8338    "reload_completed
8339     && QI_REG_P (operands[0])
8340     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8341     && !(~INTVAL (operands[2]) & ~(255 << 8))
8342     && GET_MODE (operands[0]) != QImode"
8343   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8344                    (and:SI (zero_extract:SI (match_dup 1)
8345                                             (const_int 8) (const_int 8))
8346                            (match_dup 2)))
8347               (clobber (reg:CC FLAGS_REG))])]
8348   "operands[0] = gen_lowpart (SImode, operands[0]);
8349    operands[1] = gen_lowpart (SImode, operands[1]);
8350    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8352 ;; Since AND can be encoded with sign extended immediate, this is only
8353 ;; profitable when 7th bit is not set.
8354 (define_split
8355   [(set (match_operand 0 "register_operand" "")
8356         (and (match_operand 1 "general_operand" "")
8357              (match_operand 2 "const_int_operand" "")))
8358    (clobber (reg:CC FLAGS_REG))]
8359    "reload_completed
8360     && ANY_QI_REG_P (operands[0])
8361     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8362     && !(~INTVAL (operands[2]) & ~255)
8363     && !(INTVAL (operands[2]) & 128)
8364     && GET_MODE (operands[0]) != QImode"
8365   [(parallel [(set (strict_low_part (match_dup 0))
8366                    (and:QI (match_dup 1)
8367                            (match_dup 2)))
8368               (clobber (reg:CC FLAGS_REG))])]
8369   "operands[0] = gen_lowpart (QImode, operands[0]);
8370    operands[1] = gen_lowpart (QImode, operands[1]);
8371    operands[2] = gen_lowpart (QImode, operands[2]);")
8373 ;; Logical inclusive OR instructions
8375 ;; %%% This used to optimize known byte-wide and operations to memory.
8376 ;; If this is considered useful, it should be done with splitters.
8378 (define_expand "iordi3"
8379   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8380         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8381                 (match_operand:DI 2 "x86_64_general_operand" "")))
8382    (clobber (reg:CC FLAGS_REG))]
8383   "TARGET_64BIT"
8384   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8386 (define_insn "*iordi_1_rex64"
8387   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8388         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8389                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8390    (clobber (reg:CC FLAGS_REG))]
8391   "TARGET_64BIT
8392    && ix86_binary_operator_ok (IOR, DImode, operands)"
8393   "or{q}\t{%2, %0|%0, %2}"
8394   [(set_attr "type" "alu")
8395    (set_attr "mode" "DI")])
8397 (define_insn "*iordi_2_rex64"
8398   [(set (reg FLAGS_REG)
8399         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8400                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8401                  (const_int 0)))
8402    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8403         (ior:DI (match_dup 1) (match_dup 2)))]
8404   "TARGET_64BIT
8405    && ix86_match_ccmode (insn, CCNOmode)
8406    && ix86_binary_operator_ok (IOR, DImode, operands)"
8407   "or{q}\t{%2, %0|%0, %2}"
8408   [(set_attr "type" "alu")
8409    (set_attr "mode" "DI")])
8411 (define_insn "*iordi_3_rex64"
8412   [(set (reg FLAGS_REG)
8413         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8414                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8415                  (const_int 0)))
8416    (clobber (match_scratch:DI 0 "=r"))]
8417   "TARGET_64BIT
8418    && ix86_match_ccmode (insn, CCNOmode)
8419    && ix86_binary_operator_ok (IOR, DImode, operands)"
8420   "or{q}\t{%2, %0|%0, %2}"
8421   [(set_attr "type" "alu")
8422    (set_attr "mode" "DI")])
8425 (define_expand "iorsi3"
8426   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8427         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8428                 (match_operand:SI 2 "general_operand" "")))
8429    (clobber (reg:CC FLAGS_REG))]
8430   ""
8431   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8433 (define_insn "*iorsi_1"
8434   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8435         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8436                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8437    (clobber (reg:CC FLAGS_REG))]
8438   "ix86_binary_operator_ok (IOR, SImode, operands)"
8439   "or{l}\t{%2, %0|%0, %2}"
8440   [(set_attr "type" "alu")
8441    (set_attr "mode" "SI")])
8443 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8444 (define_insn "*iorsi_1_zext"
8445   [(set (match_operand:DI 0 "register_operand" "=rm")
8446         (zero_extend:DI
8447           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8448                   (match_operand:SI 2 "general_operand" "rim"))))
8449    (clobber (reg:CC FLAGS_REG))]
8450   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8451   "or{l}\t{%2, %k0|%k0, %2}"
8452   [(set_attr "type" "alu")
8453    (set_attr "mode" "SI")])
8455 (define_insn "*iorsi_1_zext_imm"
8456   [(set (match_operand:DI 0 "register_operand" "=rm")
8457         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8458                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8459    (clobber (reg:CC FLAGS_REG))]
8460   "TARGET_64BIT"
8461   "or{l}\t{%2, %k0|%k0, %2}"
8462   [(set_attr "type" "alu")
8463    (set_attr "mode" "SI")])
8465 (define_insn "*iorsi_2"
8466   [(set (reg FLAGS_REG)
8467         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8468                          (match_operand:SI 2 "general_operand" "rim,ri"))
8469                  (const_int 0)))
8470    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8471         (ior:SI (match_dup 1) (match_dup 2)))]
8472   "ix86_match_ccmode (insn, CCNOmode)
8473    && ix86_binary_operator_ok (IOR, SImode, operands)"
8474   "or{l}\t{%2, %0|%0, %2}"
8475   [(set_attr "type" "alu")
8476    (set_attr "mode" "SI")])
8478 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8479 ;; ??? Special case for immediate operand is missing - it is tricky.
8480 (define_insn "*iorsi_2_zext"
8481   [(set (reg FLAGS_REG)
8482         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8483                          (match_operand:SI 2 "general_operand" "rim"))
8484                  (const_int 0)))
8485    (set (match_operand:DI 0 "register_operand" "=r")
8486         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8487   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8488    && ix86_binary_operator_ok (IOR, SImode, operands)"
8489   "or{l}\t{%2, %k0|%k0, %2}"
8490   [(set_attr "type" "alu")
8491    (set_attr "mode" "SI")])
8493 (define_insn "*iorsi_2_zext_imm"
8494   [(set (reg FLAGS_REG)
8495         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8496                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8497                  (const_int 0)))
8498    (set (match_operand:DI 0 "register_operand" "=r")
8499         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8500   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8501    && ix86_binary_operator_ok (IOR, SImode, operands)"
8502   "or{l}\t{%2, %k0|%k0, %2}"
8503   [(set_attr "type" "alu")
8504    (set_attr "mode" "SI")])
8506 (define_insn "*iorsi_3"
8507   [(set (reg FLAGS_REG)
8508         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8509                          (match_operand:SI 2 "general_operand" "rim"))
8510                  (const_int 0)))
8511    (clobber (match_scratch:SI 0 "=r"))]
8512   "ix86_match_ccmode (insn, CCNOmode)
8513    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8514   "or{l}\t{%2, %0|%0, %2}"
8515   [(set_attr "type" "alu")
8516    (set_attr "mode" "SI")])
8518 (define_expand "iorhi3"
8519   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8520         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8521                 (match_operand:HI 2 "general_operand" "")))
8522    (clobber (reg:CC FLAGS_REG))]
8523   "TARGET_HIMODE_MATH"
8524   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8526 (define_insn "*iorhi_1"
8527   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8528         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8529                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8530    (clobber (reg:CC FLAGS_REG))]
8531   "ix86_binary_operator_ok (IOR, HImode, operands)"
8532   "or{w}\t{%2, %0|%0, %2}"
8533   [(set_attr "type" "alu")
8534    (set_attr "mode" "HI")])
8536 (define_insn "*iorhi_2"
8537   [(set (reg FLAGS_REG)
8538         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8539                          (match_operand:HI 2 "general_operand" "rim,ri"))
8540                  (const_int 0)))
8541    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8542         (ior:HI (match_dup 1) (match_dup 2)))]
8543   "ix86_match_ccmode (insn, CCNOmode)
8544    && ix86_binary_operator_ok (IOR, HImode, operands)"
8545   "or{w}\t{%2, %0|%0, %2}"
8546   [(set_attr "type" "alu")
8547    (set_attr "mode" "HI")])
8549 (define_insn "*iorhi_3"
8550   [(set (reg FLAGS_REG)
8551         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8552                          (match_operand:HI 2 "general_operand" "rim"))
8553                  (const_int 0)))
8554    (clobber (match_scratch:HI 0 "=r"))]
8555   "ix86_match_ccmode (insn, CCNOmode)
8556    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8557   "or{w}\t{%2, %0|%0, %2}"
8558   [(set_attr "type" "alu")
8559    (set_attr "mode" "HI")])
8561 (define_expand "iorqi3"
8562   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8563         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8564                 (match_operand:QI 2 "general_operand" "")))
8565    (clobber (reg:CC FLAGS_REG))]
8566   "TARGET_QIMODE_MATH"
8567   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8569 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8570 (define_insn "*iorqi_1"
8571   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8572         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8573                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8574    (clobber (reg:CC FLAGS_REG))]
8575   "ix86_binary_operator_ok (IOR, QImode, operands)"
8576   "@
8577    or{b}\t{%2, %0|%0, %2}
8578    or{b}\t{%2, %0|%0, %2}
8579    or{l}\t{%k2, %k0|%k0, %k2}"
8580   [(set_attr "type" "alu")
8581    (set_attr "mode" "QI,QI,SI")])
8583 (define_insn "*iorqi_1_slp"
8584   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8585         (ior:QI (match_dup 0)
8586                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8587    (clobber (reg:CC FLAGS_REG))]
8588   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8589    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8590   "or{b}\t{%1, %0|%0, %1}"
8591   [(set_attr "type" "alu1")
8592    (set_attr "mode" "QI")])
8594 (define_insn "*iorqi_2"
8595   [(set (reg FLAGS_REG)
8596         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8597                          (match_operand:QI 2 "general_operand" "qim,qi"))
8598                  (const_int 0)))
8599    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8600         (ior:QI (match_dup 1) (match_dup 2)))]
8601   "ix86_match_ccmode (insn, CCNOmode)
8602    && ix86_binary_operator_ok (IOR, QImode, operands)"
8603   "or{b}\t{%2, %0|%0, %2}"
8604   [(set_attr "type" "alu")
8605    (set_attr "mode" "QI")])
8607 (define_insn "*iorqi_2_slp"
8608   [(set (reg FLAGS_REG)
8609         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8610                          (match_operand:QI 1 "general_operand" "qim,qi"))
8611                  (const_int 0)))
8612    (set (strict_low_part (match_dup 0))
8613         (ior:QI (match_dup 0) (match_dup 1)))]
8614   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8615    && ix86_match_ccmode (insn, CCNOmode)
8616    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8617   "or{b}\t{%1, %0|%0, %1}"
8618   [(set_attr "type" "alu1")
8619    (set_attr "mode" "QI")])
8621 (define_insn "*iorqi_3"
8622   [(set (reg FLAGS_REG)
8623         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8624                          (match_operand:QI 2 "general_operand" "qim"))
8625                  (const_int 0)))
8626    (clobber (match_scratch:QI 0 "=q"))]
8627   "ix86_match_ccmode (insn, CCNOmode)
8628    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8629   "or{b}\t{%2, %0|%0, %2}"
8630   [(set_attr "type" "alu")
8631    (set_attr "mode" "QI")])
8633 (define_insn "iorqi_ext_0"
8634   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8635                          (const_int 8)
8636                          (const_int 8))
8637         (ior:SI 
8638           (zero_extract:SI
8639             (match_operand 1 "ext_register_operand" "0")
8640             (const_int 8)
8641             (const_int 8))
8642           (match_operand 2 "const_int_operand" "n")))
8643    (clobber (reg:CC FLAGS_REG))]
8644   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8645   "or{b}\t{%2, %h0|%h0, %2}"
8646   [(set_attr "type" "alu")
8647    (set_attr "length_immediate" "1")
8648    (set_attr "mode" "QI")])
8650 (define_insn "*iorqi_ext_1"
8651   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8652                          (const_int 8)
8653                          (const_int 8))
8654         (ior:SI 
8655           (zero_extract:SI
8656             (match_operand 1 "ext_register_operand" "0")
8657             (const_int 8)
8658             (const_int 8))
8659           (zero_extend:SI
8660             (match_operand:QI 2 "general_operand" "Qm"))))
8661    (clobber (reg:CC FLAGS_REG))]
8662   "!TARGET_64BIT
8663    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8664   "or{b}\t{%2, %h0|%h0, %2}"
8665   [(set_attr "type" "alu")
8666    (set_attr "length_immediate" "0")
8667    (set_attr "mode" "QI")])
8669 (define_insn "*iorqi_ext_1_rex64"
8670   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8671                          (const_int 8)
8672                          (const_int 8))
8673         (ior:SI 
8674           (zero_extract:SI
8675             (match_operand 1 "ext_register_operand" "0")
8676             (const_int 8)
8677             (const_int 8))
8678           (zero_extend:SI
8679             (match_operand 2 "ext_register_operand" "Q"))))
8680    (clobber (reg:CC FLAGS_REG))]
8681   "TARGET_64BIT
8682    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8683   "or{b}\t{%2, %h0|%h0, %2}"
8684   [(set_attr "type" "alu")
8685    (set_attr "length_immediate" "0")
8686    (set_attr "mode" "QI")])
8688 (define_insn "*iorqi_ext_2"
8689   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8690                          (const_int 8)
8691                          (const_int 8))
8692         (ior:SI 
8693           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8694                            (const_int 8)
8695                            (const_int 8))
8696           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8697                            (const_int 8)
8698                            (const_int 8))))
8699    (clobber (reg:CC FLAGS_REG))]
8700   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8701   "ior{b}\t{%h2, %h0|%h0, %h2}"
8702   [(set_attr "type" "alu")
8703    (set_attr "length_immediate" "0")
8704    (set_attr "mode" "QI")])
8706 (define_split
8707   [(set (match_operand 0 "register_operand" "")
8708         (ior (match_operand 1 "register_operand" "")
8709              (match_operand 2 "const_int_operand" "")))
8710    (clobber (reg:CC FLAGS_REG))]
8711    "reload_completed
8712     && QI_REG_P (operands[0])
8713     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8714     && !(INTVAL (operands[2]) & ~(255 << 8))
8715     && GET_MODE (operands[0]) != QImode"
8716   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8717                    (ior:SI (zero_extract:SI (match_dup 1)
8718                                             (const_int 8) (const_int 8))
8719                            (match_dup 2)))
8720               (clobber (reg:CC FLAGS_REG))])]
8721   "operands[0] = gen_lowpart (SImode, operands[0]);
8722    operands[1] = gen_lowpart (SImode, operands[1]);
8723    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8725 ;; Since OR can be encoded with sign extended immediate, this is only
8726 ;; profitable when 7th bit is set.
8727 (define_split
8728   [(set (match_operand 0 "register_operand" "")
8729         (ior (match_operand 1 "general_operand" "")
8730              (match_operand 2 "const_int_operand" "")))
8731    (clobber (reg:CC FLAGS_REG))]
8732    "reload_completed
8733     && ANY_QI_REG_P (operands[0])
8734     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8735     && !(INTVAL (operands[2]) & ~255)
8736     && (INTVAL (operands[2]) & 128)
8737     && GET_MODE (operands[0]) != QImode"
8738   [(parallel [(set (strict_low_part (match_dup 0))
8739                    (ior:QI (match_dup 1)
8740                            (match_dup 2)))
8741               (clobber (reg:CC FLAGS_REG))])]
8742   "operands[0] = gen_lowpart (QImode, operands[0]);
8743    operands[1] = gen_lowpart (QImode, operands[1]);
8744    operands[2] = gen_lowpart (QImode, operands[2]);")
8746 ;; Logical XOR instructions
8748 ;; %%% This used to optimize known byte-wide and operations to memory.
8749 ;; If this is considered useful, it should be done with splitters.
8751 (define_expand "xordi3"
8752   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8753         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8754                 (match_operand:DI 2 "x86_64_general_operand" "")))
8755    (clobber (reg:CC FLAGS_REG))]
8756   "TARGET_64BIT"
8757   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8759 (define_insn "*xordi_1_rex64"
8760   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8761         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8762                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8763    (clobber (reg:CC FLAGS_REG))]
8764   "TARGET_64BIT
8765    && ix86_binary_operator_ok (XOR, DImode, operands)"
8766   "@
8767    xor{q}\t{%2, %0|%0, %2}
8768    xor{q}\t{%2, %0|%0, %2}"
8769   [(set_attr "type" "alu")
8770    (set_attr "mode" "DI,DI")])
8772 (define_insn "*xordi_2_rex64"
8773   [(set (reg FLAGS_REG)
8774         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8775                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8776                  (const_int 0)))
8777    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8778         (xor:DI (match_dup 1) (match_dup 2)))]
8779   "TARGET_64BIT
8780    && ix86_match_ccmode (insn, CCNOmode)
8781    && ix86_binary_operator_ok (XOR, DImode, operands)"
8782   "@
8783    xor{q}\t{%2, %0|%0, %2}
8784    xor{q}\t{%2, %0|%0, %2}"
8785   [(set_attr "type" "alu")
8786    (set_attr "mode" "DI,DI")])
8788 (define_insn "*xordi_3_rex64"
8789   [(set (reg FLAGS_REG)
8790         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8791                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8792                  (const_int 0)))
8793    (clobber (match_scratch:DI 0 "=r"))]
8794   "TARGET_64BIT
8795    && ix86_match_ccmode (insn, CCNOmode)
8796    && ix86_binary_operator_ok (XOR, DImode, operands)"
8797   "xor{q}\t{%2, %0|%0, %2}"
8798   [(set_attr "type" "alu")
8799    (set_attr "mode" "DI")])
8801 (define_expand "xorsi3"
8802   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8803         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8804                 (match_operand:SI 2 "general_operand" "")))
8805    (clobber (reg:CC FLAGS_REG))]
8806   ""
8807   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8809 (define_insn "*xorsi_1"
8810   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8811         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8812                 (match_operand:SI 2 "general_operand" "ri,rm")))
8813    (clobber (reg:CC FLAGS_REG))]
8814   "ix86_binary_operator_ok (XOR, SImode, operands)"
8815   "xor{l}\t{%2, %0|%0, %2}"
8816   [(set_attr "type" "alu")
8817    (set_attr "mode" "SI")])
8819 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8820 ;; Add speccase for immediates
8821 (define_insn "*xorsi_1_zext"
8822   [(set (match_operand:DI 0 "register_operand" "=r")
8823         (zero_extend:DI
8824           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8825                   (match_operand:SI 2 "general_operand" "rim"))))
8826    (clobber (reg:CC FLAGS_REG))]
8827   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8828   "xor{l}\t{%2, %k0|%k0, %2}"
8829   [(set_attr "type" "alu")
8830    (set_attr "mode" "SI")])
8832 (define_insn "*xorsi_1_zext_imm"
8833   [(set (match_operand:DI 0 "register_operand" "=r")
8834         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8835                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8836    (clobber (reg:CC FLAGS_REG))]
8837   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8838   "xor{l}\t{%2, %k0|%k0, %2}"
8839   [(set_attr "type" "alu")
8840    (set_attr "mode" "SI")])
8842 (define_insn "*xorsi_2"
8843   [(set (reg FLAGS_REG)
8844         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8845                          (match_operand:SI 2 "general_operand" "rim,ri"))
8846                  (const_int 0)))
8847    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8848         (xor:SI (match_dup 1) (match_dup 2)))]
8849   "ix86_match_ccmode (insn, CCNOmode)
8850    && ix86_binary_operator_ok (XOR, SImode, operands)"
8851   "xor{l}\t{%2, %0|%0, %2}"
8852   [(set_attr "type" "alu")
8853    (set_attr "mode" "SI")])
8855 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8856 ;; ??? Special case for immediate operand is missing - it is tricky.
8857 (define_insn "*xorsi_2_zext"
8858   [(set (reg FLAGS_REG)
8859         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8860                          (match_operand:SI 2 "general_operand" "rim"))
8861                  (const_int 0)))
8862    (set (match_operand:DI 0 "register_operand" "=r")
8863         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8864   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8865    && ix86_binary_operator_ok (XOR, SImode, operands)"
8866   "xor{l}\t{%2, %k0|%k0, %2}"
8867   [(set_attr "type" "alu")
8868    (set_attr "mode" "SI")])
8870 (define_insn "*xorsi_2_zext_imm"
8871   [(set (reg FLAGS_REG)
8872         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8873                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8874                  (const_int 0)))
8875    (set (match_operand:DI 0 "register_operand" "=r")
8876         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8877   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8878    && ix86_binary_operator_ok (XOR, SImode, operands)"
8879   "xor{l}\t{%2, %k0|%k0, %2}"
8880   [(set_attr "type" "alu")
8881    (set_attr "mode" "SI")])
8883 (define_insn "*xorsi_3"
8884   [(set (reg FLAGS_REG)
8885         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8886                          (match_operand:SI 2 "general_operand" "rim"))
8887                  (const_int 0)))
8888    (clobber (match_scratch:SI 0 "=r"))]
8889   "ix86_match_ccmode (insn, CCNOmode)
8890    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8891   "xor{l}\t{%2, %0|%0, %2}"
8892   [(set_attr "type" "alu")
8893    (set_attr "mode" "SI")])
8895 (define_expand "xorhi3"
8896   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8897         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8898                 (match_operand:HI 2 "general_operand" "")))
8899    (clobber (reg:CC FLAGS_REG))]
8900   "TARGET_HIMODE_MATH"
8901   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8903 (define_insn "*xorhi_1"
8904   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8905         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8906                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8907    (clobber (reg:CC FLAGS_REG))]
8908   "ix86_binary_operator_ok (XOR, HImode, operands)"
8909   "xor{w}\t{%2, %0|%0, %2}"
8910   [(set_attr "type" "alu")
8911    (set_attr "mode" "HI")])
8913 (define_insn "*xorhi_2"
8914   [(set (reg FLAGS_REG)
8915         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8916                          (match_operand:HI 2 "general_operand" "rim,ri"))
8917                  (const_int 0)))
8918    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8919         (xor:HI (match_dup 1) (match_dup 2)))]
8920   "ix86_match_ccmode (insn, CCNOmode)
8921    && ix86_binary_operator_ok (XOR, HImode, operands)"
8922   "xor{w}\t{%2, %0|%0, %2}"
8923   [(set_attr "type" "alu")
8924    (set_attr "mode" "HI")])
8926 (define_insn "*xorhi_3"
8927   [(set (reg FLAGS_REG)
8928         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8929                          (match_operand:HI 2 "general_operand" "rim"))
8930                  (const_int 0)))
8931    (clobber (match_scratch:HI 0 "=r"))]
8932   "ix86_match_ccmode (insn, CCNOmode)
8933    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8934   "xor{w}\t{%2, %0|%0, %2}"
8935   [(set_attr "type" "alu")
8936    (set_attr "mode" "HI")])
8938 (define_expand "xorqi3"
8939   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8940         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8941                 (match_operand:QI 2 "general_operand" "")))
8942    (clobber (reg:CC FLAGS_REG))]
8943   "TARGET_QIMODE_MATH"
8944   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8946 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8947 (define_insn "*xorqi_1"
8948   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8949         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8950                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8951    (clobber (reg:CC FLAGS_REG))]
8952   "ix86_binary_operator_ok (XOR, QImode, operands)"
8953   "@
8954    xor{b}\t{%2, %0|%0, %2}
8955    xor{b}\t{%2, %0|%0, %2}
8956    xor{l}\t{%k2, %k0|%k0, %k2}"
8957   [(set_attr "type" "alu")
8958    (set_attr "mode" "QI,QI,SI")])
8960 (define_insn "*xorqi_1_slp"
8961   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8962         (xor:QI (match_dup 0)
8963                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8964    (clobber (reg:CC FLAGS_REG))]
8965   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8966    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8967   "xor{b}\t{%1, %0|%0, %1}"
8968   [(set_attr "type" "alu1")
8969    (set_attr "mode" "QI")])
8971 (define_insn "xorqi_ext_0"
8972   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8973                          (const_int 8)
8974                          (const_int 8))
8975         (xor:SI 
8976           (zero_extract:SI
8977             (match_operand 1 "ext_register_operand" "0")
8978             (const_int 8)
8979             (const_int 8))
8980           (match_operand 2 "const_int_operand" "n")))
8981    (clobber (reg:CC FLAGS_REG))]
8982   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8983   "xor{b}\t{%2, %h0|%h0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "length_immediate" "1")
8986    (set_attr "mode" "QI")])
8988 (define_insn "*xorqi_ext_1"
8989   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8990                          (const_int 8)
8991                          (const_int 8))
8992         (xor:SI 
8993           (zero_extract:SI
8994             (match_operand 1 "ext_register_operand" "0")
8995             (const_int 8)
8996             (const_int 8))
8997           (zero_extend:SI
8998             (match_operand:QI 2 "general_operand" "Qm"))))
8999    (clobber (reg:CC FLAGS_REG))]
9000   "!TARGET_64BIT
9001    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9002   "xor{b}\t{%2, %h0|%h0, %2}"
9003   [(set_attr "type" "alu")
9004    (set_attr "length_immediate" "0")
9005    (set_attr "mode" "QI")])
9007 (define_insn "*xorqi_ext_1_rex64"
9008   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9009                          (const_int 8)
9010                          (const_int 8))
9011         (xor:SI 
9012           (zero_extract:SI
9013             (match_operand 1 "ext_register_operand" "0")
9014             (const_int 8)
9015             (const_int 8))
9016           (zero_extend:SI
9017             (match_operand 2 "ext_register_operand" "Q"))))
9018    (clobber (reg:CC FLAGS_REG))]
9019   "TARGET_64BIT
9020    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9021   "xor{b}\t{%2, %h0|%h0, %2}"
9022   [(set_attr "type" "alu")
9023    (set_attr "length_immediate" "0")
9024    (set_attr "mode" "QI")])
9026 (define_insn "*xorqi_ext_2"
9027   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9028                          (const_int 8)
9029                          (const_int 8))
9030         (xor:SI 
9031           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9032                            (const_int 8)
9033                            (const_int 8))
9034           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9035                            (const_int 8)
9036                            (const_int 8))))
9037    (clobber (reg:CC FLAGS_REG))]
9038   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9039   "xor{b}\t{%h2, %h0|%h0, %h2}"
9040   [(set_attr "type" "alu")
9041    (set_attr "length_immediate" "0")
9042    (set_attr "mode" "QI")])
9044 (define_insn "*xorqi_cc_1"
9045   [(set (reg FLAGS_REG)
9046         (compare
9047           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9048                   (match_operand:QI 2 "general_operand" "qim,qi"))
9049           (const_int 0)))
9050    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9051         (xor:QI (match_dup 1) (match_dup 2)))]
9052   "ix86_match_ccmode (insn, CCNOmode)
9053    && ix86_binary_operator_ok (XOR, QImode, operands)"
9054   "xor{b}\t{%2, %0|%0, %2}"
9055   [(set_attr "type" "alu")
9056    (set_attr "mode" "QI")])
9058 (define_insn "*xorqi_2_slp"
9059   [(set (reg FLAGS_REG)
9060         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9061                          (match_operand:QI 1 "general_operand" "qim,qi"))
9062                  (const_int 0)))
9063    (set (strict_low_part (match_dup 0))
9064         (xor:QI (match_dup 0) (match_dup 1)))]
9065   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9066    && ix86_match_ccmode (insn, CCNOmode)
9067    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9068   "xor{b}\t{%1, %0|%0, %1}"
9069   [(set_attr "type" "alu1")
9070    (set_attr "mode" "QI")])
9072 (define_insn "*xorqi_cc_2"
9073   [(set (reg FLAGS_REG)
9074         (compare
9075           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9076                   (match_operand:QI 2 "general_operand" "qim"))
9077           (const_int 0)))
9078    (clobber (match_scratch:QI 0 "=q"))]
9079   "ix86_match_ccmode (insn, CCNOmode)
9080    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9081   "xor{b}\t{%2, %0|%0, %2}"
9082   [(set_attr "type" "alu")
9083    (set_attr "mode" "QI")])
9085 (define_insn "*xorqi_cc_ext_1"
9086   [(set (reg FLAGS_REG)
9087         (compare
9088           (xor:SI
9089             (zero_extract:SI
9090               (match_operand 1 "ext_register_operand" "0")
9091               (const_int 8)
9092               (const_int 8))
9093             (match_operand:QI 2 "general_operand" "qmn"))
9094           (const_int 0)))
9095    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9096                          (const_int 8)
9097                          (const_int 8))
9098         (xor:SI 
9099           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9100           (match_dup 2)))]
9101   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9102   "xor{b}\t{%2, %h0|%h0, %2}"
9103   [(set_attr "type" "alu")
9104    (set_attr "mode" "QI")])
9106 (define_insn "*xorqi_cc_ext_1_rex64"
9107   [(set (reg FLAGS_REG)
9108         (compare
9109           (xor:SI
9110             (zero_extract:SI
9111               (match_operand 1 "ext_register_operand" "0")
9112               (const_int 8)
9113               (const_int 8))
9114             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9115           (const_int 0)))
9116    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9117                          (const_int 8)
9118                          (const_int 8))
9119         (xor:SI 
9120           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9121           (match_dup 2)))]
9122   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9123   "xor{b}\t{%2, %h0|%h0, %2}"
9124   [(set_attr "type" "alu")
9125    (set_attr "mode" "QI")])
9127 (define_expand "xorqi_cc_ext_1"
9128   [(parallel [
9129      (set (reg:CCNO FLAGS_REG)
9130           (compare:CCNO
9131             (xor:SI
9132               (zero_extract:SI
9133                 (match_operand 1 "ext_register_operand" "")
9134                 (const_int 8)
9135                 (const_int 8))
9136               (match_operand:QI 2 "general_operand" ""))
9137             (const_int 0)))
9138      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9139                            (const_int 8)
9140                            (const_int 8))
9141           (xor:SI 
9142             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9143             (match_dup 2)))])]
9144   ""
9145   "")
9147 (define_split
9148   [(set (match_operand 0 "register_operand" "")
9149         (xor (match_operand 1 "register_operand" "")
9150              (match_operand 2 "const_int_operand" "")))
9151    (clobber (reg:CC FLAGS_REG))]
9152    "reload_completed
9153     && QI_REG_P (operands[0])
9154     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9155     && !(INTVAL (operands[2]) & ~(255 << 8))
9156     && GET_MODE (operands[0]) != QImode"
9157   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9158                    (xor:SI (zero_extract:SI (match_dup 1)
9159                                             (const_int 8) (const_int 8))
9160                            (match_dup 2)))
9161               (clobber (reg:CC FLAGS_REG))])]
9162   "operands[0] = gen_lowpart (SImode, operands[0]);
9163    operands[1] = gen_lowpart (SImode, operands[1]);
9164    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9166 ;; Since XOR can be encoded with sign extended immediate, this is only
9167 ;; profitable when 7th bit is set.
9168 (define_split
9169   [(set (match_operand 0 "register_operand" "")
9170         (xor (match_operand 1 "general_operand" "")
9171              (match_operand 2 "const_int_operand" "")))
9172    (clobber (reg:CC FLAGS_REG))]
9173    "reload_completed
9174     && ANY_QI_REG_P (operands[0])
9175     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9176     && !(INTVAL (operands[2]) & ~255)
9177     && (INTVAL (operands[2]) & 128)
9178     && GET_MODE (operands[0]) != QImode"
9179   [(parallel [(set (strict_low_part (match_dup 0))
9180                    (xor:QI (match_dup 1)
9181                            (match_dup 2)))
9182               (clobber (reg:CC FLAGS_REG))])]
9183   "operands[0] = gen_lowpart (QImode, operands[0]);
9184    operands[1] = gen_lowpart (QImode, operands[1]);
9185    operands[2] = gen_lowpart (QImode, operands[2]);")
9187 ;; Negation instructions
9189 (define_expand "negdi2"
9190   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9191                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9192               (clobber (reg:CC FLAGS_REG))])]
9193   ""
9194   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9196 (define_insn "*negdi2_1"
9197   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9198         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9199    (clobber (reg:CC FLAGS_REG))]
9200   "!TARGET_64BIT
9201    && ix86_unary_operator_ok (NEG, DImode, operands)"
9202   "#")
9204 (define_split
9205   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9206         (neg:DI (match_operand:DI 1 "general_operand" "")))
9207    (clobber (reg:CC FLAGS_REG))]
9208   "!TARGET_64BIT && reload_completed"
9209   [(parallel
9210     [(set (reg:CCZ FLAGS_REG)
9211           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9212      (set (match_dup 0) (neg:SI (match_dup 2)))])
9213    (parallel
9214     [(set (match_dup 1)
9215           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9216                             (match_dup 3))
9217                    (const_int 0)))
9218      (clobber (reg:CC FLAGS_REG))])
9219    (parallel
9220     [(set (match_dup 1)
9221           (neg:SI (match_dup 1)))
9222      (clobber (reg:CC FLAGS_REG))])]
9223   "split_di (operands+1, 1, operands+2, operands+3);
9224    split_di (operands+0, 1, operands+0, operands+1);")
9226 (define_insn "*negdi2_1_rex64"
9227   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9228         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9229    (clobber (reg:CC FLAGS_REG))]
9230   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9231   "neg{q}\t%0"
9232   [(set_attr "type" "negnot")
9233    (set_attr "mode" "DI")])
9235 ;; The problem with neg is that it does not perform (compare x 0),
9236 ;; it really performs (compare 0 x), which leaves us with the zero
9237 ;; flag being the only useful item.
9239 (define_insn "*negdi2_cmpz_rex64"
9240   [(set (reg:CCZ FLAGS_REG)
9241         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9242                      (const_int 0)))
9243    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9244         (neg:DI (match_dup 1)))]
9245   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9246   "neg{q}\t%0"
9247   [(set_attr "type" "negnot")
9248    (set_attr "mode" "DI")])
9251 (define_expand "negsi2"
9252   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9253                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9254               (clobber (reg:CC FLAGS_REG))])]
9255   ""
9256   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9258 (define_insn "*negsi2_1"
9259   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9260         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9261    (clobber (reg:CC FLAGS_REG))]
9262   "ix86_unary_operator_ok (NEG, SImode, operands)"
9263   "neg{l}\t%0"
9264   [(set_attr "type" "negnot")
9265    (set_attr "mode" "SI")])
9267 ;; Combine is quite creative about this pattern.
9268 (define_insn "*negsi2_1_zext"
9269   [(set (match_operand:DI 0 "register_operand" "=r")
9270         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9271                                         (const_int 32)))
9272                      (const_int 32)))
9273    (clobber (reg:CC FLAGS_REG))]
9274   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9275   "neg{l}\t%k0"
9276   [(set_attr "type" "negnot")
9277    (set_attr "mode" "SI")])
9279 ;; The problem with neg is that it does not perform (compare x 0),
9280 ;; it really performs (compare 0 x), which leaves us with the zero
9281 ;; flag being the only useful item.
9283 (define_insn "*negsi2_cmpz"
9284   [(set (reg:CCZ FLAGS_REG)
9285         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9286                      (const_int 0)))
9287    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9288         (neg:SI (match_dup 1)))]
9289   "ix86_unary_operator_ok (NEG, SImode, operands)"
9290   "neg{l}\t%0"
9291   [(set_attr "type" "negnot")
9292    (set_attr "mode" "SI")])
9294 (define_insn "*negsi2_cmpz_zext"
9295   [(set (reg:CCZ FLAGS_REG)
9296         (compare:CCZ (lshiftrt:DI
9297                        (neg:DI (ashift:DI
9298                                  (match_operand:DI 1 "register_operand" "0")
9299                                  (const_int 32)))
9300                        (const_int 32))
9301                      (const_int 0)))
9302    (set (match_operand:DI 0 "register_operand" "=r")
9303         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9304                                         (const_int 32)))
9305                      (const_int 32)))]
9306   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9307   "neg{l}\t%k0"
9308   [(set_attr "type" "negnot")
9309    (set_attr "mode" "SI")])
9311 (define_expand "neghi2"
9312   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9313                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9314               (clobber (reg:CC FLAGS_REG))])]
9315   "TARGET_HIMODE_MATH"
9316   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9318 (define_insn "*neghi2_1"
9319   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9320         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9321    (clobber (reg:CC FLAGS_REG))]
9322   "ix86_unary_operator_ok (NEG, HImode, operands)"
9323   "neg{w}\t%0"
9324   [(set_attr "type" "negnot")
9325    (set_attr "mode" "HI")])
9327 (define_insn "*neghi2_cmpz"
9328   [(set (reg:CCZ FLAGS_REG)
9329         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9330                      (const_int 0)))
9331    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9332         (neg:HI (match_dup 1)))]
9333   "ix86_unary_operator_ok (NEG, HImode, operands)"
9334   "neg{w}\t%0"
9335   [(set_attr "type" "negnot")
9336    (set_attr "mode" "HI")])
9338 (define_expand "negqi2"
9339   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9340                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9341               (clobber (reg:CC FLAGS_REG))])]
9342   "TARGET_QIMODE_MATH"
9343   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9345 (define_insn "*negqi2_1"
9346   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9347         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9348    (clobber (reg:CC FLAGS_REG))]
9349   "ix86_unary_operator_ok (NEG, QImode, operands)"
9350   "neg{b}\t%0"
9351   [(set_attr "type" "negnot")
9352    (set_attr "mode" "QI")])
9354 (define_insn "*negqi2_cmpz"
9355   [(set (reg:CCZ FLAGS_REG)
9356         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9357                      (const_int 0)))
9358    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9359         (neg:QI (match_dup 1)))]
9360   "ix86_unary_operator_ok (NEG, QImode, operands)"
9361   "neg{b}\t%0"
9362   [(set_attr "type" "negnot")
9363    (set_attr "mode" "QI")])
9365 ;; Changing of sign for FP values is doable using integer unit too.
9367 (define_expand "negsf2"
9368   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9369         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9370   "TARGET_80387 || TARGET_SSE_MATH"
9371   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9373 (define_expand "abssf2"
9374   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9375         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9376   "TARGET_80387 || TARGET_SSE_MATH"
9377   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9379 (define_insn "*absnegsf2_mixed"
9380   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9381         (match_operator:SF 3 "absneg_operator"
9382           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9383    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9384    (clobber (reg:CC FLAGS_REG))]
9385   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9386    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9387   "#")
9389 (define_insn "*absnegsf2_sse"
9390   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9391         (match_operator:SF 3 "absneg_operator"
9392           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9393    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9394    (clobber (reg:CC FLAGS_REG))]
9395   "TARGET_SSE_MATH
9396    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9397   "#")
9399 (define_insn "*absnegsf2_i387"
9400   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9401         (match_operator:SF 3 "absneg_operator"
9402           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9403    (use (match_operand 2 "" ""))
9404    (clobber (reg:CC FLAGS_REG))]
9405   "TARGET_80387 && !TARGET_SSE_MATH
9406    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9407   "#")
9409 (define_expand "copysignsf3"
9410   [(match_operand:SF 0 "register_operand" "")
9411    (match_operand:SF 1 "nonmemory_operand" "")
9412    (match_operand:SF 2 "register_operand" "")]
9413   "TARGET_SSE_MATH"
9415   ix86_expand_copysign (operands);
9416   DONE;
9419 (define_insn_and_split "copysignsf3_const"
9420   [(set (match_operand:SF 0 "register_operand"          "=x")
9421         (unspec:SF
9422           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9423            (match_operand:SF 2 "register_operand"       "0")
9424            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9425           UNSPEC_COPYSIGN))]
9426   "TARGET_SSE_MATH"
9427   "#"
9428   "&& reload_completed"
9429   [(const_int 0)]
9431   ix86_split_copysign_const (operands);
9432   DONE;
9435 (define_insn "copysignsf3_var"
9436   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9437         (unspec:SF
9438           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9439            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9440            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9441            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9442           UNSPEC_COPYSIGN))
9443    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9444   "TARGET_SSE_MATH"
9445   "#")
9447 (define_split
9448   [(set (match_operand:SF 0 "register_operand" "")
9449         (unspec:SF
9450           [(match_operand:SF 2 "register_operand" "")
9451            (match_operand:SF 3 "register_operand" "")
9452            (match_operand:V4SF 4 "" "")
9453            (match_operand:V4SF 5 "" "")]
9454           UNSPEC_COPYSIGN))
9455    (clobber (match_scratch:V4SF 1 ""))]
9456   "TARGET_SSE_MATH && reload_completed"
9457   [(const_int 0)]
9459   ix86_split_copysign_var (operands);
9460   DONE;
9463 (define_expand "negdf2"
9464   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9465         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9466   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9467   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9469 (define_expand "absdf2"
9470   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9471         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9472   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9473   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9475 (define_insn "*absnegdf2_mixed"
9476   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9477         (match_operator:DF 3 "absneg_operator"
9478           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9479    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9480    (clobber (reg:CC FLAGS_REG))]
9481   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9482    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9483   "#")
9485 (define_insn "*absnegdf2_sse"
9486   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9487         (match_operator:DF 3 "absneg_operator"
9488           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9489    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9490    (clobber (reg:CC FLAGS_REG))]
9491   "TARGET_SSE2 && TARGET_SSE_MATH
9492    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9493   "#")
9495 (define_insn "*absnegdf2_i387"
9496   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9497         (match_operator:DF 3 "absneg_operator"
9498           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9499    (use (match_operand 2 "" ""))
9500    (clobber (reg:CC FLAGS_REG))]
9501   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9502    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9503   "#")
9505 (define_expand "copysigndf3"
9506   [(match_operand:DF 0 "register_operand" "")
9507    (match_operand:DF 1 "nonmemory_operand" "")
9508    (match_operand:DF 2 "register_operand" "")]
9509   "TARGET_SSE2 && TARGET_SSE_MATH"
9511   ix86_expand_copysign (operands);
9512   DONE;
9515 (define_insn_and_split "copysigndf3_const"
9516   [(set (match_operand:DF 0 "register_operand"          "=x")
9517         (unspec:DF
9518           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9519            (match_operand:DF 2 "register_operand"       "0")
9520            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9521           UNSPEC_COPYSIGN))]
9522   "TARGET_SSE2 && TARGET_SSE_MATH"
9523   "#"
9524   "&& reload_completed"
9525   [(const_int 0)]
9527   ix86_split_copysign_const (operands);
9528   DONE;
9531 (define_insn "copysigndf3_var"
9532   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9533         (unspec:DF
9534           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9535            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9536            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9537            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9538           UNSPEC_COPYSIGN))
9539    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9540   "TARGET_SSE2 && TARGET_SSE_MATH"
9541   "#")
9543 (define_split
9544   [(set (match_operand:DF 0 "register_operand" "")
9545         (unspec:DF
9546           [(match_operand:DF 2 "register_operand" "")
9547            (match_operand:DF 3 "register_operand" "")
9548            (match_operand:V2DF 4 "" "")
9549            (match_operand:V2DF 5 "" "")]
9550           UNSPEC_COPYSIGN))
9551    (clobber (match_scratch:V2DF 1 ""))]
9552   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9553   [(const_int 0)]
9555   ix86_split_copysign_var (operands);
9556   DONE;
9559 (define_expand "negxf2"
9560   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9561         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9562   "TARGET_80387"
9563   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9565 (define_expand "absxf2"
9566   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9567         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9568   "TARGET_80387"
9569   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9571 (define_insn "*absnegxf2_i387"
9572   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9573         (match_operator:XF 3 "absneg_operator"
9574           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9575    (use (match_operand 2 "" ""))
9576    (clobber (reg:CC FLAGS_REG))]
9577   "TARGET_80387
9578    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9579   "#")
9581 ;; Splitters for fp abs and neg.
9583 (define_split
9584   [(set (match_operand 0 "fp_register_operand" "")
9585         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9586    (use (match_operand 2 "" ""))
9587    (clobber (reg:CC FLAGS_REG))]
9588   "reload_completed"
9589   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9591 (define_split
9592   [(set (match_operand 0 "register_operand" "")
9593         (match_operator 3 "absneg_operator"
9594           [(match_operand 1 "register_operand" "")]))
9595    (use (match_operand 2 "nonimmediate_operand" ""))
9596    (clobber (reg:CC FLAGS_REG))]
9597   "reload_completed && SSE_REG_P (operands[0])"
9598   [(set (match_dup 0) (match_dup 3))]
9600   enum machine_mode mode = GET_MODE (operands[0]);
9601   enum machine_mode vmode = GET_MODE (operands[2]);
9602   rtx tmp;
9603   
9604   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9605   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9606   if (operands_match_p (operands[0], operands[2]))
9607     {
9608       tmp = operands[1];
9609       operands[1] = operands[2];
9610       operands[2] = tmp;
9611     }
9612   if (GET_CODE (operands[3]) == ABS)
9613     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9614   else
9615     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9616   operands[3] = tmp;
9619 (define_split
9620   [(set (match_operand:SF 0 "register_operand" "")
9621         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9622    (use (match_operand:V4SF 2 "" ""))
9623    (clobber (reg:CC FLAGS_REG))]
9624   "reload_completed"
9625   [(parallel [(set (match_dup 0) (match_dup 1))
9626               (clobber (reg:CC FLAGS_REG))])]
9628   rtx tmp;
9629   operands[0] = gen_lowpart (SImode, operands[0]);
9630   if (GET_CODE (operands[1]) == ABS)
9631     {
9632       tmp = gen_int_mode (0x7fffffff, SImode);
9633       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9634     }
9635   else
9636     {
9637       tmp = gen_int_mode (0x80000000, SImode);
9638       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9639     }
9640   operands[1] = tmp;
9643 (define_split
9644   [(set (match_operand:DF 0 "register_operand" "")
9645         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9646    (use (match_operand 2 "" ""))
9647    (clobber (reg:CC FLAGS_REG))]
9648   "reload_completed"
9649   [(parallel [(set (match_dup 0) (match_dup 1))
9650               (clobber (reg:CC FLAGS_REG))])]
9652   rtx tmp;
9653   if (TARGET_64BIT)
9654     {
9655       tmp = gen_lowpart (DImode, operands[0]);
9656       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9657       operands[0] = tmp;
9659       if (GET_CODE (operands[1]) == ABS)
9660         tmp = const0_rtx;
9661       else
9662         tmp = gen_rtx_NOT (DImode, tmp);
9663     }
9664   else
9665     {
9666       operands[0] = gen_highpart (SImode, operands[0]);
9667       if (GET_CODE (operands[1]) == ABS)
9668         {
9669           tmp = gen_int_mode (0x7fffffff, SImode);
9670           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9671         }
9672       else
9673         {
9674           tmp = gen_int_mode (0x80000000, SImode);
9675           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9676         }
9677     }
9678   operands[1] = tmp;
9681 (define_split
9682   [(set (match_operand:XF 0 "register_operand" "")
9683         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9684    (use (match_operand 2 "" ""))
9685    (clobber (reg:CC FLAGS_REG))]
9686   "reload_completed"
9687   [(parallel [(set (match_dup 0) (match_dup 1))
9688               (clobber (reg:CC FLAGS_REG))])]
9690   rtx tmp;
9691   operands[0] = gen_rtx_REG (SImode,
9692                              true_regnum (operands[0])
9693                              + (TARGET_64BIT ? 1 : 2));
9694   if (GET_CODE (operands[1]) == ABS)
9695     {
9696       tmp = GEN_INT (0x7fff);
9697       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9698     }
9699   else
9700     {
9701       tmp = GEN_INT (0x8000);
9702       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9703     }
9704   operands[1] = tmp;
9707 (define_split
9708   [(set (match_operand 0 "memory_operand" "")
9709         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9710    (use (match_operand 2 "" ""))
9711    (clobber (reg:CC FLAGS_REG))]
9712   "reload_completed"
9713   [(parallel [(set (match_dup 0) (match_dup 1))
9714               (clobber (reg:CC FLAGS_REG))])]
9716   enum machine_mode mode = GET_MODE (operands[0]);
9717   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9718   rtx tmp;
9720   operands[0] = adjust_address (operands[0], QImode, size - 1);
9721   if (GET_CODE (operands[1]) == ABS)
9722     {
9723       tmp = gen_int_mode (0x7f, QImode);
9724       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9725     }
9726   else
9727     {
9728       tmp = gen_int_mode (0x80, QImode);
9729       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9730     }
9731   operands[1] = tmp;
9734 ;; Conditionalize these after reload. If they match before reload, we 
9735 ;; lose the clobber and ability to use integer instructions.
9737 (define_insn "*negsf2_1"
9738   [(set (match_operand:SF 0 "register_operand" "=f")
9739         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9740   "TARGET_80387 && reload_completed"
9741   "fchs"
9742   [(set_attr "type" "fsgn")
9743    (set_attr "mode" "SF")])
9745 (define_insn "*negdf2_1"
9746   [(set (match_operand:DF 0 "register_operand" "=f")
9747         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9748   "TARGET_80387 && reload_completed"
9749   "fchs"
9750   [(set_attr "type" "fsgn")
9751    (set_attr "mode" "DF")])
9753 (define_insn "*negxf2_1"
9754   [(set (match_operand:XF 0 "register_operand" "=f")
9755         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9756   "TARGET_80387 && reload_completed"
9757   "fchs"
9758   [(set_attr "type" "fsgn")
9759    (set_attr "mode" "XF")])
9761 (define_insn "*abssf2_1"
9762   [(set (match_operand:SF 0 "register_operand" "=f")
9763         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9764   "TARGET_80387 && reload_completed"
9765   "fabs"
9766   [(set_attr "type" "fsgn")
9767    (set_attr "mode" "SF")])
9769 (define_insn "*absdf2_1"
9770   [(set (match_operand:DF 0 "register_operand" "=f")
9771         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9772   "TARGET_80387 && reload_completed"
9773   "fabs"
9774   [(set_attr "type" "fsgn")
9775    (set_attr "mode" "DF")])
9777 (define_insn "*absxf2_1"
9778   [(set (match_operand:XF 0 "register_operand" "=f")
9779         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9780   "TARGET_80387 && reload_completed"
9781   "fabs"
9782   [(set_attr "type" "fsgn")
9783    (set_attr "mode" "DF")])
9785 (define_insn "*negextendsfdf2"
9786   [(set (match_operand:DF 0 "register_operand" "=f")
9787         (neg:DF (float_extend:DF
9788                   (match_operand:SF 1 "register_operand" "0"))))]
9789   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9790   "fchs"
9791   [(set_attr "type" "fsgn")
9792    (set_attr "mode" "DF")])
9794 (define_insn "*negextenddfxf2"
9795   [(set (match_operand:XF 0 "register_operand" "=f")
9796         (neg:XF (float_extend:XF
9797                   (match_operand:DF 1 "register_operand" "0"))))]
9798   "TARGET_80387"
9799   "fchs"
9800   [(set_attr "type" "fsgn")
9801    (set_attr "mode" "XF")])
9803 (define_insn "*negextendsfxf2"
9804   [(set (match_operand:XF 0 "register_operand" "=f")
9805         (neg:XF (float_extend:XF
9806                   (match_operand:SF 1 "register_operand" "0"))))]
9807   "TARGET_80387"
9808   "fchs"
9809   [(set_attr "type" "fsgn")
9810    (set_attr "mode" "XF")])
9812 (define_insn "*absextendsfdf2"
9813   [(set (match_operand:DF 0 "register_operand" "=f")
9814         (abs:DF (float_extend:DF
9815                   (match_operand:SF 1 "register_operand" "0"))))]
9816   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9817   "fabs"
9818   [(set_attr "type" "fsgn")
9819    (set_attr "mode" "DF")])
9821 (define_insn "*absextenddfxf2"
9822   [(set (match_operand:XF 0 "register_operand" "=f")
9823         (abs:XF (float_extend:XF
9824           (match_operand:DF 1 "register_operand" "0"))))]
9825   "TARGET_80387"
9826   "fabs"
9827   [(set_attr "type" "fsgn")
9828    (set_attr "mode" "XF")])
9830 (define_insn "*absextendsfxf2"
9831   [(set (match_operand:XF 0 "register_operand" "=f")
9832         (abs:XF (float_extend:XF
9833           (match_operand:SF 1 "register_operand" "0"))))]
9834   "TARGET_80387"
9835   "fabs"
9836   [(set_attr "type" "fsgn")
9837    (set_attr "mode" "XF")])
9839 ;; One complement instructions
9841 (define_expand "one_cmpldi2"
9842   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9843         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9844   "TARGET_64BIT"
9845   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9847 (define_insn "*one_cmpldi2_1_rex64"
9848   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9849         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9850   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9851   "not{q}\t%0"
9852   [(set_attr "type" "negnot")
9853    (set_attr "mode" "DI")])
9855 (define_insn "*one_cmpldi2_2_rex64"
9856   [(set (reg FLAGS_REG)
9857         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9858                  (const_int 0)))
9859    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9860         (not:DI (match_dup 1)))]
9861   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9862    && ix86_unary_operator_ok (NOT, DImode, operands)"
9863   "#"
9864   [(set_attr "type" "alu1")
9865    (set_attr "mode" "DI")])
9867 (define_split
9868   [(set (match_operand 0 "flags_reg_operand" "")
9869         (match_operator 2 "compare_operator"
9870           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9871            (const_int 0)]))
9872    (set (match_operand:DI 1 "nonimmediate_operand" "")
9873         (not:DI (match_dup 3)))]
9874   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9875   [(parallel [(set (match_dup 0)
9876                    (match_op_dup 2
9877                      [(xor:DI (match_dup 3) (const_int -1))
9878                       (const_int 0)]))
9879               (set (match_dup 1)
9880                    (xor:DI (match_dup 3) (const_int -1)))])]
9881   "")
9883 (define_expand "one_cmplsi2"
9884   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9885         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9886   ""
9887   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9889 (define_insn "*one_cmplsi2_1"
9890   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9891         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9892   "ix86_unary_operator_ok (NOT, SImode, operands)"
9893   "not{l}\t%0"
9894   [(set_attr "type" "negnot")
9895    (set_attr "mode" "SI")])
9897 ;; ??? Currently never generated - xor is used instead.
9898 (define_insn "*one_cmplsi2_1_zext"
9899   [(set (match_operand:DI 0 "register_operand" "=r")
9900         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9901   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9902   "not{l}\t%k0"
9903   [(set_attr "type" "negnot")
9904    (set_attr "mode" "SI")])
9906 (define_insn "*one_cmplsi2_2"
9907   [(set (reg FLAGS_REG)
9908         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9909                  (const_int 0)))
9910    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9911         (not:SI (match_dup 1)))]
9912   "ix86_match_ccmode (insn, CCNOmode)
9913    && ix86_unary_operator_ok (NOT, SImode, operands)"
9914   "#"
9915   [(set_attr "type" "alu1")
9916    (set_attr "mode" "SI")])
9918 (define_split
9919   [(set (match_operand 0 "flags_reg_operand" "")
9920         (match_operator 2 "compare_operator"
9921           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9922            (const_int 0)]))
9923    (set (match_operand:SI 1 "nonimmediate_operand" "")
9924         (not:SI (match_dup 3)))]
9925   "ix86_match_ccmode (insn, CCNOmode)"
9926   [(parallel [(set (match_dup 0)
9927                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9928                                     (const_int 0)]))
9929               (set (match_dup 1)
9930                    (xor:SI (match_dup 3) (const_int -1)))])]
9931   "")
9933 ;; ??? Currently never generated - xor is used instead.
9934 (define_insn "*one_cmplsi2_2_zext"
9935   [(set (reg FLAGS_REG)
9936         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9937                  (const_int 0)))
9938    (set (match_operand:DI 0 "register_operand" "=r")
9939         (zero_extend:DI (not:SI (match_dup 1))))]
9940   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9941    && ix86_unary_operator_ok (NOT, SImode, operands)"
9942   "#"
9943   [(set_attr "type" "alu1")
9944    (set_attr "mode" "SI")])
9946 (define_split
9947   [(set (match_operand 0 "flags_reg_operand" "")
9948         (match_operator 2 "compare_operator"
9949           [(not:SI (match_operand:SI 3 "register_operand" ""))
9950            (const_int 0)]))
9951    (set (match_operand:DI 1 "register_operand" "")
9952         (zero_extend:DI (not:SI (match_dup 3))))]
9953   "ix86_match_ccmode (insn, CCNOmode)"
9954   [(parallel [(set (match_dup 0)
9955                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9956                                     (const_int 0)]))
9957               (set (match_dup 1)
9958                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9959   "")
9961 (define_expand "one_cmplhi2"
9962   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9963         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9964   "TARGET_HIMODE_MATH"
9965   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9967 (define_insn "*one_cmplhi2_1"
9968   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9969         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9970   "ix86_unary_operator_ok (NOT, HImode, operands)"
9971   "not{w}\t%0"
9972   [(set_attr "type" "negnot")
9973    (set_attr "mode" "HI")])
9975 (define_insn "*one_cmplhi2_2"
9976   [(set (reg FLAGS_REG)
9977         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9978                  (const_int 0)))
9979    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9980         (not:HI (match_dup 1)))]
9981   "ix86_match_ccmode (insn, CCNOmode)
9982    && ix86_unary_operator_ok (NEG, HImode, operands)"
9983   "#"
9984   [(set_attr "type" "alu1")
9985    (set_attr "mode" "HI")])
9987 (define_split
9988   [(set (match_operand 0 "flags_reg_operand" "")
9989         (match_operator 2 "compare_operator"
9990           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
9991            (const_int 0)]))
9992    (set (match_operand:HI 1 "nonimmediate_operand" "")
9993         (not:HI (match_dup 3)))]
9994   "ix86_match_ccmode (insn, CCNOmode)"
9995   [(parallel [(set (match_dup 0)
9996                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
9997                                     (const_int 0)]))
9998               (set (match_dup 1)
9999                    (xor:HI (match_dup 3) (const_int -1)))])]
10000   "")
10002 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10003 (define_expand "one_cmplqi2"
10004   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10005         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10006   "TARGET_QIMODE_MATH"
10007   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10009 (define_insn "*one_cmplqi2_1"
10010   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10011         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10012   "ix86_unary_operator_ok (NOT, QImode, operands)"
10013   "@
10014    not{b}\t%0
10015    not{l}\t%k0"
10016   [(set_attr "type" "negnot")
10017    (set_attr "mode" "QI,SI")])
10019 (define_insn "*one_cmplqi2_2"
10020   [(set (reg FLAGS_REG)
10021         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10022                  (const_int 0)))
10023    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10024         (not:QI (match_dup 1)))]
10025   "ix86_match_ccmode (insn, CCNOmode)
10026    && ix86_unary_operator_ok (NOT, QImode, operands)"
10027   "#"
10028   [(set_attr "type" "alu1")
10029    (set_attr "mode" "QI")])
10031 (define_split
10032   [(set (match_operand 0 "flags_reg_operand" "")
10033         (match_operator 2 "compare_operator"
10034           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10035            (const_int 0)]))
10036    (set (match_operand:QI 1 "nonimmediate_operand" "")
10037         (not:QI (match_dup 3)))]
10038   "ix86_match_ccmode (insn, CCNOmode)"
10039   [(parallel [(set (match_dup 0)
10040                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10041                                     (const_int 0)]))
10042               (set (match_dup 1)
10043                    (xor:QI (match_dup 3) (const_int -1)))])]
10044   "")
10046 ;; Arithmetic shift instructions
10048 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10049 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10050 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10051 ;; from the assembler input.
10053 ;; This instruction shifts the target reg/mem as usual, but instead of
10054 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10055 ;; is a left shift double, bits are taken from the high order bits of
10056 ;; reg, else if the insn is a shift right double, bits are taken from the
10057 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10058 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10060 ;; Since sh[lr]d does not change the `reg' operand, that is done
10061 ;; separately, making all shifts emit pairs of shift double and normal
10062 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10063 ;; support a 63 bit shift, each shift where the count is in a reg expands
10064 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10066 ;; If the shift count is a constant, we need never emit more than one
10067 ;; shift pair, instead using moves and sign extension for counts greater
10068 ;; than 31.
10070 (define_expand "ashldi3"
10071   [(set (match_operand:DI 0 "shiftdi_operand" "")
10072         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10073                    (match_operand:QI 2 "nonmemory_operand" "")))]
10074   ""
10075   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10077 (define_insn "*ashldi3_1_rex64"
10078   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10079         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10080                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10081    (clobber (reg:CC FLAGS_REG))]
10082   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10084   switch (get_attr_type (insn))
10085     {
10086     case TYPE_ALU:
10087       gcc_assert (operands[2] == const1_rtx);
10088       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10089       return "add{q}\t{%0, %0|%0, %0}";
10091     case TYPE_LEA:
10092       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10093       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10094       operands[1] = gen_rtx_MULT (DImode, operands[1],
10095                                   GEN_INT (1 << INTVAL (operands[2])));
10096       return "lea{q}\t{%a1, %0|%0, %a1}";
10098     default:
10099       if (REG_P (operands[2]))
10100         return "sal{q}\t{%b2, %0|%0, %b2}";
10101       else if (operands[2] == const1_rtx
10102                && (TARGET_SHIFT1 || optimize_size))
10103         return "sal{q}\t%0";
10104       else
10105         return "sal{q}\t{%2, %0|%0, %2}";
10106     }
10108   [(set (attr "type")
10109      (cond [(eq_attr "alternative" "1")
10110               (const_string "lea")
10111             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10112                           (const_int 0))
10113                       (match_operand 0 "register_operand" ""))
10114                  (match_operand 2 "const1_operand" ""))
10115               (const_string "alu")
10116            ]
10117            (const_string "ishift")))
10118    (set_attr "mode" "DI")])
10120 ;; Convert lea to the lea pattern to avoid flags dependency.
10121 (define_split
10122   [(set (match_operand:DI 0 "register_operand" "")
10123         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10124                    (match_operand:QI 2 "immediate_operand" "")))
10125    (clobber (reg:CC FLAGS_REG))]
10126   "TARGET_64BIT && reload_completed
10127    && true_regnum (operands[0]) != true_regnum (operands[1])"
10128   [(set (match_dup 0)
10129         (mult:DI (match_dup 1)
10130                  (match_dup 2)))]
10131   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10133 ;; This pattern can't accept a variable shift count, since shifts by
10134 ;; zero don't affect the flags.  We assume that shifts by constant
10135 ;; zero are optimized away.
10136 (define_insn "*ashldi3_cmp_rex64"
10137   [(set (reg FLAGS_REG)
10138         (compare
10139           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10140                      (match_operand:QI 2 "immediate_operand" "e"))
10141           (const_int 0)))
10142    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10143         (ashift:DI (match_dup 1) (match_dup 2)))]
10144   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10145    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10147   switch (get_attr_type (insn))
10148     {
10149     case TYPE_ALU:
10150       gcc_assert (operands[2] == const1_rtx);
10151       return "add{q}\t{%0, %0|%0, %0}";
10153     default:
10154       if (REG_P (operands[2]))
10155         return "sal{q}\t{%b2, %0|%0, %b2}";
10156       else if (operands[2] == const1_rtx
10157                && (TARGET_SHIFT1 || optimize_size))
10158         return "sal{q}\t%0";
10159       else
10160         return "sal{q}\t{%2, %0|%0, %2}";
10161     }
10163   [(set (attr "type")
10164      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10165                           (const_int 0))
10166                       (match_operand 0 "register_operand" ""))
10167                  (match_operand 2 "const1_operand" ""))
10168               (const_string "alu")
10169            ]
10170            (const_string "ishift")))
10171    (set_attr "mode" "DI")])
10173 (define_insn "*ashldi3_1"
10174   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10175         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10176                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10177    (clobber (reg:CC FLAGS_REG))]
10178   "!TARGET_64BIT"
10179   "#"
10180   [(set_attr "type" "multi")])
10182 ;; By default we don't ask for a scratch register, because when DImode
10183 ;; values are manipulated, registers are already at a premium.  But if
10184 ;; we have one handy, we won't turn it away.
10185 (define_peephole2
10186   [(match_scratch:SI 3 "r")
10187    (parallel [(set (match_operand:DI 0 "register_operand" "")
10188                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10189                               (match_operand:QI 2 "nonmemory_operand" "")))
10190               (clobber (reg:CC FLAGS_REG))])
10191    (match_dup 3)]
10192   "!TARGET_64BIT && TARGET_CMOVE"
10193   [(const_int 0)]
10194   "ix86_split_ashldi (operands, operands[3]); DONE;")
10196 (define_split
10197   [(set (match_operand:DI 0 "register_operand" "")
10198         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10199                    (match_operand:QI 2 "nonmemory_operand" "")))
10200    (clobber (reg:CC FLAGS_REG))]
10201   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10202   [(const_int 0)]
10203   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10205 (define_insn "x86_shld_1"
10206   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10207         (ior:SI (ashift:SI (match_dup 0)
10208                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10209                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10210                   (minus:QI (const_int 32) (match_dup 2)))))
10211    (clobber (reg:CC FLAGS_REG))]
10212   ""
10213   "@
10214    shld{l}\t{%2, %1, %0|%0, %1, %2}
10215    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10216   [(set_attr "type" "ishift")
10217    (set_attr "prefix_0f" "1")
10218    (set_attr "mode" "SI")
10219    (set_attr "pent_pair" "np")
10220    (set_attr "athlon_decode" "vector")])
10222 (define_expand "x86_shift_adj_1"
10223   [(set (reg:CCZ FLAGS_REG)
10224         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10225                              (const_int 32))
10226                      (const_int 0)))
10227    (set (match_operand:SI 0 "register_operand" "")
10228         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10229                          (match_operand:SI 1 "register_operand" "")
10230                          (match_dup 0)))
10231    (set (match_dup 1)
10232         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10233                          (match_operand:SI 3 "register_operand" "r")
10234                          (match_dup 1)))]
10235   "TARGET_CMOVE"
10236   "")
10238 (define_expand "x86_shift_adj_2"
10239   [(use (match_operand:SI 0 "register_operand" ""))
10240    (use (match_operand:SI 1 "register_operand" ""))
10241    (use (match_operand:QI 2 "register_operand" ""))]
10242   ""
10244   rtx label = gen_label_rtx ();
10245   rtx tmp;
10247   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10249   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10250   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10251   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10252                               gen_rtx_LABEL_REF (VOIDmode, label),
10253                               pc_rtx);
10254   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10255   JUMP_LABEL (tmp) = label;
10257   emit_move_insn (operands[0], operands[1]);
10258   ix86_expand_clear (operands[1]);
10260   emit_label (label);
10261   LABEL_NUSES (label) = 1;
10263   DONE;
10266 (define_expand "ashlsi3"
10267   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10268         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10269                    (match_operand:QI 2 "nonmemory_operand" "")))
10270    (clobber (reg:CC FLAGS_REG))]
10271   ""
10272   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10274 (define_insn "*ashlsi3_1"
10275   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10276         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10277                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10278    (clobber (reg:CC FLAGS_REG))]
10279   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10281   switch (get_attr_type (insn))
10282     {
10283     case TYPE_ALU:
10284       gcc_assert (operands[2] == const1_rtx);
10285       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10286       return "add{l}\t{%0, %0|%0, %0}";
10288     case TYPE_LEA:
10289       return "#";
10291     default:
10292       if (REG_P (operands[2]))
10293         return "sal{l}\t{%b2, %0|%0, %b2}";
10294       else if (operands[2] == const1_rtx
10295                && (TARGET_SHIFT1 || optimize_size))
10296         return "sal{l}\t%0";
10297       else
10298         return "sal{l}\t{%2, %0|%0, %2}";
10299     }
10301   [(set (attr "type")
10302      (cond [(eq_attr "alternative" "1")
10303               (const_string "lea")
10304             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10305                           (const_int 0))
10306                       (match_operand 0 "register_operand" ""))
10307                  (match_operand 2 "const1_operand" ""))
10308               (const_string "alu")
10309            ]
10310            (const_string "ishift")))
10311    (set_attr "mode" "SI")])
10313 ;; Convert lea to the lea pattern to avoid flags dependency.
10314 (define_split
10315   [(set (match_operand 0 "register_operand" "")
10316         (ashift (match_operand 1 "index_register_operand" "")
10317                 (match_operand:QI 2 "const_int_operand" "")))
10318    (clobber (reg:CC FLAGS_REG))]
10319   "reload_completed
10320    && true_regnum (operands[0]) != true_regnum (operands[1])
10321    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10322   [(const_int 0)]
10324   rtx pat;
10325   enum machine_mode mode = GET_MODE (operands[0]);
10327   if (GET_MODE_SIZE (mode) < 4)
10328     operands[0] = gen_lowpart (SImode, operands[0]);
10329   if (mode != Pmode)
10330     operands[1] = gen_lowpart (Pmode, operands[1]);
10331   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10333   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10334   if (Pmode != SImode)
10335     pat = gen_rtx_SUBREG (SImode, pat, 0);
10336   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10337   DONE;
10340 ;; Rare case of shifting RSP is handled by generating move and shift
10341 (define_split
10342   [(set (match_operand 0 "register_operand" "")
10343         (ashift (match_operand 1 "register_operand" "")
10344                 (match_operand:QI 2 "const_int_operand" "")))
10345    (clobber (reg:CC FLAGS_REG))]
10346   "reload_completed
10347    && true_regnum (operands[0]) != true_regnum (operands[1])"
10348   [(const_int 0)]
10350   rtx pat, clob;
10351   emit_move_insn (operands[1], operands[0]);
10352   pat = gen_rtx_SET (VOIDmode, operands[0],
10353                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10354                                      operands[0], operands[2]));
10355   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10356   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10357   DONE;
10360 (define_insn "*ashlsi3_1_zext"
10361   [(set (match_operand:DI 0 "register_operand" "=r,r")
10362         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10363                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10364    (clobber (reg:CC FLAGS_REG))]
10365   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10367   switch (get_attr_type (insn))
10368     {
10369     case TYPE_ALU:
10370       gcc_assert (operands[2] == const1_rtx);
10371       return "add{l}\t{%k0, %k0|%k0, %k0}";
10373     case TYPE_LEA:
10374       return "#";
10376     default:
10377       if (REG_P (operands[2]))
10378         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10379       else if (operands[2] == const1_rtx
10380                && (TARGET_SHIFT1 || optimize_size))
10381         return "sal{l}\t%k0";
10382       else
10383         return "sal{l}\t{%2, %k0|%k0, %2}";
10384     }
10386   [(set (attr "type")
10387      (cond [(eq_attr "alternative" "1")
10388               (const_string "lea")
10389             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10390                      (const_int 0))
10391                  (match_operand 2 "const1_operand" ""))
10392               (const_string "alu")
10393            ]
10394            (const_string "ishift")))
10395    (set_attr "mode" "SI")])
10397 ;; Convert lea to the lea pattern to avoid flags dependency.
10398 (define_split
10399   [(set (match_operand:DI 0 "register_operand" "")
10400         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10401                                 (match_operand:QI 2 "const_int_operand" ""))))
10402    (clobber (reg:CC FLAGS_REG))]
10403   "TARGET_64BIT && reload_completed
10404    && true_regnum (operands[0]) != true_regnum (operands[1])"
10405   [(set (match_dup 0) (zero_extend:DI
10406                         (subreg:SI (mult:SI (match_dup 1)
10407                                             (match_dup 2)) 0)))]
10409   operands[1] = gen_lowpart (Pmode, operands[1]);
10410   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10413 ;; This pattern can't accept a variable shift count, since shifts by
10414 ;; zero don't affect the flags.  We assume that shifts by constant
10415 ;; zero are optimized away.
10416 (define_insn "*ashlsi3_cmp"
10417   [(set (reg FLAGS_REG)
10418         (compare
10419           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10420                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10421           (const_int 0)))
10422    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10423         (ashift:SI (match_dup 1) (match_dup 2)))]
10424   "ix86_match_ccmode (insn, CCGOCmode)
10425    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10427   switch (get_attr_type (insn))
10428     {
10429     case TYPE_ALU:
10430       gcc_assert (operands[2] == const1_rtx);
10431       return "add{l}\t{%0, %0|%0, %0}";
10433     default:
10434       if (REG_P (operands[2]))
10435         return "sal{l}\t{%b2, %0|%0, %b2}";
10436       else if (operands[2] == const1_rtx
10437                && (TARGET_SHIFT1 || optimize_size))
10438         return "sal{l}\t%0";
10439       else
10440         return "sal{l}\t{%2, %0|%0, %2}";
10441     }
10443   [(set (attr "type")
10444      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10445                           (const_int 0))
10446                       (match_operand 0 "register_operand" ""))
10447                  (match_operand 2 "const1_operand" ""))
10448               (const_string "alu")
10449            ]
10450            (const_string "ishift")))
10451    (set_attr "mode" "SI")])
10453 (define_insn "*ashlsi3_cmp_zext"
10454   [(set (reg FLAGS_REG)
10455         (compare
10456           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10457                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10458           (const_int 0)))
10459    (set (match_operand:DI 0 "register_operand" "=r")
10460         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10461   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10462    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10464   switch (get_attr_type (insn))
10465     {
10466     case TYPE_ALU:
10467       gcc_assert (operands[2] == const1_rtx);
10468       return "add{l}\t{%k0, %k0|%k0, %k0}";
10470     default:
10471       if (REG_P (operands[2]))
10472         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10473       else if (operands[2] == const1_rtx
10474                && (TARGET_SHIFT1 || optimize_size))
10475         return "sal{l}\t%k0";
10476       else
10477         return "sal{l}\t{%2, %k0|%k0, %2}";
10478     }
10480   [(set (attr "type")
10481      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10482                      (const_int 0))
10483                  (match_operand 2 "const1_operand" ""))
10484               (const_string "alu")
10485            ]
10486            (const_string "ishift")))
10487    (set_attr "mode" "SI")])
10489 (define_expand "ashlhi3"
10490   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10491         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10492                    (match_operand:QI 2 "nonmemory_operand" "")))
10493    (clobber (reg:CC FLAGS_REG))]
10494   "TARGET_HIMODE_MATH"
10495   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10497 (define_insn "*ashlhi3_1_lea"
10498   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10499         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10500                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10501    (clobber (reg:CC FLAGS_REG))]
10502   "!TARGET_PARTIAL_REG_STALL
10503    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10505   switch (get_attr_type (insn))
10506     {
10507     case TYPE_LEA:
10508       return "#";
10509     case TYPE_ALU:
10510       gcc_assert (operands[2] == const1_rtx);
10511       return "add{w}\t{%0, %0|%0, %0}";
10513     default:
10514       if (REG_P (operands[2]))
10515         return "sal{w}\t{%b2, %0|%0, %b2}";
10516       else if (operands[2] == const1_rtx
10517                && (TARGET_SHIFT1 || optimize_size))
10518         return "sal{w}\t%0";
10519       else
10520         return "sal{w}\t{%2, %0|%0, %2}";
10521     }
10523   [(set (attr "type")
10524      (cond [(eq_attr "alternative" "1")
10525               (const_string "lea")
10526             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10527                           (const_int 0))
10528                       (match_operand 0 "register_operand" ""))
10529                  (match_operand 2 "const1_operand" ""))
10530               (const_string "alu")
10531            ]
10532            (const_string "ishift")))
10533    (set_attr "mode" "HI,SI")])
10535 (define_insn "*ashlhi3_1"
10536   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10537         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10538                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10539    (clobber (reg:CC FLAGS_REG))]
10540   "TARGET_PARTIAL_REG_STALL
10541    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10543   switch (get_attr_type (insn))
10544     {
10545     case TYPE_ALU:
10546       gcc_assert (operands[2] == const1_rtx);
10547       return "add{w}\t{%0, %0|%0, %0}";
10549     default:
10550       if (REG_P (operands[2]))
10551         return "sal{w}\t{%b2, %0|%0, %b2}";
10552       else if (operands[2] == const1_rtx
10553                && (TARGET_SHIFT1 || optimize_size))
10554         return "sal{w}\t%0";
10555       else
10556         return "sal{w}\t{%2, %0|%0, %2}";
10557     }
10559   [(set (attr "type")
10560      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10561                           (const_int 0))
10562                       (match_operand 0 "register_operand" ""))
10563                  (match_operand 2 "const1_operand" ""))
10564               (const_string "alu")
10565            ]
10566            (const_string "ishift")))
10567    (set_attr "mode" "HI")])
10569 ;; This pattern can't accept a variable shift count, since shifts by
10570 ;; zero don't affect the flags.  We assume that shifts by constant
10571 ;; zero are optimized away.
10572 (define_insn "*ashlhi3_cmp"
10573   [(set (reg FLAGS_REG)
10574         (compare
10575           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10576                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10577           (const_int 0)))
10578    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10579         (ashift:HI (match_dup 1) (match_dup 2)))]
10580   "ix86_match_ccmode (insn, CCGOCmode)
10581    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10583   switch (get_attr_type (insn))
10584     {
10585     case TYPE_ALU:
10586       gcc_assert (operands[2] == const1_rtx);
10587       return "add{w}\t{%0, %0|%0, %0}";
10589     default:
10590       if (REG_P (operands[2]))
10591         return "sal{w}\t{%b2, %0|%0, %b2}";
10592       else if (operands[2] == const1_rtx
10593                && (TARGET_SHIFT1 || optimize_size))
10594         return "sal{w}\t%0";
10595       else
10596         return "sal{w}\t{%2, %0|%0, %2}";
10597     }
10599   [(set (attr "type")
10600      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10601                           (const_int 0))
10602                       (match_operand 0 "register_operand" ""))
10603                  (match_operand 2 "const1_operand" ""))
10604               (const_string "alu")
10605            ]
10606            (const_string "ishift")))
10607    (set_attr "mode" "HI")])
10609 (define_expand "ashlqi3"
10610   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10611         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10612                    (match_operand:QI 2 "nonmemory_operand" "")))
10613    (clobber (reg:CC FLAGS_REG))]
10614   "TARGET_QIMODE_MATH"
10615   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10617 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10619 (define_insn "*ashlqi3_1_lea"
10620   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10621         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10622                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10623    (clobber (reg:CC FLAGS_REG))]
10624   "!TARGET_PARTIAL_REG_STALL
10625    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10627   switch (get_attr_type (insn))
10628     {
10629     case TYPE_LEA:
10630       return "#";
10631     case TYPE_ALU:
10632       gcc_assert (operands[2] == const1_rtx);
10633       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10634         return "add{l}\t{%k0, %k0|%k0, %k0}";
10635       else
10636         return "add{b}\t{%0, %0|%0, %0}";
10638     default:
10639       if (REG_P (operands[2]))
10640         {
10641           if (get_attr_mode (insn) == MODE_SI)
10642             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10643           else
10644             return "sal{b}\t{%b2, %0|%0, %b2}";
10645         }
10646       else if (operands[2] == const1_rtx
10647                && (TARGET_SHIFT1 || optimize_size))
10648         {
10649           if (get_attr_mode (insn) == MODE_SI)
10650             return "sal{l}\t%0";
10651           else
10652             return "sal{b}\t%0";
10653         }
10654       else
10655         {
10656           if (get_attr_mode (insn) == MODE_SI)
10657             return "sal{l}\t{%2, %k0|%k0, %2}";
10658           else
10659             return "sal{b}\t{%2, %0|%0, %2}";
10660         }
10661     }
10663   [(set (attr "type")
10664      (cond [(eq_attr "alternative" "2")
10665               (const_string "lea")
10666             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10667                           (const_int 0))
10668                       (match_operand 0 "register_operand" ""))
10669                  (match_operand 2 "const1_operand" ""))
10670               (const_string "alu")
10671            ]
10672            (const_string "ishift")))
10673    (set_attr "mode" "QI,SI,SI")])
10675 (define_insn "*ashlqi3_1"
10676   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10677         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10678                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10679    (clobber (reg:CC FLAGS_REG))]
10680   "TARGET_PARTIAL_REG_STALL
10681    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10683   switch (get_attr_type (insn))
10684     {
10685     case TYPE_ALU:
10686       gcc_assert (operands[2] == const1_rtx);
10687       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10688         return "add{l}\t{%k0, %k0|%k0, %k0}";
10689       else
10690         return "add{b}\t{%0, %0|%0, %0}";
10692     default:
10693       if (REG_P (operands[2]))
10694         {
10695           if (get_attr_mode (insn) == MODE_SI)
10696             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10697           else
10698             return "sal{b}\t{%b2, %0|%0, %b2}";
10699         }
10700       else if (operands[2] == const1_rtx
10701                && (TARGET_SHIFT1 || optimize_size))
10702         {
10703           if (get_attr_mode (insn) == MODE_SI)
10704             return "sal{l}\t%0";
10705           else
10706             return "sal{b}\t%0";
10707         }
10708       else
10709         {
10710           if (get_attr_mode (insn) == MODE_SI)
10711             return "sal{l}\t{%2, %k0|%k0, %2}";
10712           else
10713             return "sal{b}\t{%2, %0|%0, %2}";
10714         }
10715     }
10717   [(set (attr "type")
10718      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10719                           (const_int 0))
10720                       (match_operand 0 "register_operand" ""))
10721                  (match_operand 2 "const1_operand" ""))
10722               (const_string "alu")
10723            ]
10724            (const_string "ishift")))
10725    (set_attr "mode" "QI,SI")])
10727 ;; This pattern can't accept a variable shift count, since shifts by
10728 ;; zero don't affect the flags.  We assume that shifts by constant
10729 ;; zero are optimized away.
10730 (define_insn "*ashlqi3_cmp"
10731   [(set (reg FLAGS_REG)
10732         (compare
10733           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10734                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10735           (const_int 0)))
10736    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10737         (ashift:QI (match_dup 1) (match_dup 2)))]
10738   "ix86_match_ccmode (insn, CCGOCmode)
10739    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10741   switch (get_attr_type (insn))
10742     {
10743     case TYPE_ALU:
10744       gcc_assert (operands[2] == const1_rtx);
10745       return "add{b}\t{%0, %0|%0, %0}";
10747     default:
10748       if (REG_P (operands[2]))
10749         return "sal{b}\t{%b2, %0|%0, %b2}";
10750       else if (operands[2] == const1_rtx
10751                && (TARGET_SHIFT1 || optimize_size))
10752         return "sal{b}\t%0";
10753       else
10754         return "sal{b}\t{%2, %0|%0, %2}";
10755     }
10757   [(set (attr "type")
10758      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10759                           (const_int 0))
10760                       (match_operand 0 "register_operand" ""))
10761                  (match_operand 2 "const1_operand" ""))
10762               (const_string "alu")
10763            ]
10764            (const_string "ishift")))
10765    (set_attr "mode" "QI")])
10767 ;; See comment above `ashldi3' about how this works.
10769 (define_expand "ashrdi3"
10770   [(set (match_operand:DI 0 "shiftdi_operand" "")
10771         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10772                      (match_operand:QI 2 "nonmemory_operand" "")))]
10773   ""
10774   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10776 (define_insn "*ashrdi3_63_rex64"
10777   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10778         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10779                      (match_operand:DI 2 "const_int_operand" "i,i")))
10780    (clobber (reg:CC FLAGS_REG))]
10781   "TARGET_64BIT && INTVAL (operands[2]) == 63
10782    && (TARGET_USE_CLTD || optimize_size)
10783    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10784   "@
10785    {cqto|cqo}
10786    sar{q}\t{%2, %0|%0, %2}"
10787   [(set_attr "type" "imovx,ishift")
10788    (set_attr "prefix_0f" "0,*")
10789    (set_attr "length_immediate" "0,*")
10790    (set_attr "modrm" "0,1")
10791    (set_attr "mode" "DI")])
10793 (define_insn "*ashrdi3_1_one_bit_rex64"
10794   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10795         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10796                      (match_operand:QI 2 "const1_operand" "")))
10797    (clobber (reg:CC FLAGS_REG))]
10798   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10799    && (TARGET_SHIFT1 || optimize_size)"
10800   "sar{q}\t%0"
10801   [(set_attr "type" "ishift")
10802    (set (attr "length") 
10803      (if_then_else (match_operand:DI 0 "register_operand" "") 
10804         (const_string "2")
10805         (const_string "*")))])
10807 (define_insn "*ashrdi3_1_rex64"
10808   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10809         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10810                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10811    (clobber (reg:CC FLAGS_REG))]
10812   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10813   "@
10814    sar{q}\t{%2, %0|%0, %2}
10815    sar{q}\t{%b2, %0|%0, %b2}"
10816   [(set_attr "type" "ishift")
10817    (set_attr "mode" "DI")])
10819 ;; This pattern can't accept a variable shift count, since shifts by
10820 ;; zero don't affect the flags.  We assume that shifts by constant
10821 ;; zero are optimized away.
10822 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10823   [(set (reg FLAGS_REG)
10824         (compare
10825           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10826                        (match_operand:QI 2 "const1_operand" ""))
10827           (const_int 0)))
10828    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10829         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10830   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10831    && (TARGET_SHIFT1 || optimize_size)
10832    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10833   "sar{q}\t%0"
10834   [(set_attr "type" "ishift")
10835    (set (attr "length") 
10836      (if_then_else (match_operand:DI 0 "register_operand" "") 
10837         (const_string "2")
10838         (const_string "*")))])
10840 ;; This pattern can't accept a variable shift count, since shifts by
10841 ;; zero don't affect the flags.  We assume that shifts by constant
10842 ;; zero are optimized away.
10843 (define_insn "*ashrdi3_cmp_rex64"
10844   [(set (reg FLAGS_REG)
10845         (compare
10846           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10847                        (match_operand:QI 2 "const_int_operand" "n"))
10848           (const_int 0)))
10849    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10850         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10851   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10852    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10853   "sar{q}\t{%2, %0|%0, %2}"
10854   [(set_attr "type" "ishift")
10855    (set_attr "mode" "DI")])
10857 (define_insn "*ashrdi3_1"
10858   [(set (match_operand:DI 0 "register_operand" "=r")
10859         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10860                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10861    (clobber (reg:CC FLAGS_REG))]
10862   "!TARGET_64BIT"
10863   "#"
10864   [(set_attr "type" "multi")])
10866 ;; By default we don't ask for a scratch register, because when DImode
10867 ;; values are manipulated, registers are already at a premium.  But if
10868 ;; we have one handy, we won't turn it away.
10869 (define_peephole2
10870   [(match_scratch:SI 3 "r")
10871    (parallel [(set (match_operand:DI 0 "register_operand" "")
10872                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10873                                 (match_operand:QI 2 "nonmemory_operand" "")))
10874               (clobber (reg:CC FLAGS_REG))])
10875    (match_dup 3)]
10876   "!TARGET_64BIT && TARGET_CMOVE"
10877   [(const_int 0)]
10878   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10880 (define_split
10881   [(set (match_operand:DI 0 "register_operand" "")
10882         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10883                      (match_operand:QI 2 "nonmemory_operand" "")))
10884    (clobber (reg:CC FLAGS_REG))]
10885   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10886   [(const_int 0)]
10887   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10889 (define_insn "x86_shrd_1"
10890   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10891         (ior:SI (ashiftrt:SI (match_dup 0)
10892                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10893                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10894                   (minus:QI (const_int 32) (match_dup 2)))))
10895    (clobber (reg:CC FLAGS_REG))]
10896   ""
10897   "@
10898    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10899    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10900   [(set_attr "type" "ishift")
10901    (set_attr "prefix_0f" "1")
10902    (set_attr "pent_pair" "np")
10903    (set_attr "mode" "SI")])
10905 (define_expand "x86_shift_adj_3"
10906   [(use (match_operand:SI 0 "register_operand" ""))
10907    (use (match_operand:SI 1 "register_operand" ""))
10908    (use (match_operand:QI 2 "register_operand" ""))]
10909   ""
10911   rtx label = gen_label_rtx ();
10912   rtx tmp;
10914   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10916   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10917   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10918   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10919                               gen_rtx_LABEL_REF (VOIDmode, label),
10920                               pc_rtx);
10921   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10922   JUMP_LABEL (tmp) = label;
10924   emit_move_insn (operands[0], operands[1]);
10925   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10927   emit_label (label);
10928   LABEL_NUSES (label) = 1;
10930   DONE;
10933 (define_insn "ashrsi3_31"
10934   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10935         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10936                      (match_operand:SI 2 "const_int_operand" "i,i")))
10937    (clobber (reg:CC FLAGS_REG))]
10938   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10939    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10940   "@
10941    {cltd|cdq}
10942    sar{l}\t{%2, %0|%0, %2}"
10943   [(set_attr "type" "imovx,ishift")
10944    (set_attr "prefix_0f" "0,*")
10945    (set_attr "length_immediate" "0,*")
10946    (set_attr "modrm" "0,1")
10947    (set_attr "mode" "SI")])
10949 (define_insn "*ashrsi3_31_zext"
10950   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10951         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10952                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10953    (clobber (reg:CC FLAGS_REG))]
10954   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10955    && INTVAL (operands[2]) == 31
10956    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10957   "@
10958    {cltd|cdq}
10959    sar{l}\t{%2, %k0|%k0, %2}"
10960   [(set_attr "type" "imovx,ishift")
10961    (set_attr "prefix_0f" "0,*")
10962    (set_attr "length_immediate" "0,*")
10963    (set_attr "modrm" "0,1")
10964    (set_attr "mode" "SI")])
10966 (define_expand "ashrsi3"
10967   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10968         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10969                      (match_operand:QI 2 "nonmemory_operand" "")))
10970    (clobber (reg:CC FLAGS_REG))]
10971   ""
10972   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10974 (define_insn "*ashrsi3_1_one_bit"
10975   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10976         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10977                      (match_operand:QI 2 "const1_operand" "")))
10978    (clobber (reg:CC FLAGS_REG))]
10979   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10980    && (TARGET_SHIFT1 || optimize_size)"
10981   "sar{l}\t%0"
10982   [(set_attr "type" "ishift")
10983    (set (attr "length") 
10984      (if_then_else (match_operand:SI 0 "register_operand" "") 
10985         (const_string "2")
10986         (const_string "*")))])
10988 (define_insn "*ashrsi3_1_one_bit_zext"
10989   [(set (match_operand:DI 0 "register_operand" "=r")
10990         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10991                                      (match_operand:QI 2 "const1_operand" ""))))
10992    (clobber (reg:CC FLAGS_REG))]
10993   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10994    && (TARGET_SHIFT1 || optimize_size)"
10995   "sar{l}\t%k0"
10996   [(set_attr "type" "ishift")
10997    (set_attr "length" "2")])
10999 (define_insn "*ashrsi3_1"
11000   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11001         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11002                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11003    (clobber (reg:CC FLAGS_REG))]
11004   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11005   "@
11006    sar{l}\t{%2, %0|%0, %2}
11007    sar{l}\t{%b2, %0|%0, %b2}"
11008   [(set_attr "type" "ishift")
11009    (set_attr "mode" "SI")])
11011 (define_insn "*ashrsi3_1_zext"
11012   [(set (match_operand:DI 0 "register_operand" "=r,r")
11013         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11014                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11015    (clobber (reg:CC FLAGS_REG))]
11016   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11017   "@
11018    sar{l}\t{%2, %k0|%k0, %2}
11019    sar{l}\t{%b2, %k0|%k0, %b2}"
11020   [(set_attr "type" "ishift")
11021    (set_attr "mode" "SI")])
11023 ;; This pattern can't accept a variable shift count, since shifts by
11024 ;; zero don't affect the flags.  We assume that shifts by constant
11025 ;; zero are optimized away.
11026 (define_insn "*ashrsi3_one_bit_cmp"
11027   [(set (reg FLAGS_REG)
11028         (compare
11029           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11030                        (match_operand:QI 2 "const1_operand" ""))
11031           (const_int 0)))
11032    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11033         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11034   "ix86_match_ccmode (insn, CCGOCmode)
11035    && (TARGET_SHIFT1 || optimize_size)
11036    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11037   "sar{l}\t%0"
11038   [(set_attr "type" "ishift")
11039    (set (attr "length") 
11040      (if_then_else (match_operand:SI 0 "register_operand" "") 
11041         (const_string "2")
11042         (const_string "*")))])
11044 (define_insn "*ashrsi3_one_bit_cmp_zext"
11045   [(set (reg FLAGS_REG)
11046         (compare
11047           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11048                        (match_operand:QI 2 "const1_operand" ""))
11049           (const_int 0)))
11050    (set (match_operand:DI 0 "register_operand" "=r")
11051         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11052   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11053    && (TARGET_SHIFT1 || optimize_size)
11054    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11055   "sar{l}\t%k0"
11056   [(set_attr "type" "ishift")
11057    (set_attr "length" "2")])
11059 ;; This pattern can't accept a variable shift count, since shifts by
11060 ;; zero don't affect the flags.  We assume that shifts by constant
11061 ;; zero are optimized away.
11062 (define_insn "*ashrsi3_cmp"
11063   [(set (reg FLAGS_REG)
11064         (compare
11065           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11066                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11067           (const_int 0)))
11068    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11069         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11070   "ix86_match_ccmode (insn, CCGOCmode)
11071    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11072   "sar{l}\t{%2, %0|%0, %2}"
11073   [(set_attr "type" "ishift")
11074    (set_attr "mode" "SI")])
11076 (define_insn "*ashrsi3_cmp_zext"
11077   [(set (reg FLAGS_REG)
11078         (compare
11079           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11080                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11081           (const_int 0)))
11082    (set (match_operand:DI 0 "register_operand" "=r")
11083         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11084   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11085    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11086   "sar{l}\t{%2, %k0|%k0, %2}"
11087   [(set_attr "type" "ishift")
11088    (set_attr "mode" "SI")])
11090 (define_expand "ashrhi3"
11091   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11092         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11093                      (match_operand:QI 2 "nonmemory_operand" "")))
11094    (clobber (reg:CC FLAGS_REG))]
11095   "TARGET_HIMODE_MATH"
11096   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11098 (define_insn "*ashrhi3_1_one_bit"
11099   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11100         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11101                      (match_operand:QI 2 "const1_operand" "")))
11102    (clobber (reg:CC FLAGS_REG))]
11103   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11104    && (TARGET_SHIFT1 || optimize_size)"
11105   "sar{w}\t%0"
11106   [(set_attr "type" "ishift")
11107    (set (attr "length") 
11108      (if_then_else (match_operand 0 "register_operand" "") 
11109         (const_string "2")
11110         (const_string "*")))])
11112 (define_insn "*ashrhi3_1"
11113   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11114         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11115                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11116    (clobber (reg:CC FLAGS_REG))]
11117   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11118   "@
11119    sar{w}\t{%2, %0|%0, %2}
11120    sar{w}\t{%b2, %0|%0, %b2}"
11121   [(set_attr "type" "ishift")
11122    (set_attr "mode" "HI")])
11124 ;; This pattern can't accept a variable shift count, since shifts by
11125 ;; zero don't affect the flags.  We assume that shifts by constant
11126 ;; zero are optimized away.
11127 (define_insn "*ashrhi3_one_bit_cmp"
11128   [(set (reg FLAGS_REG)
11129         (compare
11130           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11131                        (match_operand:QI 2 "const1_operand" ""))
11132           (const_int 0)))
11133    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11134         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11135   "ix86_match_ccmode (insn, CCGOCmode)
11136    && (TARGET_SHIFT1 || optimize_size)
11137    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11138   "sar{w}\t%0"
11139   [(set_attr "type" "ishift")
11140    (set (attr "length") 
11141      (if_then_else (match_operand 0 "register_operand" "") 
11142         (const_string "2")
11143         (const_string "*")))])
11145 ;; This pattern can't accept a variable shift count, since shifts by
11146 ;; zero don't affect the flags.  We assume that shifts by constant
11147 ;; zero are optimized away.
11148 (define_insn "*ashrhi3_cmp"
11149   [(set (reg FLAGS_REG)
11150         (compare
11151           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11152                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11153           (const_int 0)))
11154    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11155         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11156   "ix86_match_ccmode (insn, CCGOCmode)
11157    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11158   "sar{w}\t{%2, %0|%0, %2}"
11159   [(set_attr "type" "ishift")
11160    (set_attr "mode" "HI")])
11162 (define_expand "ashrqi3"
11163   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11164         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11165                      (match_operand:QI 2 "nonmemory_operand" "")))
11166    (clobber (reg:CC FLAGS_REG))]
11167   "TARGET_QIMODE_MATH"
11168   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11170 (define_insn "*ashrqi3_1_one_bit"
11171   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11172         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11173                      (match_operand:QI 2 "const1_operand" "")))
11174    (clobber (reg:CC FLAGS_REG))]
11175   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11176    && (TARGET_SHIFT1 || optimize_size)"
11177   "sar{b}\t%0"
11178   [(set_attr "type" "ishift")
11179    (set (attr "length") 
11180      (if_then_else (match_operand 0 "register_operand" "") 
11181         (const_string "2")
11182         (const_string "*")))])
11184 (define_insn "*ashrqi3_1_one_bit_slp"
11185   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11186         (ashiftrt:QI (match_dup 0)
11187                      (match_operand:QI 1 "const1_operand" "")))
11188    (clobber (reg:CC FLAGS_REG))]
11189   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11190    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11191    && (TARGET_SHIFT1 || optimize_size)"
11192   "sar{b}\t%0"
11193   [(set_attr "type" "ishift1")
11194    (set (attr "length") 
11195      (if_then_else (match_operand 0 "register_operand" "") 
11196         (const_string "2")
11197         (const_string "*")))])
11199 (define_insn "*ashrqi3_1"
11200   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11201         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11202                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11203    (clobber (reg:CC FLAGS_REG))]
11204   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11205   "@
11206    sar{b}\t{%2, %0|%0, %2}
11207    sar{b}\t{%b2, %0|%0, %b2}"
11208   [(set_attr "type" "ishift")
11209    (set_attr "mode" "QI")])
11211 (define_insn "*ashrqi3_1_slp"
11212   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11213         (ashiftrt:QI (match_dup 0)
11214                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11215    (clobber (reg:CC FLAGS_REG))]
11216   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11217    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11218   "@
11219    sar{b}\t{%1, %0|%0, %1}
11220    sar{b}\t{%b1, %0|%0, %b1}"
11221   [(set_attr "type" "ishift1")
11222    (set_attr "mode" "QI")])
11224 ;; This pattern can't accept a variable shift count, since shifts by
11225 ;; zero don't affect the flags.  We assume that shifts by constant
11226 ;; zero are optimized away.
11227 (define_insn "*ashrqi3_one_bit_cmp"
11228   [(set (reg FLAGS_REG)
11229         (compare
11230           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11231                        (match_operand:QI 2 "const1_operand" "I"))
11232           (const_int 0)))
11233    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11234         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11235   "ix86_match_ccmode (insn, CCGOCmode)
11236    && (TARGET_SHIFT1 || optimize_size)
11237    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11238   "sar{b}\t%0"
11239   [(set_attr "type" "ishift")
11240    (set (attr "length") 
11241      (if_then_else (match_operand 0 "register_operand" "") 
11242         (const_string "2")
11243         (const_string "*")))])
11245 ;; This pattern can't accept a variable shift count, since shifts by
11246 ;; zero don't affect the flags.  We assume that shifts by constant
11247 ;; zero are optimized away.
11248 (define_insn "*ashrqi3_cmp"
11249   [(set (reg FLAGS_REG)
11250         (compare
11251           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11252                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11253           (const_int 0)))
11254    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11255         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11256   "ix86_match_ccmode (insn, CCGOCmode)
11257    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11258   "sar{b}\t{%2, %0|%0, %2}"
11259   [(set_attr "type" "ishift")
11260    (set_attr "mode" "QI")])
11262 ;; Logical shift instructions
11264 ;; See comment above `ashldi3' about how this works.
11266 (define_expand "lshrdi3"
11267   [(set (match_operand:DI 0 "shiftdi_operand" "")
11268         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11269                      (match_operand:QI 2 "nonmemory_operand" "")))]
11270   ""
11271   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11273 (define_insn "*lshrdi3_1_one_bit_rex64"
11274   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11275         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11276                      (match_operand:QI 2 "const1_operand" "")))
11277    (clobber (reg:CC FLAGS_REG))]
11278   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11279    && (TARGET_SHIFT1 || optimize_size)"
11280   "shr{q}\t%0"
11281   [(set_attr "type" "ishift")
11282    (set (attr "length") 
11283      (if_then_else (match_operand:DI 0 "register_operand" "") 
11284         (const_string "2")
11285         (const_string "*")))])
11287 (define_insn "*lshrdi3_1_rex64"
11288   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11289         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11290                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11291    (clobber (reg:CC FLAGS_REG))]
11292   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11293   "@
11294    shr{q}\t{%2, %0|%0, %2}
11295    shr{q}\t{%b2, %0|%0, %b2}"
11296   [(set_attr "type" "ishift")
11297    (set_attr "mode" "DI")])
11299 ;; This pattern can't accept a variable shift count, since shifts by
11300 ;; zero don't affect the flags.  We assume that shifts by constant
11301 ;; zero are optimized away.
11302 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11303   [(set (reg FLAGS_REG)
11304         (compare
11305           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11306                        (match_operand:QI 2 "const1_operand" ""))
11307           (const_int 0)))
11308    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11309         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11310   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11311    && (TARGET_SHIFT1 || optimize_size)
11312    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11313   "shr{q}\t%0"
11314   [(set_attr "type" "ishift")
11315    (set (attr "length") 
11316      (if_then_else (match_operand:DI 0 "register_operand" "") 
11317         (const_string "2")
11318         (const_string "*")))])
11320 ;; This pattern can't accept a variable shift count, since shifts by
11321 ;; zero don't affect the flags.  We assume that shifts by constant
11322 ;; zero are optimized away.
11323 (define_insn "*lshrdi3_cmp_rex64"
11324   [(set (reg FLAGS_REG)
11325         (compare
11326           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11327                        (match_operand:QI 2 "const_int_operand" "e"))
11328           (const_int 0)))
11329    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11330         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11331   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11332    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11333   "shr{q}\t{%2, %0|%0, %2}"
11334   [(set_attr "type" "ishift")
11335    (set_attr "mode" "DI")])
11337 (define_insn "*lshrdi3_1"
11338   [(set (match_operand:DI 0 "register_operand" "=r")
11339         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11340                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11341    (clobber (reg:CC FLAGS_REG))]
11342   "!TARGET_64BIT"
11343   "#"
11344   [(set_attr "type" "multi")])
11346 ;; By default we don't ask for a scratch register, because when DImode
11347 ;; values are manipulated, registers are already at a premium.  But if
11348 ;; we have one handy, we won't turn it away.
11349 (define_peephole2
11350   [(match_scratch:SI 3 "r")
11351    (parallel [(set (match_operand:DI 0 "register_operand" "")
11352                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11353                                 (match_operand:QI 2 "nonmemory_operand" "")))
11354               (clobber (reg:CC FLAGS_REG))])
11355    (match_dup 3)]
11356   "!TARGET_64BIT && TARGET_CMOVE"
11357   [(const_int 0)]
11358   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11360 (define_split 
11361   [(set (match_operand:DI 0 "register_operand" "")
11362         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11363                      (match_operand:QI 2 "nonmemory_operand" "")))
11364    (clobber (reg:CC FLAGS_REG))]
11365   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11366   [(const_int 0)]
11367   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11369 (define_expand "lshrsi3"
11370   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11371         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11372                      (match_operand:QI 2 "nonmemory_operand" "")))
11373    (clobber (reg:CC FLAGS_REG))]
11374   ""
11375   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11377 (define_insn "*lshrsi3_1_one_bit"
11378   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11379         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11380                      (match_operand:QI 2 "const1_operand" "")))
11381    (clobber (reg:CC FLAGS_REG))]
11382   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11383    && (TARGET_SHIFT1 || optimize_size)"
11384   "shr{l}\t%0"
11385   [(set_attr "type" "ishift")
11386    (set (attr "length") 
11387      (if_then_else (match_operand:SI 0 "register_operand" "") 
11388         (const_string "2")
11389         (const_string "*")))])
11391 (define_insn "*lshrsi3_1_one_bit_zext"
11392   [(set (match_operand:DI 0 "register_operand" "=r")
11393         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11394                      (match_operand:QI 2 "const1_operand" "")))
11395    (clobber (reg:CC FLAGS_REG))]
11396   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11397    && (TARGET_SHIFT1 || optimize_size)"
11398   "shr{l}\t%k0"
11399   [(set_attr "type" "ishift")
11400    (set_attr "length" "2")])
11402 (define_insn "*lshrsi3_1"
11403   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11404         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11405                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11406    (clobber (reg:CC FLAGS_REG))]
11407   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11408   "@
11409    shr{l}\t{%2, %0|%0, %2}
11410    shr{l}\t{%b2, %0|%0, %b2}"
11411   [(set_attr "type" "ishift")
11412    (set_attr "mode" "SI")])
11414 (define_insn "*lshrsi3_1_zext"
11415   [(set (match_operand:DI 0 "register_operand" "=r,r")
11416         (zero_extend:DI
11417           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11418                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11419    (clobber (reg:CC FLAGS_REG))]
11420   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11421   "@
11422    shr{l}\t{%2, %k0|%k0, %2}
11423    shr{l}\t{%b2, %k0|%k0, %b2}"
11424   [(set_attr "type" "ishift")
11425    (set_attr "mode" "SI")])
11427 ;; This pattern can't accept a variable shift count, since shifts by
11428 ;; zero don't affect the flags.  We assume that shifts by constant
11429 ;; zero are optimized away.
11430 (define_insn "*lshrsi3_one_bit_cmp"
11431   [(set (reg FLAGS_REG)
11432         (compare
11433           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11434                        (match_operand:QI 2 "const1_operand" ""))
11435           (const_int 0)))
11436    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11437         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11438   "ix86_match_ccmode (insn, CCGOCmode)
11439    && (TARGET_SHIFT1 || optimize_size)
11440    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11441   "shr{l}\t%0"
11442   [(set_attr "type" "ishift")
11443    (set (attr "length") 
11444      (if_then_else (match_operand:SI 0 "register_operand" "") 
11445         (const_string "2")
11446         (const_string "*")))])
11448 (define_insn "*lshrsi3_cmp_one_bit_zext"
11449   [(set (reg FLAGS_REG)
11450         (compare
11451           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11452                        (match_operand:QI 2 "const1_operand" ""))
11453           (const_int 0)))
11454    (set (match_operand:DI 0 "register_operand" "=r")
11455         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11456   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11457    && (TARGET_SHIFT1 || optimize_size)
11458    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11459   "shr{l}\t%k0"
11460   [(set_attr "type" "ishift")
11461    (set_attr "length" "2")])
11463 ;; This pattern can't accept a variable shift count, since shifts by
11464 ;; zero don't affect the flags.  We assume that shifts by constant
11465 ;; zero are optimized away.
11466 (define_insn "*lshrsi3_cmp"
11467   [(set (reg FLAGS_REG)
11468         (compare
11469           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11470                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11471           (const_int 0)))
11472    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11473         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11474   "ix86_match_ccmode (insn, CCGOCmode)
11475    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11476   "shr{l}\t{%2, %0|%0, %2}"
11477   [(set_attr "type" "ishift")
11478    (set_attr "mode" "SI")])
11480 (define_insn "*lshrsi3_cmp_zext"
11481   [(set (reg FLAGS_REG)
11482         (compare
11483           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11484                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11485           (const_int 0)))
11486    (set (match_operand:DI 0 "register_operand" "=r")
11487         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11488   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11489    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11490   "shr{l}\t{%2, %k0|%k0, %2}"
11491   [(set_attr "type" "ishift")
11492    (set_attr "mode" "SI")])
11494 (define_expand "lshrhi3"
11495   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11496         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11497                      (match_operand:QI 2 "nonmemory_operand" "")))
11498    (clobber (reg:CC FLAGS_REG))]
11499   "TARGET_HIMODE_MATH"
11500   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11502 (define_insn "*lshrhi3_1_one_bit"
11503   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11504         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11505                      (match_operand:QI 2 "const1_operand" "")))
11506    (clobber (reg:CC FLAGS_REG))]
11507   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11508    && (TARGET_SHIFT1 || optimize_size)"
11509   "shr{w}\t%0"
11510   [(set_attr "type" "ishift")
11511    (set (attr "length") 
11512      (if_then_else (match_operand 0 "register_operand" "") 
11513         (const_string "2")
11514         (const_string "*")))])
11516 (define_insn "*lshrhi3_1"
11517   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11518         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11519                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11520    (clobber (reg:CC FLAGS_REG))]
11521   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11522   "@
11523    shr{w}\t{%2, %0|%0, %2}
11524    shr{w}\t{%b2, %0|%0, %b2}"
11525   [(set_attr "type" "ishift")
11526    (set_attr "mode" "HI")])
11528 ;; This pattern can't accept a variable shift count, since shifts by
11529 ;; zero don't affect the flags.  We assume that shifts by constant
11530 ;; zero are optimized away.
11531 (define_insn "*lshrhi3_one_bit_cmp"
11532   [(set (reg FLAGS_REG)
11533         (compare
11534           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11535                        (match_operand:QI 2 "const1_operand" ""))
11536           (const_int 0)))
11537    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11538         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11539   "ix86_match_ccmode (insn, CCGOCmode)
11540    && (TARGET_SHIFT1 || optimize_size)
11541    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11542   "shr{w}\t%0"
11543   [(set_attr "type" "ishift")
11544    (set (attr "length") 
11545      (if_then_else (match_operand:SI 0 "register_operand" "") 
11546         (const_string "2")
11547         (const_string "*")))])
11549 ;; This pattern can't accept a variable shift count, since shifts by
11550 ;; zero don't affect the flags.  We assume that shifts by constant
11551 ;; zero are optimized away.
11552 (define_insn "*lshrhi3_cmp"
11553   [(set (reg FLAGS_REG)
11554         (compare
11555           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11556                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11557           (const_int 0)))
11558    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11559         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11560   "ix86_match_ccmode (insn, CCGOCmode)
11561    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11562   "shr{w}\t{%2, %0|%0, %2}"
11563   [(set_attr "type" "ishift")
11564    (set_attr "mode" "HI")])
11566 (define_expand "lshrqi3"
11567   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11568         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11569                      (match_operand:QI 2 "nonmemory_operand" "")))
11570    (clobber (reg:CC FLAGS_REG))]
11571   "TARGET_QIMODE_MATH"
11572   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11574 (define_insn "*lshrqi3_1_one_bit"
11575   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11576         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11577                      (match_operand:QI 2 "const1_operand" "")))
11578    (clobber (reg:CC FLAGS_REG))]
11579   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11580    && (TARGET_SHIFT1 || optimize_size)"
11581   "shr{b}\t%0"
11582   [(set_attr "type" "ishift")
11583    (set (attr "length") 
11584      (if_then_else (match_operand 0 "register_operand" "") 
11585         (const_string "2")
11586         (const_string "*")))])
11588 (define_insn "*lshrqi3_1_one_bit_slp"
11589   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11590         (lshiftrt:QI (match_dup 0)
11591                      (match_operand:QI 1 "const1_operand" "")))
11592    (clobber (reg:CC FLAGS_REG))]
11593   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11594    && (TARGET_SHIFT1 || optimize_size)"
11595   "shr{b}\t%0"
11596   [(set_attr "type" "ishift1")
11597    (set (attr "length") 
11598      (if_then_else (match_operand 0 "register_operand" "") 
11599         (const_string "2")
11600         (const_string "*")))])
11602 (define_insn "*lshrqi3_1"
11603   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11604         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11605                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11606    (clobber (reg:CC FLAGS_REG))]
11607   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11608   "@
11609    shr{b}\t{%2, %0|%0, %2}
11610    shr{b}\t{%b2, %0|%0, %b2}"
11611   [(set_attr "type" "ishift")
11612    (set_attr "mode" "QI")])
11614 (define_insn "*lshrqi3_1_slp"
11615   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11616         (lshiftrt:QI (match_dup 0)
11617                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11618    (clobber (reg:CC FLAGS_REG))]
11619   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11620    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11621   "@
11622    shr{b}\t{%1, %0|%0, %1}
11623    shr{b}\t{%b1, %0|%0, %b1}"
11624   [(set_attr "type" "ishift1")
11625    (set_attr "mode" "QI")])
11627 ;; This pattern can't accept a variable shift count, since shifts by
11628 ;; zero don't affect the flags.  We assume that shifts by constant
11629 ;; zero are optimized away.
11630 (define_insn "*lshrqi2_one_bit_cmp"
11631   [(set (reg FLAGS_REG)
11632         (compare
11633           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11634                        (match_operand:QI 2 "const1_operand" ""))
11635           (const_int 0)))
11636    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11637         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11638   "ix86_match_ccmode (insn, CCGOCmode)
11639    && (TARGET_SHIFT1 || optimize_size)
11640    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11641   "shr{b}\t%0"
11642   [(set_attr "type" "ishift")
11643    (set (attr "length") 
11644      (if_then_else (match_operand:SI 0 "register_operand" "") 
11645         (const_string "2")
11646         (const_string "*")))])
11648 ;; This pattern can't accept a variable shift count, since shifts by
11649 ;; zero don't affect the flags.  We assume that shifts by constant
11650 ;; zero are optimized away.
11651 (define_insn "*lshrqi2_cmp"
11652   [(set (reg FLAGS_REG)
11653         (compare
11654           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11655                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11656           (const_int 0)))
11657    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11658         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11659   "ix86_match_ccmode (insn, CCGOCmode)
11660    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11661   "shr{b}\t{%2, %0|%0, %2}"
11662   [(set_attr "type" "ishift")
11663    (set_attr "mode" "QI")])
11665 ;; Rotate instructions
11667 (define_expand "rotldi3"
11668   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11669         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11670                    (match_operand:QI 2 "nonmemory_operand" "")))
11671    (clobber (reg:CC FLAGS_REG))]
11672   "TARGET_64BIT"
11673   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11675 (define_insn "*rotlsi3_1_one_bit_rex64"
11676   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11677         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11678                    (match_operand:QI 2 "const1_operand" "")))
11679    (clobber (reg:CC FLAGS_REG))]
11680   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11681    && (TARGET_SHIFT1 || optimize_size)"
11682   "rol{q}\t%0"
11683   [(set_attr "type" "rotate")
11684    (set (attr "length") 
11685      (if_then_else (match_operand:DI 0 "register_operand" "") 
11686         (const_string "2")
11687         (const_string "*")))])
11689 (define_insn "*rotldi3_1_rex64"
11690   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11691         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11692                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11693    (clobber (reg:CC FLAGS_REG))]
11694   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11695   "@
11696    rol{q}\t{%2, %0|%0, %2}
11697    rol{q}\t{%b2, %0|%0, %b2}"
11698   [(set_attr "type" "rotate")
11699    (set_attr "mode" "DI")])
11701 (define_expand "rotlsi3"
11702   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11703         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11704                    (match_operand:QI 2 "nonmemory_operand" "")))
11705    (clobber (reg:CC FLAGS_REG))]
11706   ""
11707   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11709 (define_insn "*rotlsi3_1_one_bit"
11710   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11711         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11712                    (match_operand:QI 2 "const1_operand" "")))
11713    (clobber (reg:CC FLAGS_REG))]
11714   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11715    && (TARGET_SHIFT1 || optimize_size)"
11716   "rol{l}\t%0"
11717   [(set_attr "type" "rotate")
11718    (set (attr "length") 
11719      (if_then_else (match_operand:SI 0 "register_operand" "") 
11720         (const_string "2")
11721         (const_string "*")))])
11723 (define_insn "*rotlsi3_1_one_bit_zext"
11724   [(set (match_operand:DI 0 "register_operand" "=r")
11725         (zero_extend:DI
11726           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11727                      (match_operand:QI 2 "const1_operand" ""))))
11728    (clobber (reg:CC FLAGS_REG))]
11729   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11730    && (TARGET_SHIFT1 || optimize_size)"
11731   "rol{l}\t%k0"
11732   [(set_attr "type" "rotate")
11733    (set_attr "length" "2")])
11735 (define_insn "*rotlsi3_1"
11736   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11737         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11738                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11739    (clobber (reg:CC FLAGS_REG))]
11740   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11741   "@
11742    rol{l}\t{%2, %0|%0, %2}
11743    rol{l}\t{%b2, %0|%0, %b2}"
11744   [(set_attr "type" "rotate")
11745    (set_attr "mode" "SI")])
11747 (define_insn "*rotlsi3_1_zext"
11748   [(set (match_operand:DI 0 "register_operand" "=r,r")
11749         (zero_extend:DI
11750           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11751                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11752    (clobber (reg:CC FLAGS_REG))]
11753   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11754   "@
11755    rol{l}\t{%2, %k0|%k0, %2}
11756    rol{l}\t{%b2, %k0|%k0, %b2}"
11757   [(set_attr "type" "rotate")
11758    (set_attr "mode" "SI")])
11760 (define_expand "rotlhi3"
11761   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11762         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11763                    (match_operand:QI 2 "nonmemory_operand" "")))
11764    (clobber (reg:CC FLAGS_REG))]
11765   "TARGET_HIMODE_MATH"
11766   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11768 (define_insn "*rotlhi3_1_one_bit"
11769   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11770         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11771                    (match_operand:QI 2 "const1_operand" "")))
11772    (clobber (reg:CC FLAGS_REG))]
11773   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11774    && (TARGET_SHIFT1 || optimize_size)"
11775   "rol{w}\t%0"
11776   [(set_attr "type" "rotate")
11777    (set (attr "length") 
11778      (if_then_else (match_operand 0 "register_operand" "") 
11779         (const_string "2")
11780         (const_string "*")))])
11782 (define_insn "*rotlhi3_1"
11783   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11784         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11785                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11786    (clobber (reg:CC FLAGS_REG))]
11787   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11788   "@
11789    rol{w}\t{%2, %0|%0, %2}
11790    rol{w}\t{%b2, %0|%0, %b2}"
11791   [(set_attr "type" "rotate")
11792    (set_attr "mode" "HI")])
11794 (define_expand "rotlqi3"
11795   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11796         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11797                    (match_operand:QI 2 "nonmemory_operand" "")))
11798    (clobber (reg:CC FLAGS_REG))]
11799   "TARGET_QIMODE_MATH"
11800   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11802 (define_insn "*rotlqi3_1_one_bit_slp"
11803   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11804         (rotate:QI (match_dup 0)
11805                    (match_operand:QI 1 "const1_operand" "")))
11806    (clobber (reg:CC FLAGS_REG))]
11807   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11808    && (TARGET_SHIFT1 || optimize_size)"
11809   "rol{b}\t%0"
11810   [(set_attr "type" "rotate1")
11811    (set (attr "length") 
11812      (if_then_else (match_operand 0 "register_operand" "") 
11813         (const_string "2")
11814         (const_string "*")))])
11816 (define_insn "*rotlqi3_1_one_bit"
11817   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11818         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11819                    (match_operand:QI 2 "const1_operand" "")))
11820    (clobber (reg:CC FLAGS_REG))]
11821   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11822    && (TARGET_SHIFT1 || optimize_size)"
11823   "rol{b}\t%0"
11824   [(set_attr "type" "rotate")
11825    (set (attr "length") 
11826      (if_then_else (match_operand 0 "register_operand" "") 
11827         (const_string "2")
11828         (const_string "*")))])
11830 (define_insn "*rotlqi3_1_slp"
11831   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11832         (rotate:QI (match_dup 0)
11833                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11834    (clobber (reg:CC FLAGS_REG))]
11835   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11836    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11837   "@
11838    rol{b}\t{%1, %0|%0, %1}
11839    rol{b}\t{%b1, %0|%0, %b1}"
11840   [(set_attr "type" "rotate1")
11841    (set_attr "mode" "QI")])
11843 (define_insn "*rotlqi3_1"
11844   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11845         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11846                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11847    (clobber (reg:CC FLAGS_REG))]
11848   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11849   "@
11850    rol{b}\t{%2, %0|%0, %2}
11851    rol{b}\t{%b2, %0|%0, %b2}"
11852   [(set_attr "type" "rotate")
11853    (set_attr "mode" "QI")])
11855 (define_expand "rotrdi3"
11856   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11857         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11858                      (match_operand:QI 2 "nonmemory_operand" "")))
11859    (clobber (reg:CC FLAGS_REG))]
11860   "TARGET_64BIT"
11861   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11863 (define_insn "*rotrdi3_1_one_bit_rex64"
11864   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11865         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11866                      (match_operand:QI 2 "const1_operand" "")))
11867    (clobber (reg:CC FLAGS_REG))]
11868   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11869    && (TARGET_SHIFT1 || optimize_size)"
11870   "ror{q}\t%0"
11871   [(set_attr "type" "rotate")
11872    (set (attr "length") 
11873      (if_then_else (match_operand:DI 0 "register_operand" "") 
11874         (const_string "2")
11875         (const_string "*")))])
11877 (define_insn "*rotrdi3_1_rex64"
11878   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11879         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11880                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11881    (clobber (reg:CC FLAGS_REG))]
11882   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11883   "@
11884    ror{q}\t{%2, %0|%0, %2}
11885    ror{q}\t{%b2, %0|%0, %b2}"
11886   [(set_attr "type" "rotate")
11887    (set_attr "mode" "DI")])
11889 (define_expand "rotrsi3"
11890   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11891         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11892                      (match_operand:QI 2 "nonmemory_operand" "")))
11893    (clobber (reg:CC FLAGS_REG))]
11894   ""
11895   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11897 (define_insn "*rotrsi3_1_one_bit"
11898   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11899         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11900                      (match_operand:QI 2 "const1_operand" "")))
11901    (clobber (reg:CC FLAGS_REG))]
11902   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11903    && (TARGET_SHIFT1 || optimize_size)"
11904   "ror{l}\t%0"
11905   [(set_attr "type" "rotate")
11906    (set (attr "length") 
11907      (if_then_else (match_operand:SI 0 "register_operand" "") 
11908         (const_string "2")
11909         (const_string "*")))])
11911 (define_insn "*rotrsi3_1_one_bit_zext"
11912   [(set (match_operand:DI 0 "register_operand" "=r")
11913         (zero_extend:DI
11914           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11915                        (match_operand:QI 2 "const1_operand" ""))))
11916    (clobber (reg:CC FLAGS_REG))]
11917   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11918    && (TARGET_SHIFT1 || optimize_size)"
11919   "ror{l}\t%k0"
11920   [(set_attr "type" "rotate")
11921    (set (attr "length") 
11922      (if_then_else (match_operand:SI 0 "register_operand" "") 
11923         (const_string "2")
11924         (const_string "*")))])
11926 (define_insn "*rotrsi3_1"
11927   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11928         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11929                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11930    (clobber (reg:CC FLAGS_REG))]
11931   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11932   "@
11933    ror{l}\t{%2, %0|%0, %2}
11934    ror{l}\t{%b2, %0|%0, %b2}"
11935   [(set_attr "type" "rotate")
11936    (set_attr "mode" "SI")])
11938 (define_insn "*rotrsi3_1_zext"
11939   [(set (match_operand:DI 0 "register_operand" "=r,r")
11940         (zero_extend:DI
11941           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11942                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11943    (clobber (reg:CC FLAGS_REG))]
11944   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11945   "@
11946    ror{l}\t{%2, %k0|%k0, %2}
11947    ror{l}\t{%b2, %k0|%k0, %b2}"
11948   [(set_attr "type" "rotate")
11949    (set_attr "mode" "SI")])
11951 (define_expand "rotrhi3"
11952   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11953         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11954                      (match_operand:QI 2 "nonmemory_operand" "")))
11955    (clobber (reg:CC FLAGS_REG))]
11956   "TARGET_HIMODE_MATH"
11957   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11959 (define_insn "*rotrhi3_one_bit"
11960   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11961         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11962                      (match_operand:QI 2 "const1_operand" "")))
11963    (clobber (reg:CC FLAGS_REG))]
11964   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11965    && (TARGET_SHIFT1 || optimize_size)"
11966   "ror{w}\t%0"
11967   [(set_attr "type" "rotate")
11968    (set (attr "length") 
11969      (if_then_else (match_operand 0 "register_operand" "") 
11970         (const_string "2")
11971         (const_string "*")))])
11973 (define_insn "*rotrhi3"
11974   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11975         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11976                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11977    (clobber (reg:CC FLAGS_REG))]
11978   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11979   "@
11980    ror{w}\t{%2, %0|%0, %2}
11981    ror{w}\t{%b2, %0|%0, %b2}"
11982   [(set_attr "type" "rotate")
11983    (set_attr "mode" "HI")])
11985 (define_expand "rotrqi3"
11986   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11987         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
11988                      (match_operand:QI 2 "nonmemory_operand" "")))
11989    (clobber (reg:CC FLAGS_REG))]
11990   "TARGET_QIMODE_MATH"
11991   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
11993 (define_insn "*rotrqi3_1_one_bit"
11994   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11995         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11996                      (match_operand:QI 2 "const1_operand" "")))
11997    (clobber (reg:CC FLAGS_REG))]
11998   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
11999    && (TARGET_SHIFT1 || optimize_size)"
12000   "ror{b}\t%0"
12001   [(set_attr "type" "rotate")
12002    (set (attr "length") 
12003      (if_then_else (match_operand 0 "register_operand" "") 
12004         (const_string "2")
12005         (const_string "*")))])
12007 (define_insn "*rotrqi3_1_one_bit_slp"
12008   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12009         (rotatert:QI (match_dup 0)
12010                      (match_operand:QI 1 "const1_operand" "")))
12011    (clobber (reg:CC FLAGS_REG))]
12012   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12013    && (TARGET_SHIFT1 || optimize_size)"
12014   "ror{b}\t%0"
12015   [(set_attr "type" "rotate1")
12016    (set (attr "length") 
12017      (if_then_else (match_operand 0 "register_operand" "") 
12018         (const_string "2")
12019         (const_string "*")))])
12021 (define_insn "*rotrqi3_1"
12022   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12023         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12024                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12025    (clobber (reg:CC FLAGS_REG))]
12026   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12027   "@
12028    ror{b}\t{%2, %0|%0, %2}
12029    ror{b}\t{%b2, %0|%0, %b2}"
12030   [(set_attr "type" "rotate")
12031    (set_attr "mode" "QI")])
12033 (define_insn "*rotrqi3_1_slp"
12034   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12035         (rotatert:QI (match_dup 0)
12036                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12037    (clobber (reg:CC FLAGS_REG))]
12038   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12039    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12040   "@
12041    ror{b}\t{%1, %0|%0, %1}
12042    ror{b}\t{%b1, %0|%0, %b1}"
12043   [(set_attr "type" "rotate1")
12044    (set_attr "mode" "QI")])
12046 ;; Bit set / bit test instructions
12048 (define_expand "extv"
12049   [(set (match_operand:SI 0 "register_operand" "")
12050         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12051                          (match_operand:SI 2 "immediate_operand" "")
12052                          (match_operand:SI 3 "immediate_operand" "")))]
12053   ""
12055   /* Handle extractions from %ah et al.  */
12056   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12057     FAIL;
12059   /* From mips.md: extract_bit_field doesn't verify that our source
12060      matches the predicate, so check it again here.  */
12061   if (! ext_register_operand (operands[1], VOIDmode))
12062     FAIL;
12065 (define_expand "extzv"
12066   [(set (match_operand:SI 0 "register_operand" "")
12067         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12068                          (match_operand:SI 2 "immediate_operand" "")
12069                          (match_operand:SI 3 "immediate_operand" "")))]
12070   ""
12072   /* Handle extractions from %ah et al.  */
12073   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12074     FAIL;
12076   /* From mips.md: extract_bit_field doesn't verify that our source
12077      matches the predicate, so check it again here.  */
12078   if (! ext_register_operand (operands[1], VOIDmode))
12079     FAIL;
12082 (define_expand "insv"
12083   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12084                       (match_operand 1 "immediate_operand" "")
12085                       (match_operand 2 "immediate_operand" ""))
12086         (match_operand 3 "register_operand" ""))]
12087   ""
12089   /* Handle extractions from %ah et al.  */
12090   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12091     FAIL;
12093   /* From mips.md: insert_bit_field doesn't verify that our source
12094      matches the predicate, so check it again here.  */
12095   if (! ext_register_operand (operands[0], VOIDmode))
12096     FAIL;
12098   if (TARGET_64BIT)
12099     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12100   else
12101     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12103   DONE;
12106 ;; %%% bts, btr, btc, bt.
12107 ;; In general these instructions are *slow* when applied to memory,
12108 ;; since they enforce atomic operation.  When applied to registers,
12109 ;; it depends on the cpu implementation.  They're never faster than
12110 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12111 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12112 ;; within the instruction itself, so operating on bits in the high
12113 ;; 32-bits of a register becomes easier.
12115 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12116 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12117 ;; negdf respectively, so they can never be disabled entirely.
12119 (define_insn "*btsq"
12120   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12121                          (const_int 1)
12122                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12123         (const_int 1))
12124    (clobber (reg:CC FLAGS_REG))]
12125   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12126   "bts{q} %1,%0"
12127   [(set_attr "type" "alu1")])
12129 (define_insn "*btrq"
12130   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12131                          (const_int 1)
12132                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12133         (const_int 0))
12134    (clobber (reg:CC FLAGS_REG))]
12135   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12136   "btr{q} %1,%0"
12137   [(set_attr "type" "alu1")])
12139 (define_insn "*btcq"
12140   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12141                          (const_int 1)
12142                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12143         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12144    (clobber (reg:CC FLAGS_REG))]
12145   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12146   "btc{q} %1,%0"
12147   [(set_attr "type" "alu1")])
12149 ;; Allow Nocona to avoid these instructions if a register is available.
12151 (define_peephole2
12152   [(match_scratch:DI 2 "r")
12153    (parallel [(set (zero_extract:DI
12154                      (match_operand:DI 0 "register_operand" "")
12155                      (const_int 1)
12156                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12157                    (const_int 1))
12158               (clobber (reg:CC FLAGS_REG))])]
12159   "TARGET_64BIT && !TARGET_USE_BT"
12160   [(const_int 0)]
12162   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12163   rtx op1;
12165   if (HOST_BITS_PER_WIDE_INT >= 64)
12166     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12167   else if (i < HOST_BITS_PER_WIDE_INT)
12168     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12169   else
12170     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12172   op1 = immed_double_const (lo, hi, DImode);
12173   if (i >= 31)
12174     {
12175       emit_move_insn (operands[2], op1);
12176       op1 = operands[2];
12177     }
12179   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12180   DONE;
12183 (define_peephole2
12184   [(match_scratch:DI 2 "r")
12185    (parallel [(set (zero_extract:DI
12186                      (match_operand:DI 0 "register_operand" "")
12187                      (const_int 1)
12188                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12189                    (const_int 0))
12190               (clobber (reg:CC FLAGS_REG))])]
12191   "TARGET_64BIT && !TARGET_USE_BT"
12192   [(const_int 0)]
12194   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12195   rtx op1;
12197   if (HOST_BITS_PER_WIDE_INT >= 64)
12198     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12199   else if (i < HOST_BITS_PER_WIDE_INT)
12200     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12201   else
12202     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12204   op1 = immed_double_const (~lo, ~hi, DImode);
12205   if (i >= 32)
12206     {
12207       emit_move_insn (operands[2], op1);
12208       op1 = operands[2];
12209     }
12211   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12212   DONE;
12215 (define_peephole2
12216   [(match_scratch:DI 2 "r")
12217    (parallel [(set (zero_extract:DI
12218                      (match_operand:DI 0 "register_operand" "")
12219                      (const_int 1)
12220                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12221               (not:DI (zero_extract:DI
12222                         (match_dup 0) (const_int 1) (match_dup 1))))
12223               (clobber (reg:CC FLAGS_REG))])]
12224   "TARGET_64BIT && !TARGET_USE_BT"
12225   [(const_int 0)]
12227   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12228   rtx op1;
12230   if (HOST_BITS_PER_WIDE_INT >= 64)
12231     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12232   else if (i < HOST_BITS_PER_WIDE_INT)
12233     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12234   else
12235     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12237   op1 = immed_double_const (lo, hi, DImode);
12238   if (i >= 31)
12239     {
12240       emit_move_insn (operands[2], op1);
12241       op1 = operands[2];
12242     }
12244   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12245   DONE;
12248 ;; Store-flag instructions.
12250 ;; For all sCOND expanders, also expand the compare or test insn that
12251 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12253 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12254 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12255 ;; way, which can later delete the movzx if only QImode is needed.
12257 (define_expand "seq"
12258   [(set (match_operand:QI 0 "register_operand" "")
12259         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12260   ""
12261   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12263 (define_expand "sne"
12264   [(set (match_operand:QI 0 "register_operand" "")
12265         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12266   ""
12267   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12269 (define_expand "sgt"
12270   [(set (match_operand:QI 0 "register_operand" "")
12271         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12272   ""
12273   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12275 (define_expand "sgtu"
12276   [(set (match_operand:QI 0 "register_operand" "")
12277         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12278   ""
12279   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12281 (define_expand "slt"
12282   [(set (match_operand:QI 0 "register_operand" "")
12283         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12284   ""
12285   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12287 (define_expand "sltu"
12288   [(set (match_operand:QI 0 "register_operand" "")
12289         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12290   ""
12291   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12293 (define_expand "sge"
12294   [(set (match_operand:QI 0 "register_operand" "")
12295         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12296   ""
12297   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12299 (define_expand "sgeu"
12300   [(set (match_operand:QI 0 "register_operand" "")
12301         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12302   ""
12303   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12305 (define_expand "sle"
12306   [(set (match_operand:QI 0 "register_operand" "")
12307         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12308   ""
12309   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12311 (define_expand "sleu"
12312   [(set (match_operand:QI 0 "register_operand" "")
12313         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12314   ""
12315   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12317 (define_expand "sunordered"
12318   [(set (match_operand:QI 0 "register_operand" "")
12319         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12320   "TARGET_80387 || TARGET_SSE"
12321   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12323 (define_expand "sordered"
12324   [(set (match_operand:QI 0 "register_operand" "")
12325         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12326   "TARGET_80387"
12327   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12329 (define_expand "suneq"
12330   [(set (match_operand:QI 0 "register_operand" "")
12331         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12332   "TARGET_80387 || TARGET_SSE"
12333   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12335 (define_expand "sunge"
12336   [(set (match_operand:QI 0 "register_operand" "")
12337         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12338   "TARGET_80387 || TARGET_SSE"
12339   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12341 (define_expand "sungt"
12342   [(set (match_operand:QI 0 "register_operand" "")
12343         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12344   "TARGET_80387 || TARGET_SSE"
12345   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12347 (define_expand "sunle"
12348   [(set (match_operand:QI 0 "register_operand" "")
12349         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12350   "TARGET_80387 || TARGET_SSE"
12351   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12353 (define_expand "sunlt"
12354   [(set (match_operand:QI 0 "register_operand" "")
12355         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12356   "TARGET_80387 || TARGET_SSE"
12357   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12359 (define_expand "sltgt"
12360   [(set (match_operand:QI 0 "register_operand" "")
12361         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12362   "TARGET_80387 || TARGET_SSE"
12363   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12365 (define_insn "*setcc_1"
12366   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12367         (match_operator:QI 1 "ix86_comparison_operator"
12368           [(reg FLAGS_REG) (const_int 0)]))]
12369   ""
12370   "set%C1\t%0"
12371   [(set_attr "type" "setcc")
12372    (set_attr "mode" "QI")])
12374 (define_insn "*setcc_2"
12375   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12376         (match_operator:QI 1 "ix86_comparison_operator"
12377           [(reg FLAGS_REG) (const_int 0)]))]
12378   ""
12379   "set%C1\t%0"
12380   [(set_attr "type" "setcc")
12381    (set_attr "mode" "QI")])
12383 ;; In general it is not safe to assume too much about CCmode registers,
12384 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12385 ;; conditions this is safe on x86, so help combine not create
12387 ;;      seta    %al
12388 ;;      testb   %al, %al
12389 ;;      sete    %al
12391 (define_split 
12392   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12393         (ne:QI (match_operator 1 "ix86_comparison_operator"
12394                  [(reg FLAGS_REG) (const_int 0)])
12395             (const_int 0)))]
12396   ""
12397   [(set (match_dup 0) (match_dup 1))]
12399   PUT_MODE (operands[1], QImode);
12402 (define_split 
12403   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12404         (ne:QI (match_operator 1 "ix86_comparison_operator"
12405                  [(reg FLAGS_REG) (const_int 0)])
12406             (const_int 0)))]
12407   ""
12408   [(set (match_dup 0) (match_dup 1))]
12410   PUT_MODE (operands[1], QImode);
12413 (define_split 
12414   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12415         (eq:QI (match_operator 1 "ix86_comparison_operator"
12416                  [(reg FLAGS_REG) (const_int 0)])
12417             (const_int 0)))]
12418   ""
12419   [(set (match_dup 0) (match_dup 1))]
12421   rtx new_op1 = copy_rtx (operands[1]);
12422   operands[1] = new_op1;
12423   PUT_MODE (new_op1, QImode);
12424   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12425                                              GET_MODE (XEXP (new_op1, 0))));
12427   /* Make sure that (a) the CCmode we have for the flags is strong
12428      enough for the reversed compare or (b) we have a valid FP compare.  */
12429   if (! ix86_comparison_operator (new_op1, VOIDmode))
12430     FAIL;
12433 (define_split 
12434   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12435         (eq:QI (match_operator 1 "ix86_comparison_operator"
12436                  [(reg FLAGS_REG) (const_int 0)])
12437             (const_int 0)))]
12438   ""
12439   [(set (match_dup 0) (match_dup 1))]
12441   rtx new_op1 = copy_rtx (operands[1]);
12442   operands[1] = new_op1;
12443   PUT_MODE (new_op1, QImode);
12444   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12445                                              GET_MODE (XEXP (new_op1, 0))));
12447   /* Make sure that (a) the CCmode we have for the flags is strong
12448      enough for the reversed compare or (b) we have a valid FP compare.  */
12449   if (! ix86_comparison_operator (new_op1, VOIDmode))
12450     FAIL;
12453 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12454 ;; subsequent logical operations are used to imitate conditional moves.
12455 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12456 ;; it directly.
12458 (define_insn "*sse_setccsf"
12459   [(set (match_operand:SF 0 "register_operand" "=x")
12460         (match_operator:SF 1 "sse_comparison_operator"
12461           [(match_operand:SF 2 "register_operand" "0")
12462            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12463   "TARGET_SSE"
12464   "cmp%D1ss\t{%3, %0|%0, %3}"
12465   [(set_attr "type" "ssecmp")
12466    (set_attr "mode" "SF")])
12468 (define_insn "*sse_setccdf"
12469   [(set (match_operand:DF 0 "register_operand" "=Y")
12470         (match_operator:DF 1 "sse_comparison_operator"
12471           [(match_operand:DF 2 "register_operand" "0")
12472            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12473   "TARGET_SSE2"
12474   "cmp%D1sd\t{%3, %0|%0, %3}"
12475   [(set_attr "type" "ssecmp")
12476    (set_attr "mode" "DF")])
12478 ;; Basic conditional jump instructions.
12479 ;; We ignore the overflow flag for signed branch instructions.
12481 ;; For all bCOND expanders, also expand the compare or test insn that
12482 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12484 (define_expand "beq"
12485   [(set (pc)
12486         (if_then_else (match_dup 1)
12487                       (label_ref (match_operand 0 "" ""))
12488                       (pc)))]
12489   ""
12490   "ix86_expand_branch (EQ, operands[0]); DONE;")
12492 (define_expand "bne"
12493   [(set (pc)
12494         (if_then_else (match_dup 1)
12495                       (label_ref (match_operand 0 "" ""))
12496                       (pc)))]
12497   ""
12498   "ix86_expand_branch (NE, operands[0]); DONE;")
12500 (define_expand "bgt"
12501   [(set (pc)
12502         (if_then_else (match_dup 1)
12503                       (label_ref (match_operand 0 "" ""))
12504                       (pc)))]
12505   ""
12506   "ix86_expand_branch (GT, operands[0]); DONE;")
12508 (define_expand "bgtu"
12509   [(set (pc)
12510         (if_then_else (match_dup 1)
12511                       (label_ref (match_operand 0 "" ""))
12512                       (pc)))]
12513   ""
12514   "ix86_expand_branch (GTU, operands[0]); DONE;")
12516 (define_expand "blt"
12517   [(set (pc)
12518         (if_then_else (match_dup 1)
12519                       (label_ref (match_operand 0 "" ""))
12520                       (pc)))]
12521   ""
12522   "ix86_expand_branch (LT, operands[0]); DONE;")
12524 (define_expand "bltu"
12525   [(set (pc)
12526         (if_then_else (match_dup 1)
12527                       (label_ref (match_operand 0 "" ""))
12528                       (pc)))]
12529   ""
12530   "ix86_expand_branch (LTU, operands[0]); DONE;")
12532 (define_expand "bge"
12533   [(set (pc)
12534         (if_then_else (match_dup 1)
12535                       (label_ref (match_operand 0 "" ""))
12536                       (pc)))]
12537   ""
12538   "ix86_expand_branch (GE, operands[0]); DONE;")
12540 (define_expand "bgeu"
12541   [(set (pc)
12542         (if_then_else (match_dup 1)
12543                       (label_ref (match_operand 0 "" ""))
12544                       (pc)))]
12545   ""
12546   "ix86_expand_branch (GEU, operands[0]); DONE;")
12548 (define_expand "ble"
12549   [(set (pc)
12550         (if_then_else (match_dup 1)
12551                       (label_ref (match_operand 0 "" ""))
12552                       (pc)))]
12553   ""
12554   "ix86_expand_branch (LE, operands[0]); DONE;")
12556 (define_expand "bleu"
12557   [(set (pc)
12558         (if_then_else (match_dup 1)
12559                       (label_ref (match_operand 0 "" ""))
12560                       (pc)))]
12561   ""
12562   "ix86_expand_branch (LEU, operands[0]); DONE;")
12564 (define_expand "bunordered"
12565   [(set (pc)
12566         (if_then_else (match_dup 1)
12567                       (label_ref (match_operand 0 "" ""))
12568                       (pc)))]
12569   "TARGET_80387 || TARGET_SSE_MATH"
12570   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12572 (define_expand "bordered"
12573   [(set (pc)
12574         (if_then_else (match_dup 1)
12575                       (label_ref (match_operand 0 "" ""))
12576                       (pc)))]
12577   "TARGET_80387 || TARGET_SSE_MATH"
12578   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12580 (define_expand "buneq"
12581   [(set (pc)
12582         (if_then_else (match_dup 1)
12583                       (label_ref (match_operand 0 "" ""))
12584                       (pc)))]
12585   "TARGET_80387 || TARGET_SSE_MATH"
12586   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12588 (define_expand "bunge"
12589   [(set (pc)
12590         (if_then_else (match_dup 1)
12591                       (label_ref (match_operand 0 "" ""))
12592                       (pc)))]
12593   "TARGET_80387 || TARGET_SSE_MATH"
12594   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12596 (define_expand "bungt"
12597   [(set (pc)
12598         (if_then_else (match_dup 1)
12599                       (label_ref (match_operand 0 "" ""))
12600                       (pc)))]
12601   "TARGET_80387 || TARGET_SSE_MATH"
12602   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12604 (define_expand "bunle"
12605   [(set (pc)
12606         (if_then_else (match_dup 1)
12607                       (label_ref (match_operand 0 "" ""))
12608                       (pc)))]
12609   "TARGET_80387 || TARGET_SSE_MATH"
12610   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12612 (define_expand "bunlt"
12613   [(set (pc)
12614         (if_then_else (match_dup 1)
12615                       (label_ref (match_operand 0 "" ""))
12616                       (pc)))]
12617   "TARGET_80387 || TARGET_SSE_MATH"
12618   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12620 (define_expand "bltgt"
12621   [(set (pc)
12622         (if_then_else (match_dup 1)
12623                       (label_ref (match_operand 0 "" ""))
12624                       (pc)))]
12625   "TARGET_80387 || TARGET_SSE_MATH"
12626   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12628 (define_insn "*jcc_1"
12629   [(set (pc)
12630         (if_then_else (match_operator 1 "ix86_comparison_operator"
12631                                       [(reg FLAGS_REG) (const_int 0)])
12632                       (label_ref (match_operand 0 "" ""))
12633                       (pc)))]
12634   ""
12635   "%+j%C1\t%l0"
12636   [(set_attr "type" "ibr")
12637    (set_attr "modrm" "0")
12638    (set (attr "length")
12639            (if_then_else (and (ge (minus (match_dup 0) (pc))
12640                                   (const_int -126))
12641                               (lt (minus (match_dup 0) (pc))
12642                                   (const_int 128)))
12643              (const_int 2)
12644              (const_int 6)))])
12646 (define_insn "*jcc_2"
12647   [(set (pc)
12648         (if_then_else (match_operator 1 "ix86_comparison_operator"
12649                                       [(reg FLAGS_REG) (const_int 0)])
12650                       (pc)
12651                       (label_ref (match_operand 0 "" ""))))]
12652   ""
12653   "%+j%c1\t%l0"
12654   [(set_attr "type" "ibr")
12655    (set_attr "modrm" "0")
12656    (set (attr "length")
12657            (if_then_else (and (ge (minus (match_dup 0) (pc))
12658                                   (const_int -126))
12659                               (lt (minus (match_dup 0) (pc))
12660                                   (const_int 128)))
12661              (const_int 2)
12662              (const_int 6)))])
12664 ;; In general it is not safe to assume too much about CCmode registers,
12665 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12666 ;; conditions this is safe on x86, so help combine not create
12668 ;;      seta    %al
12669 ;;      testb   %al, %al
12670 ;;      je      Lfoo
12672 (define_split 
12673   [(set (pc)
12674         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12675                                       [(reg FLAGS_REG) (const_int 0)])
12676                           (const_int 0))
12677                       (label_ref (match_operand 1 "" ""))
12678                       (pc)))]
12679   ""
12680   [(set (pc)
12681         (if_then_else (match_dup 0)
12682                       (label_ref (match_dup 1))
12683                       (pc)))]
12685   PUT_MODE (operands[0], VOIDmode);
12687   
12688 (define_split 
12689   [(set (pc)
12690         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12691                                       [(reg FLAGS_REG) (const_int 0)])
12692                           (const_int 0))
12693                       (label_ref (match_operand 1 "" ""))
12694                       (pc)))]
12695   ""
12696   [(set (pc)
12697         (if_then_else (match_dup 0)
12698                       (label_ref (match_dup 1))
12699                       (pc)))]
12701   rtx new_op0 = copy_rtx (operands[0]);
12702   operands[0] = new_op0;
12703   PUT_MODE (new_op0, VOIDmode);
12704   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12705                                              GET_MODE (XEXP (new_op0, 0))));
12707   /* Make sure that (a) the CCmode we have for the flags is strong
12708      enough for the reversed compare or (b) we have a valid FP compare.  */
12709   if (! ix86_comparison_operator (new_op0, VOIDmode))
12710     FAIL;
12713 ;; Define combination compare-and-branch fp compare instructions to use
12714 ;; during early optimization.  Splitting the operation apart early makes
12715 ;; for bad code when we want to reverse the operation.
12717 (define_insn "*fp_jcc_1_mixed"
12718   [(set (pc)
12719         (if_then_else (match_operator 0 "comparison_operator"
12720                         [(match_operand 1 "register_operand" "f#x,x#f")
12721                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12722           (label_ref (match_operand 3 "" ""))
12723           (pc)))
12724    (clobber (reg:CCFP FPSR_REG))
12725    (clobber (reg:CCFP FLAGS_REG))]
12726   "TARGET_MIX_SSE_I387
12727    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12728    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12729    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12730   "#")
12732 (define_insn "*fp_jcc_1_sse"
12733   [(set (pc)
12734         (if_then_else (match_operator 0 "comparison_operator"
12735                         [(match_operand 1 "register_operand" "x")
12736                          (match_operand 2 "nonimmediate_operand" "xm")])
12737           (label_ref (match_operand 3 "" ""))
12738           (pc)))
12739    (clobber (reg:CCFP FPSR_REG))
12740    (clobber (reg:CCFP FLAGS_REG))]
12741   "TARGET_SSE_MATH
12742    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12743    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12744    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12745   "#")
12747 (define_insn "*fp_jcc_1_387"
12748   [(set (pc)
12749         (if_then_else (match_operator 0 "comparison_operator"
12750                         [(match_operand 1 "register_operand" "f")
12751                          (match_operand 2 "register_operand" "f")])
12752           (label_ref (match_operand 3 "" ""))
12753           (pc)))
12754    (clobber (reg:CCFP FPSR_REG))
12755    (clobber (reg:CCFP FLAGS_REG))]
12756   "TARGET_CMOVE && TARGET_80387
12757    && FLOAT_MODE_P (GET_MODE (operands[1]))
12758    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12759    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12760   "#")
12762 (define_insn "*fp_jcc_2_mixed"
12763   [(set (pc)
12764         (if_then_else (match_operator 0 "comparison_operator"
12765                         [(match_operand 1 "register_operand" "f#x,x#f")
12766                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12767           (pc)
12768           (label_ref (match_operand 3 "" ""))))
12769    (clobber (reg:CCFP FPSR_REG))
12770    (clobber (reg:CCFP FLAGS_REG))]
12771   "TARGET_MIX_SSE_I387
12772    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12773    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12774    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12775   "#")
12777 (define_insn "*fp_jcc_2_sse"
12778   [(set (pc)
12779         (if_then_else (match_operator 0 "comparison_operator"
12780                         [(match_operand 1 "register_operand" "x")
12781                          (match_operand 2 "nonimmediate_operand" "xm")])
12782           (pc)
12783           (label_ref (match_operand 3 "" ""))))
12784    (clobber (reg:CCFP FPSR_REG))
12785    (clobber (reg:CCFP FLAGS_REG))]
12786   "TARGET_SSE_MATH
12787    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12788    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12789    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12790   "#")
12792 (define_insn "*fp_jcc_2_387"
12793   [(set (pc)
12794         (if_then_else (match_operator 0 "comparison_operator"
12795                         [(match_operand 1 "register_operand" "f")
12796                          (match_operand 2 "register_operand" "f")])
12797           (pc)
12798           (label_ref (match_operand 3 "" ""))))
12799    (clobber (reg:CCFP FPSR_REG))
12800    (clobber (reg:CCFP FLAGS_REG))]
12801   "TARGET_CMOVE && TARGET_80387
12802    && FLOAT_MODE_P (GET_MODE (operands[1]))
12803    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12804    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12805   "#")
12807 (define_insn "*fp_jcc_3_387"
12808   [(set (pc)
12809         (if_then_else (match_operator 0 "comparison_operator"
12810                         [(match_operand 1 "register_operand" "f")
12811                          (match_operand 2 "nonimmediate_operand" "fm")])
12812           (label_ref (match_operand 3 "" ""))
12813           (pc)))
12814    (clobber (reg:CCFP FPSR_REG))
12815    (clobber (reg:CCFP FLAGS_REG))
12816    (clobber (match_scratch:HI 4 "=a"))]
12817   "TARGET_80387
12818    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12819    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12820    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12821    && SELECT_CC_MODE (GET_CODE (operands[0]),
12822                       operands[1], operands[2]) == CCFPmode
12823    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12824   "#")
12826 (define_insn "*fp_jcc_4_387"
12827   [(set (pc)
12828         (if_then_else (match_operator 0 "comparison_operator"
12829                         [(match_operand 1 "register_operand" "f")
12830                          (match_operand 2 "nonimmediate_operand" "fm")])
12831           (pc)
12832           (label_ref (match_operand 3 "" ""))))
12833    (clobber (reg:CCFP FPSR_REG))
12834    (clobber (reg:CCFP FLAGS_REG))
12835    (clobber (match_scratch:HI 4 "=a"))]
12836   "TARGET_80387
12837    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12838    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12839    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12840    && SELECT_CC_MODE (GET_CODE (operands[0]),
12841                       operands[1], operands[2]) == CCFPmode
12842    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12843   "#")
12845 (define_insn "*fp_jcc_5_387"
12846   [(set (pc)
12847         (if_then_else (match_operator 0 "comparison_operator"
12848                         [(match_operand 1 "register_operand" "f")
12849                          (match_operand 2 "register_operand" "f")])
12850           (label_ref (match_operand 3 "" ""))
12851           (pc)))
12852    (clobber (reg:CCFP FPSR_REG))
12853    (clobber (reg:CCFP FLAGS_REG))
12854    (clobber (match_scratch:HI 4 "=a"))]
12855   "TARGET_80387
12856    && FLOAT_MODE_P (GET_MODE (operands[1]))
12857    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12858    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12859   "#")
12861 (define_insn "*fp_jcc_6_387"
12862   [(set (pc)
12863         (if_then_else (match_operator 0 "comparison_operator"
12864                         [(match_operand 1 "register_operand" "f")
12865                          (match_operand 2 "register_operand" "f")])
12866           (pc)
12867           (label_ref (match_operand 3 "" ""))))
12868    (clobber (reg:CCFP FPSR_REG))
12869    (clobber (reg:CCFP FLAGS_REG))
12870    (clobber (match_scratch:HI 4 "=a"))]
12871   "TARGET_80387
12872    && FLOAT_MODE_P (GET_MODE (operands[1]))
12873    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12874    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12875   "#")
12877 (define_insn "*fp_jcc_7_387"
12878   [(set (pc)
12879         (if_then_else (match_operator 0 "comparison_operator"
12880                         [(match_operand 1 "register_operand" "f")
12881                          (match_operand 2 "const0_operand" "X")])
12882           (label_ref (match_operand 3 "" ""))
12883           (pc)))
12884    (clobber (reg:CCFP FPSR_REG))
12885    (clobber (reg:CCFP FLAGS_REG))
12886    (clobber (match_scratch:HI 4 "=a"))]
12887   "TARGET_80387
12888    && FLOAT_MODE_P (GET_MODE (operands[1]))
12889    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12890    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12891    && SELECT_CC_MODE (GET_CODE (operands[0]),
12892                       operands[1], operands[2]) == CCFPmode
12893    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12894   "#")
12896 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12897 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12898 ;; with a precedence over other operators and is always put in the first
12899 ;; place. Swap condition and operands to match ficom instruction.
12901 (define_insn "*fp_jcc_8<mode>_387"
12902   [(set (pc)
12903         (if_then_else (match_operator 0 "comparison_operator"
12904                         [(match_operator 1 "float_operator"
12905                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12906                            (match_operand 3 "register_operand" "f,f")])
12907           (label_ref (match_operand 4 "" ""))
12908           (pc)))
12909    (clobber (reg:CCFP FPSR_REG))
12910    (clobber (reg:CCFP FLAGS_REG))
12911    (clobber (match_scratch:HI 5 "=a,a"))]
12912   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
12913    && FLOAT_MODE_P (GET_MODE (operands[3]))
12914    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12915    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12916    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12917    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12918   "#")
12920 (define_split
12921   [(set (pc)
12922         (if_then_else (match_operator 0 "comparison_operator"
12923                         [(match_operand 1 "register_operand" "")
12924                          (match_operand 2 "nonimmediate_operand" "")])
12925           (match_operand 3 "" "")
12926           (match_operand 4 "" "")))
12927    (clobber (reg:CCFP FPSR_REG))
12928    (clobber (reg:CCFP FLAGS_REG))]
12929   "reload_completed"
12930   [(const_int 0)]
12932   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12933                         operands[3], operands[4], NULL_RTX, NULL_RTX);
12934   DONE;
12937 (define_split
12938   [(set (pc)
12939         (if_then_else (match_operator 0 "comparison_operator"
12940                         [(match_operand 1 "register_operand" "")
12941                          (match_operand 2 "general_operand" "")])
12942           (match_operand 3 "" "")
12943           (match_operand 4 "" "")))
12944    (clobber (reg:CCFP FPSR_REG))
12945    (clobber (reg:CCFP FLAGS_REG))
12946    (clobber (match_scratch:HI 5 "=a"))]
12947   "reload_completed"
12948   [(const_int 0)]
12950   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12951                         operands[3], operands[4], operands[5], NULL_RTX);
12952   DONE;
12955 (define_split
12956   [(set (pc)
12957         (if_then_else (match_operator 0 "comparison_operator"
12958                         [(match_operator 1 "float_operator"
12959                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
12960                            (match_operand 3 "register_operand" "")])
12961           (match_operand 4 "" "")
12962           (match_operand 5 "" "")))
12963    (clobber (reg:CCFP FPSR_REG))
12964    (clobber (reg:CCFP FLAGS_REG))
12965    (clobber (match_scratch:HI 6 "=a"))]
12966   "reload_completed"
12967   [(const_int 0)]
12969   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12970   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12971                         operands[3], operands[7],
12972                         operands[4], operands[5], operands[6], NULL_RTX);
12973   DONE;
12976 ;; %%% Kill this when reload knows how to do it.
12977 (define_split
12978   [(set (pc)
12979         (if_then_else (match_operator 0 "comparison_operator"
12980                         [(match_operator 1 "float_operator"
12981                            [(match_operand:X87MODEI12 2 "register_operand" "")])
12982                            (match_operand 3 "register_operand" "")])
12983           (match_operand 4 "" "")
12984           (match_operand 5 "" "")))
12985    (clobber (reg:CCFP FPSR_REG))
12986    (clobber (reg:CCFP FLAGS_REG))
12987    (clobber (match_scratch:HI 6 "=a"))]
12988   "reload_completed"
12989   [(const_int 0)]
12991   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12992   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
12993   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12994                         operands[3], operands[7],
12995                         operands[4], operands[5], operands[6], operands[2]);
12996   DONE;
12999 ;; Unconditional and other jump instructions
13001 (define_insn "jump"
13002   [(set (pc)
13003         (label_ref (match_operand 0 "" "")))]
13004   ""
13005   "jmp\t%l0"
13006   [(set_attr "type" "ibr")
13007    (set (attr "length")
13008            (if_then_else (and (ge (minus (match_dup 0) (pc))
13009                                   (const_int -126))
13010                               (lt (minus (match_dup 0) (pc))
13011                                   (const_int 128)))
13012              (const_int 2)
13013              (const_int 5)))
13014    (set_attr "modrm" "0")])
13016 (define_expand "indirect_jump"
13017   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13018   ""
13019   "")
13021 (define_insn "*indirect_jump"
13022   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13023   "!TARGET_64BIT"
13024   "jmp\t%A0"
13025   [(set_attr "type" "ibr")
13026    (set_attr "length_immediate" "0")])
13028 (define_insn "*indirect_jump_rtx64"
13029   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13030   "TARGET_64BIT"
13031   "jmp\t%A0"
13032   [(set_attr "type" "ibr")
13033    (set_attr "length_immediate" "0")])
13035 (define_expand "tablejump"
13036   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13037               (use (label_ref (match_operand 1 "" "")))])]
13038   ""
13040   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13041      relative.  Convert the relative address to an absolute address.  */
13042   if (flag_pic)
13043     {
13044       rtx op0, op1;
13045       enum rtx_code code;
13047       if (TARGET_64BIT)
13048         {
13049           code = PLUS;
13050           op0 = operands[0];
13051           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13052         }
13053       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13054         {
13055           code = PLUS;
13056           op0 = operands[0];
13057           op1 = pic_offset_table_rtx;
13058         }
13059       else
13060         {
13061           code = MINUS;
13062           op0 = pic_offset_table_rtx;
13063           op1 = operands[0];
13064         }
13066       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13067                                          OPTAB_DIRECT);
13068     }
13071 (define_insn "*tablejump_1"
13072   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13073    (use (label_ref (match_operand 1 "" "")))]
13074   "!TARGET_64BIT"
13075   "jmp\t%A0"
13076   [(set_attr "type" "ibr")
13077    (set_attr "length_immediate" "0")])
13079 (define_insn "*tablejump_1_rtx64"
13080   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13081    (use (label_ref (match_operand 1 "" "")))]
13082   "TARGET_64BIT"
13083   "jmp\t%A0"
13084   [(set_attr "type" "ibr")
13085    (set_attr "length_immediate" "0")])
13087 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13089 (define_peephole2
13090   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13091    (set (match_operand:QI 1 "register_operand" "")
13092         (match_operator:QI 2 "ix86_comparison_operator"
13093           [(reg FLAGS_REG) (const_int 0)]))
13094    (set (match_operand 3 "q_regs_operand" "")
13095         (zero_extend (match_dup 1)))]
13096   "(peep2_reg_dead_p (3, operands[1])
13097     || operands_match_p (operands[1], operands[3]))
13098    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13099   [(set (match_dup 4) (match_dup 0))
13100    (set (strict_low_part (match_dup 5))
13101         (match_dup 2))]
13103   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13104   operands[5] = gen_lowpart (QImode, operands[3]);
13105   ix86_expand_clear (operands[3]);
13108 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13110 (define_peephole2
13111   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13112    (set (match_operand:QI 1 "register_operand" "")
13113         (match_operator:QI 2 "ix86_comparison_operator"
13114           [(reg FLAGS_REG) (const_int 0)]))
13115    (parallel [(set (match_operand 3 "q_regs_operand" "")
13116                    (zero_extend (match_dup 1)))
13117               (clobber (reg:CC FLAGS_REG))])]
13118   "(peep2_reg_dead_p (3, operands[1])
13119     || operands_match_p (operands[1], operands[3]))
13120    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13121   [(set (match_dup 4) (match_dup 0))
13122    (set (strict_low_part (match_dup 5))
13123         (match_dup 2))]
13125   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13126   operands[5] = gen_lowpart (QImode, operands[3]);
13127   ix86_expand_clear (operands[3]);
13130 ;; Call instructions.
13132 ;; The predicates normally associated with named expanders are not properly
13133 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13134 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13136 ;; Call subroutine returning no value.
13138 (define_expand "call_pop"
13139   [(parallel [(call (match_operand:QI 0 "" "")
13140                     (match_operand:SI 1 "" ""))
13141               (set (reg:SI SP_REG)
13142                    (plus:SI (reg:SI SP_REG)
13143                             (match_operand:SI 3 "" "")))])]
13144   "!TARGET_64BIT"
13146   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13147   DONE;
13150 (define_insn "*call_pop_0"
13151   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13152          (match_operand:SI 1 "" ""))
13153    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13154                             (match_operand:SI 2 "immediate_operand" "")))]
13155   "!TARGET_64BIT"
13157   if (SIBLING_CALL_P (insn))
13158     return "jmp\t%P0";
13159   else
13160     return "call\t%P0";
13162   [(set_attr "type" "call")])
13163   
13164 (define_insn "*call_pop_1"
13165   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13166          (match_operand:SI 1 "" ""))
13167    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13168                             (match_operand:SI 2 "immediate_operand" "i")))]
13169   "!TARGET_64BIT"
13171   if (constant_call_address_operand (operands[0], Pmode))
13172     {
13173       if (SIBLING_CALL_P (insn))
13174         return "jmp\t%P0";
13175       else
13176         return "call\t%P0";
13177     }
13178   if (SIBLING_CALL_P (insn))
13179     return "jmp\t%A0";
13180   else
13181     return "call\t%A0";
13183   [(set_attr "type" "call")])
13185 (define_expand "call"
13186   [(call (match_operand:QI 0 "" "")
13187          (match_operand 1 "" ""))
13188    (use (match_operand 2 "" ""))]
13189   ""
13191   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13192   DONE;
13195 (define_expand "sibcall"
13196   [(call (match_operand:QI 0 "" "")
13197          (match_operand 1 "" ""))
13198    (use (match_operand 2 "" ""))]
13199   ""
13201   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13202   DONE;
13205 (define_insn "*call_0"
13206   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13207          (match_operand 1 "" ""))]
13208   ""
13210   if (SIBLING_CALL_P (insn))
13211     return "jmp\t%P0";
13212   else
13213     return "call\t%P0";
13215   [(set_attr "type" "call")])
13217 (define_insn "*call_1"
13218   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13219          (match_operand 1 "" ""))]
13220   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13222   if (constant_call_address_operand (operands[0], Pmode))
13223     return "call\t%P0";
13224   return "call\t%A0";
13226   [(set_attr "type" "call")])
13228 (define_insn "*sibcall_1"
13229   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13230          (match_operand 1 "" ""))]
13231   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13233   if (constant_call_address_operand (operands[0], Pmode))
13234     return "jmp\t%P0";
13235   return "jmp\t%A0";
13237   [(set_attr "type" "call")])
13239 (define_insn "*call_1_rex64"
13240   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13241          (match_operand 1 "" ""))]
13242   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13244   if (constant_call_address_operand (operands[0], Pmode))
13245     return "call\t%P0";
13246   return "call\t%A0";
13248   [(set_attr "type" "call")])
13250 (define_insn "*sibcall_1_rex64"
13251   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13252          (match_operand 1 "" ""))]
13253   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13254   "jmp\t%P0"
13255   [(set_attr "type" "call")])
13257 (define_insn "*sibcall_1_rex64_v"
13258   [(call (mem:QI (reg:DI 40))
13259          (match_operand 0 "" ""))]
13260   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13261   "jmp\t*%%r11"
13262   [(set_attr "type" "call")])
13265 ;; Call subroutine, returning value in operand 0
13267 (define_expand "call_value_pop"
13268   [(parallel [(set (match_operand 0 "" "")
13269                    (call (match_operand:QI 1 "" "")
13270                          (match_operand:SI 2 "" "")))
13271               (set (reg:SI SP_REG)
13272                    (plus:SI (reg:SI SP_REG)
13273                             (match_operand:SI 4 "" "")))])]
13274   "!TARGET_64BIT"
13276   ix86_expand_call (operands[0], operands[1], operands[2],
13277                     operands[3], operands[4], 0);
13278   DONE;
13281 (define_expand "call_value"
13282   [(set (match_operand 0 "" "")
13283         (call (match_operand:QI 1 "" "")
13284               (match_operand:SI 2 "" "")))
13285    (use (match_operand:SI 3 "" ""))]
13286   ;; Operand 2 not used on the i386.
13287   ""
13289   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13290   DONE;
13293 (define_expand "sibcall_value"
13294   [(set (match_operand 0 "" "")
13295         (call (match_operand:QI 1 "" "")
13296               (match_operand:SI 2 "" "")))
13297    (use (match_operand:SI 3 "" ""))]
13298   ;; Operand 2 not used on the i386.
13299   ""
13301   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13302   DONE;
13305 ;; Call subroutine returning any type.
13307 (define_expand "untyped_call"
13308   [(parallel [(call (match_operand 0 "" "")
13309                     (const_int 0))
13310               (match_operand 1 "" "")
13311               (match_operand 2 "" "")])]
13312   ""
13314   int i;
13316   /* In order to give reg-stack an easier job in validating two
13317      coprocessor registers as containing a possible return value,
13318      simply pretend the untyped call returns a complex long double
13319      value.  */
13321   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13322                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13323                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13324                     NULL, 0);
13326   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13327     {
13328       rtx set = XVECEXP (operands[2], 0, i);
13329       emit_move_insn (SET_DEST (set), SET_SRC (set));
13330     }
13332   /* The optimizer does not know that the call sets the function value
13333      registers we stored in the result block.  We avoid problems by
13334      claiming that all hard registers are used and clobbered at this
13335      point.  */
13336   emit_insn (gen_blockage (const0_rtx));
13338   DONE;
13341 ;; Prologue and epilogue instructions
13343 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13344 ;; all of memory.  This blocks insns from being moved across this point.
13346 (define_insn "blockage"
13347   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13348   ""
13349   ""
13350   [(set_attr "length" "0")])
13352 ;; Insn emitted into the body of a function to return from a function.
13353 ;; This is only done if the function's epilogue is known to be simple.
13354 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13356 (define_expand "return"
13357   [(return)]
13358   "ix86_can_use_return_insn_p ()"
13360   if (current_function_pops_args)
13361     {
13362       rtx popc = GEN_INT (current_function_pops_args);
13363       emit_jump_insn (gen_return_pop_internal (popc));
13364       DONE;
13365     }
13368 (define_insn "return_internal"
13369   [(return)]
13370   "reload_completed"
13371   "ret"
13372   [(set_attr "length" "1")
13373    (set_attr "length_immediate" "0")
13374    (set_attr "modrm" "0")])
13376 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13377 ;; instruction Athlon and K8 have.
13379 (define_insn "return_internal_long"
13380   [(return)
13381    (unspec [(const_int 0)] UNSPEC_REP)]
13382   "reload_completed"
13383   "rep {;} ret"
13384   [(set_attr "length" "1")
13385    (set_attr "length_immediate" "0")
13386    (set_attr "prefix_rep" "1")
13387    (set_attr "modrm" "0")])
13389 (define_insn "return_pop_internal"
13390   [(return)
13391    (use (match_operand:SI 0 "const_int_operand" ""))]
13392   "reload_completed"
13393   "ret\t%0"
13394   [(set_attr "length" "3")
13395    (set_attr "length_immediate" "2")
13396    (set_attr "modrm" "0")])
13398 (define_insn "return_indirect_internal"
13399   [(return)
13400    (use (match_operand:SI 0 "register_operand" "r"))]
13401   "reload_completed"
13402   "jmp\t%A0"
13403   [(set_attr "type" "ibr")
13404    (set_attr "length_immediate" "0")])
13406 (define_insn "nop"
13407   [(const_int 0)]
13408   ""
13409   "nop"
13410   [(set_attr "length" "1")
13411    (set_attr "length_immediate" "0")
13412    (set_attr "modrm" "0")])
13414 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13415 ;; branch prediction penalty for the third jump in a 16-byte
13416 ;; block on K8.
13418 (define_insn "align"
13419   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13420   ""
13422 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13423   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13424 #else
13425   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13426      The align insn is used to avoid 3 jump instructions in the row to improve
13427      branch prediction and the benefits hardly outweight the cost of extra 8
13428      nops on the average inserted by full alignment pseudo operation.  */
13429 #endif
13430   return "";
13432   [(set_attr "length" "16")])
13434 (define_expand "prologue"
13435   [(const_int 1)]
13436   ""
13437   "ix86_expand_prologue (); DONE;")
13439 (define_insn "set_got"
13440   [(set (match_operand:SI 0 "register_operand" "=r")
13441         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13442    (clobber (reg:CC FLAGS_REG))]
13443   "!TARGET_64BIT"
13444   { return output_set_got (operands[0]); }
13445   [(set_attr "type" "multi")
13446    (set_attr "length" "12")])
13448 (define_expand "epilogue"
13449   [(const_int 1)]
13450   ""
13451   "ix86_expand_epilogue (1); DONE;")
13453 (define_expand "sibcall_epilogue"
13454   [(const_int 1)]
13455   ""
13456   "ix86_expand_epilogue (0); DONE;")
13458 (define_expand "eh_return"
13459   [(use (match_operand 0 "register_operand" ""))]
13460   ""
13462   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13464   /* Tricky bit: we write the address of the handler to which we will
13465      be returning into someone else's stack frame, one word below the
13466      stack address we wish to restore.  */
13467   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13468   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13469   tmp = gen_rtx_MEM (Pmode, tmp);
13470   emit_move_insn (tmp, ra);
13472   if (Pmode == SImode)
13473     emit_jump_insn (gen_eh_return_si (sa));
13474   else
13475     emit_jump_insn (gen_eh_return_di (sa));
13476   emit_barrier ();
13477   DONE;
13480 (define_insn_and_split "eh_return_si"
13481   [(set (pc) 
13482         (unspec [(match_operand:SI 0 "register_operand" "c")]
13483                  UNSPEC_EH_RETURN))]
13484   "!TARGET_64BIT"
13485   "#"
13486   "reload_completed"
13487   [(const_int 1)]
13488   "ix86_expand_epilogue (2); DONE;")
13490 (define_insn_and_split "eh_return_di"
13491   [(set (pc) 
13492         (unspec [(match_operand:DI 0 "register_operand" "c")]
13493                  UNSPEC_EH_RETURN))]
13494   "TARGET_64BIT"
13495   "#"
13496   "reload_completed"
13497   [(const_int 1)]
13498   "ix86_expand_epilogue (2); DONE;")
13500 (define_insn "leave"
13501   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13502    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13503    (clobber (mem:BLK (scratch)))]
13504   "!TARGET_64BIT"
13505   "leave"
13506   [(set_attr "type" "leave")])
13508 (define_insn "leave_rex64"
13509   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13510    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13511    (clobber (mem:BLK (scratch)))]
13512   "TARGET_64BIT"
13513   "leave"
13514   [(set_attr "type" "leave")])
13516 (define_expand "ffssi2"
13517   [(parallel
13518      [(set (match_operand:SI 0 "register_operand" "") 
13519            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13520       (clobber (match_scratch:SI 2 ""))
13521       (clobber (reg:CC FLAGS_REG))])]
13522   ""
13523   "")
13525 (define_insn_and_split "*ffs_cmove"
13526   [(set (match_operand:SI 0 "register_operand" "=r") 
13527         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13528    (clobber (match_scratch:SI 2 "=&r"))
13529    (clobber (reg:CC FLAGS_REG))]
13530   "TARGET_CMOVE"
13531   "#"
13532   "&& reload_completed"
13533   [(set (match_dup 2) (const_int -1))
13534    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13535               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13536    (set (match_dup 0) (if_then_else:SI
13537                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13538                         (match_dup 2)
13539                         (match_dup 0)))
13540    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13541               (clobber (reg:CC FLAGS_REG))])]
13542   "")
13544 (define_insn_and_split "*ffs_no_cmove"
13545   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13546         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13547    (clobber (match_scratch:SI 2 "=&q"))
13548    (clobber (reg:CC FLAGS_REG))]
13549   ""
13550   "#"
13551   "reload_completed"
13552   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13553               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13554    (set (strict_low_part (match_dup 3))
13555         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13556    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13557               (clobber (reg:CC FLAGS_REG))])
13558    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13559               (clobber (reg:CC FLAGS_REG))])
13560    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13561               (clobber (reg:CC FLAGS_REG))])]
13563   operands[3] = gen_lowpart (QImode, operands[2]);
13564   ix86_expand_clear (operands[2]);
13567 (define_insn "*ffssi_1"
13568   [(set (reg:CCZ FLAGS_REG)
13569         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13570                      (const_int 0)))
13571    (set (match_operand:SI 0 "register_operand" "=r")
13572         (ctz:SI (match_dup 1)))]
13573   ""
13574   "bsf{l}\t{%1, %0|%0, %1}"
13575   [(set_attr "prefix_0f" "1")])
13577 (define_expand "ffsdi2"
13578   [(parallel
13579      [(set (match_operand:DI 0 "register_operand" "") 
13580            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13581       (clobber (match_scratch:DI 2 ""))
13582       (clobber (reg:CC FLAGS_REG))])]
13583   "TARGET_64BIT && TARGET_CMOVE"
13584   "")
13586 (define_insn_and_split "*ffs_rex64"
13587   [(set (match_operand:DI 0 "register_operand" "=r") 
13588         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13589    (clobber (match_scratch:DI 2 "=&r"))
13590    (clobber (reg:CC FLAGS_REG))]
13591   "TARGET_64BIT && TARGET_CMOVE"
13592   "#"
13593   "&& reload_completed"
13594   [(set (match_dup 2) (const_int -1))
13595    (parallel [(set (reg:CCZ FLAGS_REG)
13596                    (compare:CCZ (match_dup 1) (const_int 0)))
13597               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13598    (set (match_dup 0) (if_then_else:DI
13599                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13600                         (match_dup 2)
13601                         (match_dup 0)))
13602    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13603               (clobber (reg:CC FLAGS_REG))])]
13604   "")
13606 (define_insn "*ffsdi_1"
13607   [(set (reg:CCZ FLAGS_REG)
13608         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13609                      (const_int 0)))
13610    (set (match_operand:DI 0 "register_operand" "=r")
13611         (ctz:DI (match_dup 1)))]
13612   "TARGET_64BIT"
13613   "bsf{q}\t{%1, %0|%0, %1}"
13614   [(set_attr "prefix_0f" "1")])
13616 (define_insn "ctzsi2"
13617   [(set (match_operand:SI 0 "register_operand" "=r")
13618         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13619    (clobber (reg:CC FLAGS_REG))]
13620   ""
13621   "bsf{l}\t{%1, %0|%0, %1}"
13622   [(set_attr "prefix_0f" "1")])
13624 (define_insn "ctzdi2"
13625   [(set (match_operand:DI 0 "register_operand" "=r")
13626         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13627    (clobber (reg:CC FLAGS_REG))]
13628   "TARGET_64BIT"
13629   "bsf{q}\t{%1, %0|%0, %1}"
13630   [(set_attr "prefix_0f" "1")])
13632 (define_expand "clzsi2"
13633   [(parallel
13634      [(set (match_operand:SI 0 "register_operand" "")
13635            (minus:SI (const_int 31)
13636                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13637       (clobber (reg:CC FLAGS_REG))])
13638    (parallel
13639      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13640       (clobber (reg:CC FLAGS_REG))])]
13641   ""
13642   "")
13644 (define_insn "*bsr"
13645   [(set (match_operand:SI 0 "register_operand" "=r")
13646         (minus:SI (const_int 31)
13647                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13648    (clobber (reg:CC FLAGS_REG))]
13649   ""
13650   "bsr{l}\t{%1, %0|%0, %1}"
13651   [(set_attr "prefix_0f" "1")])
13653 (define_expand "clzdi2"
13654   [(parallel
13655      [(set (match_operand:DI 0 "register_operand" "")
13656            (minus:DI (const_int 63)
13657                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13658       (clobber (reg:CC FLAGS_REG))])
13659    (parallel
13660      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13661       (clobber (reg:CC FLAGS_REG))])]
13662   "TARGET_64BIT"
13663   "")
13665 (define_insn "*bsr_rex64"
13666   [(set (match_operand:DI 0 "register_operand" "=r")
13667         (minus:DI (const_int 63)
13668                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13669    (clobber (reg:CC FLAGS_REG))]
13670   "TARGET_64BIT"
13671   "bsr{q}\t{%1, %0|%0, %1}"
13672   [(set_attr "prefix_0f" "1")])
13674 ;; Thread-local storage patterns for ELF.
13676 ;; Note that these code sequences must appear exactly as shown
13677 ;; in order to allow linker relaxation.
13679 (define_insn "*tls_global_dynamic_32_gnu"
13680   [(set (match_operand:SI 0 "register_operand" "=a")
13681         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13682                     (match_operand:SI 2 "tls_symbolic_operand" "")
13683                     (match_operand:SI 3 "call_insn_operand" "")]
13684                     UNSPEC_TLS_GD))
13685    (clobber (match_scratch:SI 4 "=d"))
13686    (clobber (match_scratch:SI 5 "=c"))
13687    (clobber (reg:CC FLAGS_REG))]
13688   "!TARGET_64BIT && TARGET_GNU_TLS"
13689   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13690   [(set_attr "type" "multi")
13691    (set_attr "length" "12")])
13693 (define_insn "*tls_global_dynamic_32_sun"
13694   [(set (match_operand:SI 0 "register_operand" "=a")
13695         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13696                     (match_operand:SI 2 "tls_symbolic_operand" "")
13697                     (match_operand:SI 3 "call_insn_operand" "")]
13698                     UNSPEC_TLS_GD))
13699    (clobber (match_scratch:SI 4 "=d"))
13700    (clobber (match_scratch:SI 5 "=c"))
13701    (clobber (reg:CC FLAGS_REG))]
13702   "!TARGET_64BIT && TARGET_SUN_TLS"
13703   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13704         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13705   [(set_attr "type" "multi")
13706    (set_attr "length" "14")])
13708 (define_expand "tls_global_dynamic_32"
13709   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13710                    (unspec:SI
13711                     [(match_dup 2)
13712                      (match_operand:SI 1 "tls_symbolic_operand" "")
13713                      (match_dup 3)]
13714                     UNSPEC_TLS_GD))
13715               (clobber (match_scratch:SI 4 ""))
13716               (clobber (match_scratch:SI 5 ""))
13717               (clobber (reg:CC FLAGS_REG))])]
13718   ""
13720   if (flag_pic)
13721     operands[2] = pic_offset_table_rtx;
13722   else
13723     {
13724       operands[2] = gen_reg_rtx (Pmode);
13725       emit_insn (gen_set_got (operands[2]));
13726     }
13727   operands[3] = ix86_tls_get_addr ();
13730 (define_insn "*tls_global_dynamic_64"
13731   [(set (match_operand:DI 0 "register_operand" "=a")
13732         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13733                       (match_operand:DI 3 "" "")))
13734    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13735               UNSPEC_TLS_GD)]
13736   "TARGET_64BIT"
13737   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13738   [(set_attr "type" "multi")
13739    (set_attr "length" "16")])
13741 (define_expand "tls_global_dynamic_64"
13742   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13743                    (call (mem:QI (match_dup 2)) (const_int 0)))
13744               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13745                          UNSPEC_TLS_GD)])]
13746   ""
13748   operands[2] = ix86_tls_get_addr ();
13751 (define_insn "*tls_local_dynamic_base_32_gnu"
13752   [(set (match_operand:SI 0 "register_operand" "=a")
13753         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13754                     (match_operand:SI 2 "call_insn_operand" "")]
13755                    UNSPEC_TLS_LD_BASE))
13756    (clobber (match_scratch:SI 3 "=d"))
13757    (clobber (match_scratch:SI 4 "=c"))
13758    (clobber (reg:CC FLAGS_REG))]
13759   "!TARGET_64BIT && TARGET_GNU_TLS"
13760   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13761   [(set_attr "type" "multi")
13762    (set_attr "length" "11")])
13764 (define_insn "*tls_local_dynamic_base_32_sun"
13765   [(set (match_operand:SI 0 "register_operand" "=a")
13766         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13767                     (match_operand:SI 2 "call_insn_operand" "")]
13768                    UNSPEC_TLS_LD_BASE))
13769    (clobber (match_scratch:SI 3 "=d"))
13770    (clobber (match_scratch:SI 4 "=c"))
13771    (clobber (reg:CC FLAGS_REG))]
13772   "!TARGET_64BIT && TARGET_SUN_TLS"
13773   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13774         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13775   [(set_attr "type" "multi")
13776    (set_attr "length" "13")])
13778 (define_expand "tls_local_dynamic_base_32"
13779   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13780                    (unspec:SI [(match_dup 1) (match_dup 2)]
13781                               UNSPEC_TLS_LD_BASE))
13782               (clobber (match_scratch:SI 3 ""))
13783               (clobber (match_scratch:SI 4 ""))
13784               (clobber (reg:CC FLAGS_REG))])]
13785   ""
13787   if (flag_pic)
13788     operands[1] = pic_offset_table_rtx;
13789   else
13790     {
13791       operands[1] = gen_reg_rtx (Pmode);
13792       emit_insn (gen_set_got (operands[1]));
13793     }
13794   operands[2] = ix86_tls_get_addr ();
13797 (define_insn "*tls_local_dynamic_base_64"
13798   [(set (match_operand:DI 0 "register_operand" "=a")
13799         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13800                       (match_operand:DI 2 "" "")))
13801    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13802   "TARGET_64BIT"
13803   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13804   [(set_attr "type" "multi")
13805    (set_attr "length" "12")])
13807 (define_expand "tls_local_dynamic_base_64"
13808   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13809                    (call (mem:QI (match_dup 1)) (const_int 0)))
13810               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13811   ""
13813   operands[1] = ix86_tls_get_addr ();
13816 ;; Local dynamic of a single variable is a lose.  Show combine how
13817 ;; to convert that back to global dynamic.
13819 (define_insn_and_split "*tls_local_dynamic_32_once"
13820   [(set (match_operand:SI 0 "register_operand" "=a")
13821         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13822                              (match_operand:SI 2 "call_insn_operand" "")]
13823                             UNSPEC_TLS_LD_BASE)
13824                  (const:SI (unspec:SI
13825                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13826                             UNSPEC_DTPOFF))))
13827    (clobber (match_scratch:SI 4 "=d"))
13828    (clobber (match_scratch:SI 5 "=c"))
13829    (clobber (reg:CC FLAGS_REG))]
13830   ""
13831   "#"
13832   ""
13833   [(parallel [(set (match_dup 0)
13834                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13835                               UNSPEC_TLS_GD))
13836               (clobber (match_dup 4))
13837               (clobber (match_dup 5))
13838               (clobber (reg:CC FLAGS_REG))])]
13839   "")
13841 ;; Load and add the thread base pointer from %gs:0.
13843 (define_insn "*load_tp_si"
13844   [(set (match_operand:SI 0 "register_operand" "=r")
13845         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13846   "!TARGET_64BIT"
13847   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13848   [(set_attr "type" "imov")
13849    (set_attr "modrm" "0")
13850    (set_attr "length" "7")
13851    (set_attr "memory" "load")
13852    (set_attr "imm_disp" "false")])
13854 (define_insn "*add_tp_si"
13855   [(set (match_operand:SI 0 "register_operand" "=r")
13856         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13857                  (match_operand:SI 1 "register_operand" "0")))
13858    (clobber (reg:CC FLAGS_REG))]
13859   "!TARGET_64BIT"
13860   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13861   [(set_attr "type" "alu")
13862    (set_attr "modrm" "0")
13863    (set_attr "length" "7")
13864    (set_attr "memory" "load")
13865    (set_attr "imm_disp" "false")])
13867 (define_insn "*load_tp_di"
13868   [(set (match_operand:DI 0 "register_operand" "=r")
13869         (unspec:DI [(const_int 0)] UNSPEC_TP))]
13870   "TARGET_64BIT"
13871   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13872   [(set_attr "type" "imov")
13873    (set_attr "modrm" "0")
13874    (set_attr "length" "7")
13875    (set_attr "memory" "load")
13876    (set_attr "imm_disp" "false")])
13878 (define_insn "*add_tp_di"
13879   [(set (match_operand:DI 0 "register_operand" "=r")
13880         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
13881                  (match_operand:DI 1 "register_operand" "0")))
13882    (clobber (reg:CC FLAGS_REG))]
13883   "TARGET_64BIT"
13884   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13885   [(set_attr "type" "alu")
13886    (set_attr "modrm" "0")
13887    (set_attr "length" "7")
13888    (set_attr "memory" "load")
13889    (set_attr "imm_disp" "false")])
13891 ;; These patterns match the binary 387 instructions for addM3, subM3,
13892 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13893 ;; SFmode.  The first is the normal insn, the second the same insn but
13894 ;; with one operand a conversion, and the third the same insn but with
13895 ;; the other operand a conversion.  The conversion may be SFmode or
13896 ;; SImode if the target mode DFmode, but only SImode if the target mode
13897 ;; is SFmode.
13899 ;; Gcc is slightly more smart about handling normal two address instructions
13900 ;; so use special patterns for add and mull.
13902 (define_insn "*fop_sf_comm_mixed"
13903   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13904         (match_operator:SF 3 "binary_fp_operator"
13905                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
13906                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13907   "TARGET_MIX_SSE_I387
13908    && COMMUTATIVE_ARITH_P (operands[3])
13909    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13910   "* return output_387_binary_op (insn, operands);"
13911   [(set (attr "type") 
13912         (if_then_else (eq_attr "alternative" "1")
13913            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13914               (const_string "ssemul")
13915               (const_string "sseadd"))
13916            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13917               (const_string "fmul")
13918               (const_string "fop"))))
13919    (set_attr "mode" "SF")])
13921 (define_insn "*fop_sf_comm_sse"
13922   [(set (match_operand:SF 0 "register_operand" "=x")
13923         (match_operator:SF 3 "binary_fp_operator"
13924                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
13925                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13926   "TARGET_SSE_MATH
13927    && COMMUTATIVE_ARITH_P (operands[3])
13928    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13929   "* return output_387_binary_op (insn, operands);"
13930   [(set (attr "type") 
13931         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13932            (const_string "ssemul")
13933            (const_string "sseadd")))
13934    (set_attr "mode" "SF")])
13936 (define_insn "*fop_sf_comm_i387"
13937   [(set (match_operand:SF 0 "register_operand" "=f")
13938         (match_operator:SF 3 "binary_fp_operator"
13939                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
13940                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
13941   "TARGET_80387
13942    && COMMUTATIVE_ARITH_P (operands[3])
13943    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13944   "* return output_387_binary_op (insn, operands);"
13945   [(set (attr "type") 
13946         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13947            (const_string "fmul")
13948            (const_string "fop")))
13949    (set_attr "mode" "SF")])
13951 (define_insn "*fop_sf_1_mixed"
13952   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
13953         (match_operator:SF 3 "binary_fp_operator"
13954                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13955                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13956   "TARGET_MIX_SSE_I387
13957    && !COMMUTATIVE_ARITH_P (operands[3])
13958    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13959   "* return output_387_binary_op (insn, operands);"
13960   [(set (attr "type") 
13961         (cond [(and (eq_attr "alternative" "2")
13962                     (match_operand:SF 3 "mult_operator" ""))
13963                  (const_string "ssemul")
13964                (and (eq_attr "alternative" "2")
13965                     (match_operand:SF 3 "div_operator" ""))
13966                  (const_string "ssediv")
13967                (eq_attr "alternative" "2")
13968                  (const_string "sseadd")
13969                (match_operand:SF 3 "mult_operator" "") 
13970                  (const_string "fmul")
13971                (match_operand:SF 3 "div_operator" "") 
13972                  (const_string "fdiv")
13973               ]
13974               (const_string "fop")))
13975    (set_attr "mode" "SF")])
13977 (define_insn "*fop_sf_1_sse"
13978   [(set (match_operand:SF 0 "register_operand" "=x")
13979         (match_operator:SF 3 "binary_fp_operator"
13980                         [(match_operand:SF 1 "register_operand" "0")
13981                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13982   "TARGET_SSE_MATH
13983    && !COMMUTATIVE_ARITH_P (operands[3])"
13984   "* return output_387_binary_op (insn, operands);"
13985   [(set (attr "type") 
13986         (cond [(match_operand:SF 3 "mult_operator" "")
13987                  (const_string "ssemul")
13988                (match_operand:SF 3 "div_operator" "")
13989                  (const_string "ssediv")
13990               ]
13991               (const_string "sseadd")))
13992    (set_attr "mode" "SF")])
13994 ;; This pattern is not fully shadowed by the pattern above.
13995 (define_insn "*fop_sf_1_i387"
13996   [(set (match_operand:SF 0 "register_operand" "=f,f")
13997         (match_operator:SF 3 "binary_fp_operator"
13998                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
13999                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14000   "TARGET_80387 && !TARGET_SSE_MATH
14001    && !COMMUTATIVE_ARITH_P (operands[3])
14002    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14003   "* return output_387_binary_op (insn, operands);"
14004   [(set (attr "type") 
14005         (cond [(match_operand:SF 3 "mult_operator" "") 
14006                  (const_string "fmul")
14007                (match_operand:SF 3 "div_operator" "") 
14008                  (const_string "fdiv")
14009               ]
14010               (const_string "fop")))
14011    (set_attr "mode" "SF")])
14013 ;; ??? Add SSE splitters for these!
14014 (define_insn "*fop_sf_2<mode>_i387"
14015   [(set (match_operand:SF 0 "register_operand" "=f,f")
14016         (match_operator:SF 3 "binary_fp_operator"
14017           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14018            (match_operand:SF 2 "register_operand" "0,0")]))]
14019   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14020   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14021   [(set (attr "type") 
14022         (cond [(match_operand:SF 3 "mult_operator" "") 
14023                  (const_string "fmul")
14024                (match_operand:SF 3 "div_operator" "") 
14025                  (const_string "fdiv")
14026               ]
14027               (const_string "fop")))
14028    (set_attr "fp_int_src" "true")
14029    (set_attr "mode" "<MODE>")])
14031 (define_insn "*fop_sf_3<mode>_i387"
14032   [(set (match_operand:SF 0 "register_operand" "=f,f")
14033         (match_operator:SF 3 "binary_fp_operator"
14034           [(match_operand:SF 1 "register_operand" "0,0")
14035            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14036   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14037   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14038   [(set (attr "type") 
14039         (cond [(match_operand:SF 3 "mult_operator" "") 
14040                  (const_string "fmul")
14041                (match_operand:SF 3 "div_operator" "") 
14042                  (const_string "fdiv")
14043               ]
14044               (const_string "fop")))
14045    (set_attr "fp_int_src" "true")
14046    (set_attr "mode" "<MODE>")])
14048 (define_insn "*fop_df_comm_mixed"
14049   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14050         (match_operator:DF 3 "binary_fp_operator"
14051                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14052                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14053   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14054    && COMMUTATIVE_ARITH_P (operands[3])
14055    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14056   "* return output_387_binary_op (insn, operands);"
14057   [(set (attr "type") 
14058         (if_then_else (eq_attr "alternative" "1")
14059            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14060               (const_string "ssemul")
14061               (const_string "sseadd"))
14062            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14063               (const_string "fmul")
14064               (const_string "fop"))))
14065    (set_attr "mode" "DF")])
14067 (define_insn "*fop_df_comm_sse"
14068   [(set (match_operand:DF 0 "register_operand" "=Y")
14069         (match_operator:DF 3 "binary_fp_operator"
14070                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14071                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14072   "TARGET_SSE2 && TARGET_SSE_MATH
14073    && COMMUTATIVE_ARITH_P (operands[3])
14074    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14075   "* return output_387_binary_op (insn, operands);"
14076   [(set (attr "type") 
14077         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14078            (const_string "ssemul")
14079            (const_string "sseadd")))
14080    (set_attr "mode" "DF")])
14082 (define_insn "*fop_df_comm_i387"
14083   [(set (match_operand:DF 0 "register_operand" "=f")
14084         (match_operator:DF 3 "binary_fp_operator"
14085                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14086                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14087   "TARGET_80387
14088    && COMMUTATIVE_ARITH_P (operands[3])
14089    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14090   "* return output_387_binary_op (insn, operands);"
14091   [(set (attr "type") 
14092         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14093            (const_string "fmul")
14094            (const_string "fop")))
14095    (set_attr "mode" "DF")])
14097 (define_insn "*fop_df_1_mixed"
14098   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14099         (match_operator:DF 3 "binary_fp_operator"
14100                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14101                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14102   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14103    && !COMMUTATIVE_ARITH_P (operands[3])
14104    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14105   "* return output_387_binary_op (insn, operands);"
14106   [(set (attr "type") 
14107         (cond [(and (eq_attr "alternative" "2")
14108                     (match_operand:SF 3 "mult_operator" ""))
14109                  (const_string "ssemul")
14110                (and (eq_attr "alternative" "2")
14111                     (match_operand:SF 3 "div_operator" ""))
14112                  (const_string "ssediv")
14113                (eq_attr "alternative" "2")
14114                  (const_string "sseadd")
14115                (match_operand:DF 3 "mult_operator" "") 
14116                  (const_string "fmul")
14117                (match_operand:DF 3 "div_operator" "") 
14118                  (const_string "fdiv")
14119               ]
14120               (const_string "fop")))
14121    (set_attr "mode" "DF")])
14123 (define_insn "*fop_df_1_sse"
14124   [(set (match_operand:DF 0 "register_operand" "=Y")
14125         (match_operator:DF 3 "binary_fp_operator"
14126                         [(match_operand:DF 1 "register_operand" "0")
14127                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14128   "TARGET_SSE2 && TARGET_SSE_MATH
14129    && !COMMUTATIVE_ARITH_P (operands[3])"
14130   "* return output_387_binary_op (insn, operands);"
14131   [(set_attr "mode" "DF")
14132    (set (attr "type") 
14133         (cond [(match_operand:SF 3 "mult_operator" "")
14134                  (const_string "ssemul")
14135                (match_operand:SF 3 "div_operator" "")
14136                  (const_string "ssediv")
14137               ]
14138               (const_string "sseadd")))])
14140 ;; This pattern is not fully shadowed by the pattern above.
14141 (define_insn "*fop_df_1_i387"
14142   [(set (match_operand:DF 0 "register_operand" "=f,f")
14143         (match_operator:DF 3 "binary_fp_operator"
14144                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14145                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14146   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14147    && !COMMUTATIVE_ARITH_P (operands[3])
14148    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14149   "* return output_387_binary_op (insn, operands);"
14150   [(set (attr "type") 
14151         (cond [(match_operand:DF 3 "mult_operator" "") 
14152                  (const_string "fmul")
14153                (match_operand:DF 3 "div_operator" "")
14154                  (const_string "fdiv")
14155               ]
14156               (const_string "fop")))
14157    (set_attr "mode" "DF")])
14159 ;; ??? Add SSE splitters for these!
14160 (define_insn "*fop_df_2<mode>_i387"
14161   [(set (match_operand:DF 0 "register_operand" "=f,f")
14162         (match_operator:DF 3 "binary_fp_operator"
14163            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14164             (match_operand:DF 2 "register_operand" "0,0")]))]
14165   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14166    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14167   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14168   [(set (attr "type") 
14169         (cond [(match_operand:DF 3 "mult_operator" "") 
14170                  (const_string "fmul")
14171                (match_operand:DF 3 "div_operator" "") 
14172                  (const_string "fdiv")
14173               ]
14174               (const_string "fop")))
14175    (set_attr "fp_int_src" "true")
14176    (set_attr "mode" "<MODE>")])
14178 (define_insn "*fop_df_3<mode>_i387"
14179   [(set (match_operand:DF 0 "register_operand" "=f,f")
14180         (match_operator:DF 3 "binary_fp_operator"
14181            [(match_operand:DF 1 "register_operand" "0,0")
14182             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14183   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14184    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14185   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14186   [(set (attr "type") 
14187         (cond [(match_operand:DF 3 "mult_operator" "") 
14188                  (const_string "fmul")
14189                (match_operand:DF 3 "div_operator" "") 
14190                  (const_string "fdiv")
14191               ]
14192               (const_string "fop")))
14193    (set_attr "fp_int_src" "true")
14194    (set_attr "mode" "<MODE>")])
14196 (define_insn "*fop_df_4_i387"
14197   [(set (match_operand:DF 0 "register_operand" "=f,f")
14198         (match_operator:DF 3 "binary_fp_operator"
14199            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14200             (match_operand:DF 2 "register_operand" "0,f")]))]
14201   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14202    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14203   "* return output_387_binary_op (insn, operands);"
14204   [(set (attr "type") 
14205         (cond [(match_operand:DF 3 "mult_operator" "") 
14206                  (const_string "fmul")
14207                (match_operand:DF 3 "div_operator" "") 
14208                  (const_string "fdiv")
14209               ]
14210               (const_string "fop")))
14211    (set_attr "mode" "SF")])
14213 (define_insn "*fop_df_5_i387"
14214   [(set (match_operand:DF 0 "register_operand" "=f,f")
14215         (match_operator:DF 3 "binary_fp_operator"
14216           [(match_operand:DF 1 "register_operand" "0,f")
14217            (float_extend:DF
14218             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14219   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14220   "* return output_387_binary_op (insn, operands);"
14221   [(set (attr "type") 
14222         (cond [(match_operand:DF 3 "mult_operator" "") 
14223                  (const_string "fmul")
14224                (match_operand:DF 3 "div_operator" "") 
14225                  (const_string "fdiv")
14226               ]
14227               (const_string "fop")))
14228    (set_attr "mode" "SF")])
14230 (define_insn "*fop_df_6_i387"
14231   [(set (match_operand:DF 0 "register_operand" "=f,f")
14232         (match_operator:DF 3 "binary_fp_operator"
14233           [(float_extend:DF
14234             (match_operand:SF 1 "register_operand" "0,f"))
14235            (float_extend:DF
14236             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14237   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14238   "* return output_387_binary_op (insn, operands);"
14239   [(set (attr "type") 
14240         (cond [(match_operand:DF 3 "mult_operator" "") 
14241                  (const_string "fmul")
14242                (match_operand:DF 3 "div_operator" "") 
14243                  (const_string "fdiv")
14244               ]
14245               (const_string "fop")))
14246    (set_attr "mode" "SF")])
14248 (define_insn "*fop_xf_comm_i387"
14249   [(set (match_operand:XF 0 "register_operand" "=f")
14250         (match_operator:XF 3 "binary_fp_operator"
14251                         [(match_operand:XF 1 "register_operand" "%0")
14252                          (match_operand:XF 2 "register_operand" "f")]))]
14253   "TARGET_80387
14254    && COMMUTATIVE_ARITH_P (operands[3])"
14255   "* return output_387_binary_op (insn, operands);"
14256   [(set (attr "type") 
14257         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14258            (const_string "fmul")
14259            (const_string "fop")))
14260    (set_attr "mode" "XF")])
14262 (define_insn "*fop_xf_1_i387"
14263   [(set (match_operand:XF 0 "register_operand" "=f,f")
14264         (match_operator:XF 3 "binary_fp_operator"
14265                         [(match_operand:XF 1 "register_operand" "0,f")
14266                          (match_operand:XF 2 "register_operand" "f,0")]))]
14267   "TARGET_80387
14268    && !COMMUTATIVE_ARITH_P (operands[3])"
14269   "* return output_387_binary_op (insn, operands);"
14270   [(set (attr "type") 
14271         (cond [(match_operand:XF 3 "mult_operator" "") 
14272                  (const_string "fmul")
14273                (match_operand:XF 3 "div_operator" "") 
14274                  (const_string "fdiv")
14275               ]
14276               (const_string "fop")))
14277    (set_attr "mode" "XF")])
14279 (define_insn "*fop_xf_2<mode>_i387"
14280   [(set (match_operand:XF 0 "register_operand" "=f,f")
14281         (match_operator:XF 3 "binary_fp_operator"
14282            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14283             (match_operand:XF 2 "register_operand" "0,0")]))]
14284   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14285   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14286   [(set (attr "type") 
14287         (cond [(match_operand:XF 3 "mult_operator" "") 
14288                  (const_string "fmul")
14289                (match_operand:XF 3 "div_operator" "") 
14290                  (const_string "fdiv")
14291               ]
14292               (const_string "fop")))
14293    (set_attr "fp_int_src" "true")
14294    (set_attr "mode" "<MODE>")])
14296 (define_insn "*fop_xf_3<mode>_i387"
14297   [(set (match_operand:XF 0 "register_operand" "=f,f")
14298         (match_operator:XF 3 "binary_fp_operator"
14299           [(match_operand:XF 1 "register_operand" "0,0")
14300            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14301   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14302   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14303   [(set (attr "type") 
14304         (cond [(match_operand:XF 3 "mult_operator" "") 
14305                  (const_string "fmul")
14306                (match_operand:XF 3 "div_operator" "") 
14307                  (const_string "fdiv")
14308               ]
14309               (const_string "fop")))
14310    (set_attr "fp_int_src" "true")
14311    (set_attr "mode" "<MODE>")])
14313 (define_insn "*fop_xf_4_i387"
14314   [(set (match_operand:XF 0 "register_operand" "=f,f")
14315         (match_operator:XF 3 "binary_fp_operator"
14316            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14317             (match_operand:XF 2 "register_operand" "0,f")]))]
14318   "TARGET_80387"
14319   "* return output_387_binary_op (insn, operands);"
14320   [(set (attr "type") 
14321         (cond [(match_operand:XF 3 "mult_operator" "") 
14322                  (const_string "fmul")
14323                (match_operand:XF 3 "div_operator" "") 
14324                  (const_string "fdiv")
14325               ]
14326               (const_string "fop")))
14327    (set_attr "mode" "SF")])
14329 (define_insn "*fop_xf_5_i387"
14330   [(set (match_operand:XF 0 "register_operand" "=f,f")
14331         (match_operator:XF 3 "binary_fp_operator"
14332           [(match_operand:XF 1 "register_operand" "0,f")
14333            (float_extend:XF
14334             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14335   "TARGET_80387"
14336   "* return output_387_binary_op (insn, operands);"
14337   [(set (attr "type") 
14338         (cond [(match_operand:XF 3 "mult_operator" "") 
14339                  (const_string "fmul")
14340                (match_operand:XF 3 "div_operator" "") 
14341                  (const_string "fdiv")
14342               ]
14343               (const_string "fop")))
14344    (set_attr "mode" "SF")])
14346 (define_insn "*fop_xf_6_i387"
14347   [(set (match_operand:XF 0 "register_operand" "=f,f")
14348         (match_operator:XF 3 "binary_fp_operator"
14349           [(float_extend:XF
14350             (match_operand 1 "register_operand" "0,f"))
14351            (float_extend:XF
14352             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14353   "TARGET_80387"
14354   "* return output_387_binary_op (insn, operands);"
14355   [(set (attr "type") 
14356         (cond [(match_operand:XF 3 "mult_operator" "") 
14357                  (const_string "fmul")
14358                (match_operand:XF 3 "div_operator" "") 
14359                  (const_string "fdiv")
14360               ]
14361               (const_string "fop")))
14362    (set_attr "mode" "SF")])
14364 (define_split
14365   [(set (match_operand 0 "register_operand" "")
14366         (match_operator 3 "binary_fp_operator"
14367            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14368             (match_operand 2 "register_operand" "")]))]
14369   "TARGET_80387 && reload_completed
14370    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14371   [(const_int 0)]
14373   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14374   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14375   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14376                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14377                                           GET_MODE (operands[3]),
14378                                           operands[4],
14379                                           operands[2])));
14380   ix86_free_from_memory (GET_MODE (operands[1]));
14381   DONE;
14384 (define_split
14385   [(set (match_operand 0 "register_operand" "")
14386         (match_operator 3 "binary_fp_operator"
14387            [(match_operand 1 "register_operand" "")
14388             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14389   "TARGET_80387 && reload_completed
14390    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14391   [(const_int 0)]
14393   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14394   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14395   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14396                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14397                                           GET_MODE (operands[3]),
14398                                           operands[1],
14399                                           operands[4])));
14400   ix86_free_from_memory (GET_MODE (operands[2]));
14401   DONE;
14404 ;; FPU special functions.
14406 (define_expand "sqrtsf2"
14407   [(set (match_operand:SF 0 "register_operand" "")
14408         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14409   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14411   if (!TARGET_SSE_MATH)
14412     operands[1] = force_reg (SFmode, operands[1]);
14415 (define_insn "*sqrtsf2_mixed"
14416   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14417         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14418   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14419   "@
14420    fsqrt
14421    sqrtss\t{%1, %0|%0, %1}"
14422   [(set_attr "type" "fpspc,sse")
14423    (set_attr "mode" "SF,SF")
14424    (set_attr "athlon_decode" "direct,*")])
14426 (define_insn "*sqrtsf2_sse"
14427   [(set (match_operand:SF 0 "register_operand" "=x")
14428         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14429   "TARGET_SSE_MATH"
14430   "sqrtss\t{%1, %0|%0, %1}"
14431   [(set_attr "type" "sse")
14432    (set_attr "mode" "SF")
14433    (set_attr "athlon_decode" "*")])
14435 (define_insn "*sqrtsf2_i387"
14436   [(set (match_operand:SF 0 "register_operand" "=f")
14437         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14438   "TARGET_USE_FANCY_MATH_387"
14439   "fsqrt"
14440   [(set_attr "type" "fpspc")
14441    (set_attr "mode" "SF")
14442    (set_attr "athlon_decode" "direct")])
14444 (define_expand "sqrtdf2"
14445   [(set (match_operand:DF 0 "register_operand" "")
14446         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14447   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14449   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14450     operands[1] = force_reg (DFmode, operands[1]);
14453 (define_insn "*sqrtdf2_mixed"
14454   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14455         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14456   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14457   "@
14458    fsqrt
14459    sqrtsd\t{%1, %0|%0, %1}"
14460   [(set_attr "type" "fpspc,sse")
14461    (set_attr "mode" "DF,DF")
14462    (set_attr "athlon_decode" "direct,*")])
14464 (define_insn "*sqrtdf2_sse"
14465   [(set (match_operand:DF 0 "register_operand" "=Y")
14466         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14467   "TARGET_SSE2 && TARGET_SSE_MATH"
14468   "sqrtsd\t{%1, %0|%0, %1}"
14469   [(set_attr "type" "sse")
14470    (set_attr "mode" "DF")
14471    (set_attr "athlon_decode" "*")])
14473 (define_insn "*sqrtdf2_i387"
14474   [(set (match_operand:DF 0 "register_operand" "=f")
14475         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14476   "TARGET_USE_FANCY_MATH_387"
14477   "fsqrt"
14478   [(set_attr "type" "fpspc")
14479    (set_attr "mode" "DF")
14480    (set_attr "athlon_decode" "direct")])
14482 (define_insn "*sqrtextendsfdf2_i387"
14483   [(set (match_operand:DF 0 "register_operand" "=f")
14484         (sqrt:DF (float_extend:DF
14485                   (match_operand:SF 1 "register_operand" "0"))))]
14486   "TARGET_USE_FANCY_MATH_387
14487    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14488   "fsqrt"
14489   [(set_attr "type" "fpspc")
14490    (set_attr "mode" "DF")
14491    (set_attr "athlon_decode" "direct")])
14493 (define_insn "sqrtxf2"
14494   [(set (match_operand:XF 0 "register_operand" "=f")
14495         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14496   "TARGET_USE_FANCY_MATH_387 
14497    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14498   "fsqrt"
14499   [(set_attr "type" "fpspc")
14500    (set_attr "mode" "XF")
14501    (set_attr "athlon_decode" "direct")])
14503 (define_insn "*sqrtextendsfxf2_i387"
14504   [(set (match_operand:XF 0 "register_operand" "=f")
14505         (sqrt:XF (float_extend:XF
14506                   (match_operand:SF 1 "register_operand" "0"))))]
14507   "TARGET_USE_FANCY_MATH_387"
14508   "fsqrt"
14509   [(set_attr "type" "fpspc")
14510    (set_attr "mode" "XF")
14511    (set_attr "athlon_decode" "direct")])
14513 (define_insn "*sqrtextenddfxf2_i387"
14514   [(set (match_operand:XF 0 "register_operand" "=f")
14515         (sqrt:XF (float_extend:XF
14516                   (match_operand:DF 1 "register_operand" "0"))))]
14517   "TARGET_USE_FANCY_MATH_387"
14518   "fsqrt"
14519   [(set_attr "type" "fpspc")
14520    (set_attr "mode" "XF")
14521    (set_attr "athlon_decode" "direct")])
14523 (define_insn "fpremxf4"
14524   [(set (match_operand:XF 0 "register_operand" "=f")
14525         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14526                     (match_operand:XF 3 "register_operand" "1")]
14527                    UNSPEC_FPREM_F))
14528    (set (match_operand:XF 1 "register_operand" "=u")
14529         (unspec:XF [(match_dup 2) (match_dup 3)]
14530                    UNSPEC_FPREM_U))
14531    (set (reg:CCFP FPSR_REG)
14532         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14533   "TARGET_USE_FANCY_MATH_387
14534    && flag_unsafe_math_optimizations"
14535   "fprem"
14536   [(set_attr "type" "fpspc")
14537    (set_attr "mode" "XF")])
14539 (define_expand "fmodsf3"
14540   [(use (match_operand:SF 0 "register_operand" ""))
14541    (use (match_operand:SF 1 "register_operand" ""))
14542    (use (match_operand:SF 2 "register_operand" ""))]
14543   "TARGET_USE_FANCY_MATH_387
14544    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14545    && flag_unsafe_math_optimizations"
14547   rtx label = gen_label_rtx ();
14549   rtx op1 = gen_reg_rtx (XFmode);
14550   rtx op2 = gen_reg_rtx (XFmode);
14552   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14553   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14555   emit_label (label);
14557   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14558   ix86_emit_fp_unordered_jump (label);
14560   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14561   DONE;
14564 (define_expand "fmoddf3"
14565   [(use (match_operand:DF 0 "register_operand" ""))
14566    (use (match_operand:DF 1 "register_operand" ""))
14567    (use (match_operand:DF 2 "register_operand" ""))]
14568   "TARGET_USE_FANCY_MATH_387
14569    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14570    && flag_unsafe_math_optimizations"
14572   rtx label = gen_label_rtx ();
14574   rtx op1 = gen_reg_rtx (XFmode);
14575   rtx op2 = gen_reg_rtx (XFmode);
14577   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14578   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14580   emit_label (label);
14582   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14583   ix86_emit_fp_unordered_jump (label);
14585   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14586   DONE;
14589 (define_expand "fmodxf3"
14590   [(use (match_operand:XF 0 "register_operand" ""))
14591    (use (match_operand:XF 1 "register_operand" ""))
14592    (use (match_operand:XF 2 "register_operand" ""))]
14593   "TARGET_USE_FANCY_MATH_387
14594    && flag_unsafe_math_optimizations"
14596   rtx label = gen_label_rtx ();
14598   emit_label (label);
14600   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14601                            operands[1], operands[2]));
14602   ix86_emit_fp_unordered_jump (label);
14604   emit_move_insn (operands[0], operands[1]);
14605   DONE;
14608 (define_insn "fprem1xf4"
14609   [(set (match_operand:XF 0 "register_operand" "=f")
14610         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14611                     (match_operand:XF 3 "register_operand" "1")]
14612                    UNSPEC_FPREM1_F))
14613    (set (match_operand:XF 1 "register_operand" "=u")
14614         (unspec:XF [(match_dup 2) (match_dup 3)]
14615                    UNSPEC_FPREM1_U))
14616    (set (reg:CCFP FPSR_REG)
14617         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14618   "TARGET_USE_FANCY_MATH_387
14619    && flag_unsafe_math_optimizations"
14620   "fprem1"
14621   [(set_attr "type" "fpspc")
14622    (set_attr "mode" "XF")])
14624 (define_expand "dremsf3"
14625   [(use (match_operand:SF 0 "register_operand" ""))
14626    (use (match_operand:SF 1 "register_operand" ""))
14627    (use (match_operand:SF 2 "register_operand" ""))]
14628   "TARGET_USE_FANCY_MATH_387
14629    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14630    && flag_unsafe_math_optimizations"
14632   rtx label = gen_label_rtx ();
14634   rtx op1 = gen_reg_rtx (XFmode);
14635   rtx op2 = gen_reg_rtx (XFmode);
14637   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14638   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14640   emit_label (label);
14642   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14643   ix86_emit_fp_unordered_jump (label);
14645   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14646   DONE;
14649 (define_expand "dremdf3"
14650   [(use (match_operand:DF 0 "register_operand" ""))
14651    (use (match_operand:DF 1 "register_operand" ""))
14652    (use (match_operand:DF 2 "register_operand" ""))]
14653   "TARGET_USE_FANCY_MATH_387
14654    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14655    && flag_unsafe_math_optimizations"
14657   rtx label = gen_label_rtx ();
14659   rtx op1 = gen_reg_rtx (XFmode);
14660   rtx op2 = gen_reg_rtx (XFmode);
14662   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14663   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14665   emit_label (label);
14667   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14668   ix86_emit_fp_unordered_jump (label);
14670   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14671   DONE;
14674 (define_expand "dremxf3"
14675   [(use (match_operand:XF 0 "register_operand" ""))
14676    (use (match_operand:XF 1 "register_operand" ""))
14677    (use (match_operand:XF 2 "register_operand" ""))]
14678   "TARGET_USE_FANCY_MATH_387
14679    && flag_unsafe_math_optimizations"
14681   rtx label = gen_label_rtx ();
14683   emit_label (label);
14685   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14686                             operands[1], operands[2]));
14687   ix86_emit_fp_unordered_jump (label);
14689   emit_move_insn (operands[0], operands[1]);
14690   DONE;
14693 (define_insn "*sindf2"
14694   [(set (match_operand:DF 0 "register_operand" "=f")
14695         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14696   "TARGET_USE_FANCY_MATH_387
14697    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14698    && flag_unsafe_math_optimizations"
14699   "fsin"
14700   [(set_attr "type" "fpspc")
14701    (set_attr "mode" "DF")])
14703 (define_insn "*sinsf2"
14704   [(set (match_operand:SF 0 "register_operand" "=f")
14705         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14706   "TARGET_USE_FANCY_MATH_387
14707    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14708    && flag_unsafe_math_optimizations"
14709   "fsin"
14710   [(set_attr "type" "fpspc")
14711    (set_attr "mode" "SF")])
14713 (define_insn "*sinextendsfdf2"
14714   [(set (match_operand:DF 0 "register_operand" "=f")
14715         (unspec:DF [(float_extend:DF
14716                      (match_operand:SF 1 "register_operand" "0"))]
14717                    UNSPEC_SIN))]
14718   "TARGET_USE_FANCY_MATH_387
14719    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14720    && flag_unsafe_math_optimizations"
14721   "fsin"
14722   [(set_attr "type" "fpspc")
14723    (set_attr "mode" "DF")])
14725 (define_insn "*sinxf2"
14726   [(set (match_operand:XF 0 "register_operand" "=f")
14727         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14728   "TARGET_USE_FANCY_MATH_387
14729    && flag_unsafe_math_optimizations"
14730   "fsin"
14731   [(set_attr "type" "fpspc")
14732    (set_attr "mode" "XF")])
14734 (define_insn "*cosdf2"
14735   [(set (match_operand:DF 0 "register_operand" "=f")
14736         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14737   "TARGET_USE_FANCY_MATH_387
14738    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14739    && flag_unsafe_math_optimizations"
14740   "fcos"
14741   [(set_attr "type" "fpspc")
14742    (set_attr "mode" "DF")])
14744 (define_insn "*cossf2"
14745   [(set (match_operand:SF 0 "register_operand" "=f")
14746         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14747   "TARGET_USE_FANCY_MATH_387
14748    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14749    && flag_unsafe_math_optimizations"
14750   "fcos"
14751   [(set_attr "type" "fpspc")
14752    (set_attr "mode" "SF")])
14754 (define_insn "*cosextendsfdf2"
14755   [(set (match_operand:DF 0 "register_operand" "=f")
14756         (unspec:DF [(float_extend:DF
14757                      (match_operand:SF 1 "register_operand" "0"))]
14758                    UNSPEC_COS))]
14759   "TARGET_USE_FANCY_MATH_387
14760    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14761    && flag_unsafe_math_optimizations"
14762   "fcos"
14763   [(set_attr "type" "fpspc")
14764    (set_attr "mode" "DF")])
14766 (define_insn "*cosxf2"
14767   [(set (match_operand:XF 0 "register_operand" "=f")
14768         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14769   "TARGET_USE_FANCY_MATH_387
14770    && flag_unsafe_math_optimizations"
14771   "fcos"
14772   [(set_attr "type" "fpspc")
14773    (set_attr "mode" "XF")])
14775 ;; With sincos pattern defined, sin and cos builtin function will be
14776 ;; expanded to sincos pattern with one of its outputs left unused. 
14777 ;; Cse pass  will detected, if two sincos patterns can be combined,
14778 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14779 ;; depending on the unused output.
14781 (define_insn "sincosdf3"
14782   [(set (match_operand:DF 0 "register_operand" "=f")
14783         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14784                    UNSPEC_SINCOS_COS))
14785    (set (match_operand:DF 1 "register_operand" "=u")
14786         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14787   "TARGET_USE_FANCY_MATH_387
14788    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14789    && flag_unsafe_math_optimizations"
14790   "fsincos"
14791   [(set_attr "type" "fpspc")
14792    (set_attr "mode" "DF")])
14794 (define_split
14795   [(set (match_operand:DF 0 "register_operand" "")
14796         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14797                    UNSPEC_SINCOS_COS))
14798    (set (match_operand:DF 1 "register_operand" "")
14799         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14800   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14801    && !reload_completed && !reload_in_progress"
14802   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14803   "")
14805 (define_split
14806   [(set (match_operand:DF 0 "register_operand" "")
14807         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14808                    UNSPEC_SINCOS_COS))
14809    (set (match_operand:DF 1 "register_operand" "")
14810         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14811   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14812    && !reload_completed && !reload_in_progress"
14813   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14814   "")
14816 (define_insn "sincossf3"
14817   [(set (match_operand:SF 0 "register_operand" "=f")
14818         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14819                    UNSPEC_SINCOS_COS))
14820    (set (match_operand:SF 1 "register_operand" "=u")
14821         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14822   "TARGET_USE_FANCY_MATH_387
14823    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14824    && flag_unsafe_math_optimizations"
14825   "fsincos"
14826   [(set_attr "type" "fpspc")
14827    (set_attr "mode" "SF")])
14829 (define_split
14830   [(set (match_operand:SF 0 "register_operand" "")
14831         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14832                    UNSPEC_SINCOS_COS))
14833    (set (match_operand:SF 1 "register_operand" "")
14834         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14835   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14836    && !reload_completed && !reload_in_progress"
14837   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14838   "")
14840 (define_split
14841   [(set (match_operand:SF 0 "register_operand" "")
14842         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14843                    UNSPEC_SINCOS_COS))
14844    (set (match_operand:SF 1 "register_operand" "")
14845         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14846   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14847    && !reload_completed && !reload_in_progress"
14848   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14849   "")
14851 (define_insn "*sincosextendsfdf3"
14852   [(set (match_operand:DF 0 "register_operand" "=f")
14853         (unspec:DF [(float_extend:DF
14854                      (match_operand:SF 2 "register_operand" "0"))]
14855                    UNSPEC_SINCOS_COS))
14856    (set (match_operand:DF 1 "register_operand" "=u")
14857         (unspec:DF [(float_extend:DF
14858                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14859   "TARGET_USE_FANCY_MATH_387
14860    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14861    && flag_unsafe_math_optimizations"
14862   "fsincos"
14863   [(set_attr "type" "fpspc")
14864    (set_attr "mode" "DF")])
14866 (define_split
14867   [(set (match_operand:DF 0 "register_operand" "")
14868         (unspec:DF [(float_extend:DF
14869                      (match_operand:SF 2 "register_operand" ""))]
14870                    UNSPEC_SINCOS_COS))
14871    (set (match_operand:DF 1 "register_operand" "")
14872         (unspec:DF [(float_extend:DF
14873                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14874   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14875    && !reload_completed && !reload_in_progress"
14876   [(set (match_dup 1) (unspec:DF [(float_extend:DF
14877                                    (match_dup 2))] UNSPEC_SIN))]
14878   "")
14880 (define_split
14881   [(set (match_operand:DF 0 "register_operand" "")
14882         (unspec:DF [(float_extend:DF
14883                      (match_operand:SF 2 "register_operand" ""))]
14884                    UNSPEC_SINCOS_COS))
14885    (set (match_operand:DF 1 "register_operand" "")
14886         (unspec:DF [(float_extend:DF
14887                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14888   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14889    && !reload_completed && !reload_in_progress"
14890   [(set (match_dup 0) (unspec:DF [(float_extend:DF
14891                                    (match_dup 2))] UNSPEC_COS))]
14892   "")
14894 (define_insn "sincosxf3"
14895   [(set (match_operand:XF 0 "register_operand" "=f")
14896         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14897                    UNSPEC_SINCOS_COS))
14898    (set (match_operand:XF 1 "register_operand" "=u")
14899         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14900   "TARGET_USE_FANCY_MATH_387
14901    && flag_unsafe_math_optimizations"
14902   "fsincos"
14903   [(set_attr "type" "fpspc")
14904    (set_attr "mode" "XF")])
14906 (define_split
14907   [(set (match_operand:XF 0 "register_operand" "")
14908         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14909                    UNSPEC_SINCOS_COS))
14910    (set (match_operand:XF 1 "register_operand" "")
14911         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14912   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14913    && !reload_completed && !reload_in_progress"
14914   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
14915   "")
14917 (define_split
14918   [(set (match_operand:XF 0 "register_operand" "")
14919         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14920                    UNSPEC_SINCOS_COS))
14921    (set (match_operand:XF 1 "register_operand" "")
14922         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14923   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14924    && !reload_completed && !reload_in_progress"
14925   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
14926   "")
14928 (define_insn "*tandf3_1"
14929   [(set (match_operand:DF 0 "register_operand" "=f")
14930         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14931                    UNSPEC_TAN_ONE))
14932    (set (match_operand:DF 1 "register_operand" "=u")
14933         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
14934   "TARGET_USE_FANCY_MATH_387
14935    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14936    && flag_unsafe_math_optimizations"
14937   "fptan"
14938   [(set_attr "type" "fpspc")
14939    (set_attr "mode" "DF")])
14941 ;; optimize sequence: fptan
14942 ;;                    fstp    %st(0)
14943 ;;                    fld1
14944 ;; into fptan insn.
14946 (define_peephole2
14947   [(parallel[(set (match_operand:DF 0 "register_operand" "")
14948                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14949                              UNSPEC_TAN_ONE))
14950              (set (match_operand:DF 1 "register_operand" "")
14951                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
14952    (set (match_dup 0)
14953         (match_operand:DF 3 "immediate_operand" ""))]
14954   "standard_80387_constant_p (operands[3]) == 2"
14955   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
14956              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
14957   "")
14959 (define_expand "tandf2"
14960   [(parallel [(set (match_dup 2)
14961                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
14962                               UNSPEC_TAN_ONE))
14963               (set (match_operand:DF 0 "register_operand" "")
14964                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
14965   "TARGET_USE_FANCY_MATH_387
14966    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14967    && flag_unsafe_math_optimizations"
14969   operands[2] = gen_reg_rtx (DFmode);
14972 (define_insn "*tansf3_1"
14973   [(set (match_operand:SF 0 "register_operand" "=f")
14974         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14975                    UNSPEC_TAN_ONE))
14976    (set (match_operand:SF 1 "register_operand" "=u")
14977         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
14978   "TARGET_USE_FANCY_MATH_387
14979    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14980    && flag_unsafe_math_optimizations"
14981   "fptan"
14982   [(set_attr "type" "fpspc")
14983    (set_attr "mode" "SF")])
14985 ;; optimize sequence: fptan
14986 ;;                    fstp    %st(0)
14987 ;;                    fld1
14988 ;; into fptan insn.
14990 (define_peephole2
14991   [(parallel[(set (match_operand:SF 0 "register_operand" "")
14992                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14993                              UNSPEC_TAN_ONE))
14994              (set (match_operand:SF 1 "register_operand" "")
14995                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
14996    (set (match_dup 0)
14997         (match_operand:SF 3 "immediate_operand" ""))]
14998   "standard_80387_constant_p (operands[3]) == 2"
14999   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15000              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15001   "")
15003 (define_expand "tansf2"
15004   [(parallel [(set (match_dup 2)
15005                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15006                               UNSPEC_TAN_ONE))
15007               (set (match_operand:SF 0 "register_operand" "")
15008                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15009   "TARGET_USE_FANCY_MATH_387
15010    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15011    && flag_unsafe_math_optimizations"
15013   operands[2] = gen_reg_rtx (SFmode);
15016 (define_insn "*tanxf3_1"
15017   [(set (match_operand:XF 0 "register_operand" "=f")
15018         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15019                    UNSPEC_TAN_ONE))
15020    (set (match_operand:XF 1 "register_operand" "=u")
15021         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15022   "TARGET_USE_FANCY_MATH_387
15023    && flag_unsafe_math_optimizations"
15024   "fptan"
15025   [(set_attr "type" "fpspc")
15026    (set_attr "mode" "XF")])
15028 ;; optimize sequence: fptan
15029 ;;                    fstp    %st(0)
15030 ;;                    fld1
15031 ;; into fptan insn.
15033 (define_peephole2
15034   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15035                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15036                              UNSPEC_TAN_ONE))
15037              (set (match_operand:XF 1 "register_operand" "")
15038                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15039    (set (match_dup 0)
15040         (match_operand:XF 3 "immediate_operand" ""))]
15041   "standard_80387_constant_p (operands[3]) == 2"
15042   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15043              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15044   "")
15046 (define_expand "tanxf2"
15047   [(parallel [(set (match_dup 2)
15048                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15049                               UNSPEC_TAN_ONE))
15050               (set (match_operand:XF 0 "register_operand" "")
15051                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15052   "TARGET_USE_FANCY_MATH_387
15053    && flag_unsafe_math_optimizations"
15055   operands[2] = gen_reg_rtx (XFmode);
15058 (define_insn "atan2df3_1"
15059   [(set (match_operand:DF 0 "register_operand" "=f")
15060         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15061                     (match_operand:DF 1 "register_operand" "u")]
15062                    UNSPEC_FPATAN))
15063    (clobber (match_scratch:DF 3 "=1"))]
15064   "TARGET_USE_FANCY_MATH_387
15065    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15066    && flag_unsafe_math_optimizations"
15067   "fpatan"
15068   [(set_attr "type" "fpspc")
15069    (set_attr "mode" "DF")])
15071 (define_expand "atan2df3"
15072   [(use (match_operand:DF 0 "register_operand" ""))
15073    (use (match_operand:DF 2 "register_operand" ""))
15074    (use (match_operand:DF 1 "register_operand" ""))]
15075   "TARGET_USE_FANCY_MATH_387
15076    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15077    && flag_unsafe_math_optimizations"
15079   rtx copy = gen_reg_rtx (DFmode);
15080   emit_move_insn (copy, operands[1]);
15081   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15082   DONE;
15085 (define_expand "atandf2"
15086   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15087                    (unspec:DF [(match_dup 2)
15088                                (match_operand:DF 1 "register_operand" "")]
15089                     UNSPEC_FPATAN))
15090               (clobber (match_scratch:DF 3 ""))])]
15091   "TARGET_USE_FANCY_MATH_387
15092    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15093    && flag_unsafe_math_optimizations"
15095   operands[2] = gen_reg_rtx (DFmode);
15096   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15099 (define_insn "atan2sf3_1"
15100   [(set (match_operand:SF 0 "register_operand" "=f")
15101         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15102                     (match_operand:SF 1 "register_operand" "u")]
15103                    UNSPEC_FPATAN))
15104    (clobber (match_scratch:SF 3 "=1"))]
15105   "TARGET_USE_FANCY_MATH_387
15106    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15107    && flag_unsafe_math_optimizations"
15108   "fpatan"
15109   [(set_attr "type" "fpspc")
15110    (set_attr "mode" "SF")])
15112 (define_expand "atan2sf3"
15113   [(use (match_operand:SF 0 "register_operand" ""))
15114    (use (match_operand:SF 2 "register_operand" ""))
15115    (use (match_operand:SF 1 "register_operand" ""))]
15116   "TARGET_USE_FANCY_MATH_387
15117    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15118    && flag_unsafe_math_optimizations"
15120   rtx copy = gen_reg_rtx (SFmode);
15121   emit_move_insn (copy, operands[1]);
15122   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15123   DONE;
15126 (define_expand "atansf2"
15127   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15128                    (unspec:SF [(match_dup 2)
15129                                (match_operand:SF 1 "register_operand" "")]
15130                     UNSPEC_FPATAN))
15131               (clobber (match_scratch:SF 3 ""))])]
15132   "TARGET_USE_FANCY_MATH_387
15133    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15134    && flag_unsafe_math_optimizations"
15136   operands[2] = gen_reg_rtx (SFmode);
15137   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15140 (define_insn "atan2xf3_1"
15141   [(set (match_operand:XF 0 "register_operand" "=f")
15142         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15143                     (match_operand:XF 1 "register_operand" "u")]
15144                    UNSPEC_FPATAN))
15145    (clobber (match_scratch:XF 3 "=1"))]
15146   "TARGET_USE_FANCY_MATH_387
15147    && flag_unsafe_math_optimizations"
15148   "fpatan"
15149   [(set_attr "type" "fpspc")
15150    (set_attr "mode" "XF")])
15152 (define_expand "atan2xf3"
15153   [(use (match_operand:XF 0 "register_operand" ""))
15154    (use (match_operand:XF 2 "register_operand" ""))
15155    (use (match_operand:XF 1 "register_operand" ""))]
15156   "TARGET_USE_FANCY_MATH_387
15157    && flag_unsafe_math_optimizations"
15159   rtx copy = gen_reg_rtx (XFmode);
15160   emit_move_insn (copy, operands[1]);
15161   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15162   DONE;
15165 (define_expand "atanxf2"
15166   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15167                    (unspec:XF [(match_dup 2)
15168                                (match_operand:XF 1 "register_operand" "")]
15169                     UNSPEC_FPATAN))
15170               (clobber (match_scratch:XF 3 ""))])]
15171   "TARGET_USE_FANCY_MATH_387
15172    && flag_unsafe_math_optimizations"
15174   operands[2] = gen_reg_rtx (XFmode);
15175   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15178 (define_expand "asindf2"
15179   [(set (match_dup 2)
15180         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15181    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15182    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15183    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15184    (parallel [(set (match_dup 7)
15185                    (unspec:XF [(match_dup 6) (match_dup 2)]
15186                               UNSPEC_FPATAN))
15187               (clobber (match_scratch:XF 8 ""))])
15188    (set (match_operand:DF 0 "register_operand" "")
15189         (float_truncate:DF (match_dup 7)))]
15190   "TARGET_USE_FANCY_MATH_387
15191    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15192    && flag_unsafe_math_optimizations"
15194   int i;
15196   for (i=2; i<8; i++)
15197     operands[i] = gen_reg_rtx (XFmode);
15199   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15202 (define_expand "asinsf2"
15203   [(set (match_dup 2)
15204         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15205    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15206    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15207    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15208    (parallel [(set (match_dup 7)
15209                    (unspec:XF [(match_dup 6) (match_dup 2)]
15210                               UNSPEC_FPATAN))
15211               (clobber (match_scratch:XF 8 ""))])
15212    (set (match_operand:SF 0 "register_operand" "")
15213         (float_truncate:SF (match_dup 7)))]
15214   "TARGET_USE_FANCY_MATH_387
15215    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15216    && flag_unsafe_math_optimizations"
15218   int i;
15220   for (i=2; i<8; i++)
15221     operands[i] = gen_reg_rtx (XFmode);
15223   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15226 (define_expand "asinxf2"
15227   [(set (match_dup 2)
15228         (mult:XF (match_operand:XF 1 "register_operand" "")
15229                  (match_dup 1)))
15230    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15231    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15232    (parallel [(set (match_operand:XF 0 "register_operand" "")
15233                    (unspec:XF [(match_dup 5) (match_dup 1)]
15234                               UNSPEC_FPATAN))
15235               (clobber (match_scratch:XF 6 ""))])]
15236   "TARGET_USE_FANCY_MATH_387
15237    && flag_unsafe_math_optimizations"
15239   int i;
15241   for (i=2; i<6; i++)
15242     operands[i] = gen_reg_rtx (XFmode);
15244   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15247 (define_expand "acosdf2"
15248   [(set (match_dup 2)
15249         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15250    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15251    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15252    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15253    (parallel [(set (match_dup 7)
15254                    (unspec:XF [(match_dup 2) (match_dup 6)]
15255                               UNSPEC_FPATAN))
15256               (clobber (match_scratch:XF 8 ""))])
15257    (set (match_operand:DF 0 "register_operand" "")
15258         (float_truncate:DF (match_dup 7)))]
15259   "TARGET_USE_FANCY_MATH_387
15260    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15261    && flag_unsafe_math_optimizations"
15263   int i;
15265   for (i=2; i<8; i++)
15266     operands[i] = gen_reg_rtx (XFmode);
15268   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15271 (define_expand "acossf2"
15272   [(set (match_dup 2)
15273         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15274    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15275    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15276    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15277    (parallel [(set (match_dup 7)
15278                    (unspec:XF [(match_dup 2) (match_dup 6)]
15279                               UNSPEC_FPATAN))
15280               (clobber (match_scratch:XF 8 ""))])
15281    (set (match_operand:SF 0 "register_operand" "")
15282         (float_truncate:SF (match_dup 7)))]
15283   "TARGET_USE_FANCY_MATH_387
15284    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15285    && flag_unsafe_math_optimizations"
15287   int i;
15289   for (i=2; i<8; i++)
15290     operands[i] = gen_reg_rtx (XFmode);
15292   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15295 (define_expand "acosxf2"
15296   [(set (match_dup 2)
15297         (mult:XF (match_operand:XF 1 "register_operand" "")
15298                  (match_dup 1)))
15299    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15300    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15301    (parallel [(set (match_operand:XF 0 "register_operand" "")
15302                    (unspec:XF [(match_dup 1) (match_dup 5)]
15303                               UNSPEC_FPATAN))
15304               (clobber (match_scratch:XF 6 ""))])]
15305   "TARGET_USE_FANCY_MATH_387
15306    && flag_unsafe_math_optimizations"
15308   int i;
15310   for (i=2; i<6; i++)
15311     operands[i] = gen_reg_rtx (XFmode);
15313   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15316 (define_insn "fyl2x_xf3"
15317   [(set (match_operand:XF 0 "register_operand" "=f")
15318         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15319                     (match_operand:XF 1 "register_operand" "u")]
15320                    UNSPEC_FYL2X))
15321    (clobber (match_scratch:XF 3 "=1"))]
15322   "TARGET_USE_FANCY_MATH_387
15323    && flag_unsafe_math_optimizations"
15324   "fyl2x"
15325   [(set_attr "type" "fpspc")
15326    (set_attr "mode" "XF")])
15328 (define_expand "logsf2"
15329   [(set (match_dup 2)
15330         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15331    (parallel [(set (match_dup 4)
15332                    (unspec:XF [(match_dup 2)
15333                                (match_dup 3)] UNSPEC_FYL2X))
15334               (clobber (match_scratch:XF 5 ""))])
15335    (set (match_operand:SF 0 "register_operand" "")
15336         (float_truncate:SF (match_dup 4)))]
15337   "TARGET_USE_FANCY_MATH_387
15338    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15339    && flag_unsafe_math_optimizations"
15341   rtx temp;
15343   operands[2] = gen_reg_rtx (XFmode);
15344   operands[3] = gen_reg_rtx (XFmode);
15345   operands[4] = gen_reg_rtx (XFmode);
15347   temp = standard_80387_constant_rtx (4); /* fldln2 */
15348   emit_move_insn (operands[3], temp);
15351 (define_expand "logdf2"
15352   [(set (match_dup 2)
15353         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15354    (parallel [(set (match_dup 4)
15355                    (unspec:XF [(match_dup 2)
15356                                (match_dup 3)] UNSPEC_FYL2X))
15357               (clobber (match_scratch:XF 5 ""))])
15358    (set (match_operand:DF 0 "register_operand" "")
15359         (float_truncate:DF (match_dup 4)))]
15360   "TARGET_USE_FANCY_MATH_387
15361    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15362    && flag_unsafe_math_optimizations"
15364   rtx temp;
15366   operands[2] = gen_reg_rtx (XFmode);
15367   operands[3] = gen_reg_rtx (XFmode);
15368   operands[4] = gen_reg_rtx (XFmode);
15370   temp = standard_80387_constant_rtx (4); /* fldln2 */
15371   emit_move_insn (operands[3], temp);
15374 (define_expand "logxf2"
15375   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15376                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15377                                (match_dup 2)] UNSPEC_FYL2X))
15378               (clobber (match_scratch:XF 3 ""))])]
15379   "TARGET_USE_FANCY_MATH_387
15380    && flag_unsafe_math_optimizations"
15382   rtx temp;
15384   operands[2] = gen_reg_rtx (XFmode);
15385   temp = standard_80387_constant_rtx (4); /* fldln2 */
15386   emit_move_insn (operands[2], temp);
15389 (define_expand "log10sf2"
15390   [(set (match_dup 2)
15391         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15392    (parallel [(set (match_dup 4)
15393                    (unspec:XF [(match_dup 2)
15394                                (match_dup 3)] UNSPEC_FYL2X))
15395               (clobber (match_scratch:XF 5 ""))])
15396    (set (match_operand:SF 0 "register_operand" "")
15397         (float_truncate:SF (match_dup 4)))]
15398   "TARGET_USE_FANCY_MATH_387
15399    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15400    && flag_unsafe_math_optimizations"
15402   rtx temp;
15404   operands[2] = gen_reg_rtx (XFmode);
15405   operands[3] = gen_reg_rtx (XFmode);
15406   operands[4] = gen_reg_rtx (XFmode);
15408   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15409   emit_move_insn (operands[3], temp);
15412 (define_expand "log10df2"
15413   [(set (match_dup 2)
15414         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15415    (parallel [(set (match_dup 4)
15416                    (unspec:XF [(match_dup 2)
15417                                (match_dup 3)] UNSPEC_FYL2X))
15418               (clobber (match_scratch:XF 5 ""))])
15419    (set (match_operand:DF 0 "register_operand" "")
15420         (float_truncate:DF (match_dup 4)))]
15421   "TARGET_USE_FANCY_MATH_387
15422    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15423    && flag_unsafe_math_optimizations"
15425   rtx temp;
15427   operands[2] = gen_reg_rtx (XFmode);
15428   operands[3] = gen_reg_rtx (XFmode);
15429   operands[4] = gen_reg_rtx (XFmode);
15431   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15432   emit_move_insn (operands[3], temp);
15435 (define_expand "log10xf2"
15436   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15437                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15438                                (match_dup 2)] UNSPEC_FYL2X))
15439               (clobber (match_scratch:XF 3 ""))])]
15440   "TARGET_USE_FANCY_MATH_387
15441    && flag_unsafe_math_optimizations"
15443   rtx temp;
15445   operands[2] = gen_reg_rtx (XFmode);
15446   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15447   emit_move_insn (operands[2], temp);
15450 (define_expand "log2sf2"
15451   [(set (match_dup 2)
15452         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15453    (parallel [(set (match_dup 4)
15454                    (unspec:XF [(match_dup 2)
15455                                (match_dup 3)] UNSPEC_FYL2X))
15456               (clobber (match_scratch:XF 5 ""))])
15457    (set (match_operand:SF 0 "register_operand" "")
15458         (float_truncate:SF (match_dup 4)))]
15459   "TARGET_USE_FANCY_MATH_387
15460    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15461    && flag_unsafe_math_optimizations"
15463   operands[2] = gen_reg_rtx (XFmode);
15464   operands[3] = gen_reg_rtx (XFmode);
15465   operands[4] = gen_reg_rtx (XFmode);
15467   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15470 (define_expand "log2df2"
15471   [(set (match_dup 2)
15472         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15473    (parallel [(set (match_dup 4)
15474                    (unspec:XF [(match_dup 2)
15475                                (match_dup 3)] UNSPEC_FYL2X))
15476               (clobber (match_scratch:XF 5 ""))])
15477    (set (match_operand:DF 0 "register_operand" "")
15478         (float_truncate:DF (match_dup 4)))]
15479   "TARGET_USE_FANCY_MATH_387
15480    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15481    && flag_unsafe_math_optimizations"
15483   operands[2] = gen_reg_rtx (XFmode);
15484   operands[3] = gen_reg_rtx (XFmode);
15485   operands[4] = gen_reg_rtx (XFmode);
15487   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15490 (define_expand "log2xf2"
15491   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15492                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15493                                (match_dup 2)] UNSPEC_FYL2X))
15494               (clobber (match_scratch:XF 3 ""))])]
15495   "TARGET_USE_FANCY_MATH_387
15496    && flag_unsafe_math_optimizations"
15498   operands[2] = gen_reg_rtx (XFmode);
15499   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15502 (define_insn "fyl2xp1_xf3"
15503   [(set (match_operand:XF 0 "register_operand" "=f")
15504         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15505                     (match_operand:XF 1 "register_operand" "u")]
15506                    UNSPEC_FYL2XP1))
15507    (clobber (match_scratch:XF 3 "=1"))]
15508   "TARGET_USE_FANCY_MATH_387
15509    && flag_unsafe_math_optimizations"
15510   "fyl2xp1"
15511   [(set_attr "type" "fpspc")
15512    (set_attr "mode" "XF")])
15514 (define_expand "log1psf2"
15515   [(use (match_operand:SF 0 "register_operand" ""))
15516    (use (match_operand:SF 1 "register_operand" ""))]
15517   "TARGET_USE_FANCY_MATH_387
15518    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15519    && flag_unsafe_math_optimizations"
15521   rtx op0 = gen_reg_rtx (XFmode);
15522   rtx op1 = gen_reg_rtx (XFmode);
15524   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15525   ix86_emit_i387_log1p (op0, op1);
15526   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15527   DONE;
15530 (define_expand "log1pdf2"
15531   [(use (match_operand:DF 0 "register_operand" ""))
15532    (use (match_operand:DF 1 "register_operand" ""))]
15533   "TARGET_USE_FANCY_MATH_387
15534    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15535    && flag_unsafe_math_optimizations"
15537   rtx op0 = gen_reg_rtx (XFmode);
15538   rtx op1 = gen_reg_rtx (XFmode);
15540   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15541   ix86_emit_i387_log1p (op0, op1);
15542   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15543   DONE;
15546 (define_expand "log1pxf2"
15547   [(use (match_operand:XF 0 "register_operand" ""))
15548    (use (match_operand:XF 1 "register_operand" ""))]
15549   "TARGET_USE_FANCY_MATH_387
15550    && flag_unsafe_math_optimizations"
15552   ix86_emit_i387_log1p (operands[0], operands[1]);
15553   DONE;
15556 (define_insn "*fxtractxf3"
15557   [(set (match_operand:XF 0 "register_operand" "=f")
15558         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15559                    UNSPEC_XTRACT_FRACT))
15560    (set (match_operand:XF 1 "register_operand" "=u")
15561         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15562   "TARGET_USE_FANCY_MATH_387
15563    && flag_unsafe_math_optimizations"
15564   "fxtract"
15565   [(set_attr "type" "fpspc")
15566    (set_attr "mode" "XF")])
15568 (define_expand "logbsf2"
15569   [(set (match_dup 2)
15570         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15571    (parallel [(set (match_dup 3)
15572                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15573               (set (match_dup 4)
15574                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15575    (set (match_operand:SF 0 "register_operand" "")
15576         (float_truncate:SF (match_dup 4)))]
15577   "TARGET_USE_FANCY_MATH_387
15578    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15579    && flag_unsafe_math_optimizations"
15581   operands[2] = gen_reg_rtx (XFmode);
15582   operands[3] = gen_reg_rtx (XFmode);
15583   operands[4] = gen_reg_rtx (XFmode);
15586 (define_expand "logbdf2"
15587   [(set (match_dup 2)
15588         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15589    (parallel [(set (match_dup 3)
15590                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15591               (set (match_dup 4)
15592                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15593    (set (match_operand:DF 0 "register_operand" "")
15594         (float_truncate:DF (match_dup 4)))]
15595   "TARGET_USE_FANCY_MATH_387
15596    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15597    && flag_unsafe_math_optimizations"
15599   operands[2] = gen_reg_rtx (XFmode);
15600   operands[3] = gen_reg_rtx (XFmode);
15601   operands[4] = gen_reg_rtx (XFmode);
15604 (define_expand "logbxf2"
15605   [(parallel [(set (match_dup 2)
15606                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15607                               UNSPEC_XTRACT_FRACT))
15608               (set (match_operand:XF 0 "register_operand" "")
15609                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15610   "TARGET_USE_FANCY_MATH_387
15611    && flag_unsafe_math_optimizations"
15613   operands[2] = gen_reg_rtx (XFmode);
15616 (define_expand "ilogbsi2"
15617   [(parallel [(set (match_dup 2)
15618                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15619                               UNSPEC_XTRACT_FRACT))
15620               (set (match_operand:XF 3 "register_operand" "")
15621                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15622    (parallel [(set (match_operand:SI 0 "register_operand" "")
15623                    (fix:SI (match_dup 3)))
15624               (clobber (reg:CC FLAGS_REG))])]
15625   "TARGET_USE_FANCY_MATH_387
15626    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15627    && flag_unsafe_math_optimizations"
15629   operands[2] = gen_reg_rtx (XFmode);
15630   operands[3] = gen_reg_rtx (XFmode);
15633 (define_insn "*f2xm1xf2"
15634   [(set (match_operand:XF 0 "register_operand" "=f")
15635         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15636          UNSPEC_F2XM1))]
15637   "TARGET_USE_FANCY_MATH_387
15638    && flag_unsafe_math_optimizations"
15639   "f2xm1"
15640   [(set_attr "type" "fpspc")
15641    (set_attr "mode" "XF")])
15643 (define_insn "*fscalexf4"
15644   [(set (match_operand:XF 0 "register_operand" "=f")
15645         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15646                     (match_operand:XF 3 "register_operand" "1")]
15647                    UNSPEC_FSCALE_FRACT))
15648    (set (match_operand:XF 1 "register_operand" "=u")
15649         (unspec:XF [(match_dup 2) (match_dup 3)]
15650                    UNSPEC_FSCALE_EXP))]
15651   "TARGET_USE_FANCY_MATH_387
15652    && flag_unsafe_math_optimizations"
15653   "fscale"
15654   [(set_attr "type" "fpspc")
15655    (set_attr "mode" "XF")])
15657 (define_expand "expsf2"
15658   [(set (match_dup 2)
15659         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15660    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15661    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15662    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15663    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15664    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15665    (parallel [(set (match_dup 10)
15666                    (unspec:XF [(match_dup 9) (match_dup 5)]
15667                               UNSPEC_FSCALE_FRACT))
15668               (set (match_dup 11)
15669                    (unspec:XF [(match_dup 9) (match_dup 5)]
15670                               UNSPEC_FSCALE_EXP))])
15671    (set (match_operand:SF 0 "register_operand" "")
15672         (float_truncate:SF (match_dup 10)))]
15673   "TARGET_USE_FANCY_MATH_387
15674    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15675    && flag_unsafe_math_optimizations"
15677   rtx temp;
15678   int i;
15680   for (i=2; i<12; i++)
15681     operands[i] = gen_reg_rtx (XFmode);
15682   temp = standard_80387_constant_rtx (5); /* fldl2e */
15683   emit_move_insn (operands[3], temp);
15684   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15687 (define_expand "expdf2"
15688   [(set (match_dup 2)
15689         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15690    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15691    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15692    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15693    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15694    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15695    (parallel [(set (match_dup 10)
15696                    (unspec:XF [(match_dup 9) (match_dup 5)]
15697                               UNSPEC_FSCALE_FRACT))
15698               (set (match_dup 11)
15699                    (unspec:XF [(match_dup 9) (match_dup 5)]
15700                               UNSPEC_FSCALE_EXP))])
15701    (set (match_operand:DF 0 "register_operand" "")
15702         (float_truncate:DF (match_dup 10)))]
15703   "TARGET_USE_FANCY_MATH_387
15704    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15705    && flag_unsafe_math_optimizations"
15707   rtx temp;
15708   int i;
15710   for (i=2; i<12; i++)
15711     operands[i] = gen_reg_rtx (XFmode);
15712   temp = standard_80387_constant_rtx (5); /* fldl2e */
15713   emit_move_insn (operands[3], temp);
15714   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15717 (define_expand "expxf2"
15718   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15719                                (match_dup 2)))
15720    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15721    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15722    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15723    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15724    (parallel [(set (match_operand:XF 0 "register_operand" "")
15725                    (unspec:XF [(match_dup 8) (match_dup 4)]
15726                               UNSPEC_FSCALE_FRACT))
15727               (set (match_dup 9)
15728                    (unspec:XF [(match_dup 8) (match_dup 4)]
15729                               UNSPEC_FSCALE_EXP))])]
15730   "TARGET_USE_FANCY_MATH_387
15731    && flag_unsafe_math_optimizations"
15733   rtx temp;
15734   int i;
15736   for (i=2; i<10; i++)
15737     operands[i] = gen_reg_rtx (XFmode);
15738   temp = standard_80387_constant_rtx (5); /* fldl2e */
15739   emit_move_insn (operands[2], temp);
15740   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15743 (define_expand "exp10sf2"
15744   [(set (match_dup 2)
15745         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15746    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15747    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15748    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15749    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15750    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15751    (parallel [(set (match_dup 10)
15752                    (unspec:XF [(match_dup 9) (match_dup 5)]
15753                               UNSPEC_FSCALE_FRACT))
15754               (set (match_dup 11)
15755                    (unspec:XF [(match_dup 9) (match_dup 5)]
15756                               UNSPEC_FSCALE_EXP))])
15757    (set (match_operand:SF 0 "register_operand" "")
15758         (float_truncate:SF (match_dup 10)))]
15759   "TARGET_USE_FANCY_MATH_387
15760    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15761    && flag_unsafe_math_optimizations"
15763   rtx temp;
15764   int i;
15766   for (i=2; i<12; i++)
15767     operands[i] = gen_reg_rtx (XFmode);
15768   temp = standard_80387_constant_rtx (6); /* fldl2t */
15769   emit_move_insn (operands[3], temp);
15770   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15773 (define_expand "exp10df2"
15774   [(set (match_dup 2)
15775         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15776    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15777    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15778    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15779    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15780    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15781    (parallel [(set (match_dup 10)
15782                    (unspec:XF [(match_dup 9) (match_dup 5)]
15783                               UNSPEC_FSCALE_FRACT))
15784               (set (match_dup 11)
15785                    (unspec:XF [(match_dup 9) (match_dup 5)]
15786                               UNSPEC_FSCALE_EXP))])
15787    (set (match_operand:DF 0 "register_operand" "")
15788         (float_truncate:DF (match_dup 10)))]
15789   "TARGET_USE_FANCY_MATH_387
15790    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15791    && flag_unsafe_math_optimizations"
15793   rtx temp;
15794   int i;
15796   for (i=2; i<12; i++)
15797     operands[i] = gen_reg_rtx (XFmode);
15798   temp = standard_80387_constant_rtx (6); /* fldl2t */
15799   emit_move_insn (operands[3], temp);
15800   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15803 (define_expand "exp10xf2"
15804   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15805                                (match_dup 2)))
15806    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15807    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15808    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15809    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15810    (parallel [(set (match_operand:XF 0 "register_operand" "")
15811                    (unspec:XF [(match_dup 8) (match_dup 4)]
15812                               UNSPEC_FSCALE_FRACT))
15813               (set (match_dup 9)
15814                    (unspec:XF [(match_dup 8) (match_dup 4)]
15815                               UNSPEC_FSCALE_EXP))])]
15816   "TARGET_USE_FANCY_MATH_387
15817    && flag_unsafe_math_optimizations"
15819   rtx temp;
15820   int i;
15822   for (i=2; i<10; i++)
15823     operands[i] = gen_reg_rtx (XFmode);
15824   temp = standard_80387_constant_rtx (6); /* fldl2t */
15825   emit_move_insn (operands[2], temp);
15826   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15829 (define_expand "exp2sf2"
15830   [(set (match_dup 2)
15831         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15832    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15833    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15834    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15835    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15836    (parallel [(set (match_dup 8)
15837                    (unspec:XF [(match_dup 7) (match_dup 3)]
15838                               UNSPEC_FSCALE_FRACT))
15839               (set (match_dup 9)
15840                    (unspec:XF [(match_dup 7) (match_dup 3)]
15841                               UNSPEC_FSCALE_EXP))])
15842    (set (match_operand:SF 0 "register_operand" "")
15843         (float_truncate:SF (match_dup 8)))]
15844   "TARGET_USE_FANCY_MATH_387
15845    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15846    && flag_unsafe_math_optimizations"
15848   int i;
15850   for (i=2; i<10; i++)
15851     operands[i] = gen_reg_rtx (XFmode);
15852   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15855 (define_expand "exp2df2"
15856   [(set (match_dup 2)
15857         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15858    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15859    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15860    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15861    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15862    (parallel [(set (match_dup 8)
15863                    (unspec:XF [(match_dup 7) (match_dup 3)]
15864                               UNSPEC_FSCALE_FRACT))
15865               (set (match_dup 9)
15866                    (unspec:XF [(match_dup 7) (match_dup 3)]
15867                               UNSPEC_FSCALE_EXP))])
15868    (set (match_operand:DF 0 "register_operand" "")
15869         (float_truncate:DF (match_dup 8)))]
15870   "TARGET_USE_FANCY_MATH_387
15871    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15872    && flag_unsafe_math_optimizations"
15874   int i;
15876   for (i=2; i<10; i++)
15877     operands[i] = gen_reg_rtx (XFmode);
15878   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15881 (define_expand "exp2xf2"
15882   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15883    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15884    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15885    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15886    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15887    (parallel [(set (match_operand:XF 0 "register_operand" "")
15888                    (unspec:XF [(match_dup 7) (match_dup 3)]
15889                               UNSPEC_FSCALE_FRACT))
15890               (set (match_dup 8)
15891                    (unspec:XF [(match_dup 7) (match_dup 3)]
15892                               UNSPEC_FSCALE_EXP))])]
15893   "TARGET_USE_FANCY_MATH_387
15894    && flag_unsafe_math_optimizations"
15896   int i;
15898   for (i=2; i<9; i++)
15899     operands[i] = gen_reg_rtx (XFmode);
15900   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15903 (define_expand "expm1df2"
15904   [(set (match_dup 2)
15905         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15906    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15907    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15908    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15909    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15910    (parallel [(set (match_dup 8)
15911                    (unspec:XF [(match_dup 7) (match_dup 5)]
15912                               UNSPEC_FSCALE_FRACT))
15913                    (set (match_dup 9)
15914                    (unspec:XF [(match_dup 7) (match_dup 5)]
15915                               UNSPEC_FSCALE_EXP))])
15916    (parallel [(set (match_dup 11)
15917                    (unspec:XF [(match_dup 10) (match_dup 9)]
15918                               UNSPEC_FSCALE_FRACT))
15919               (set (match_dup 12)
15920                    (unspec:XF [(match_dup 10) (match_dup 9)]
15921                               UNSPEC_FSCALE_EXP))])
15922    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15923    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15924    (set (match_operand:DF 0 "register_operand" "")
15925         (float_truncate:DF (match_dup 14)))]
15926   "TARGET_USE_FANCY_MATH_387
15927    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15928    && flag_unsafe_math_optimizations"
15930   rtx temp;
15931   int i;
15933   for (i=2; i<15; i++)
15934     operands[i] = gen_reg_rtx (XFmode);
15935   temp = standard_80387_constant_rtx (5); /* fldl2e */
15936   emit_move_insn (operands[3], temp);
15937   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
15940 (define_expand "expm1sf2"
15941   [(set (match_dup 2)
15942         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15943    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15944    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15945    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15946    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15947    (parallel [(set (match_dup 8)
15948                    (unspec:XF [(match_dup 7) (match_dup 5)]
15949                               UNSPEC_FSCALE_FRACT))
15950                    (set (match_dup 9)
15951                    (unspec:XF [(match_dup 7) (match_dup 5)]
15952                               UNSPEC_FSCALE_EXP))])
15953    (parallel [(set (match_dup 11)
15954                    (unspec:XF [(match_dup 10) (match_dup 9)]
15955                               UNSPEC_FSCALE_FRACT))
15956               (set (match_dup 12)
15957                    (unspec:XF [(match_dup 10) (match_dup 9)]
15958                               UNSPEC_FSCALE_EXP))])
15959    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15960    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15961    (set (match_operand:SF 0 "register_operand" "")
15962         (float_truncate:SF (match_dup 14)))]
15963   "TARGET_USE_FANCY_MATH_387
15964    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15965    && flag_unsafe_math_optimizations"
15967   rtx temp;
15968   int i;
15970   for (i=2; i<15; i++)
15971     operands[i] = gen_reg_rtx (XFmode);
15972   temp = standard_80387_constant_rtx (5); /* fldl2e */
15973   emit_move_insn (operands[3], temp);
15974   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
15977 (define_expand "expm1xf2"
15978   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15979                                (match_dup 2)))
15980    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15981    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15982    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15983    (parallel [(set (match_dup 7)
15984                    (unspec:XF [(match_dup 6) (match_dup 4)]
15985                               UNSPEC_FSCALE_FRACT))
15986                    (set (match_dup 8)
15987                    (unspec:XF [(match_dup 6) (match_dup 4)]
15988                               UNSPEC_FSCALE_EXP))])
15989    (parallel [(set (match_dup 10)
15990                    (unspec:XF [(match_dup 9) (match_dup 8)]
15991                               UNSPEC_FSCALE_FRACT))
15992               (set (match_dup 11)
15993                    (unspec:XF [(match_dup 9) (match_dup 8)]
15994                               UNSPEC_FSCALE_EXP))])
15995    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
15996    (set (match_operand:XF 0 "register_operand" "")
15997         (plus:XF (match_dup 12) (match_dup 7)))]
15998   "TARGET_USE_FANCY_MATH_387
15999    && flag_unsafe_math_optimizations"
16001   rtx temp;
16002   int i;
16004   for (i=2; i<13; i++)
16005     operands[i] = gen_reg_rtx (XFmode);
16006   temp = standard_80387_constant_rtx (5); /* fldl2e */
16007   emit_move_insn (operands[2], temp);
16008   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16011 (define_expand "ldexpdf3"
16012   [(set (match_dup 3)
16013         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16014    (set (match_dup 4)
16015         (float:XF (match_operand:SI 2 "register_operand" "")))
16016    (parallel [(set (match_dup 5)
16017                    (unspec:XF [(match_dup 3) (match_dup 4)]
16018                               UNSPEC_FSCALE_FRACT))
16019               (set (match_dup 6)
16020                    (unspec:XF [(match_dup 3) (match_dup 4)]
16021                               UNSPEC_FSCALE_EXP))])
16022    (set (match_operand:DF 0 "register_operand" "")
16023         (float_truncate:DF (match_dup 5)))]
16024   "TARGET_USE_FANCY_MATH_387
16025    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16026    && flag_unsafe_math_optimizations"
16028   int i;
16030   for (i=3; i<7; i++)
16031     operands[i] = gen_reg_rtx (XFmode);
16034 (define_expand "ldexpsf3"
16035   [(set (match_dup 3)
16036         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16037    (set (match_dup 4)
16038         (float:XF (match_operand:SI 2 "register_operand" "")))
16039    (parallel [(set (match_dup 5)
16040                    (unspec:XF [(match_dup 3) (match_dup 4)]
16041                               UNSPEC_FSCALE_FRACT))
16042               (set (match_dup 6)
16043                    (unspec:XF [(match_dup 3) (match_dup 4)]
16044                               UNSPEC_FSCALE_EXP))])
16045    (set (match_operand:SF 0 "register_operand" "")
16046         (float_truncate:SF (match_dup 5)))]
16047   "TARGET_USE_FANCY_MATH_387
16048    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16049    && flag_unsafe_math_optimizations"
16051   int i;
16053   for (i=3; i<7; i++)
16054     operands[i] = gen_reg_rtx (XFmode);
16057 (define_expand "ldexpxf3"
16058   [(set (match_dup 3)
16059         (float:XF (match_operand:SI 2 "register_operand" "")))
16060    (parallel [(set (match_operand:XF 0 " register_operand" "")
16061                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16062                                (match_dup 3)]
16063                               UNSPEC_FSCALE_FRACT))
16064               (set (match_dup 4)
16065                    (unspec:XF [(match_dup 1) (match_dup 3)]
16066                               UNSPEC_FSCALE_EXP))])]
16067   "TARGET_USE_FANCY_MATH_387
16068    && flag_unsafe_math_optimizations"
16070   int i;
16072   for (i=3; i<5; i++)
16073     operands[i] = gen_reg_rtx (XFmode);
16077 (define_insn "frndintxf2"
16078   [(set (match_operand:XF 0 "register_operand" "=f")
16079         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16080          UNSPEC_FRNDINT))]
16081   "TARGET_USE_FANCY_MATH_387
16082    && flag_unsafe_math_optimizations"
16083   "frndint"
16084   [(set_attr "type" "fpspc")
16085    (set_attr "mode" "XF")])
16087 (define_expand "rintdf2"
16088   [(use (match_operand:DF 0 "register_operand" ""))
16089    (use (match_operand:DF 1 "register_operand" ""))]
16090   "TARGET_USE_FANCY_MATH_387
16091    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16092    && flag_unsafe_math_optimizations"
16094   rtx op0 = gen_reg_rtx (XFmode);
16095   rtx op1 = gen_reg_rtx (XFmode);
16097   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16098   emit_insn (gen_frndintxf2 (op0, op1));
16100   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16101   DONE;
16104 (define_expand "rintsf2"
16105   [(use (match_operand:SF 0 "register_operand" ""))
16106    (use (match_operand:SF 1 "register_operand" ""))]
16107   "TARGET_USE_FANCY_MATH_387
16108    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16109    && flag_unsafe_math_optimizations"
16111   rtx op0 = gen_reg_rtx (XFmode);
16112   rtx op1 = gen_reg_rtx (XFmode);
16114   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16115   emit_insn (gen_frndintxf2 (op0, op1));
16117   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16118   DONE;
16121 (define_expand "rintxf2"
16122   [(use (match_operand:XF 0 "register_operand" ""))
16123    (use (match_operand:XF 1 "register_operand" ""))]
16124   "TARGET_USE_FANCY_MATH_387
16125    && flag_unsafe_math_optimizations"
16127   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16128   DONE;
16131 (define_insn "fistdi2"
16132   [(set (match_operand:DI 0 "memory_operand" "=m")
16133         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16134          UNSPEC_FIST))
16135    (clobber (match_scratch:XF 2 "=&1f"))]
16136   "TARGET_USE_FANCY_MATH_387
16137    && flag_unsafe_math_optimizations"
16138   "* return output_fix_trunc (insn, operands, 0);"
16139   [(set_attr "type" "fpspc")
16140    (set_attr "mode" "DI")])
16142 (define_insn "fistdi2_with_temp"
16143   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16144         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16145          UNSPEC_FIST))
16146    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16147    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16148   "TARGET_USE_FANCY_MATH_387
16149    && flag_unsafe_math_optimizations"
16150   "#"
16151   [(set_attr "type" "fpspc")
16152    (set_attr "mode" "DI")])
16154 (define_split 
16155   [(set (match_operand:DI 0 "register_operand" "")
16156         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16157          UNSPEC_FIST))
16158    (clobber (match_operand:DI 2 "memory_operand" ""))
16159    (clobber (match_scratch 3 ""))]
16160   "reload_completed"
16161   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16162               (clobber (match_dup 3))])
16163    (set (match_dup 0) (match_dup 2))]
16164   "")
16166 (define_split 
16167   [(set (match_operand:DI 0 "memory_operand" "")
16168         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16169          UNSPEC_FIST))
16170    (clobber (match_operand:DI 2 "memory_operand" ""))
16171    (clobber (match_scratch 3 ""))]
16172   "reload_completed"
16173   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16174               (clobber (match_dup 3))])]
16175   "")
16177 (define_insn "fist<mode>2"
16178   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16179         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16180          UNSPEC_FIST))]
16181   "TARGET_USE_FANCY_MATH_387
16182    && flag_unsafe_math_optimizations"
16183   "* return output_fix_trunc (insn, operands, 0);"
16184   [(set_attr "type" "fpspc")
16185    (set_attr "mode" "<MODE>")])
16187 (define_insn "fist<mode>2_with_temp"
16188   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16189         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16190          UNSPEC_FIST))
16191    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16192   "TARGET_USE_FANCY_MATH_387
16193    && flag_unsafe_math_optimizations"
16194   "#"
16195   [(set_attr "type" "fpspc")
16196    (set_attr "mode" "<MODE>")])
16198 (define_split 
16199   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16200         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16201          UNSPEC_FIST))
16202    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16203   "reload_completed"
16204   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16205                        UNSPEC_FIST))
16206    (set (match_dup 0) (match_dup 2))]
16207   "")
16209 (define_split 
16210   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16211         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16212          UNSPEC_FIST))
16213    (clobber (match_scratch 2 ""))]
16214   "reload_completed"
16215   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16216                        UNSPEC_FIST))]
16217   "")
16219 (define_expand "lrint<mode>2"
16220   [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16221    (use (match_operand:XF 1 "register_operand" ""))]
16222   "TARGET_USE_FANCY_MATH_387
16223    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16224    && flag_unsafe_math_optimizations"
16226   if (memory_operand (operands[0], VOIDmode))
16227     emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16228   else
16229     {
16230       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16231       emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16232                                             operands[2]));
16233     }
16234   DONE;
16237 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16238 (define_insn_and_split "frndintxf2_floor"
16239   [(set (match_operand:XF 0 "register_operand" "=f")
16240         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16241          UNSPEC_FRNDINT_FLOOR))
16242    (clobber (reg:CC FLAGS_REG))]
16243   "TARGET_USE_FANCY_MATH_387
16244    && flag_unsafe_math_optimizations
16245    && !(reload_completed || reload_in_progress)"
16246   "#"
16247   "&& 1"
16248   [(const_int 0)]
16250   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16252   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16253   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16255   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16256                                         operands[2], operands[3]));
16257   DONE;
16259   [(set_attr "type" "frndint")
16260    (set_attr "i387_cw" "floor")
16261    (set_attr "mode" "XF")])
16263 (define_insn "frndintxf2_floor_i387"
16264   [(set (match_operand:XF 0 "register_operand" "=f")
16265         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16266          UNSPEC_FRNDINT_FLOOR))
16267    (use (match_operand:HI 2 "memory_operand" "m"))
16268    (use (match_operand:HI 3 "memory_operand" "m"))]
16269   "TARGET_USE_FANCY_MATH_387
16270    && flag_unsafe_math_optimizations"
16271   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16272   [(set_attr "type" "frndint")
16273    (set_attr "i387_cw" "floor")
16274    (set_attr "mode" "XF")])
16276 (define_expand "floorxf2"
16277   [(use (match_operand:XF 0 "register_operand" ""))
16278    (use (match_operand:XF 1 "register_operand" ""))]
16279   "TARGET_USE_FANCY_MATH_387
16280    && flag_unsafe_math_optimizations"
16282   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16283   DONE;
16286 (define_expand "floordf2"
16287   [(use (match_operand:DF 0 "register_operand" ""))
16288    (use (match_operand:DF 1 "register_operand" ""))]
16289   "TARGET_USE_FANCY_MATH_387
16290    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16291    && flag_unsafe_math_optimizations"
16293   rtx op0 = gen_reg_rtx (XFmode);
16294   rtx op1 = gen_reg_rtx (XFmode);
16296   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16297   emit_insn (gen_frndintxf2_floor (op0, op1));
16299   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16300   DONE;
16303 (define_expand "floorsf2"
16304   [(use (match_operand:SF 0 "register_operand" ""))
16305    (use (match_operand:SF 1 "register_operand" ""))]
16306   "TARGET_USE_FANCY_MATH_387
16307    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16308    && flag_unsafe_math_optimizations"
16310   rtx op0 = gen_reg_rtx (XFmode);
16311   rtx op1 = gen_reg_rtx (XFmode);
16313   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16314   emit_insn (gen_frndintxf2_floor (op0, op1));
16316   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16317   DONE;
16320 (define_insn_and_split "*fist<mode>2_floor_1"
16321   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16322         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16323          UNSPEC_FIST_FLOOR))
16324    (clobber (reg:CC FLAGS_REG))]
16325   "TARGET_USE_FANCY_MATH_387
16326    && flag_unsafe_math_optimizations
16327    && !(reload_completed || reload_in_progress)"
16328   "#"
16329   "&& 1"
16330   [(const_int 0)]
16332   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16334   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16335   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16336   if (memory_operand (operands[0], VOIDmode))
16337     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16338                                       operands[2], operands[3]));
16339   else
16340     {
16341       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16342       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16343                                                   operands[2], operands[3],
16344                                                   operands[4]));
16345     }
16346   DONE;
16348   [(set_attr "type" "fistp")
16349    (set_attr "i387_cw" "floor")
16350    (set_attr "mode" "<MODE>")])
16352 (define_insn "fistdi2_floor"
16353   [(set (match_operand:DI 0 "memory_operand" "=m")
16354         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16355          UNSPEC_FIST_FLOOR))
16356    (use (match_operand:HI 2 "memory_operand" "m"))
16357    (use (match_operand:HI 3 "memory_operand" "m"))
16358    (clobber (match_scratch:XF 4 "=&1f"))]
16359   "TARGET_USE_FANCY_MATH_387
16360    && flag_unsafe_math_optimizations"
16361   "* return output_fix_trunc (insn, operands, 0);"
16362   [(set_attr "type" "fistp")
16363    (set_attr "i387_cw" "floor")
16364    (set_attr "mode" "DI")])
16366 (define_insn "fistdi2_floor_with_temp"
16367   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16368         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16369          UNSPEC_FIST_FLOOR))
16370    (use (match_operand:HI 2 "memory_operand" "m,m"))
16371    (use (match_operand:HI 3 "memory_operand" "m,m"))
16372    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16373    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16374   "TARGET_USE_FANCY_MATH_387
16375    && flag_unsafe_math_optimizations"
16376   "#"
16377   [(set_attr "type" "fistp")
16378    (set_attr "i387_cw" "floor")
16379    (set_attr "mode" "DI")])
16381 (define_split 
16382   [(set (match_operand:DI 0 "register_operand" "")
16383         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16384          UNSPEC_FIST_FLOOR))
16385    (use (match_operand:HI 2 "memory_operand" ""))
16386    (use (match_operand:HI 3 "memory_operand" ""))
16387    (clobber (match_operand:DI 4 "memory_operand" ""))
16388    (clobber (match_scratch 5 ""))]
16389   "reload_completed"
16390   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16391               (use (match_dup 2))
16392               (use (match_dup 3))
16393               (clobber (match_dup 5))])
16394    (set (match_dup 0) (match_dup 4))]
16395   "")
16397 (define_split 
16398   [(set (match_operand:DI 0 "memory_operand" "")
16399         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16400          UNSPEC_FIST_FLOOR))
16401    (use (match_operand:HI 2 "memory_operand" ""))
16402    (use (match_operand:HI 3 "memory_operand" ""))
16403    (clobber (match_operand:DI 4 "memory_operand" ""))
16404    (clobber (match_scratch 5 ""))]
16405   "reload_completed"
16406   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16407               (use (match_dup 2))
16408               (use (match_dup 3))
16409               (clobber (match_dup 5))])]
16410   "")
16412 (define_insn "fist<mode>2_floor"
16413   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16414         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16415          UNSPEC_FIST_FLOOR))
16416    (use (match_operand:HI 2 "memory_operand" "m"))
16417    (use (match_operand:HI 3 "memory_operand" "m"))]
16418   "TARGET_USE_FANCY_MATH_387
16419    && flag_unsafe_math_optimizations"
16420   "* return output_fix_trunc (insn, operands, 0);"
16421   [(set_attr "type" "fistp")
16422    (set_attr "i387_cw" "floor")
16423    (set_attr "mode" "<MODE>")])
16425 (define_insn "fist<mode>2_floor_with_temp"
16426   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16427         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16428          UNSPEC_FIST_FLOOR))
16429    (use (match_operand:HI 2 "memory_operand" "m,m"))
16430    (use (match_operand:HI 3 "memory_operand" "m,m"))
16431    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16432   "TARGET_USE_FANCY_MATH_387
16433    && flag_unsafe_math_optimizations"
16434   "#"
16435   [(set_attr "type" "fistp")
16436    (set_attr "i387_cw" "floor")
16437    (set_attr "mode" "<MODE>")])
16439 (define_split 
16440   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16441         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16442          UNSPEC_FIST_FLOOR))
16443    (use (match_operand:HI 2 "memory_operand" ""))
16444    (use (match_operand:HI 3 "memory_operand" ""))
16445    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16446   "reload_completed"
16447   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16448                                   UNSPEC_FIST_FLOOR))
16449               (use (match_dup 2))
16450               (use (match_dup 3))])
16451    (set (match_dup 0) (match_dup 4))]
16452   "")
16454 (define_split 
16455   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16456         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16457          UNSPEC_FIST_FLOOR))
16458    (use (match_operand:HI 2 "memory_operand" ""))
16459    (use (match_operand:HI 3 "memory_operand" ""))
16460    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16461   "reload_completed"
16462   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16463                                   UNSPEC_FIST_FLOOR))
16464               (use (match_dup 2))
16465               (use (match_dup 3))])]
16466   "")
16468 (define_expand "lfloor<mode>2"
16469   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16470                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16471                     UNSPEC_FIST_FLOOR))
16472               (clobber (reg:CC FLAGS_REG))])]
16473   "TARGET_USE_FANCY_MATH_387
16474    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16475    && flag_unsafe_math_optimizations"
16476   "")
16478 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16479 (define_insn_and_split "frndintxf2_ceil"
16480   [(set (match_operand:XF 0 "register_operand" "=f")
16481         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16482          UNSPEC_FRNDINT_CEIL))
16483    (clobber (reg:CC FLAGS_REG))]
16484   "TARGET_USE_FANCY_MATH_387
16485    && flag_unsafe_math_optimizations
16486    && !(reload_completed || reload_in_progress)"
16487   "#"
16488   "&& 1"
16489   [(const_int 0)]
16491   ix86_optimize_mode_switching[I387_CEIL] = 1;
16493   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16494   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16496   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16497                                        operands[2], operands[3]));
16498   DONE;
16500   [(set_attr "type" "frndint")
16501    (set_attr "i387_cw" "ceil")
16502    (set_attr "mode" "XF")])
16504 (define_insn "frndintxf2_ceil_i387"
16505   [(set (match_operand:XF 0 "register_operand" "=f")
16506         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16507          UNSPEC_FRNDINT_CEIL))
16508    (use (match_operand:HI 2 "memory_operand" "m"))
16509    (use (match_operand:HI 3 "memory_operand" "m"))]
16510   "TARGET_USE_FANCY_MATH_387
16511    && flag_unsafe_math_optimizations"
16512   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16513   [(set_attr "type" "frndint")
16514    (set_attr "i387_cw" "ceil")
16515    (set_attr "mode" "XF")])
16517 (define_expand "ceilxf2"
16518   [(use (match_operand:XF 0 "register_operand" ""))
16519    (use (match_operand:XF 1 "register_operand" ""))]
16520   "TARGET_USE_FANCY_MATH_387
16521    && flag_unsafe_math_optimizations"
16523   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16524   DONE;
16527 (define_expand "ceildf2"
16528   [(use (match_operand:DF 0 "register_operand" ""))
16529    (use (match_operand:DF 1 "register_operand" ""))]
16530   "TARGET_USE_FANCY_MATH_387
16531    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16532    && flag_unsafe_math_optimizations"
16534   rtx op0 = gen_reg_rtx (XFmode);
16535   rtx op1 = gen_reg_rtx (XFmode);
16537   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16538   emit_insn (gen_frndintxf2_ceil (op0, op1));
16540   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16541   DONE;
16544 (define_expand "ceilsf2"
16545   [(use (match_operand:SF 0 "register_operand" ""))
16546    (use (match_operand:SF 1 "register_operand" ""))]
16547   "TARGET_USE_FANCY_MATH_387
16548    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16549    && flag_unsafe_math_optimizations"
16551   rtx op0 = gen_reg_rtx (XFmode);
16552   rtx op1 = gen_reg_rtx (XFmode);
16554   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16555   emit_insn (gen_frndintxf2_ceil (op0, op1));
16557   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16558   DONE;
16561 (define_insn_and_split "*fist<mode>2_ceil_1"
16562   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16563         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16564          UNSPEC_FIST_CEIL))
16565    (clobber (reg:CC FLAGS_REG))]
16566   "TARGET_USE_FANCY_MATH_387
16567    && flag_unsafe_math_optimizations
16568    && !(reload_completed || reload_in_progress)"
16569   "#"
16570   "&& 1"
16571   [(const_int 0)]
16573   ix86_optimize_mode_switching[I387_CEIL] = 1;
16575   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16576   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16577   if (memory_operand (operands[0], VOIDmode))
16578     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16579                                      operands[2], operands[3]));
16580   else
16581     {
16582       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16583       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16584                                                  operands[2], operands[3],
16585                                                  operands[4]));
16586     }
16587   DONE;
16589   [(set_attr "type" "fistp")
16590    (set_attr "i387_cw" "ceil")
16591    (set_attr "mode" "<MODE>")])
16593 (define_insn "fistdi2_ceil"
16594   [(set (match_operand:DI 0 "memory_operand" "=m")
16595         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16596          UNSPEC_FIST_CEIL))
16597    (use (match_operand:HI 2 "memory_operand" "m"))
16598    (use (match_operand:HI 3 "memory_operand" "m"))
16599    (clobber (match_scratch:XF 4 "=&1f"))]
16600   "TARGET_USE_FANCY_MATH_387
16601    && flag_unsafe_math_optimizations"
16602   "* return output_fix_trunc (insn, operands, 0);"
16603   [(set_attr "type" "fistp")
16604    (set_attr "i387_cw" "ceil")
16605    (set_attr "mode" "DI")])
16607 (define_insn "fistdi2_ceil_with_temp"
16608   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16609         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16610          UNSPEC_FIST_CEIL))
16611    (use (match_operand:HI 2 "memory_operand" "m,m"))
16612    (use (match_operand:HI 3 "memory_operand" "m,m"))
16613    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16614    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16615   "TARGET_USE_FANCY_MATH_387
16616    && flag_unsafe_math_optimizations"
16617   "#"
16618   [(set_attr "type" "fistp")
16619    (set_attr "i387_cw" "ceil")
16620    (set_attr "mode" "DI")])
16622 (define_split 
16623   [(set (match_operand:DI 0 "register_operand" "")
16624         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16625          UNSPEC_FIST_CEIL))
16626    (use (match_operand:HI 2 "memory_operand" ""))
16627    (use (match_operand:HI 3 "memory_operand" ""))
16628    (clobber (match_operand:DI 4 "memory_operand" ""))
16629    (clobber (match_scratch 5 ""))]
16630   "reload_completed"
16631   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16632               (use (match_dup 2))
16633               (use (match_dup 3))
16634               (clobber (match_dup 5))])
16635    (set (match_dup 0) (match_dup 4))]
16636   "")
16638 (define_split 
16639   [(set (match_operand:DI 0 "memory_operand" "")
16640         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16641          UNSPEC_FIST_CEIL))
16642    (use (match_operand:HI 2 "memory_operand" ""))
16643    (use (match_operand:HI 3 "memory_operand" ""))
16644    (clobber (match_operand:DI 4 "memory_operand" ""))
16645    (clobber (match_scratch 5 ""))]
16646   "reload_completed"
16647   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16648               (use (match_dup 2))
16649               (use (match_dup 3))
16650               (clobber (match_dup 5))])]
16651   "")
16653 (define_insn "fist<mode>2_ceil"
16654   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16655         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16656          UNSPEC_FIST_CEIL))
16657    (use (match_operand:HI 2 "memory_operand" "m"))
16658    (use (match_operand:HI 3 "memory_operand" "m"))]
16659   "TARGET_USE_FANCY_MATH_387
16660    && flag_unsafe_math_optimizations"
16661   "* return output_fix_trunc (insn, operands, 0);"
16662   [(set_attr "type" "fistp")
16663    (set_attr "i387_cw" "ceil")
16664    (set_attr "mode" "<MODE>")])
16666 (define_insn "fist<mode>2_ceil_with_temp"
16667   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16668         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16669          UNSPEC_FIST_CEIL))
16670    (use (match_operand:HI 2 "memory_operand" "m,m"))
16671    (use (match_operand:HI 3 "memory_operand" "m,m"))
16672    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16673   "TARGET_USE_FANCY_MATH_387
16674    && flag_unsafe_math_optimizations"
16675   "#"
16676   [(set_attr "type" "fistp")
16677    (set_attr "i387_cw" "ceil")
16678    (set_attr "mode" "<MODE>")])
16680 (define_split 
16681   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16682         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16683          UNSPEC_FIST_CEIL))
16684    (use (match_operand:HI 2 "memory_operand" ""))
16685    (use (match_operand:HI 3 "memory_operand" ""))
16686    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16687   "reload_completed"
16688   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16689                                   UNSPEC_FIST_CEIL))
16690               (use (match_dup 2))
16691               (use (match_dup 3))])
16692    (set (match_dup 0) (match_dup 4))]
16693   "")
16695 (define_split 
16696   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16697         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16698          UNSPEC_FIST_CEIL))
16699    (use (match_operand:HI 2 "memory_operand" ""))
16700    (use (match_operand:HI 3 "memory_operand" ""))
16701    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16702   "reload_completed"
16703   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16704                                   UNSPEC_FIST_CEIL))
16705               (use (match_dup 2))
16706               (use (match_dup 3))])]
16707   "")
16709 (define_expand "lceil<mode>2"
16710   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16711                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16712                     UNSPEC_FIST_CEIL))
16713               (clobber (reg:CC FLAGS_REG))])]
16714   "TARGET_USE_FANCY_MATH_387
16715    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16716    && flag_unsafe_math_optimizations"
16717   "")
16719 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16720 (define_insn_and_split "frndintxf2_trunc"
16721   [(set (match_operand:XF 0 "register_operand" "=f")
16722         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16723          UNSPEC_FRNDINT_TRUNC))
16724    (clobber (reg:CC FLAGS_REG))]
16725   "TARGET_USE_FANCY_MATH_387
16726    && flag_unsafe_math_optimizations
16727    && !(reload_completed || reload_in_progress)"
16728   "#"
16729   "&& 1"
16730   [(const_int 0)]
16732   ix86_optimize_mode_switching[I387_TRUNC] = 1;
16734   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16735   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
16737   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16738                                         operands[2], operands[3]));
16739   DONE;
16741   [(set_attr "type" "frndint")
16742    (set_attr "i387_cw" "trunc")
16743    (set_attr "mode" "XF")])
16745 (define_insn "frndintxf2_trunc_i387"
16746   [(set (match_operand:XF 0 "register_operand" "=f")
16747         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16748          UNSPEC_FRNDINT_TRUNC))
16749    (use (match_operand:HI 2 "memory_operand" "m"))
16750    (use (match_operand:HI 3 "memory_operand" "m"))]
16751   "TARGET_USE_FANCY_MATH_387
16752    && flag_unsafe_math_optimizations"
16753   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16754   [(set_attr "type" "frndint")
16755    (set_attr "i387_cw" "trunc")
16756    (set_attr "mode" "XF")])
16758 (define_expand "btruncxf2"
16759   [(use (match_operand:XF 0 "register_operand" ""))
16760    (use (match_operand:XF 1 "register_operand" ""))]
16761   "TARGET_USE_FANCY_MATH_387
16762    && flag_unsafe_math_optimizations"
16764   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16765   DONE;
16768 (define_expand "btruncdf2"
16769   [(use (match_operand:DF 0 "register_operand" ""))
16770    (use (match_operand:DF 1 "register_operand" ""))]
16771   "TARGET_USE_FANCY_MATH_387
16772    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16773    && flag_unsafe_math_optimizations"
16775   rtx op0 = gen_reg_rtx (XFmode);
16776   rtx op1 = gen_reg_rtx (XFmode);
16778   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16779   emit_insn (gen_frndintxf2_trunc (op0, op1));
16781   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16782   DONE;
16785 (define_expand "btruncsf2"
16786   [(use (match_operand:SF 0 "register_operand" ""))
16787    (use (match_operand:SF 1 "register_operand" ""))]
16788   "TARGET_USE_FANCY_MATH_387
16789    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16790    && flag_unsafe_math_optimizations"
16792   rtx op0 = gen_reg_rtx (XFmode);
16793   rtx op1 = gen_reg_rtx (XFmode);
16795   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16796   emit_insn (gen_frndintxf2_trunc (op0, op1));
16798   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16799   DONE;
16802 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16803 (define_insn_and_split "frndintxf2_mask_pm"
16804   [(set (match_operand:XF 0 "register_operand" "=f")
16805         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16806          UNSPEC_FRNDINT_MASK_PM))
16807    (clobber (reg:CC FLAGS_REG))]
16808   "TARGET_USE_FANCY_MATH_387
16809    && flag_unsafe_math_optimizations
16810    && !(reload_completed || reload_in_progress)"
16811   "#"
16812   "&& 1"
16813   [(const_int 0)]
16815   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16817   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16818   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16820   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16821                                           operands[2], operands[3]));
16822   DONE;
16824   [(set_attr "type" "frndint")
16825    (set_attr "i387_cw" "mask_pm")
16826    (set_attr "mode" "XF")])
16828 (define_insn "frndintxf2_mask_pm_i387"
16829   [(set (match_operand:XF 0 "register_operand" "=f")
16830         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16831          UNSPEC_FRNDINT_MASK_PM))
16832    (use (match_operand:HI 2 "memory_operand" "m"))
16833    (use (match_operand:HI 3 "memory_operand" "m"))]
16834   "TARGET_USE_FANCY_MATH_387
16835    && flag_unsafe_math_optimizations"
16836   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16837   [(set_attr "type" "frndint")
16838    (set_attr "i387_cw" "mask_pm")
16839    (set_attr "mode" "XF")])
16841 (define_expand "nearbyintxf2"
16842   [(use (match_operand:XF 0 "register_operand" ""))
16843    (use (match_operand:XF 1 "register_operand" ""))]
16844   "TARGET_USE_FANCY_MATH_387
16845    && flag_unsafe_math_optimizations"
16847   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16849   DONE;
16852 (define_expand "nearbyintdf2"
16853   [(use (match_operand:DF 0 "register_operand" ""))
16854    (use (match_operand:DF 1 "register_operand" ""))]
16855   "TARGET_USE_FANCY_MATH_387
16856    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16857    && flag_unsafe_math_optimizations"
16859   rtx op0 = gen_reg_rtx (XFmode);
16860   rtx op1 = gen_reg_rtx (XFmode);
16862   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16863   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16865   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16866   DONE;
16869 (define_expand "nearbyintsf2"
16870   [(use (match_operand:SF 0 "register_operand" ""))
16871    (use (match_operand:SF 1 "register_operand" ""))]
16872   "TARGET_USE_FANCY_MATH_387
16873    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16874    && flag_unsafe_math_optimizations"
16876   rtx op0 = gen_reg_rtx (XFmode);
16877   rtx op1 = gen_reg_rtx (XFmode);
16879   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16880   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16882   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16883   DONE;
16887 ;; Block operation instructions
16889 (define_insn "cld"
16890  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16891  ""
16892  "cld"
16893   [(set_attr "type" "cld")])
16895 (define_expand "movmemsi"
16896   [(use (match_operand:BLK 0 "memory_operand" ""))
16897    (use (match_operand:BLK 1 "memory_operand" ""))
16898    (use (match_operand:SI 2 "nonmemory_operand" ""))
16899    (use (match_operand:SI 3 "const_int_operand" ""))]
16900   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16902  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16903    DONE;
16904  else
16905    FAIL;
16908 (define_expand "movmemdi"
16909   [(use (match_operand:BLK 0 "memory_operand" ""))
16910    (use (match_operand:BLK 1 "memory_operand" ""))
16911    (use (match_operand:DI 2 "nonmemory_operand" ""))
16912    (use (match_operand:DI 3 "const_int_operand" ""))]
16913   "TARGET_64BIT"
16915  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16916    DONE;
16917  else
16918    FAIL;
16921 ;; Most CPUs don't like single string operations
16922 ;; Handle this case here to simplify previous expander.
16924 (define_expand "strmov"
16925   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16926    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16927    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16928               (clobber (reg:CC FLAGS_REG))])
16929    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16930               (clobber (reg:CC FLAGS_REG))])]
16931   ""
16933   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16935   /* If .md ever supports :P for Pmode, these can be directly
16936      in the pattern above.  */
16937   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16938   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16940   if (TARGET_SINGLE_STRINGOP || optimize_size)
16941     {
16942       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16943                                       operands[2], operands[3],
16944                                       operands[5], operands[6]));
16945       DONE;
16946     }
16948   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16951 (define_expand "strmov_singleop"
16952   [(parallel [(set (match_operand 1 "memory_operand" "")
16953                    (match_operand 3 "memory_operand" ""))
16954               (set (match_operand 0 "register_operand" "")
16955                    (match_operand 4 "" ""))
16956               (set (match_operand 2 "register_operand" "")
16957                    (match_operand 5 "" ""))
16958               (use (reg:SI DIRFLAG_REG))])]
16959   "TARGET_SINGLE_STRINGOP || optimize_size"
16960   "")
16962 (define_insn "*strmovdi_rex_1"
16963   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16964         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16965    (set (match_operand:DI 0 "register_operand" "=D")
16966         (plus:DI (match_dup 2)
16967                  (const_int 8)))
16968    (set (match_operand:DI 1 "register_operand" "=S")
16969         (plus:DI (match_dup 3)
16970                  (const_int 8)))
16971    (use (reg:SI DIRFLAG_REG))]
16972   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16973   "movsq"
16974   [(set_attr "type" "str")
16975    (set_attr "mode" "DI")
16976    (set_attr "memory" "both")])
16978 (define_insn "*strmovsi_1"
16979   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16980         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16981    (set (match_operand:SI 0 "register_operand" "=D")
16982         (plus:SI (match_dup 2)
16983                  (const_int 4)))
16984    (set (match_operand:SI 1 "register_operand" "=S")
16985         (plus:SI (match_dup 3)
16986                  (const_int 4)))
16987    (use (reg:SI DIRFLAG_REG))]
16988   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16989   "{movsl|movsd}"
16990   [(set_attr "type" "str")
16991    (set_attr "mode" "SI")
16992    (set_attr "memory" "both")])
16994 (define_insn "*strmovsi_rex_1"
16995   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16996         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16997    (set (match_operand:DI 0 "register_operand" "=D")
16998         (plus:DI (match_dup 2)
16999                  (const_int 4)))
17000    (set (match_operand:DI 1 "register_operand" "=S")
17001         (plus:DI (match_dup 3)
17002                  (const_int 4)))
17003    (use (reg:SI DIRFLAG_REG))]
17004   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17005   "{movsl|movsd}"
17006   [(set_attr "type" "str")
17007    (set_attr "mode" "SI")
17008    (set_attr "memory" "both")])
17010 (define_insn "*strmovhi_1"
17011   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17012         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17013    (set (match_operand:SI 0 "register_operand" "=D")
17014         (plus:SI (match_dup 2)
17015                  (const_int 2)))
17016    (set (match_operand:SI 1 "register_operand" "=S")
17017         (plus:SI (match_dup 3)
17018                  (const_int 2)))
17019    (use (reg:SI DIRFLAG_REG))]
17020   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17021   "movsw"
17022   [(set_attr "type" "str")
17023    (set_attr "memory" "both")
17024    (set_attr "mode" "HI")])
17026 (define_insn "*strmovhi_rex_1"
17027   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17028         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17029    (set (match_operand:DI 0 "register_operand" "=D")
17030         (plus:DI (match_dup 2)
17031                  (const_int 2)))
17032    (set (match_operand:DI 1 "register_operand" "=S")
17033         (plus:DI (match_dup 3)
17034                  (const_int 2)))
17035    (use (reg:SI DIRFLAG_REG))]
17036   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17037   "movsw"
17038   [(set_attr "type" "str")
17039    (set_attr "memory" "both")
17040    (set_attr "mode" "HI")])
17042 (define_insn "*strmovqi_1"
17043   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17044         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17045    (set (match_operand:SI 0 "register_operand" "=D")
17046         (plus:SI (match_dup 2)
17047                  (const_int 1)))
17048    (set (match_operand:SI 1 "register_operand" "=S")
17049         (plus:SI (match_dup 3)
17050                  (const_int 1)))
17051    (use (reg:SI DIRFLAG_REG))]
17052   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17053   "movsb"
17054   [(set_attr "type" "str")
17055    (set_attr "memory" "both")
17056    (set_attr "mode" "QI")])
17058 (define_insn "*strmovqi_rex_1"
17059   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17060         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17061    (set (match_operand:DI 0 "register_operand" "=D")
17062         (plus:DI (match_dup 2)
17063                  (const_int 1)))
17064    (set (match_operand:DI 1 "register_operand" "=S")
17065         (plus:DI (match_dup 3)
17066                  (const_int 1)))
17067    (use (reg:SI DIRFLAG_REG))]
17068   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17069   "movsb"
17070   [(set_attr "type" "str")
17071    (set_attr "memory" "both")
17072    (set_attr "mode" "QI")])
17074 (define_expand "rep_mov"
17075   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17076               (set (match_operand 0 "register_operand" "")
17077                    (match_operand 5 "" ""))
17078               (set (match_operand 2 "register_operand" "")
17079                    (match_operand 6 "" ""))
17080               (set (match_operand 1 "memory_operand" "")
17081                    (match_operand 3 "memory_operand" ""))
17082               (use (match_dup 4))
17083               (use (reg:SI DIRFLAG_REG))])]
17084   ""
17085   "")
17087 (define_insn "*rep_movdi_rex64"
17088   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17089    (set (match_operand:DI 0 "register_operand" "=D") 
17090         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17091                             (const_int 3))
17092                  (match_operand:DI 3 "register_operand" "0")))
17093    (set (match_operand:DI 1 "register_operand" "=S") 
17094         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17095                  (match_operand:DI 4 "register_operand" "1")))
17096    (set (mem:BLK (match_dup 3))
17097         (mem:BLK (match_dup 4)))
17098    (use (match_dup 5))
17099    (use (reg:SI DIRFLAG_REG))]
17100   "TARGET_64BIT"
17101   "{rep\;movsq|rep movsq}"
17102   [(set_attr "type" "str")
17103    (set_attr "prefix_rep" "1")
17104    (set_attr "memory" "both")
17105    (set_attr "mode" "DI")])
17107 (define_insn "*rep_movsi"
17108   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17109    (set (match_operand:SI 0 "register_operand" "=D") 
17110         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17111                             (const_int 2))
17112                  (match_operand:SI 3 "register_operand" "0")))
17113    (set (match_operand:SI 1 "register_operand" "=S") 
17114         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17115                  (match_operand:SI 4 "register_operand" "1")))
17116    (set (mem:BLK (match_dup 3))
17117         (mem:BLK (match_dup 4)))
17118    (use (match_dup 5))
17119    (use (reg:SI DIRFLAG_REG))]
17120   "!TARGET_64BIT"
17121   "{rep\;movsl|rep movsd}"
17122   [(set_attr "type" "str")
17123    (set_attr "prefix_rep" "1")
17124    (set_attr "memory" "both")
17125    (set_attr "mode" "SI")])
17127 (define_insn "*rep_movsi_rex64"
17128   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17129    (set (match_operand:DI 0 "register_operand" "=D") 
17130         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17131                             (const_int 2))
17132                  (match_operand:DI 3 "register_operand" "0")))
17133    (set (match_operand:DI 1 "register_operand" "=S") 
17134         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17135                  (match_operand:DI 4 "register_operand" "1")))
17136    (set (mem:BLK (match_dup 3))
17137         (mem:BLK (match_dup 4)))
17138    (use (match_dup 5))
17139    (use (reg:SI DIRFLAG_REG))]
17140   "TARGET_64BIT"
17141   "{rep\;movsl|rep movsd}"
17142   [(set_attr "type" "str")
17143    (set_attr "prefix_rep" "1")
17144    (set_attr "memory" "both")
17145    (set_attr "mode" "SI")])
17147 (define_insn "*rep_movqi"
17148   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17149    (set (match_operand:SI 0 "register_operand" "=D") 
17150         (plus:SI (match_operand:SI 3 "register_operand" "0")
17151                  (match_operand:SI 5 "register_operand" "2")))
17152    (set (match_operand:SI 1 "register_operand" "=S") 
17153         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17154    (set (mem:BLK (match_dup 3))
17155         (mem:BLK (match_dup 4)))
17156    (use (match_dup 5))
17157    (use (reg:SI DIRFLAG_REG))]
17158   "!TARGET_64BIT"
17159   "{rep\;movsb|rep movsb}"
17160   [(set_attr "type" "str")
17161    (set_attr "prefix_rep" "1")
17162    (set_attr "memory" "both")
17163    (set_attr "mode" "SI")])
17165 (define_insn "*rep_movqi_rex64"
17166   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17167    (set (match_operand:DI 0 "register_operand" "=D") 
17168         (plus:DI (match_operand:DI 3 "register_operand" "0")
17169                  (match_operand:DI 5 "register_operand" "2")))
17170    (set (match_operand:DI 1 "register_operand" "=S") 
17171         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17172    (set (mem:BLK (match_dup 3))
17173         (mem:BLK (match_dup 4)))
17174    (use (match_dup 5))
17175    (use (reg:SI DIRFLAG_REG))]
17176   "TARGET_64BIT"
17177   "{rep\;movsb|rep movsb}"
17178   [(set_attr "type" "str")
17179    (set_attr "prefix_rep" "1")
17180    (set_attr "memory" "both")
17181    (set_attr "mode" "SI")])
17183 (define_expand "clrmemsi"
17184    [(use (match_operand:BLK 0 "memory_operand" ""))
17185     (use (match_operand:SI 1 "nonmemory_operand" ""))
17186     (use (match_operand 2 "const_int_operand" ""))]
17187   ""
17189  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17190    DONE;
17191  else
17192    FAIL;
17195 (define_expand "clrmemdi"
17196    [(use (match_operand:BLK 0 "memory_operand" ""))
17197     (use (match_operand:DI 1 "nonmemory_operand" ""))
17198     (use (match_operand 2 "const_int_operand" ""))]
17199   "TARGET_64BIT"
17201  if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17202    DONE;
17203  else
17204    FAIL;
17207 ;; Most CPUs don't like single string operations
17208 ;; Handle this case here to simplify previous expander.
17210 (define_expand "strset"
17211   [(set (match_operand 1 "memory_operand" "")
17212         (match_operand 2 "register_operand" ""))
17213    (parallel [(set (match_operand 0 "register_operand" "")
17214                    (match_dup 3))
17215               (clobber (reg:CC FLAGS_REG))])]
17216   ""
17218   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17219     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17221   /* If .md ever supports :P for Pmode, this can be directly
17222      in the pattern above.  */
17223   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17224                               GEN_INT (GET_MODE_SIZE (GET_MODE
17225                                                       (operands[2]))));
17226   if (TARGET_SINGLE_STRINGOP || optimize_size)
17227     {
17228       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17229                                       operands[3]));
17230       DONE;
17231     }
17234 (define_expand "strset_singleop"
17235   [(parallel [(set (match_operand 1 "memory_operand" "")
17236                    (match_operand 2 "register_operand" ""))
17237               (set (match_operand 0 "register_operand" "")
17238                    (match_operand 3 "" ""))
17239               (use (reg:SI DIRFLAG_REG))])]
17240   "TARGET_SINGLE_STRINGOP || optimize_size"
17241   "")
17243 (define_insn "*strsetdi_rex_1"
17244   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17245         (match_operand:DI 2 "register_operand" "a"))
17246    (set (match_operand:DI 0 "register_operand" "=D")
17247         (plus:DI (match_dup 1)
17248                  (const_int 8)))
17249    (use (reg:SI DIRFLAG_REG))]
17250   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17251   "stosq"
17252   [(set_attr "type" "str")
17253    (set_attr "memory" "store")
17254    (set_attr "mode" "DI")])
17256 (define_insn "*strsetsi_1"
17257   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17258         (match_operand:SI 2 "register_operand" "a"))
17259    (set (match_operand:SI 0 "register_operand" "=D")
17260         (plus:SI (match_dup 1)
17261                  (const_int 4)))
17262    (use (reg:SI DIRFLAG_REG))]
17263   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17264   "{stosl|stosd}"
17265   [(set_attr "type" "str")
17266    (set_attr "memory" "store")
17267    (set_attr "mode" "SI")])
17269 (define_insn "*strsetsi_rex_1"
17270   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17271         (match_operand:SI 2 "register_operand" "a"))
17272    (set (match_operand:DI 0 "register_operand" "=D")
17273         (plus:DI (match_dup 1)
17274                  (const_int 4)))
17275    (use (reg:SI DIRFLAG_REG))]
17276   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17277   "{stosl|stosd}"
17278   [(set_attr "type" "str")
17279    (set_attr "memory" "store")
17280    (set_attr "mode" "SI")])
17282 (define_insn "*strsethi_1"
17283   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17284         (match_operand:HI 2 "register_operand" "a"))
17285    (set (match_operand:SI 0 "register_operand" "=D")
17286         (plus:SI (match_dup 1)
17287                  (const_int 2)))
17288    (use (reg:SI DIRFLAG_REG))]
17289   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17290   "stosw"
17291   [(set_attr "type" "str")
17292    (set_attr "memory" "store")
17293    (set_attr "mode" "HI")])
17295 (define_insn "*strsethi_rex_1"
17296   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17297         (match_operand:HI 2 "register_operand" "a"))
17298    (set (match_operand:DI 0 "register_operand" "=D")
17299         (plus:DI (match_dup 1)
17300                  (const_int 2)))
17301    (use (reg:SI DIRFLAG_REG))]
17302   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17303   "stosw"
17304   [(set_attr "type" "str")
17305    (set_attr "memory" "store")
17306    (set_attr "mode" "HI")])
17308 (define_insn "*strsetqi_1"
17309   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17310         (match_operand:QI 2 "register_operand" "a"))
17311    (set (match_operand:SI 0 "register_operand" "=D")
17312         (plus:SI (match_dup 1)
17313                  (const_int 1)))
17314    (use (reg:SI DIRFLAG_REG))]
17315   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17316   "stosb"
17317   [(set_attr "type" "str")
17318    (set_attr "memory" "store")
17319    (set_attr "mode" "QI")])
17321 (define_insn "*strsetqi_rex_1"
17322   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17323         (match_operand:QI 2 "register_operand" "a"))
17324    (set (match_operand:DI 0 "register_operand" "=D")
17325         (plus:DI (match_dup 1)
17326                  (const_int 1)))
17327    (use (reg:SI DIRFLAG_REG))]
17328   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17329   "stosb"
17330   [(set_attr "type" "str")
17331    (set_attr "memory" "store")
17332    (set_attr "mode" "QI")])
17334 (define_expand "rep_stos"
17335   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17336               (set (match_operand 0 "register_operand" "")
17337                    (match_operand 4 "" ""))
17338               (set (match_operand 2 "memory_operand" "") (const_int 0))
17339               (use (match_operand 3 "register_operand" ""))
17340               (use (match_dup 1))
17341               (use (reg:SI DIRFLAG_REG))])]
17342   ""
17343   "")
17345 (define_insn "*rep_stosdi_rex64"
17346   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17347    (set (match_operand:DI 0 "register_operand" "=D") 
17348         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17349                             (const_int 3))
17350                  (match_operand:DI 3 "register_operand" "0")))
17351    (set (mem:BLK (match_dup 3))
17352         (const_int 0))
17353    (use (match_operand:DI 2 "register_operand" "a"))
17354    (use (match_dup 4))
17355    (use (reg:SI DIRFLAG_REG))]
17356   "TARGET_64BIT"
17357   "{rep\;stosq|rep stosq}"
17358   [(set_attr "type" "str")
17359    (set_attr "prefix_rep" "1")
17360    (set_attr "memory" "store")
17361    (set_attr "mode" "DI")])
17363 (define_insn "*rep_stossi"
17364   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17365    (set (match_operand:SI 0 "register_operand" "=D") 
17366         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17367                             (const_int 2))
17368                  (match_operand:SI 3 "register_operand" "0")))
17369    (set (mem:BLK (match_dup 3))
17370         (const_int 0))
17371    (use (match_operand:SI 2 "register_operand" "a"))
17372    (use (match_dup 4))
17373    (use (reg:SI DIRFLAG_REG))]
17374   "!TARGET_64BIT"
17375   "{rep\;stosl|rep stosd}"
17376   [(set_attr "type" "str")
17377    (set_attr "prefix_rep" "1")
17378    (set_attr "memory" "store")
17379    (set_attr "mode" "SI")])
17381 (define_insn "*rep_stossi_rex64"
17382   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17383    (set (match_operand:DI 0 "register_operand" "=D") 
17384         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17385                             (const_int 2))
17386                  (match_operand:DI 3 "register_operand" "0")))
17387    (set (mem:BLK (match_dup 3))
17388         (const_int 0))
17389    (use (match_operand:SI 2 "register_operand" "a"))
17390    (use (match_dup 4))
17391    (use (reg:SI DIRFLAG_REG))]
17392   "TARGET_64BIT"
17393   "{rep\;stosl|rep stosd}"
17394   [(set_attr "type" "str")
17395    (set_attr "prefix_rep" "1")
17396    (set_attr "memory" "store")
17397    (set_attr "mode" "SI")])
17399 (define_insn "*rep_stosqi"
17400   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17401    (set (match_operand:SI 0 "register_operand" "=D") 
17402         (plus:SI (match_operand:SI 3 "register_operand" "0")
17403                  (match_operand:SI 4 "register_operand" "1")))
17404    (set (mem:BLK (match_dup 3))
17405         (const_int 0))
17406    (use (match_operand:QI 2 "register_operand" "a"))
17407    (use (match_dup 4))
17408    (use (reg:SI DIRFLAG_REG))]
17409   "!TARGET_64BIT"
17410   "{rep\;stosb|rep stosb}"
17411   [(set_attr "type" "str")
17412    (set_attr "prefix_rep" "1")
17413    (set_attr "memory" "store")
17414    (set_attr "mode" "QI")])
17416 (define_insn "*rep_stosqi_rex64"
17417   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17418    (set (match_operand:DI 0 "register_operand" "=D") 
17419         (plus:DI (match_operand:DI 3 "register_operand" "0")
17420                  (match_operand:DI 4 "register_operand" "1")))
17421    (set (mem:BLK (match_dup 3))
17422         (const_int 0))
17423    (use (match_operand:QI 2 "register_operand" "a"))
17424    (use (match_dup 4))
17425    (use (reg:SI DIRFLAG_REG))]
17426   "TARGET_64BIT"
17427   "{rep\;stosb|rep stosb}"
17428   [(set_attr "type" "str")
17429    (set_attr "prefix_rep" "1")
17430    (set_attr "memory" "store")
17431    (set_attr "mode" "QI")])
17433 (define_expand "cmpstrsi"
17434   [(set (match_operand:SI 0 "register_operand" "")
17435         (compare:SI (match_operand:BLK 1 "general_operand" "")
17436                     (match_operand:BLK 2 "general_operand" "")))
17437    (use (match_operand 3 "general_operand" ""))
17438    (use (match_operand 4 "immediate_operand" ""))]
17439   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17441   rtx addr1, addr2, out, outlow, count, countreg, align;
17443   /* Can't use this if the user has appropriated esi or edi.  */
17444   if (global_regs[4] || global_regs[5])
17445     FAIL;
17447   out = operands[0];
17448   if (GET_CODE (out) != REG)
17449     out = gen_reg_rtx (SImode);
17451   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17452   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17453   if (addr1 != XEXP (operands[1], 0))
17454     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17455   if (addr2 != XEXP (operands[2], 0))
17456     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17458   count = operands[3];
17459   countreg = ix86_zero_extend_to_Pmode (count);
17461   /* %%% Iff we are testing strict equality, we can use known alignment
17462      to good advantage.  This may be possible with combine, particularly
17463      once cc0 is dead.  */
17464   align = operands[4];
17466   emit_insn (gen_cld ());
17467   if (GET_CODE (count) == CONST_INT)
17468     {
17469       if (INTVAL (count) == 0)
17470         {
17471           emit_move_insn (operands[0], const0_rtx);
17472           DONE;
17473         }
17474       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17475                                     operands[1], operands[2]));
17476     }
17477   else
17478     {
17479       if (TARGET_64BIT)
17480         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17481       else
17482         emit_insn (gen_cmpsi_1 (countreg, countreg));
17483       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17484                                  operands[1], operands[2]));
17485     }
17487   outlow = gen_lowpart (QImode, out);
17488   emit_insn (gen_cmpintqi (outlow));
17489   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17491   if (operands[0] != out)
17492     emit_move_insn (operands[0], out);
17494   DONE;
17497 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17499 (define_expand "cmpintqi"
17500   [(set (match_dup 1)
17501         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17502    (set (match_dup 2)
17503         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17504    (parallel [(set (match_operand:QI 0 "register_operand" "")
17505                    (minus:QI (match_dup 1)
17506                              (match_dup 2)))
17507               (clobber (reg:CC FLAGS_REG))])]
17508   ""
17509   "operands[1] = gen_reg_rtx (QImode);
17510    operands[2] = gen_reg_rtx (QImode);")
17512 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17513 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17515 (define_expand "cmpstrqi_nz_1"
17516   [(parallel [(set (reg:CC FLAGS_REG)
17517                    (compare:CC (match_operand 4 "memory_operand" "")
17518                                (match_operand 5 "memory_operand" "")))
17519               (use (match_operand 2 "register_operand" ""))
17520               (use (match_operand:SI 3 "immediate_operand" ""))
17521               (use (reg:SI DIRFLAG_REG))
17522               (clobber (match_operand 0 "register_operand" ""))
17523               (clobber (match_operand 1 "register_operand" ""))
17524               (clobber (match_dup 2))])]
17525   ""
17526   "")
17528 (define_insn "*cmpstrqi_nz_1"
17529   [(set (reg:CC FLAGS_REG)
17530         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17531                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17532    (use (match_operand:SI 6 "register_operand" "2"))
17533    (use (match_operand:SI 3 "immediate_operand" "i"))
17534    (use (reg:SI DIRFLAG_REG))
17535    (clobber (match_operand:SI 0 "register_operand" "=S"))
17536    (clobber (match_operand:SI 1 "register_operand" "=D"))
17537    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17538   "!TARGET_64BIT"
17539   "repz{\;| }cmpsb"
17540   [(set_attr "type" "str")
17541    (set_attr "mode" "QI")
17542    (set_attr "prefix_rep" "1")])
17544 (define_insn "*cmpstrqi_nz_rex_1"
17545   [(set (reg:CC FLAGS_REG)
17546         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17547                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17548    (use (match_operand:DI 6 "register_operand" "2"))
17549    (use (match_operand:SI 3 "immediate_operand" "i"))
17550    (use (reg:SI DIRFLAG_REG))
17551    (clobber (match_operand:DI 0 "register_operand" "=S"))
17552    (clobber (match_operand:DI 1 "register_operand" "=D"))
17553    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17554   "TARGET_64BIT"
17555   "repz{\;| }cmpsb"
17556   [(set_attr "type" "str")
17557    (set_attr "mode" "QI")
17558    (set_attr "prefix_rep" "1")])
17560 ;; The same, but the count is not known to not be zero.
17562 (define_expand "cmpstrqi_1"
17563   [(parallel [(set (reg:CC FLAGS_REG)
17564                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17565                                      (const_int 0))
17566                   (compare:CC (match_operand 4 "memory_operand" "")
17567                               (match_operand 5 "memory_operand" ""))
17568                   (const_int 0)))
17569               (use (match_operand:SI 3 "immediate_operand" ""))
17570               (use (reg:CC FLAGS_REG))
17571               (use (reg:SI DIRFLAG_REG))
17572               (clobber (match_operand 0 "register_operand" ""))
17573               (clobber (match_operand 1 "register_operand" ""))
17574               (clobber (match_dup 2))])]
17575   ""
17576   "")
17578 (define_insn "*cmpstrqi_1"
17579   [(set (reg:CC FLAGS_REG)
17580         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17581                              (const_int 0))
17582           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17583                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17584           (const_int 0)))
17585    (use (match_operand:SI 3 "immediate_operand" "i"))
17586    (use (reg:CC FLAGS_REG))
17587    (use (reg:SI DIRFLAG_REG))
17588    (clobber (match_operand:SI 0 "register_operand" "=S"))
17589    (clobber (match_operand:SI 1 "register_operand" "=D"))
17590    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17591   "!TARGET_64BIT"
17592   "repz{\;| }cmpsb"
17593   [(set_attr "type" "str")
17594    (set_attr "mode" "QI")
17595    (set_attr "prefix_rep" "1")])
17597 (define_insn "*cmpstrqi_rex_1"
17598   [(set (reg:CC FLAGS_REG)
17599         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17600                              (const_int 0))
17601           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17602                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17603           (const_int 0)))
17604    (use (match_operand:SI 3 "immediate_operand" "i"))
17605    (use (reg:CC FLAGS_REG))
17606    (use (reg:SI DIRFLAG_REG))
17607    (clobber (match_operand:DI 0 "register_operand" "=S"))
17608    (clobber (match_operand:DI 1 "register_operand" "=D"))
17609    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17610   "TARGET_64BIT"
17611   "repz{\;| }cmpsb"
17612   [(set_attr "type" "str")
17613    (set_attr "mode" "QI")
17614    (set_attr "prefix_rep" "1")])
17616 (define_expand "strlensi"
17617   [(set (match_operand:SI 0 "register_operand" "")
17618         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17619                     (match_operand:QI 2 "immediate_operand" "")
17620                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17621   ""
17623  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17624    DONE;
17625  else
17626    FAIL;
17629 (define_expand "strlendi"
17630   [(set (match_operand:DI 0 "register_operand" "")
17631         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17632                     (match_operand:QI 2 "immediate_operand" "")
17633                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17634   ""
17636  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17637    DONE;
17638  else
17639    FAIL;
17642 (define_expand "strlenqi_1"
17643   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17644               (use (reg:SI DIRFLAG_REG))
17645               (clobber (match_operand 1 "register_operand" ""))
17646               (clobber (reg:CC FLAGS_REG))])]
17647   ""
17648   "")
17650 (define_insn "*strlenqi_1"
17651   [(set (match_operand:SI 0 "register_operand" "=&c")
17652         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17653                     (match_operand:QI 2 "register_operand" "a")
17654                     (match_operand:SI 3 "immediate_operand" "i")
17655                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17656    (use (reg:SI DIRFLAG_REG))
17657    (clobber (match_operand:SI 1 "register_operand" "=D"))
17658    (clobber (reg:CC FLAGS_REG))]
17659   "!TARGET_64BIT"
17660   "repnz{\;| }scasb"
17661   [(set_attr "type" "str")
17662    (set_attr "mode" "QI")
17663    (set_attr "prefix_rep" "1")])
17665 (define_insn "*strlenqi_rex_1"
17666   [(set (match_operand:DI 0 "register_operand" "=&c")
17667         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17668                     (match_operand:QI 2 "register_operand" "a")
17669                     (match_operand:DI 3 "immediate_operand" "i")
17670                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17671    (use (reg:SI DIRFLAG_REG))
17672    (clobber (match_operand:DI 1 "register_operand" "=D"))
17673    (clobber (reg:CC FLAGS_REG))]
17674   "TARGET_64BIT"
17675   "repnz{\;| }scasb"
17676   [(set_attr "type" "str")
17677    (set_attr "mode" "QI")
17678    (set_attr "prefix_rep" "1")])
17680 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17681 ;; handled in combine, but it is not currently up to the task.
17682 ;; When used for their truth value, the cmpstr* expanders generate
17683 ;; code like this:
17685 ;;   repz cmpsb
17686 ;;   seta       %al
17687 ;;   setb       %dl
17688 ;;   cmpb       %al, %dl
17689 ;;   jcc        label
17691 ;; The intermediate three instructions are unnecessary.
17693 ;; This one handles cmpstr*_nz_1...
17694 (define_peephole2
17695   [(parallel[
17696      (set (reg:CC FLAGS_REG)
17697           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17698                       (mem:BLK (match_operand 5 "register_operand" ""))))
17699      (use (match_operand 6 "register_operand" ""))
17700      (use (match_operand:SI 3 "immediate_operand" ""))
17701      (use (reg:SI DIRFLAG_REG))
17702      (clobber (match_operand 0 "register_operand" ""))
17703      (clobber (match_operand 1 "register_operand" ""))
17704      (clobber (match_operand 2 "register_operand" ""))])
17705    (set (match_operand:QI 7 "register_operand" "")
17706         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17707    (set (match_operand:QI 8 "register_operand" "")
17708         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17709    (set (reg FLAGS_REG)
17710         (compare (match_dup 7) (match_dup 8)))
17711   ]
17712   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17713   [(parallel[
17714      (set (reg:CC FLAGS_REG)
17715           (compare:CC (mem:BLK (match_dup 4))
17716                       (mem:BLK (match_dup 5))))
17717      (use (match_dup 6))
17718      (use (match_dup 3))
17719      (use (reg:SI DIRFLAG_REG))
17720      (clobber (match_dup 0))
17721      (clobber (match_dup 1))
17722      (clobber (match_dup 2))])]
17723   "")
17725 ;; ...and this one handles cmpstr*_1.
17726 (define_peephole2
17727   [(parallel[
17728      (set (reg:CC FLAGS_REG)
17729           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17730                                (const_int 0))
17731             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17732                         (mem:BLK (match_operand 5 "register_operand" "")))
17733             (const_int 0)))
17734      (use (match_operand:SI 3 "immediate_operand" ""))
17735      (use (reg:CC FLAGS_REG))
17736      (use (reg:SI DIRFLAG_REG))
17737      (clobber (match_operand 0 "register_operand" ""))
17738      (clobber (match_operand 1 "register_operand" ""))
17739      (clobber (match_operand 2 "register_operand" ""))])
17740    (set (match_operand:QI 7 "register_operand" "")
17741         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17742    (set (match_operand:QI 8 "register_operand" "")
17743         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17744    (set (reg FLAGS_REG)
17745         (compare (match_dup 7) (match_dup 8)))
17746   ]
17747   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17748   [(parallel[
17749      (set (reg:CC FLAGS_REG)
17750           (if_then_else:CC (ne (match_dup 6)
17751                                (const_int 0))
17752             (compare:CC (mem:BLK (match_dup 4))
17753                         (mem:BLK (match_dup 5)))
17754             (const_int 0)))
17755      (use (match_dup 3))
17756      (use (reg:CC FLAGS_REG))
17757      (use (reg:SI DIRFLAG_REG))
17758      (clobber (match_dup 0))
17759      (clobber (match_dup 1))
17760      (clobber (match_dup 2))])]
17761   "")
17765 ;; Conditional move instructions.
17767 (define_expand "movdicc"
17768   [(set (match_operand:DI 0 "register_operand" "")
17769         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17770                          (match_operand:DI 2 "general_operand" "")
17771                          (match_operand:DI 3 "general_operand" "")))]
17772   "TARGET_64BIT"
17773   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17775 (define_insn "x86_movdicc_0_m1_rex64"
17776   [(set (match_operand:DI 0 "register_operand" "=r")
17777         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17778           (const_int -1)
17779           (const_int 0)))
17780    (clobber (reg:CC FLAGS_REG))]
17781   "TARGET_64BIT"
17782   "sbb{q}\t%0, %0"
17783   ; Since we don't have the proper number of operands for an alu insn,
17784   ; fill in all the blanks.
17785   [(set_attr "type" "alu")
17786    (set_attr "pent_pair" "pu")
17787    (set_attr "memory" "none")
17788    (set_attr "imm_disp" "false")
17789    (set_attr "mode" "DI")
17790    (set_attr "length_immediate" "0")])
17792 (define_insn "*movdicc_c_rex64"
17793   [(set (match_operand:DI 0 "register_operand" "=r,r")
17794         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17795                                 [(reg FLAGS_REG) (const_int 0)])
17796                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17797                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17798   "TARGET_64BIT && TARGET_CMOVE
17799    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17800   "@
17801    cmov%O2%C1\t{%2, %0|%0, %2}
17802    cmov%O2%c1\t{%3, %0|%0, %3}"
17803   [(set_attr "type" "icmov")
17804    (set_attr "mode" "DI")])
17806 (define_expand "movsicc"
17807   [(set (match_operand:SI 0 "register_operand" "")
17808         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17809                          (match_operand:SI 2 "general_operand" "")
17810                          (match_operand:SI 3 "general_operand" "")))]
17811   ""
17812   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17814 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17815 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17816 ;; So just document what we're doing explicitly.
17818 (define_insn "x86_movsicc_0_m1"
17819   [(set (match_operand:SI 0 "register_operand" "=r")
17820         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17821           (const_int -1)
17822           (const_int 0)))
17823    (clobber (reg:CC FLAGS_REG))]
17824   ""
17825   "sbb{l}\t%0, %0"
17826   ; Since we don't have the proper number of operands for an alu insn,
17827   ; fill in all the blanks.
17828   [(set_attr "type" "alu")
17829    (set_attr "pent_pair" "pu")
17830    (set_attr "memory" "none")
17831    (set_attr "imm_disp" "false")
17832    (set_attr "mode" "SI")
17833    (set_attr "length_immediate" "0")])
17835 (define_insn "*movsicc_noc"
17836   [(set (match_operand:SI 0 "register_operand" "=r,r")
17837         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17838                                 [(reg FLAGS_REG) (const_int 0)])
17839                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17840                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17841   "TARGET_CMOVE
17842    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17843   "@
17844    cmov%O2%C1\t{%2, %0|%0, %2}
17845    cmov%O2%c1\t{%3, %0|%0, %3}"
17846   [(set_attr "type" "icmov")
17847    (set_attr "mode" "SI")])
17849 (define_expand "movhicc"
17850   [(set (match_operand:HI 0 "register_operand" "")
17851         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17852                          (match_operand:HI 2 "general_operand" "")
17853                          (match_operand:HI 3 "general_operand" "")))]
17854   "TARGET_HIMODE_MATH"
17855   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17857 (define_insn "*movhicc_noc"
17858   [(set (match_operand:HI 0 "register_operand" "=r,r")
17859         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17860                                 [(reg FLAGS_REG) (const_int 0)])
17861                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17862                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17863   "TARGET_CMOVE
17864    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17865   "@
17866    cmov%O2%C1\t{%2, %0|%0, %2}
17867    cmov%O2%c1\t{%3, %0|%0, %3}"
17868   [(set_attr "type" "icmov")
17869    (set_attr "mode" "HI")])
17871 (define_expand "movqicc"
17872   [(set (match_operand:QI 0 "register_operand" "")
17873         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17874                          (match_operand:QI 2 "general_operand" "")
17875                          (match_operand:QI 3 "general_operand" "")))]
17876   "TARGET_QIMODE_MATH"
17877   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17879 (define_insn_and_split "*movqicc_noc"
17880   [(set (match_operand:QI 0 "register_operand" "=r,r")
17881         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17882                                 [(match_operand 4 "flags_reg_operand" "")
17883                                  (const_int 0)])
17884                       (match_operand:QI 2 "register_operand" "r,0")
17885                       (match_operand:QI 3 "register_operand" "0,r")))]
17886   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17887   "#"
17888   "&& reload_completed"
17889   [(set (match_dup 0)
17890         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17891                       (match_dup 2)
17892                       (match_dup 3)))]
17893   "operands[0] = gen_lowpart (SImode, operands[0]);
17894    operands[2] = gen_lowpart (SImode, operands[2]);
17895    operands[3] = gen_lowpart (SImode, operands[3]);"
17896   [(set_attr "type" "icmov")
17897    (set_attr "mode" "SI")])
17899 (define_expand "movsfcc"
17900   [(set (match_operand:SF 0 "register_operand" "")
17901         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17902                          (match_operand:SF 2 "register_operand" "")
17903                          (match_operand:SF 3 "register_operand" "")))]
17904   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17905   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17907 (define_insn "*movsfcc_1_387"
17908   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17909         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17910                                 [(reg FLAGS_REG) (const_int 0)])
17911                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17912                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17913   "TARGET_80387 && TARGET_CMOVE
17914    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17915   "@
17916    fcmov%F1\t{%2, %0|%0, %2}
17917    fcmov%f1\t{%3, %0|%0, %3}
17918    cmov%O2%C1\t{%2, %0|%0, %2}
17919    cmov%O2%c1\t{%3, %0|%0, %3}"
17920   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17921    (set_attr "mode" "SF,SF,SI,SI")])
17923 (define_expand "movdfcc"
17924   [(set (match_operand:DF 0 "register_operand" "")
17925         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17926                          (match_operand:DF 2 "register_operand" "")
17927                          (match_operand:DF 3 "register_operand" "")))]
17928   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17929   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17931 (define_insn "*movdfcc_1"
17932   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17933         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17934                                 [(reg FLAGS_REG) (const_int 0)])
17935                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17936                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17937   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17938    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17939   "@
17940    fcmov%F1\t{%2, %0|%0, %2}
17941    fcmov%f1\t{%3, %0|%0, %3}
17942    #
17943    #"
17944   [(set_attr "type" "fcmov,fcmov,multi,multi")
17945    (set_attr "mode" "DF")])
17947 (define_insn "*movdfcc_1_rex64"
17948   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17949         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17950                                 [(reg FLAGS_REG) (const_int 0)])
17951                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17952                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17953   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17954    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17955   "@
17956    fcmov%F1\t{%2, %0|%0, %2}
17957    fcmov%f1\t{%3, %0|%0, %3}
17958    cmov%O2%C1\t{%2, %0|%0, %2}
17959    cmov%O2%c1\t{%3, %0|%0, %3}"
17960   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17961    (set_attr "mode" "DF")])
17963 (define_split
17964   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17965         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17966                                 [(match_operand 4 "flags_reg_operand" "")
17967                                  (const_int 0)])
17968                       (match_operand:DF 2 "nonimmediate_operand" "")
17969                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17970   "!TARGET_64BIT && reload_completed"
17971   [(set (match_dup 2)
17972         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17973                       (match_dup 5)
17974                       (match_dup 7)))
17975    (set (match_dup 3)
17976         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17977                       (match_dup 6)
17978                       (match_dup 8)))]
17979   "split_di (operands+2, 1, operands+5, operands+6);
17980    split_di (operands+3, 1, operands+7, operands+8);
17981    split_di (operands, 1, operands+2, operands+3);")
17983 (define_expand "movxfcc"
17984   [(set (match_operand:XF 0 "register_operand" "")
17985         (if_then_else:XF (match_operand 1 "comparison_operator" "")
17986                          (match_operand:XF 2 "register_operand" "")
17987                          (match_operand:XF 3 "register_operand" "")))]
17988   "TARGET_80387 && TARGET_CMOVE"
17989   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17991 (define_insn "*movxfcc_1"
17992   [(set (match_operand:XF 0 "register_operand" "=f,f")
17993         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
17994                                 [(reg FLAGS_REG) (const_int 0)])
17995                       (match_operand:XF 2 "register_operand" "f,0")
17996                       (match_operand:XF 3 "register_operand" "0,f")))]
17997   "TARGET_80387 && TARGET_CMOVE"
17998   "@
17999    fcmov%F1\t{%2, %0|%0, %2}
18000    fcmov%f1\t{%3, %0|%0, %3}"
18001   [(set_attr "type" "fcmov")
18002    (set_attr "mode" "XF")])
18004 ;; These versions of the min/max patterns are intentionally ignorant of
18005 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18006 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18007 ;; are undefined in this condition, we're certain this is correct.
18009 (define_insn "sminsf3"
18010   [(set (match_operand:SF 0 "register_operand" "=x")
18011         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18012                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18013   "TARGET_SSE_MATH"
18014   "minss\t{%2, %0|%0, %2}"
18015   [(set_attr "type" "sseadd")
18016    (set_attr "mode" "SF")])
18018 (define_insn "smaxsf3"
18019   [(set (match_operand:SF 0 "register_operand" "=x")
18020         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18021                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18022   "TARGET_SSE_MATH"
18023   "maxss\t{%2, %0|%0, %2}"
18024   [(set_attr "type" "sseadd")
18025    (set_attr "mode" "SF")])
18027 (define_insn "smindf3"
18028   [(set (match_operand:DF 0 "register_operand" "=x")
18029         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18030                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18031   "TARGET_SSE2 && TARGET_SSE_MATH"
18032   "minsd\t{%2, %0|%0, %2}"
18033   [(set_attr "type" "sseadd")
18034    (set_attr "mode" "DF")])
18036 (define_insn "smaxdf3"
18037   [(set (match_operand:DF 0 "register_operand" "=x")
18038         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18039                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18040   "TARGET_SSE2 && TARGET_SSE_MATH"
18041   "maxsd\t{%2, %0|%0, %2}"
18042   [(set_attr "type" "sseadd")
18043    (set_attr "mode" "DF")])
18045 ;; These versions of the min/max patterns implement exactly the operations
18046 ;;   min = (op1 < op2 ? op1 : op2)
18047 ;;   max = (!(op1 < op2) ? op1 : op2)
18048 ;; Their operands are not commutative, and thus they may be used in the
18049 ;; presence of -0.0 and NaN.
18051 (define_insn "*ieee_sminsf3"
18052   [(set (match_operand:SF 0 "register_operand" "=x")
18053         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18054                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18055                    UNSPEC_IEEE_MIN))]
18056   "TARGET_SSE_MATH"
18057   "minss\t{%2, %0|%0, %2}"
18058   [(set_attr "type" "sseadd")
18059    (set_attr "mode" "SF")])
18061 (define_insn "*ieee_smaxsf3"
18062   [(set (match_operand:SF 0 "register_operand" "=x")
18063         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18064                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18065                    UNSPEC_IEEE_MAX))]
18066   "TARGET_SSE_MATH"
18067   "maxss\t{%2, %0|%0, %2}"
18068   [(set_attr "type" "sseadd")
18069    (set_attr "mode" "SF")])
18071 (define_insn "*ieee_smindf3"
18072   [(set (match_operand:DF 0 "register_operand" "=x")
18073         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18074                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18075                    UNSPEC_IEEE_MIN))]
18076   "TARGET_SSE2 && TARGET_SSE_MATH"
18077   "minsd\t{%2, %0|%0, %2}"
18078   [(set_attr "type" "sseadd")
18079    (set_attr "mode" "DF")])
18081 (define_insn "*ieee_smaxdf3"
18082   [(set (match_operand:DF 0 "register_operand" "=x")
18083         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18084                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18085                    UNSPEC_IEEE_MAX))]
18086   "TARGET_SSE2 && TARGET_SSE_MATH"
18087   "maxsd\t{%2, %0|%0, %2}"
18088   [(set_attr "type" "sseadd")
18089    (set_attr "mode" "DF")])
18091 ;; Conditional addition patterns
18092 (define_expand "addqicc"
18093   [(match_operand:QI 0 "register_operand" "")
18094    (match_operand 1 "comparison_operator" "")
18095    (match_operand:QI 2 "register_operand" "")
18096    (match_operand:QI 3 "const_int_operand" "")]
18097   ""
18098   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18100 (define_expand "addhicc"
18101   [(match_operand:HI 0 "register_operand" "")
18102    (match_operand 1 "comparison_operator" "")
18103    (match_operand:HI 2 "register_operand" "")
18104    (match_operand:HI 3 "const_int_operand" "")]
18105   ""
18106   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18108 (define_expand "addsicc"
18109   [(match_operand:SI 0 "register_operand" "")
18110    (match_operand 1 "comparison_operator" "")
18111    (match_operand:SI 2 "register_operand" "")
18112    (match_operand:SI 3 "const_int_operand" "")]
18113   ""
18114   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18116 (define_expand "adddicc"
18117   [(match_operand:DI 0 "register_operand" "")
18118    (match_operand 1 "comparison_operator" "")
18119    (match_operand:DI 2 "register_operand" "")
18120    (match_operand:DI 3 "const_int_operand" "")]
18121   "TARGET_64BIT"
18122   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18125 ;; Misc patterns (?)
18127 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18128 ;; Otherwise there will be nothing to keep
18129 ;; 
18130 ;; [(set (reg ebp) (reg esp))]
18131 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18132 ;;  (clobber (eflags)]
18133 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18135 ;; in proper program order.
18136 (define_insn "pro_epilogue_adjust_stack_1"
18137   [(set (match_operand:SI 0 "register_operand" "=r,r")
18138         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18139                  (match_operand:SI 2 "immediate_operand" "i,i")))
18140    (clobber (reg:CC FLAGS_REG))
18141    (clobber (mem:BLK (scratch)))]
18142   "!TARGET_64BIT"
18144   switch (get_attr_type (insn))
18145     {
18146     case TYPE_IMOV:
18147       return "mov{l}\t{%1, %0|%0, %1}";
18149     case TYPE_ALU:
18150       if (GET_CODE (operands[2]) == CONST_INT
18151           && (INTVAL (operands[2]) == 128
18152               || (INTVAL (operands[2]) < 0
18153                   && INTVAL (operands[2]) != -128)))
18154         {
18155           operands[2] = GEN_INT (-INTVAL (operands[2]));
18156           return "sub{l}\t{%2, %0|%0, %2}";
18157         }
18158       return "add{l}\t{%2, %0|%0, %2}";
18160     case TYPE_LEA:
18161       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18162       return "lea{l}\t{%a2, %0|%0, %a2}";
18164     default:
18165       gcc_unreachable ();
18166     }
18168   [(set (attr "type")
18169         (cond [(eq_attr "alternative" "0")
18170                  (const_string "alu")
18171                (match_operand:SI 2 "const0_operand" "")
18172                  (const_string "imov")
18173               ]
18174               (const_string "lea")))
18175    (set_attr "mode" "SI")])
18177 (define_insn "pro_epilogue_adjust_stack_rex64"
18178   [(set (match_operand:DI 0 "register_operand" "=r,r")
18179         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18180                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18181    (clobber (reg:CC FLAGS_REG))
18182    (clobber (mem:BLK (scratch)))]
18183   "TARGET_64BIT"
18185   switch (get_attr_type (insn))
18186     {
18187     case TYPE_IMOV:
18188       return "mov{q}\t{%1, %0|%0, %1}";
18190     case TYPE_ALU:
18191       if (GET_CODE (operands[2]) == CONST_INT
18192           /* Avoid overflows.  */
18193           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18194           && (INTVAL (operands[2]) == 128
18195               || (INTVAL (operands[2]) < 0
18196                   && INTVAL (operands[2]) != -128)))
18197         {
18198           operands[2] = GEN_INT (-INTVAL (operands[2]));
18199           return "sub{q}\t{%2, %0|%0, %2}";
18200         }
18201       return "add{q}\t{%2, %0|%0, %2}";
18203     case TYPE_LEA:
18204       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18205       return "lea{q}\t{%a2, %0|%0, %a2}";
18207     default:
18208       gcc_unreachable ();
18209     }
18211   [(set (attr "type")
18212         (cond [(eq_attr "alternative" "0")
18213                  (const_string "alu")
18214                (match_operand:DI 2 "const0_operand" "")
18215                  (const_string "imov")
18216               ]
18217               (const_string "lea")))
18218    (set_attr "mode" "DI")])
18220 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18221   [(set (match_operand:DI 0 "register_operand" "=r,r")
18222         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18223                  (match_operand:DI 3 "immediate_operand" "i,i")))
18224    (use (match_operand:DI 2 "register_operand" "r,r"))
18225    (clobber (reg:CC FLAGS_REG))
18226    (clobber (mem:BLK (scratch)))]
18227   "TARGET_64BIT"
18229   switch (get_attr_type (insn))
18230     {
18231     case TYPE_ALU:
18232       return "add{q}\t{%2, %0|%0, %2}";
18234     case TYPE_LEA:
18235       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18236       return "lea{q}\t{%a2, %0|%0, %a2}";
18238     default:
18239       gcc_unreachable ();
18240     }
18242   [(set_attr "type" "alu,lea")
18243    (set_attr "mode" "DI")])
18245 (define_expand "allocate_stack_worker"
18246   [(match_operand:SI 0 "register_operand" "")]
18247   "TARGET_STACK_PROBE"
18249   if (reload_completed)
18250     {
18251       if (TARGET_64BIT)
18252         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18253       else
18254         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18255     }
18256   else
18257     {
18258       if (TARGET_64BIT)
18259         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18260       else
18261         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18262     }
18263   DONE;
18266 (define_insn "allocate_stack_worker_1"
18267   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18268     UNSPECV_STACK_PROBE)
18269    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18270    (clobber (match_scratch:SI 1 "=0"))
18271    (clobber (reg:CC FLAGS_REG))]
18272   "!TARGET_64BIT && TARGET_STACK_PROBE"
18273   "call\t__alloca"
18274   [(set_attr "type" "multi")
18275    (set_attr "length" "5")])
18277 (define_expand "allocate_stack_worker_postreload"
18278   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18279                                     UNSPECV_STACK_PROBE)
18280               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18281               (clobber (match_dup 0))
18282               (clobber (reg:CC FLAGS_REG))])]
18283   ""
18284   "")
18286 (define_insn "allocate_stack_worker_rex64"
18287   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18288     UNSPECV_STACK_PROBE)
18289    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18290    (clobber (match_scratch:DI 1 "=0"))
18291    (clobber (reg:CC FLAGS_REG))]
18292   "TARGET_64BIT && TARGET_STACK_PROBE"
18293   "call\t__alloca"
18294   [(set_attr "type" "multi")
18295    (set_attr "length" "5")])
18297 (define_expand "allocate_stack_worker_rex64_postreload"
18298   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18299                                     UNSPECV_STACK_PROBE)
18300               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18301               (clobber (match_dup 0))
18302               (clobber (reg:CC FLAGS_REG))])]
18303   ""
18304   "")
18306 (define_expand "allocate_stack"
18307   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18308                    (minus:SI (reg:SI SP_REG)
18309                              (match_operand:SI 1 "general_operand" "")))
18310               (clobber (reg:CC FLAGS_REG))])
18311    (parallel [(set (reg:SI SP_REG)
18312                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18313               (clobber (reg:CC FLAGS_REG))])]
18314   "TARGET_STACK_PROBE"
18316 #ifdef CHECK_STACK_LIMIT
18317   if (GET_CODE (operands[1]) == CONST_INT
18318       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18319     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18320                            operands[1]));
18321   else 
18322 #endif
18323     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18324                                                             operands[1])));
18326   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18327   DONE;
18330 (define_expand "builtin_setjmp_receiver"
18331   [(label_ref (match_operand 0 "" ""))]
18332   "!TARGET_64BIT && flag_pic"
18334   emit_insn (gen_set_got (pic_offset_table_rtx));
18335   DONE;
18338 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18340 (define_split
18341   [(set (match_operand 0 "register_operand" "")
18342         (match_operator 3 "promotable_binary_operator"
18343            [(match_operand 1 "register_operand" "")
18344             (match_operand 2 "aligned_operand" "")]))
18345    (clobber (reg:CC FLAGS_REG))]
18346   "! TARGET_PARTIAL_REG_STALL && reload_completed
18347    && ((GET_MODE (operands[0]) == HImode 
18348         && ((!optimize_size && !TARGET_FAST_PREFIX)
18349             || GET_CODE (operands[2]) != CONST_INT
18350             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18351        || (GET_MODE (operands[0]) == QImode 
18352            && (TARGET_PROMOTE_QImode || optimize_size)))"
18353   [(parallel [(set (match_dup 0)
18354                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18355               (clobber (reg:CC FLAGS_REG))])]
18356   "operands[0] = gen_lowpart (SImode, operands[0]);
18357    operands[1] = gen_lowpart (SImode, operands[1]);
18358    if (GET_CODE (operands[3]) != ASHIFT)
18359      operands[2] = gen_lowpart (SImode, operands[2]);
18360    PUT_MODE (operands[3], SImode);")
18362 ; Promote the QImode tests, as i386 has encoding of the AND
18363 ; instruction with 32-bit sign-extended immediate and thus the
18364 ; instruction size is unchanged, except in the %eax case for
18365 ; which it is increased by one byte, hence the ! optimize_size.
18366 (define_split
18367   [(set (match_operand 0 "flags_reg_operand" "")
18368         (match_operator 2 "compare_operator"
18369           [(and (match_operand 3 "aligned_operand" "")
18370                 (match_operand 4 "const_int_operand" ""))
18371            (const_int 0)]))
18372    (set (match_operand 1 "register_operand" "")
18373         (and (match_dup 3) (match_dup 4)))]
18374   "! TARGET_PARTIAL_REG_STALL && reload_completed
18375    /* Ensure that the operand will remain sign-extended immediate.  */
18376    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18377    && ! optimize_size
18378    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18379        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18380   [(parallel [(set (match_dup 0)
18381                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18382                                     (const_int 0)]))
18383               (set (match_dup 1)
18384                    (and:SI (match_dup 3) (match_dup 4)))])]
18386   operands[4]
18387     = gen_int_mode (INTVAL (operands[4])
18388                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18389   operands[1] = gen_lowpart (SImode, operands[1]);
18390   operands[3] = gen_lowpart (SImode, operands[3]);
18393 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18394 ; the TEST instruction with 32-bit sign-extended immediate and thus
18395 ; the instruction size would at least double, which is not what we
18396 ; want even with ! optimize_size.
18397 (define_split
18398   [(set (match_operand 0 "flags_reg_operand" "")
18399         (match_operator 1 "compare_operator"
18400           [(and (match_operand:HI 2 "aligned_operand" "")
18401                 (match_operand:HI 3 "const_int_operand" ""))
18402            (const_int 0)]))]
18403   "! TARGET_PARTIAL_REG_STALL && reload_completed
18404    /* Ensure that the operand will remain sign-extended immediate.  */
18405    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18406    && ! TARGET_FAST_PREFIX
18407    && ! optimize_size"
18408   [(set (match_dup 0)
18409         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18410                          (const_int 0)]))]
18412   operands[3]
18413     = gen_int_mode (INTVAL (operands[3])
18414                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18415   operands[2] = gen_lowpart (SImode, operands[2]);
18418 (define_split
18419   [(set (match_operand 0 "register_operand" "")
18420         (neg (match_operand 1 "register_operand" "")))
18421    (clobber (reg:CC FLAGS_REG))]
18422   "! TARGET_PARTIAL_REG_STALL && reload_completed
18423    && (GET_MODE (operands[0]) == HImode
18424        || (GET_MODE (operands[0]) == QImode 
18425            && (TARGET_PROMOTE_QImode || optimize_size)))"
18426   [(parallel [(set (match_dup 0)
18427                    (neg:SI (match_dup 1)))
18428               (clobber (reg:CC FLAGS_REG))])]
18429   "operands[0] = gen_lowpart (SImode, operands[0]);
18430    operands[1] = gen_lowpart (SImode, operands[1]);")
18432 (define_split
18433   [(set (match_operand 0 "register_operand" "")
18434         (not (match_operand 1 "register_operand" "")))]
18435   "! TARGET_PARTIAL_REG_STALL && reload_completed
18436    && (GET_MODE (operands[0]) == HImode
18437        || (GET_MODE (operands[0]) == QImode 
18438            && (TARGET_PROMOTE_QImode || optimize_size)))"
18439   [(set (match_dup 0)
18440         (not:SI (match_dup 1)))]
18441   "operands[0] = gen_lowpart (SImode, operands[0]);
18442    operands[1] = gen_lowpart (SImode, operands[1]);")
18444 (define_split 
18445   [(set (match_operand 0 "register_operand" "")
18446         (if_then_else (match_operator 1 "comparison_operator" 
18447                                 [(reg FLAGS_REG) (const_int 0)])
18448                       (match_operand 2 "register_operand" "")
18449                       (match_operand 3 "register_operand" "")))]
18450   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18451    && (GET_MODE (operands[0]) == HImode
18452        || (GET_MODE (operands[0]) == QImode 
18453            && (TARGET_PROMOTE_QImode || optimize_size)))"
18454   [(set (match_dup 0)
18455         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18456   "operands[0] = gen_lowpart (SImode, operands[0]);
18457    operands[2] = gen_lowpart (SImode, operands[2]);
18458    operands[3] = gen_lowpart (SImode, operands[3]);")
18459                         
18461 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18462 ;; transform a complex memory operation into two memory to register operations.
18464 ;; Don't push memory operands
18465 (define_peephole2
18466   [(set (match_operand:SI 0 "push_operand" "")
18467         (match_operand:SI 1 "memory_operand" ""))
18468    (match_scratch:SI 2 "r")]
18469   "! optimize_size && ! TARGET_PUSH_MEMORY"
18470   [(set (match_dup 2) (match_dup 1))
18471    (set (match_dup 0) (match_dup 2))]
18472   "")
18474 (define_peephole2
18475   [(set (match_operand:DI 0 "push_operand" "")
18476         (match_operand:DI 1 "memory_operand" ""))
18477    (match_scratch:DI 2 "r")]
18478   "! optimize_size && ! TARGET_PUSH_MEMORY"
18479   [(set (match_dup 2) (match_dup 1))
18480    (set (match_dup 0) (match_dup 2))]
18481   "")
18483 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18484 ;; SImode pushes.
18485 (define_peephole2
18486   [(set (match_operand:SF 0 "push_operand" "")
18487         (match_operand:SF 1 "memory_operand" ""))
18488    (match_scratch:SF 2 "r")]
18489   "! optimize_size && ! TARGET_PUSH_MEMORY"
18490   [(set (match_dup 2) (match_dup 1))
18491    (set (match_dup 0) (match_dup 2))]
18492   "")
18494 (define_peephole2
18495   [(set (match_operand:HI 0 "push_operand" "")
18496         (match_operand:HI 1 "memory_operand" ""))
18497    (match_scratch:HI 2 "r")]
18498   "! optimize_size && ! TARGET_PUSH_MEMORY"
18499   [(set (match_dup 2) (match_dup 1))
18500    (set (match_dup 0) (match_dup 2))]
18501   "")
18503 (define_peephole2
18504   [(set (match_operand:QI 0 "push_operand" "")
18505         (match_operand:QI 1 "memory_operand" ""))
18506    (match_scratch:QI 2 "q")]
18507   "! optimize_size && ! TARGET_PUSH_MEMORY"
18508   [(set (match_dup 2) (match_dup 1))
18509    (set (match_dup 0) (match_dup 2))]
18510   "")
18512 ;; Don't move an immediate directly to memory when the instruction
18513 ;; gets too big.
18514 (define_peephole2
18515   [(match_scratch:SI 1 "r")
18516    (set (match_operand:SI 0 "memory_operand" "")
18517         (const_int 0))]
18518   "! optimize_size
18519    && ! TARGET_USE_MOV0
18520    && TARGET_SPLIT_LONG_MOVES
18521    && get_attr_length (insn) >= ix86_cost->large_insn
18522    && peep2_regno_dead_p (0, FLAGS_REG)"
18523   [(parallel [(set (match_dup 1) (const_int 0))
18524               (clobber (reg:CC FLAGS_REG))])
18525    (set (match_dup 0) (match_dup 1))]
18526   "")
18528 (define_peephole2
18529   [(match_scratch:HI 1 "r")
18530    (set (match_operand:HI 0 "memory_operand" "")
18531         (const_int 0))]
18532   "! optimize_size
18533    && ! TARGET_USE_MOV0
18534    && TARGET_SPLIT_LONG_MOVES
18535    && get_attr_length (insn) >= ix86_cost->large_insn
18536    && peep2_regno_dead_p (0, FLAGS_REG)"
18537   [(parallel [(set (match_dup 2) (const_int 0))
18538               (clobber (reg:CC FLAGS_REG))])
18539    (set (match_dup 0) (match_dup 1))]
18540   "operands[2] = gen_lowpart (SImode, operands[1]);")
18542 (define_peephole2
18543   [(match_scratch:QI 1 "q")
18544    (set (match_operand:QI 0 "memory_operand" "")
18545         (const_int 0))]
18546   "! optimize_size
18547    && ! TARGET_USE_MOV0
18548    && TARGET_SPLIT_LONG_MOVES
18549    && get_attr_length (insn) >= ix86_cost->large_insn
18550    && peep2_regno_dead_p (0, FLAGS_REG)"
18551   [(parallel [(set (match_dup 2) (const_int 0))
18552               (clobber (reg:CC FLAGS_REG))])
18553    (set (match_dup 0) (match_dup 1))]
18554   "operands[2] = gen_lowpart (SImode, operands[1]);")
18556 (define_peephole2
18557   [(match_scratch:SI 2 "r")
18558    (set (match_operand:SI 0 "memory_operand" "")
18559         (match_operand:SI 1 "immediate_operand" ""))]
18560   "! optimize_size
18561    && get_attr_length (insn) >= ix86_cost->large_insn
18562    && TARGET_SPLIT_LONG_MOVES"
18563   [(set (match_dup 2) (match_dup 1))
18564    (set (match_dup 0) (match_dup 2))]
18565   "")
18567 (define_peephole2
18568   [(match_scratch:HI 2 "r")
18569    (set (match_operand:HI 0 "memory_operand" "")
18570         (match_operand:HI 1 "immediate_operand" ""))]
18571   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18572   && TARGET_SPLIT_LONG_MOVES"
18573   [(set (match_dup 2) (match_dup 1))
18574    (set (match_dup 0) (match_dup 2))]
18575   "")
18577 (define_peephole2
18578   [(match_scratch:QI 2 "q")
18579    (set (match_operand:QI 0 "memory_operand" "")
18580         (match_operand:QI 1 "immediate_operand" ""))]
18581   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18582   && TARGET_SPLIT_LONG_MOVES"
18583   [(set (match_dup 2) (match_dup 1))
18584    (set (match_dup 0) (match_dup 2))]
18585   "")
18587 ;; Don't compare memory with zero, load and use a test instead.
18588 (define_peephole2
18589   [(set (match_operand 0 "flags_reg_operand" "")
18590         (match_operator 1 "compare_operator"
18591           [(match_operand:SI 2 "memory_operand" "")
18592            (const_int 0)]))
18593    (match_scratch:SI 3 "r")]
18594   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18595   [(set (match_dup 3) (match_dup 2))
18596    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18597   "")
18599 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18600 ;; Don't split NOTs with a displacement operand, because resulting XOR
18601 ;; will not be pairable anyway.
18603 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18604 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18605 ;; so this split helps here as well.
18607 ;; Note: Can't do this as a regular split because we can't get proper
18608 ;; lifetime information then.
18610 (define_peephole2
18611   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18612         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18613   "!optimize_size
18614    && peep2_regno_dead_p (0, FLAGS_REG)
18615    && ((TARGET_PENTIUM 
18616         && (GET_CODE (operands[0]) != MEM
18617             || !memory_displacement_operand (operands[0], SImode)))
18618        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18619   [(parallel [(set (match_dup 0)
18620                    (xor:SI (match_dup 1) (const_int -1)))
18621               (clobber (reg:CC FLAGS_REG))])]
18622   "")
18624 (define_peephole2
18625   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18626         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18627   "!optimize_size
18628    && peep2_regno_dead_p (0, FLAGS_REG)
18629    && ((TARGET_PENTIUM 
18630         && (GET_CODE (operands[0]) != MEM
18631             || !memory_displacement_operand (operands[0], HImode)))
18632        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18633   [(parallel [(set (match_dup 0)
18634                    (xor:HI (match_dup 1) (const_int -1)))
18635               (clobber (reg:CC FLAGS_REG))])]
18636   "")
18638 (define_peephole2
18639   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18640         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18641   "!optimize_size
18642    && peep2_regno_dead_p (0, FLAGS_REG)
18643    && ((TARGET_PENTIUM 
18644         && (GET_CODE (operands[0]) != MEM
18645             || !memory_displacement_operand (operands[0], QImode)))
18646        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18647   [(parallel [(set (match_dup 0)
18648                    (xor:QI (match_dup 1) (const_int -1)))
18649               (clobber (reg:CC FLAGS_REG))])]
18650   "")
18652 ;; Non pairable "test imm, reg" instructions can be translated to
18653 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18654 ;; byte opcode instead of two, have a short form for byte operands),
18655 ;; so do it for other CPUs as well.  Given that the value was dead,
18656 ;; this should not create any new dependencies.  Pass on the sub-word
18657 ;; versions if we're concerned about partial register stalls.
18659 (define_peephole2
18660   [(set (match_operand 0 "flags_reg_operand" "")
18661         (match_operator 1 "compare_operator"
18662           [(and:SI (match_operand:SI 2 "register_operand" "")
18663                    (match_operand:SI 3 "immediate_operand" ""))
18664            (const_int 0)]))]
18665   "ix86_match_ccmode (insn, CCNOmode)
18666    && (true_regnum (operands[2]) != 0
18667        || (GET_CODE (operands[3]) == CONST_INT
18668            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18669    && peep2_reg_dead_p (1, operands[2])"
18670   [(parallel
18671      [(set (match_dup 0)
18672            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18673                             (const_int 0)]))
18674       (set (match_dup 2)
18675            (and:SI (match_dup 2) (match_dup 3)))])]
18676   "")
18678 ;; We don't need to handle HImode case, because it will be promoted to SImode
18679 ;; on ! TARGET_PARTIAL_REG_STALL
18681 (define_peephole2
18682   [(set (match_operand 0 "flags_reg_operand" "")
18683         (match_operator 1 "compare_operator"
18684           [(and:QI (match_operand:QI 2 "register_operand" "")
18685                    (match_operand:QI 3 "immediate_operand" ""))
18686            (const_int 0)]))]
18687   "! TARGET_PARTIAL_REG_STALL
18688    && ix86_match_ccmode (insn, CCNOmode)
18689    && true_regnum (operands[2]) != 0
18690    && peep2_reg_dead_p (1, operands[2])"
18691   [(parallel
18692      [(set (match_dup 0)
18693            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18694                             (const_int 0)]))
18695       (set (match_dup 2)
18696            (and:QI (match_dup 2) (match_dup 3)))])]
18697   "")
18699 (define_peephole2
18700   [(set (match_operand 0 "flags_reg_operand" "")
18701         (match_operator 1 "compare_operator"
18702           [(and:SI
18703              (zero_extract:SI
18704                (match_operand 2 "ext_register_operand" "")
18705                (const_int 8)
18706                (const_int 8))
18707              (match_operand 3 "const_int_operand" ""))
18708            (const_int 0)]))]
18709   "! TARGET_PARTIAL_REG_STALL
18710    && ix86_match_ccmode (insn, CCNOmode)
18711    && true_regnum (operands[2]) != 0
18712    && peep2_reg_dead_p (1, operands[2])"
18713   [(parallel [(set (match_dup 0)
18714                    (match_op_dup 1
18715                      [(and:SI
18716                         (zero_extract:SI
18717                           (match_dup 2)
18718                           (const_int 8)
18719                           (const_int 8))
18720                         (match_dup 3))
18721                       (const_int 0)]))
18722               (set (zero_extract:SI (match_dup 2)
18723                                     (const_int 8)
18724                                     (const_int 8))
18725                    (and:SI 
18726                      (zero_extract:SI
18727                        (match_dup 2)
18728                        (const_int 8)
18729                        (const_int 8))
18730                      (match_dup 3)))])]
18731   "")
18733 ;; Don't do logical operations with memory inputs.
18734 (define_peephole2
18735   [(match_scratch:SI 2 "r")
18736    (parallel [(set (match_operand:SI 0 "register_operand" "")
18737                    (match_operator:SI 3 "arith_or_logical_operator"
18738                      [(match_dup 0)
18739                       (match_operand:SI 1 "memory_operand" "")]))
18740               (clobber (reg:CC FLAGS_REG))])]
18741   "! optimize_size && ! TARGET_READ_MODIFY"
18742   [(set (match_dup 2) (match_dup 1))
18743    (parallel [(set (match_dup 0)
18744                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18745               (clobber (reg:CC FLAGS_REG))])]
18746   "")
18748 (define_peephole2
18749   [(match_scratch:SI 2 "r")
18750    (parallel [(set (match_operand:SI 0 "register_operand" "")
18751                    (match_operator:SI 3 "arith_or_logical_operator"
18752                      [(match_operand:SI 1 "memory_operand" "")
18753                       (match_dup 0)]))
18754               (clobber (reg:CC FLAGS_REG))])]
18755   "! optimize_size && ! TARGET_READ_MODIFY"
18756   [(set (match_dup 2) (match_dup 1))
18757    (parallel [(set (match_dup 0)
18758                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18759               (clobber (reg:CC FLAGS_REG))])]
18760   "")
18762 ; Don't do logical operations with memory outputs
18764 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18765 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18766 ; the same decoder scheduling characteristics as the original.
18768 (define_peephole2
18769   [(match_scratch:SI 2 "r")
18770    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18771                    (match_operator:SI 3 "arith_or_logical_operator"
18772                      [(match_dup 0)
18773                       (match_operand:SI 1 "nonmemory_operand" "")]))
18774               (clobber (reg:CC FLAGS_REG))])]
18775   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18776   [(set (match_dup 2) (match_dup 0))
18777    (parallel [(set (match_dup 2)
18778                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18779               (clobber (reg:CC FLAGS_REG))])
18780    (set (match_dup 0) (match_dup 2))]
18781   "")
18783 (define_peephole2
18784   [(match_scratch:SI 2 "r")
18785    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18786                    (match_operator:SI 3 "arith_or_logical_operator"
18787                      [(match_operand:SI 1 "nonmemory_operand" "")
18788                       (match_dup 0)]))
18789               (clobber (reg:CC FLAGS_REG))])]
18790   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18791   [(set (match_dup 2) (match_dup 0))
18792    (parallel [(set (match_dup 2)
18793                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18794               (clobber (reg:CC FLAGS_REG))])
18795    (set (match_dup 0) (match_dup 2))]
18796   "")
18798 ;; Attempt to always use XOR for zeroing registers.
18799 (define_peephole2
18800   [(set (match_operand 0 "register_operand" "")
18801         (match_operand 1 "const0_operand" ""))]
18802   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18803    && (! TARGET_USE_MOV0 || optimize_size)
18804    && GENERAL_REG_P (operands[0])
18805    && peep2_regno_dead_p (0, FLAGS_REG)"
18806   [(parallel [(set (match_dup 0) (const_int 0))
18807               (clobber (reg:CC FLAGS_REG))])]
18809   operands[0] = gen_lowpart (word_mode, operands[0]);
18812 (define_peephole2
18813   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18814         (const_int 0))]
18815   "(GET_MODE (operands[0]) == QImode
18816     || GET_MODE (operands[0]) == HImode)
18817    && (! TARGET_USE_MOV0 || optimize_size)
18818    && peep2_regno_dead_p (0, FLAGS_REG)"
18819   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18820               (clobber (reg:CC FLAGS_REG))])])
18822 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18823 (define_peephole2
18824   [(set (match_operand 0 "register_operand" "")
18825         (const_int -1))]
18826   "(GET_MODE (operands[0]) == HImode
18827     || GET_MODE (operands[0]) == SImode 
18828     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18829    && (optimize_size || TARGET_PENTIUM)
18830    && peep2_regno_dead_p (0, FLAGS_REG)"
18831   [(parallel [(set (match_dup 0) (const_int -1))
18832               (clobber (reg:CC FLAGS_REG))])]
18833   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18834                               operands[0]);")
18836 ;; Attempt to convert simple leas to adds. These can be created by
18837 ;; move expanders.
18838 (define_peephole2
18839   [(set (match_operand:SI 0 "register_operand" "")
18840         (plus:SI (match_dup 0)
18841                  (match_operand:SI 1 "nonmemory_operand" "")))]
18842   "peep2_regno_dead_p (0, FLAGS_REG)"
18843   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18844               (clobber (reg:CC FLAGS_REG))])]
18845   "")
18847 (define_peephole2
18848   [(set (match_operand:SI 0 "register_operand" "")
18849         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18850                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18851   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18852   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18853               (clobber (reg:CC FLAGS_REG))])]
18854   "operands[2] = gen_lowpart (SImode, operands[2]);")
18856 (define_peephole2
18857   [(set (match_operand:DI 0 "register_operand" "")
18858         (plus:DI (match_dup 0)
18859                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18860   "peep2_regno_dead_p (0, FLAGS_REG)"
18861   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18862               (clobber (reg:CC FLAGS_REG))])]
18863   "")
18865 (define_peephole2
18866   [(set (match_operand:SI 0 "register_operand" "")
18867         (mult:SI (match_dup 0)
18868                  (match_operand:SI 1 "const_int_operand" "")))]
18869   "exact_log2 (INTVAL (operands[1])) >= 0
18870    && peep2_regno_dead_p (0, FLAGS_REG)"
18871   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18872               (clobber (reg:CC FLAGS_REG))])]
18873   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18875 (define_peephole2
18876   [(set (match_operand:DI 0 "register_operand" "")
18877         (mult:DI (match_dup 0)
18878                  (match_operand:DI 1 "const_int_operand" "")))]
18879   "exact_log2 (INTVAL (operands[1])) >= 0
18880    && peep2_regno_dead_p (0, FLAGS_REG)"
18881   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18882               (clobber (reg:CC FLAGS_REG))])]
18883   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18885 (define_peephole2
18886   [(set (match_operand:SI 0 "register_operand" "")
18887         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18888                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18889   "exact_log2 (INTVAL (operands[2])) >= 0
18890    && REGNO (operands[0]) == REGNO (operands[1])
18891    && peep2_regno_dead_p (0, FLAGS_REG)"
18892   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18893               (clobber (reg:CC FLAGS_REG))])]
18894   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18896 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18897 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18898 ;; many CPUs it is also faster, since special hardware to avoid esp
18899 ;; dependencies is present.
18901 ;; While some of these conversions may be done using splitters, we use peepholes
18902 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18904 ;; Convert prologue esp subtractions to push.
18905 ;; We need register to push.  In order to keep verify_flow_info happy we have
18906 ;; two choices
18907 ;; - use scratch and clobber it in order to avoid dependencies
18908 ;; - use already live register
18909 ;; We can't use the second way right now, since there is no reliable way how to
18910 ;; verify that given register is live.  First choice will also most likely in
18911 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18912 ;; call clobbered registers are dead.  We may want to use base pointer as an
18913 ;; alternative when no register is available later.
18915 (define_peephole2
18916   [(match_scratch:SI 0 "r")
18917    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18918               (clobber (reg:CC FLAGS_REG))
18919               (clobber (mem:BLK (scratch)))])]
18920   "optimize_size || !TARGET_SUB_ESP_4"
18921   [(clobber (match_dup 0))
18922    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18923               (clobber (mem:BLK (scratch)))])])
18925 (define_peephole2
18926   [(match_scratch:SI 0 "r")
18927    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18928               (clobber (reg:CC FLAGS_REG))
18929               (clobber (mem:BLK (scratch)))])]
18930   "optimize_size || !TARGET_SUB_ESP_8"
18931   [(clobber (match_dup 0))
18932    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18933    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18934               (clobber (mem:BLK (scratch)))])])
18936 ;; Convert esp subtractions to push.
18937 (define_peephole2
18938   [(match_scratch:SI 0 "r")
18939    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18940               (clobber (reg:CC FLAGS_REG))])]
18941   "optimize_size || !TARGET_SUB_ESP_4"
18942   [(clobber (match_dup 0))
18943    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18945 (define_peephole2
18946   [(match_scratch:SI 0 "r")
18947    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18948               (clobber (reg:CC FLAGS_REG))])]
18949   "optimize_size || !TARGET_SUB_ESP_8"
18950   [(clobber (match_dup 0))
18951    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18952    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18954 ;; Convert epilogue deallocator to pop.
18955 (define_peephole2
18956   [(match_scratch:SI 0 "r")
18957    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18958               (clobber (reg:CC FLAGS_REG))
18959               (clobber (mem:BLK (scratch)))])]
18960   "optimize_size || !TARGET_ADD_ESP_4"
18961   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18962               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18963               (clobber (mem:BLK (scratch)))])]
18964   "")
18966 ;; Two pops case is tricky, since pop causes dependency on destination register.
18967 ;; We use two registers if available.
18968 (define_peephole2
18969   [(match_scratch:SI 0 "r")
18970    (match_scratch:SI 1 "r")
18971    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18972               (clobber (reg:CC FLAGS_REG))
18973               (clobber (mem:BLK (scratch)))])]
18974   "optimize_size || !TARGET_ADD_ESP_8"
18975   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18976               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18977               (clobber (mem:BLK (scratch)))])
18978    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18979               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18980   "")
18982 (define_peephole2
18983   [(match_scratch:SI 0 "r")
18984    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18985               (clobber (reg:CC FLAGS_REG))
18986               (clobber (mem:BLK (scratch)))])]
18987   "optimize_size"
18988   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18989               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18990               (clobber (mem:BLK (scratch)))])
18991    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18992               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18993   "")
18995 ;; Convert esp additions to pop.
18996 (define_peephole2
18997   [(match_scratch:SI 0 "r")
18998    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18999               (clobber (reg:CC FLAGS_REG))])]
19000   ""
19001   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19002               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19003   "")
19005 ;; Two pops case is tricky, since pop causes dependency on destination register.
19006 ;; We use two registers if available.
19007 (define_peephole2
19008   [(match_scratch:SI 0 "r")
19009    (match_scratch:SI 1 "r")
19010    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19011               (clobber (reg:CC FLAGS_REG))])]
19012   ""
19013   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19014               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19015    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19016               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19017   "")
19019 (define_peephole2
19020   [(match_scratch:SI 0 "r")
19021    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19022               (clobber (reg:CC FLAGS_REG))])]
19023   "optimize_size"
19024   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19025               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19026    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19027               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19028   "")
19030 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19031 ;; required and register dies.  Similarly for 128 to plus -128.
19032 (define_peephole2
19033   [(set (match_operand 0 "flags_reg_operand" "")
19034         (match_operator 1 "compare_operator"
19035           [(match_operand 2 "register_operand" "")
19036            (match_operand 3 "const_int_operand" "")]))]
19037   "(INTVAL (operands[3]) == -1
19038     || INTVAL (operands[3]) == 1
19039     || INTVAL (operands[3]) == 128)
19040    && ix86_match_ccmode (insn, CCGCmode)
19041    && peep2_reg_dead_p (1, operands[2])"
19042   [(parallel [(set (match_dup 0)
19043                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19044               (clobber (match_dup 2))])]
19045   "")
19047 (define_peephole2
19048   [(match_scratch:DI 0 "r")
19049    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19050               (clobber (reg:CC FLAGS_REG))
19051               (clobber (mem:BLK (scratch)))])]
19052   "optimize_size || !TARGET_SUB_ESP_4"
19053   [(clobber (match_dup 0))
19054    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19055               (clobber (mem:BLK (scratch)))])])
19057 (define_peephole2
19058   [(match_scratch:DI 0 "r")
19059    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19060               (clobber (reg:CC FLAGS_REG))
19061               (clobber (mem:BLK (scratch)))])]
19062   "optimize_size || !TARGET_SUB_ESP_8"
19063   [(clobber (match_dup 0))
19064    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19065    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19066               (clobber (mem:BLK (scratch)))])])
19068 ;; Convert esp subtractions to push.
19069 (define_peephole2
19070   [(match_scratch:DI 0 "r")
19071    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19072               (clobber (reg:CC FLAGS_REG))])]
19073   "optimize_size || !TARGET_SUB_ESP_4"
19074   [(clobber (match_dup 0))
19075    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19077 (define_peephole2
19078   [(match_scratch:DI 0 "r")
19079    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19080               (clobber (reg:CC FLAGS_REG))])]
19081   "optimize_size || !TARGET_SUB_ESP_8"
19082   [(clobber (match_dup 0))
19083    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19084    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19086 ;; Convert epilogue deallocator to pop.
19087 (define_peephole2
19088   [(match_scratch:DI 0 "r")
19089    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19090               (clobber (reg:CC FLAGS_REG))
19091               (clobber (mem:BLK (scratch)))])]
19092   "optimize_size || !TARGET_ADD_ESP_4"
19093   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19094               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19095               (clobber (mem:BLK (scratch)))])]
19096   "")
19098 ;; Two pops case is tricky, since pop causes dependency on destination register.
19099 ;; We use two registers if available.
19100 (define_peephole2
19101   [(match_scratch:DI 0 "r")
19102    (match_scratch:DI 1 "r")
19103    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19104               (clobber (reg:CC FLAGS_REG))
19105               (clobber (mem:BLK (scratch)))])]
19106   "optimize_size || !TARGET_ADD_ESP_8"
19107   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19108               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19109               (clobber (mem:BLK (scratch)))])
19110    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19111               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19112   "")
19114 (define_peephole2
19115   [(match_scratch:DI 0 "r")
19116    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19117               (clobber (reg:CC FLAGS_REG))
19118               (clobber (mem:BLK (scratch)))])]
19119   "optimize_size"
19120   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19121               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19122               (clobber (mem:BLK (scratch)))])
19123    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19124               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19125   "")
19127 ;; Convert esp additions to pop.
19128 (define_peephole2
19129   [(match_scratch:DI 0 "r")
19130    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19131               (clobber (reg:CC FLAGS_REG))])]
19132   ""
19133   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19134               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19135   "")
19137 ;; Two pops case is tricky, since pop causes dependency on destination register.
19138 ;; We use two registers if available.
19139 (define_peephole2
19140   [(match_scratch:DI 0 "r")
19141    (match_scratch:DI 1 "r")
19142    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19143               (clobber (reg:CC FLAGS_REG))])]
19144   ""
19145   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19146               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19147    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19148               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19149   "")
19151 (define_peephole2
19152   [(match_scratch:DI 0 "r")
19153    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19154               (clobber (reg:CC FLAGS_REG))])]
19155   "optimize_size"
19156   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19157               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19158    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19159               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19160   "")
19162 ;; Convert imul by three, five and nine into lea
19163 (define_peephole2
19164   [(parallel
19165     [(set (match_operand:SI 0 "register_operand" "")
19166           (mult:SI (match_operand:SI 1 "register_operand" "")
19167                    (match_operand:SI 2 "const_int_operand" "")))
19168      (clobber (reg:CC FLAGS_REG))])]
19169   "INTVAL (operands[2]) == 3
19170    || INTVAL (operands[2]) == 5
19171    || INTVAL (operands[2]) == 9"
19172   [(set (match_dup 0)
19173         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19174                  (match_dup 1)))]
19175   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19177 (define_peephole2
19178   [(parallel
19179     [(set (match_operand:SI 0 "register_operand" "")
19180           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19181                    (match_operand:SI 2 "const_int_operand" "")))
19182      (clobber (reg:CC FLAGS_REG))])]
19183   "!optimize_size 
19184    && (INTVAL (operands[2]) == 3
19185        || INTVAL (operands[2]) == 5
19186        || INTVAL (operands[2]) == 9)"
19187   [(set (match_dup 0) (match_dup 1))
19188    (set (match_dup 0)
19189         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19190                  (match_dup 0)))]
19191   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19193 (define_peephole2
19194   [(parallel
19195     [(set (match_operand:DI 0 "register_operand" "")
19196           (mult:DI (match_operand:DI 1 "register_operand" "")
19197                    (match_operand:DI 2 "const_int_operand" "")))
19198      (clobber (reg:CC FLAGS_REG))])]
19199   "TARGET_64BIT
19200    && (INTVAL (operands[2]) == 3
19201        || INTVAL (operands[2]) == 5
19202        || INTVAL (operands[2]) == 9)"
19203   [(set (match_dup 0)
19204         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19205                  (match_dup 1)))]
19206   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19208 (define_peephole2
19209   [(parallel
19210     [(set (match_operand:DI 0 "register_operand" "")
19211           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19212                    (match_operand:DI 2 "const_int_operand" "")))
19213      (clobber (reg:CC FLAGS_REG))])]
19214   "TARGET_64BIT
19215    && !optimize_size 
19216    && (INTVAL (operands[2]) == 3
19217        || INTVAL (operands[2]) == 5
19218        || INTVAL (operands[2]) == 9)"
19219   [(set (match_dup 0) (match_dup 1))
19220    (set (match_dup 0)
19221         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19222                  (match_dup 0)))]
19223   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19225 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19226 ;; imul $32bit_imm, reg, reg is direct decoded.
19227 (define_peephole2
19228   [(match_scratch:DI 3 "r")
19229    (parallel [(set (match_operand:DI 0 "register_operand" "")
19230                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19231                             (match_operand:DI 2 "immediate_operand" "")))
19232               (clobber (reg:CC FLAGS_REG))])]
19233   "TARGET_K8 && !optimize_size
19234    && (GET_CODE (operands[2]) != CONST_INT
19235        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19236   [(set (match_dup 3) (match_dup 1))
19237    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19238               (clobber (reg:CC FLAGS_REG))])]
19241 (define_peephole2
19242   [(match_scratch:SI 3 "r")
19243    (parallel [(set (match_operand:SI 0 "register_operand" "")
19244                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19245                             (match_operand:SI 2 "immediate_operand" "")))
19246               (clobber (reg:CC FLAGS_REG))])]
19247   "TARGET_K8 && !optimize_size
19248    && (GET_CODE (operands[2]) != CONST_INT
19249        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19250   [(set (match_dup 3) (match_dup 1))
19251    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19252               (clobber (reg:CC FLAGS_REG))])]
19255 (define_peephole2
19256   [(match_scratch:SI 3 "r")
19257    (parallel [(set (match_operand:DI 0 "register_operand" "")
19258                    (zero_extend:DI
19259                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19260                               (match_operand:SI 2 "immediate_operand" ""))))
19261               (clobber (reg:CC FLAGS_REG))])]
19262   "TARGET_K8 && !optimize_size
19263    && (GET_CODE (operands[2]) != CONST_INT
19264        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19265   [(set (match_dup 3) (match_dup 1))
19266    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19267               (clobber (reg:CC FLAGS_REG))])]
19270 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19271 ;; Convert it into imul reg, reg
19272 ;; It would be better to force assembler to encode instruction using long
19273 ;; immediate, but there is apparently no way to do so.
19274 (define_peephole2
19275   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19276                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19277                             (match_operand:DI 2 "const_int_operand" "")))
19278               (clobber (reg:CC FLAGS_REG))])
19279    (match_scratch:DI 3 "r")]
19280   "TARGET_K8 && !optimize_size
19281    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19282   [(set (match_dup 3) (match_dup 2))
19283    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19284               (clobber (reg:CC FLAGS_REG))])]
19286   if (!rtx_equal_p (operands[0], operands[1]))
19287     emit_move_insn (operands[0], operands[1]);
19290 (define_peephole2
19291   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19292                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19293                             (match_operand:SI 2 "const_int_operand" "")))
19294               (clobber (reg:CC FLAGS_REG))])
19295    (match_scratch:SI 3 "r")]
19296   "TARGET_K8 && !optimize_size
19297    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19298   [(set (match_dup 3) (match_dup 2))
19299    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19300               (clobber (reg:CC FLAGS_REG))])]
19302   if (!rtx_equal_p (operands[0], operands[1]))
19303     emit_move_insn (operands[0], operands[1]);
19306 (define_peephole2
19307   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19308                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19309                             (match_operand:HI 2 "immediate_operand" "")))
19310               (clobber (reg:CC FLAGS_REG))])
19311    (match_scratch:HI 3 "r")]
19312   "TARGET_K8 && !optimize_size"
19313   [(set (match_dup 3) (match_dup 2))
19314    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19315               (clobber (reg:CC FLAGS_REG))])]
19317   if (!rtx_equal_p (operands[0], operands[1]))
19318     emit_move_insn (operands[0], operands[1]);
19321 ;; Call-value patterns last so that the wildcard operand does not
19322 ;; disrupt insn-recog's switch tables.
19324 (define_insn "*call_value_pop_0"
19325   [(set (match_operand 0 "" "")
19326         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19327               (match_operand:SI 2 "" "")))
19328    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19329                             (match_operand:SI 3 "immediate_operand" "")))]
19330   "!TARGET_64BIT"
19332   if (SIBLING_CALL_P (insn))
19333     return "jmp\t%P1";
19334   else
19335     return "call\t%P1";
19337   [(set_attr "type" "callv")])
19339 (define_insn "*call_value_pop_1"
19340   [(set (match_operand 0 "" "")
19341         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19342               (match_operand:SI 2 "" "")))
19343    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19344                             (match_operand:SI 3 "immediate_operand" "i")))]
19345   "!TARGET_64BIT"
19347   if (constant_call_address_operand (operands[1], Pmode))
19348     {
19349       if (SIBLING_CALL_P (insn))
19350         return "jmp\t%P1";
19351       else
19352         return "call\t%P1";
19353     }
19354   if (SIBLING_CALL_P (insn))
19355     return "jmp\t%A1";
19356   else
19357     return "call\t%A1";
19359   [(set_attr "type" "callv")])
19361 (define_insn "*call_value_0"
19362   [(set (match_operand 0 "" "")
19363         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19364               (match_operand:SI 2 "" "")))]
19365   "!TARGET_64BIT"
19367   if (SIBLING_CALL_P (insn))
19368     return "jmp\t%P1";
19369   else
19370     return "call\t%P1";
19372   [(set_attr "type" "callv")])
19374 (define_insn "*call_value_0_rex64"
19375   [(set (match_operand 0 "" "")
19376         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19377               (match_operand:DI 2 "const_int_operand" "")))]
19378   "TARGET_64BIT"
19380   if (SIBLING_CALL_P (insn))
19381     return "jmp\t%P1";
19382   else
19383     return "call\t%P1";
19385   [(set_attr "type" "callv")])
19387 (define_insn "*call_value_1"
19388   [(set (match_operand 0 "" "")
19389         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19390               (match_operand:SI 2 "" "")))]
19391   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19393   if (constant_call_address_operand (operands[1], Pmode))
19394     return "call\t%P1";
19395   return "call\t%A1";
19397   [(set_attr "type" "callv")])
19399 (define_insn "*sibcall_value_1"
19400   [(set (match_operand 0 "" "")
19401         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19402               (match_operand:SI 2 "" "")))]
19403   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19405   if (constant_call_address_operand (operands[1], Pmode))
19406     return "jmp\t%P1";
19407   return "jmp\t%A1";
19409   [(set_attr "type" "callv")])
19411 (define_insn "*call_value_1_rex64"
19412   [(set (match_operand 0 "" "")
19413         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19414               (match_operand:DI 2 "" "")))]
19415   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19417   if (constant_call_address_operand (operands[1], Pmode))
19418     return "call\t%P1";
19419   return "call\t%A1";
19421   [(set_attr "type" "callv")])
19423 (define_insn "*sibcall_value_1_rex64"
19424   [(set (match_operand 0 "" "")
19425         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19426               (match_operand:DI 2 "" "")))]
19427   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19428   "jmp\t%P1"
19429   [(set_attr "type" "callv")])
19431 (define_insn "*sibcall_value_1_rex64_v"
19432   [(set (match_operand 0 "" "")
19433         (call (mem:QI (reg:DI 40))
19434               (match_operand:DI 1 "" "")))]
19435   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19436   "jmp\t*%%r11"
19437   [(set_attr "type" "callv")])
19439 (define_insn "trap"
19440   [(trap_if (const_int 1) (const_int 5))]
19441   ""
19442   "int\t$5")
19444 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19445 ;;; for the sake of bounds checking.  By emitting bounds checks as
19446 ;;; conditional traps rather than as conditional jumps around
19447 ;;; unconditional traps we avoid introducing spurious basic-block
19448 ;;; boundaries and facilitate elimination of redundant checks.  In
19449 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19450 ;;; interrupt 5.
19451 ;;; 
19452 ;;; FIXME: Static branch prediction rules for ix86 are such that
19453 ;;; forward conditional branches predict as untaken.  As implemented
19454 ;;; below, pseudo conditional traps violate that rule.  We should use
19455 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19456 ;;; section loaded at the end of the text segment and branch forward
19457 ;;; there on bounds-failure, and then jump back immediately (in case
19458 ;;; the system chooses to ignore bounds violations, or to report
19459 ;;; violations and continue execution).
19461 (define_expand "conditional_trap"
19462   [(trap_if (match_operator 0 "comparison_operator"
19463              [(match_dup 2) (const_int 0)])
19464             (match_operand 1 "const_int_operand" ""))]
19465   ""
19467   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19468                               ix86_expand_compare (GET_CODE (operands[0]),
19469                                                    NULL, NULL),
19470                               operands[1]));
19471   DONE;
19474 (define_insn "*conditional_trap_1"
19475   [(trap_if (match_operator 0 "comparison_operator"
19476              [(reg FLAGS_REG) (const_int 0)])
19477             (match_operand 1 "const_int_operand" ""))]
19478   ""
19480   operands[2] = gen_label_rtx ();
19481   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19482   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19483                              CODE_LABEL_NUMBER (operands[2]));
19484   RET;
19487 (define_expand "sse_prologue_save"
19488   [(parallel [(set (match_operand:BLK 0 "" "")
19489                    (unspec:BLK [(reg:DI 21)
19490                                 (reg:DI 22)
19491                                 (reg:DI 23)
19492                                 (reg:DI 24)
19493                                 (reg:DI 25)
19494                                 (reg:DI 26)
19495                                 (reg:DI 27)
19496                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19497               (use (match_operand:DI 1 "register_operand" ""))
19498               (use (match_operand:DI 2 "immediate_operand" ""))
19499               (use (label_ref:DI (match_operand 3 "" "")))])]
19500   "TARGET_64BIT"
19501   "")
19503 (define_insn "*sse_prologue_save_insn"
19504   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19505                           (match_operand:DI 4 "const_int_operand" "n")))
19506         (unspec:BLK [(reg:DI 21)
19507                      (reg:DI 22)
19508                      (reg:DI 23)
19509                      (reg:DI 24)
19510                      (reg:DI 25)
19511                      (reg:DI 26)
19512                      (reg:DI 27)
19513                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19514    (use (match_operand:DI 1 "register_operand" "r"))
19515    (use (match_operand:DI 2 "const_int_operand" "i"))
19516    (use (label_ref:DI (match_operand 3 "" "X")))]
19517   "TARGET_64BIT
19518    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19519    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19520   "*
19522   int i;
19523   operands[0] = gen_rtx_MEM (Pmode,
19524                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19525   output_asm_insn (\"jmp\\t%A1\", operands);
19526   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19527     {
19528       operands[4] = adjust_address (operands[0], DImode, i*16);
19529       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19530       PUT_MODE (operands[4], TImode);
19531       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19532         output_asm_insn (\"rex\", operands);
19533       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19534     }
19535   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19536                              CODE_LABEL_NUMBER (operands[3]));
19537   RET;
19539   "
19540   [(set_attr "type" "other")
19541    (set_attr "length_immediate" "0")
19542    (set_attr "length_address" "0")
19543    (set_attr "length" "135")
19544    (set_attr "memory" "store")
19545    (set_attr "modrm" "0")
19546    (set_attr "mode" "DI")])
19548 (define_expand "prefetch"
19549   [(prefetch (match_operand 0 "address_operand" "")
19550              (match_operand:SI 1 "const_int_operand" "")
19551              (match_operand:SI 2 "const_int_operand" ""))]
19552   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19554   int rw = INTVAL (operands[1]);
19555   int locality = INTVAL (operands[2]);
19557   gcc_assert (rw == 0 || rw == 1);
19558   gcc_assert (locality >= 0 && locality <= 3);
19559   gcc_assert (GET_MODE (operands[0]) == Pmode
19560               || GET_MODE (operands[0]) == VOIDmode);
19562   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19563      supported by SSE counterpart or the SSE prefetch is not available
19564      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19565      of locality.  */
19566   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19567     operands[2] = GEN_INT (3);
19568   else
19569     operands[1] = const0_rtx;
19572 (define_insn "*prefetch_sse"
19573   [(prefetch (match_operand:SI 0 "address_operand" "p")
19574              (const_int 0)
19575              (match_operand:SI 1 "const_int_operand" ""))]
19576   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19578   static const char * const patterns[4] = {
19579    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19580   };
19582   int locality = INTVAL (operands[1]);
19583   gcc_assert (locality >= 0 && locality <= 3);
19585   return patterns[locality];  
19587   [(set_attr "type" "sse")
19588    (set_attr "memory" "none")])
19590 (define_insn "*prefetch_sse_rex"
19591   [(prefetch (match_operand:DI 0 "address_operand" "p")
19592              (const_int 0)
19593              (match_operand:SI 1 "const_int_operand" ""))]
19594   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19596   static const char * const patterns[4] = {
19597    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19598   };
19600   int locality = INTVAL (operands[1]);
19601   gcc_assert (locality >= 0 && locality <= 3);
19603   return patterns[locality];  
19605   [(set_attr "type" "sse")
19606    (set_attr "memory" "none")])
19608 (define_insn "*prefetch_3dnow"
19609   [(prefetch (match_operand:SI 0 "address_operand" "p")
19610              (match_operand:SI 1 "const_int_operand" "n")
19611              (const_int 3))]
19612   "TARGET_3DNOW && !TARGET_64BIT"
19614   if (INTVAL (operands[1]) == 0)
19615     return "prefetch\t%a0";
19616   else
19617     return "prefetchw\t%a0";
19619   [(set_attr "type" "mmx")
19620    (set_attr "memory" "none")])
19622 (define_insn "*prefetch_3dnow_rex"
19623   [(prefetch (match_operand:DI 0 "address_operand" "p")
19624              (match_operand:SI 1 "const_int_operand" "n")
19625              (const_int 3))]
19626   "TARGET_3DNOW && TARGET_64BIT"
19628   if (INTVAL (operands[1]) == 0)
19629     return "prefetch\t%a0";
19630   else
19631     return "prefetchw\t%a0";
19633   [(set_attr "type" "mmx")
19634    (set_attr "memory" "none")])
19636 (include "sse.md")
19637 (include "mmx.md")
19638 (include "sync.md")