* config/i386/i386.md: Make sure cmpstr peepholes do not
[official-gcc.git] / gcc / config / i386 / i386.md
blobdc3fcee2c6b1b57d3d2f187f6919f3216e962e72
1 ;; GCC machine description for IA-32.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 ;; Free Software Foundation, Inc.
4 ;; Mostly by William Schelter.
5 ;;
6 ;; This file is part of GNU CC.
7 ;;
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA. */
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
29 ;; updates for most instructions.
31 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
32 ;; constraint letters.
34 ;; The special asm out single letter directives following a '%' are:
35 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;;     operands[1].
37 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
38 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
39 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
40 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
41 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
42 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
43 ;; 'J' Print the appropriate jump operand.
45 ;; 'b' Print the QImode name of the register for the indicated operand.
46 ;;     %b0 would print %al if operands[0] is reg 0.
47 ;; 'w' Likewise, print the HImode name of the register.
48 ;; 'k' Likewise, print the SImode name of the register.
49 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
50 ;; 'y' Print "st(0)" instead of "st" as a register.
52 ;; UNSPEC usage:
53 ;; 0  This is a `scas' operation.  The mode of the UNSPEC is always SImode.
54 ;;    operand 0 is the memory address to scan.
55 ;;    operand 1 is a register containing the value to scan for.  The mode
56 ;;       of the scas opcode will be the same as the mode of this operand.
57 ;;    operand 2 is the known alignment of operand 0.
58 ;; 1  This is a `sin' operation.  The mode of the UNSPEC is MODE_FLOAT.
59 ;;    operand 0 is the argument for `sin'.
60 ;; 2  This is a `cos' operation.  The mode of the UNSPEC is MODE_FLOAT.
61 ;;    operand 0 is the argument for `cos'.
62 ;; 3  This is part of a `stack probe' operation.  The mode of the UNSPEC is 
63 ;;    always SImode.  operand 0 is the size of the stack allocation.
64 ;; 4  This is the source of a fake SET of the frame pointer which is used to
65 ;;    prevent insns referencing it being scheduled across the initial
66 ;;    decrement of the stack pointer.
67 ;; 5  This is a `bsf' operation.
68 ;; 6  This is the @GOT offset of a PIC address.
69 ;; 7  This is the @GOTOFF offset of a PIC address.
70 ;; 8  This is a reference to a symbol's @PLT address.
71 ;; 9  This is an `fnstsw' operation.
72 ;; 10 This is a `sahf' operation.
73 ;; 11 This is a `fstcw' operation
74 ;; 12 This is behaviour of add when setting carry flag.
75 ;; 13 This is a `eh_return' placeholder.
77 ;; For SSE/MMX support:
78 ;; 30 This is `fix', guaranteed to be truncating.
79 ;; 31 This is a `emms' operation.
80 ;; 32 This is a `maskmov' operation.
81 ;; 33 This is a `movmsk' operation.
82 ;; 34 This is a `non-temporal' move.
83 ;; 35 This is a `prefetch' operation.
84 ;; 36 This is used to distinguish COMISS from UCOMISS.
85 ;; 37 This is a `ldmxcsr' operation.
86 ;; 38 This is a forced `movaps' instruction (rather than whatever movti does)
87 ;; 39 This is a forced `movups' instruction (rather than whatever movti does)
88 ;; 40 This is a `stmxcsr' operation.
89 ;; 41 This is a `shuffle' operation.
90 ;; 42 This is a `rcp' operation.
91 ;; 43 This is a `rsqsrt' operation.
92 ;; 44 This is a `sfence' operation.
93 ;; 45 This is a noop to prevent excessive combiner cleverness.
95 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
96 ;; from i386.c.
99 ;; Processor type.  This attribute must exactly match the processor_type
100 ;; enumeration in i386.h.
101 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon"
102   (const (symbol_ref "ix86_cpu")))
104 ;; A basic instruction type.  Refinements due to arguments to be
105 ;; provided in other attributes.
106 (define_attr "type"
107   "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx"
108   (const_string "other"))
110 ;; Main data type used by the insn
111 (define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF"
112   (const_string "unknown"))
114 ;; Set for i387 operations.
115 (define_attr "i387" ""
116   (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch")
117     (const_int 1)
118     (const_int 0)))
120 ;; The (bounding maximum) length of an instruction immediate.
121 (define_attr "length_immediate" ""
122   (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
123            (const_int 0)
124          (eq_attr "i387" "1")
125            (const_int 0)
126          (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
127            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
128          (eq_attr "type" "imov,test")
129            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
130          (eq_attr "type" "call")
131            (if_then_else (match_operand 0 "constant_call_address_operand" "")
132              (const_int 4)
133              (const_int 0))
134          (eq_attr "type" "callv")
135            (if_then_else (match_operand 1 "constant_call_address_operand" "")
136              (const_int 4)
137              (const_int 0))
138          (eq_attr "type" "ibr")
139            (if_then_else (and (ge (minus (match_dup 0) (pc))
140                                   (const_int -128))
141                               (lt (minus (match_dup 0) (pc))
142                                   (const_int 124)))
143              (const_int 1)
144              (const_int 4))
145          ]
146          (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
148 ;; The (bounding maximum) length of an instruction address.
149 (define_attr "length_address" ""
150   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
151            (const_int 0)
152          (and (eq_attr "type" "call")
153               (match_operand 1 "constant_call_address_operand" ""))
154              (const_int 0)
155          (and (eq_attr "type" "callv")
156               (match_operand 1 "constant_call_address_operand" ""))
157              (const_int 0)
158          ]
159          (symbol_ref "ix86_attr_length_address_default (insn)")))
161 ;; Set when length prefix is used.
162 (define_attr "prefix_data16" ""
163   (if_then_else (eq_attr "mode" "HI")
164     (const_int 1)
165     (const_int 0)))
167 ;; Set when string REP prefix is used.
168 (define_attr "prefix_rep" "" (const_int 0))
170 ;; Set when 0f opcode prefix is used.
171 (define_attr "prefix_0f" ""
172   (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
173     (const_int 1)
174     (const_int 0)))
176 ;; Set when modrm byte is used.
177 (define_attr "modrm" ""
178   (cond [(eq_attr "type" "str,cld")
179            (const_int 0)
180          (eq_attr "i387" "1")
181            (const_int 0)
182          (and (eq_attr "type" "incdec")
183               (ior (match_operand:SI 1 "register_operand" "")
184                    (match_operand:HI 1 "register_operand" "")))
185            (const_int 0)
186          (and (eq_attr "type" "push")
187               (not (match_operand 1 "memory_operand" "")))
188            (const_int 0)
189          (and (eq_attr "type" "pop")
190               (not (match_operand 0 "memory_operand" "")))
191            (const_int 0)
192          (and (eq_attr "type" "imov")
193               (and (match_operand 0 "register_operand" "")
194                    (match_operand 1 "immediate_operand" "")))
195            (const_int 0)
196          ]
197          (const_int 1)))
199 ;; The (bounding maximum) length of an instruction in bytes.
200 (define_attr "length" ""
201   (cond [(eq_attr "type" "other,multi")
202            (const_int 16)
203          ]
204          (plus (plus (attr "modrm")
205                      (plus (attr "prefix_0f")
206                            (plus (attr "i387")
207                                  (const_int 1))))
208                (plus (attr "prefix_rep")
209                      (plus (attr "prefix_data16")
210                            (plus (attr "length_immediate")
211                                  (attr "length_address")))))))
213 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
214 ;; `store' if there is a simple memory reference therein, or `unknown'
215 ;; if the instruction is complex.
217 (define_attr "memory" "none,load,store,both,unknown"
218   (cond [(eq_attr "type" "other,multi,str")
219            (const_string "unknown")
220          (eq_attr "type" "lea,fcmov,fpspc,cld")
221            (const_string "none")
222          (eq_attr "type" "push")
223            (if_then_else (match_operand 1 "memory_operand" "")
224              (const_string "both")
225              (const_string "store"))
226          (eq_attr "type" "pop,setcc")
227            (if_then_else (match_operand 0 "memory_operand" "")
228              (const_string "both")
229              (const_string "load"))
230          (eq_attr "type" "icmp,test")
231            (if_then_else (ior (match_operand 0 "memory_operand" "")
232                               (match_operand 1 "memory_operand" ""))
233              (const_string "load")
234              (const_string "none"))
235          (eq_attr "type" "ibr")
236            (if_then_else (match_operand 0 "memory_operand" "")
237              (const_string "load")
238              (const_string "none"))
239          (eq_attr "type" "call")
240            (if_then_else (match_operand 0 "constant_call_address_operand" "")
241              (const_string "none")
242              (const_string "load"))
243          (eq_attr "type" "callv")
244            (if_then_else (match_operand 1 "constant_call_address_operand" "")
245              (const_string "none")
246              (const_string "load"))
247          (and (eq_attr "type" "alu1,negnot")
248               (match_operand 1 "memory_operand" ""))
249            (const_string "both")
250          (and (match_operand 0 "memory_operand" "")
251               (match_operand 1 "memory_operand" ""))
252            (const_string "both")
253          (match_operand 0 "memory_operand" "")
254            (const_string "store")
255          (match_operand 1 "memory_operand" "")
256            (const_string "load")
257          (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
258               (match_operand 2 "memory_operand" ""))
259            (const_string "load")
260          (and (eq_attr "type" "icmov")
261               (match_operand 3 "memory_operand" ""))
262            (const_string "load")
263         ]
264         (const_string "none")))
266 ;; Indicates if an instruction has both an immediate and a displacement.
268 (define_attr "imm_disp" "false,true,unknown"
269   (cond [(eq_attr "type" "other,multi")
270            (const_string "unknown")
271          (and (eq_attr "type" "icmp,test,imov")
272               (and (match_operand 0 "memory_displacement_operand" "")
273                    (match_operand 1 "immediate_operand" "")))
274            (const_string "true")
275          (and (eq_attr "type" "alu,ishift,imul,idiv")
276               (and (match_operand 0 "memory_displacement_operand" "")
277                    (match_operand 2 "immediate_operand" "")))
278            (const_string "true")
279         ]
280         (const_string "false")))
282 ;; Indicates if an FP operation has an integer source.
284 (define_attr "fp_int_src" "false,true"
285   (const_string "false"))
287 ;; Describe a user's asm statement.
288 (define_asm_attributes
289   [(set_attr "length" "128")
290    (set_attr "type" "multi")])
292 ;; Pentium Scheduling
294 ;; The Pentium is an in-order core with two integer pipelines.
296 ;; True for insns that behave like prefixed insns on the Pentium.
297 (define_attr "pent_prefix" "false,true"
298   (if_then_else (ior (eq_attr "prefix_0f" "1")
299                      (ior (eq_attr "prefix_data16" "1")
300                           (eq_attr "prefix_rep" "1")))
301     (const_string "true")
302     (const_string "false")))
304 ;; Categorize how an instruction slots.
306 ;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
307 ;; while MMX Pentium can slot it on either U or V.  Model non-MMX Pentium
308 ;; rules, because it results in noticeably better code on non-MMX Pentium
309 ;; and doesn't hurt much on MMX.  (Prefixed instructions are not very
310 ;; common, so the scheduler usualy has a non-prefixed insn to pair).
312 (define_attr "pent_pair" "uv,pu,pv,np"
313   (cond [(eq_attr "imm_disp" "true")
314            (const_string "np")
315          (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
316               (and (eq_attr "type" "pop,push")
317                    (eq_attr "memory" "!both")))
318            (if_then_else (eq_attr "pent_prefix" "true")
319              (const_string "pu")
320              (const_string "uv"))
321          (eq_attr "type" "ibr")
322            (const_string "pv")
323          (and (eq_attr "type" "ishift")
324               (match_operand 2 "const_int_operand" ""))
325            (const_string "pu")
326          (and (eq_attr "type" "call")
327               (match_operand 0 "constant_call_address_operand" ""))
328            (const_string "pv")
329          (and (eq_attr "type" "callv")
330               (match_operand 1 "constant_call_address_operand" ""))
331            (const_string "pv")
332         ]
333         (const_string "np")))
335 ;; Rough readiness numbers.  Fine tuning happens in i386.c.
337 ;; u    describes pipe U
338 ;; v    describes pipe V
339 ;; uv   describes either pipe U or V for those that can issue to either
340 ;; np   describes not paring
341 ;; fpu  describes fpu
342 ;; fpm  describes fp insns of different types are not pipelined.
344 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
346 (define_function_unit "pent_np" 1 0
347   (and (eq_attr "cpu" "pentium")
348        (eq_attr "type" "imul"))
349   11 11)
351 (define_function_unit "pent_mul" 1 1
352   (and (eq_attr "cpu" "pentium")
353        (eq_attr "type" "imul"))
354   11 11)
356 ;; Rep movs takes minimally 12 cycles.
357 (define_function_unit "pent_np" 1 0
358   (and (eq_attr "cpu" "pentium")
359        (eq_attr "type" "str"))
360   12 12)
362 ; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
363 (define_function_unit "pent_np" 1 0
364   (and (eq_attr "cpu" "pentium")
365        (eq_attr "type" "idiv"))
366   46 46)
368 ; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
369 ; 3 cycles for XFmode.  Stores takes 2 cycles for SF/DF and 3 for XF.
370 ; fldz and fld1 takes 2 cycles.  Only reg-reg moves are pairable.
371 ; The integer <-> fp conversion is not modeled correctly. Fild behaves
372 ; like normal fp operation and fist takes 6 cycles.
374 (define_function_unit "fpu" 1 0
375   (and (eq_attr "cpu" "pentium")
376        (and (eq_attr "type" "fmov")
377             (and (eq_attr "memory" "load,store")
378                  (eq_attr "mode" "XF"))))
379   3 3)
381 (define_function_unit "pent_np" 1 0
382   (and (eq_attr "cpu" "pentium")
383        (and (eq_attr "type" "fmov")
384             (and (eq_attr "memory" "load,store")
385                  (eq_attr "mode" "XF"))))
386   3 3)
388 (define_function_unit "fpu" 1 0
389   (and (eq_attr "cpu" "pentium")
390        (and (eq_attr "type" "fmov")
391             (ior (match_operand 1 "immediate_operand" "")
392                  (eq_attr "memory" "store"))))
393   2 2)
395 (define_function_unit "pent_np" 1 0
396   (and (eq_attr "cpu" "pentium")
397        (and (eq_attr "type" "fmov")
398             (ior (match_operand 1 "immediate_operand" "")
399                  (eq_attr "memory" "store"))))
400   2 2)
402 (define_function_unit "pent_np" 1 0
403   (and (eq_attr "cpu" "pentium")
404        (eq_attr "type" "cld"))
405   2 2)
407 (define_function_unit "fpu" 1 0
408   (and (eq_attr "cpu" "pentium")
409        (and (eq_attr "type" "fmov")
410             (eq_attr "memory" "none,load")))
411   1 1)
413 ; Read/Modify/Write instructions usually take 3 cycles.
414 (define_function_unit "pent_u" 1 0
415   (and (eq_attr "cpu" "pentium")
416        (and (eq_attr "type" "alu,alu1,ishift")
417             (and (eq_attr "pent_pair" "pu")
418                  (eq_attr "memory" "both"))))
419   3 3)
421 (define_function_unit "pent_uv" 2 0
422   (and (eq_attr "cpu" "pentium")
423        (and (eq_attr "type" "alu,alu1,ishift")
424             (and (eq_attr "pent_pair" "!np")
425                  (eq_attr "memory" "both"))))
426   3 3)
428 (define_function_unit "pent_np" 1 0
429   (and (eq_attr "cpu" "pentium")
430        (and (eq_attr "type" "alu,alu1,negnot,ishift")
431             (and (eq_attr "pent_pair" "np")
432                  (eq_attr "memory" "both"))))
433   3 3)
435 ; Read/Modify or Modify/Write instructions usually take 2 cycles.
436 (define_function_unit "pent_u" 1 0
437   (and (eq_attr "cpu" "pentium")
438        (and (eq_attr "type" "alu,ishift")
439             (and (eq_attr "pent_pair" "pu")
440                  (eq_attr "memory" "load,store"))))
441   2 2)
443 (define_function_unit "pent_uv" 2 0
444   (and (eq_attr "cpu" "pentium")
445        (and (eq_attr "type" "alu,ishift")
446             (and (eq_attr "pent_pair" "!np")
447                  (eq_attr "memory" "load,store"))))
448   2 2)
450 (define_function_unit "pent_np" 1 0
451   (and (eq_attr "cpu" "pentium")
452        (and (eq_attr "type" "alu,ishift")
453             (and (eq_attr "pent_pair" "np")
454                  (eq_attr "memory" "load,store"))))
455   2 2)
457 ; Insns w/o memory operands and move instructions usually take one cycle.
458 (define_function_unit "pent_u" 1 0
459   (and (eq_attr "cpu" "pentium")
460        (eq_attr "pent_pair" "pu"))
461   1 1)
463 (define_function_unit "pent_v" 1 0
464   (and (eq_attr "cpu" "pentium")
465        (eq_attr "pent_pair" "pv"))
466   1 1)
468 (define_function_unit "pent_uv" 2 0
469   (and (eq_attr "cpu" "pentium")
470        (eq_attr "pent_pair" "!np"))
471   1 1)
473 (define_function_unit "pent_np" 1 0
474   (and (eq_attr "cpu" "pentium")
475        (eq_attr "pent_pair" "np"))
476   1 1)
478 ; Pairable insns only conflict with other non-pairable insns.
479 (define_function_unit "pent_np" 1 0
480   (and (eq_attr "cpu" "pentium")
481        (and (eq_attr "type" "alu,alu1,ishift")
482             (and (eq_attr "pent_pair" "!np")
483                  (eq_attr "memory" "both"))))
484   3 3
485   [(eq_attr "pent_pair" "np")])
487 (define_function_unit "pent_np" 1 0
488   (and (eq_attr "cpu" "pentium")
489        (and (eq_attr "type" "alu,alu1,ishift")
490             (and (eq_attr "pent_pair" "!np")
491                  (eq_attr "memory" "load,store"))))
492   2 2
493   [(eq_attr "pent_pair" "np")])
495 (define_function_unit "pent_np" 1 0
496   (and (eq_attr "cpu" "pentium")
497        (eq_attr "pent_pair" "!np"))
498   1 1
499   [(eq_attr "pent_pair" "np")])
501 ; Floating point instructions usually blocks cycle longer when combined with
502 ; integer instructions, because of the inpaired fxch instruction.
503 (define_function_unit "pent_np" 1 0
504   (and (eq_attr "cpu" "pentium")
505        (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp"))
506   2 2
507   [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp")])
509 (define_function_unit "fpu" 1 0
510   (and (eq_attr "cpu" "pentium")
511        (eq_attr "type" "fcmp,fxch,fsgn"))
512   1 1)
514 ; Addition takes 3 cycles; assume other random cruft does as well.
515 ; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
516 (define_function_unit "fpu" 1 0
517   (and (eq_attr "cpu" "pentium")
518        (eq_attr "type" "fop,fop1"))
519   3 1)
521 ; Multiplication takes 3 cycles and is only half pipelined.
522 (define_function_unit "fpu" 1 0
523   (and (eq_attr "cpu" "pentium")
524        (eq_attr "type" "fmul"))
525   3 1)
527 (define_function_unit "pent_mul" 1 1
528   (and (eq_attr "cpu" "pentium")
529        (eq_attr "type" "fmul"))
530   2 2)
532 ; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles. 
533 ; They can overlap with integer insns.  Only the last two cycles can overlap
534 ; with other fp insns.  Only fsin/fcos can overlap with multiplies.
535 ; Only last two cycles of fsin/fcos can overlap with other instructions.
536 (define_function_unit "fpu" 1 0
537   (and (eq_attr "cpu" "pentium")
538        (eq_attr "type" "fdiv"))
539   39 37)
541 (define_function_unit "pent_mul" 1 1
542   (and (eq_attr "cpu" "pentium")
543        (eq_attr "type" "fdiv"))
544   39 39)
546 (define_function_unit "fpu" 1 0
547   (and (eq_attr "cpu" "pentium")
548        (eq_attr "type" "fpspc"))
549   70 68)
551 (define_function_unit "pent_mul" 1 1
552   (and (eq_attr "cpu" "pentium")
553        (eq_attr "type" "fpspc"))
554   70 70)
556 ;; Pentium Pro/PII Scheduling
558 ;; The PPro has an out-of-order core, but the instruction decoders are
559 ;; naturally in-order and asymmetric.  We get best performance by scheduling
560 ;; for the decoders, for in doing so we give the oo execution unit the 
561 ;; most choices.
563 ;; Categorize how many uops an ia32 instruction evaluates to:
564 ;;   one --  an instruction with 1 uop can be decoded by any of the
565 ;;           three decoders.
566 ;;   few --  an instruction with 1 to 4 uops can be decoded only by 
567 ;;           decoder 0.
568 ;;   many -- a complex instruction may take an unspecified number of
569 ;;           cycles to decode in decoder 0.
571 (define_attr "ppro_uops" "one,few,many"
572   (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
573            (const_string "many")
574          (eq_attr "type" "icmov,fcmov,str,cld")
575            (const_string "few")
576          (eq_attr "type" "imov")
577            (if_then_else (eq_attr "memory" "store,both")
578              (const_string "few")
579              (const_string "one"))
580          (eq_attr "memory" "!none")
581            (const_string "few")
582         ]
583         (const_string "one")))
585 ;; Rough readiness numbers.  Fine tuning happens in i386.c.
587 ;; p0   describes port 0.
588 ;; p01  describes ports 0 and 1 as a pair; alu insns can issue to either.
589 ;; p2   describes port 2 for loads.
590 ;; p34  describes ports 3 and 4 for stores.
591 ;; fpu  describes the fpu accessed via port 0. 
592 ;;      ??? It is less than clear if there are separate fadd and fmul units
593 ;;      that could operate in parallel.
595 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
597 (define_function_unit "ppro_p0" 1 0
598   (and (eq_attr "cpu" "pentiumpro")
599        (eq_attr "type" "ishift,lea,ibr,cld"))
600   1 1)
602 (define_function_unit "ppro_p0" 1 0
603   (and (eq_attr "cpu" "pentiumpro")
604        (eq_attr "type" "imul"))
605   4 1)
607 ;; ??? Does the divider lock out the pipe while it works,
608 ;; or is there a disconnected unit?
609 (define_function_unit "ppro_p0" 1 0
610   (and (eq_attr "cpu" "pentiumpro")
611        (eq_attr "type" "idiv"))
612   17 17)
614 (define_function_unit "ppro_p0" 1 0
615   (and (eq_attr "cpu" "pentiumpro")
616        (eq_attr "type" "fop,fop1,fsgn"))
617   3 1)
619 (define_function_unit "ppro_p0" 1 0
620   (and (eq_attr "cpu" "pentiumpro")
621        (eq_attr "type" "fcmov"))
622   2 1)
624 (define_function_unit "ppro_p0" 1 0
625   (and (eq_attr "cpu" "pentiumpro")
626        (eq_attr "type" "fcmp"))
627   1 1)
629 (define_function_unit "ppro_p0" 1 0
630   (and (eq_attr "cpu" "pentiumpro")
631        (eq_attr "type" "fmov"))
632   1 1)
634 (define_function_unit "ppro_p0" 1 0
635   (and (eq_attr "cpu" "pentiumpro")
636        (eq_attr "type" "fmul"))
637   5 1)
639 (define_function_unit "ppro_p0" 1 0
640   (and (eq_attr "cpu" "pentiumpro")
641        (eq_attr "type" "fdiv,fpspc"))
642   56 1)
644 (define_function_unit "ppro_p01" 2 0
645   (and (eq_attr "cpu" "pentiumpro")
646        (eq_attr "type" "!imov,fmov"))
647   1 1)
649 (define_function_unit "ppro_p01" 2 0
650   (and (and (eq_attr "cpu" "pentiumpro")
651             (eq_attr "type" "imov,fmov"))
652        (eq_attr "memory" "none"))
653   1 1)
655 (define_function_unit "ppro_p2" 1 0
656   (and (eq_attr "cpu" "pentiumpro")
657        (ior (eq_attr "type" "pop")
658             (eq_attr "memory" "load,both")))
659   3 1)
661 (define_function_unit "ppro_p34" 1 0
662   (and (eq_attr "cpu" "pentiumpro")
663        (ior (eq_attr "type" "push")
664             (eq_attr "memory" "store,both")))
665   1 1)
667 (define_function_unit "fpu" 1 0
668   (and (eq_attr "cpu" "pentiumpro")
669        (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov"))
670   1 1)
672 (define_function_unit "fpu" 1 0
673   (and (eq_attr "cpu" "pentiumpro")
674        (eq_attr "type" "fmul"))
675   5 2)
677 (define_function_unit "fpu" 1 0
678   (and (eq_attr "cpu" "pentiumpro")
679        (eq_attr "type" "fdiv,fpspc"))
680   56 56)
682 ;; imul uses the fpu.  ??? does it have the same throughput as fmul?
683 (define_function_unit "fpu" 1 0
684   (and (eq_attr "cpu" "pentiumpro")
685        (eq_attr "type" "imul"))
686   4 1)
688 ;; AMD K6/K6-2 Scheduling
690 ;; The K6 has similar architecture to PPro.  Important difference is, that
691 ;; there are only two decoders and they seems to be much slower than execution
692 ;; units.  So we have to pay much more attention to proper decoding for
693 ;; schedulers.  We share most of scheduler code for PPro in i386.c
695 ;; The fp unit is not pipelined and do one operation per two cycles including
696 ;; the FXCH.
698 ;; alu    describes both ALU units (ALU-X and ALU-Y).
699 ;; alux   describes X alu unit
700 ;; fpu    describes FPU unit
701 ;; load   describes load unit.
702 ;; branch describes branch unit.
703 ;; store  decsribes store unit.  This unit is not modelled completely and only
704 ;;        used to model lea operation.  Otherwise it lie outside of the critical
705 ;;        path.
707 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
709 ;; The decoder specification is in the PPro section above!
711 ;; Shift instructions and certain arithmetic are issued only to X pipe.
712 (define_function_unit "k6_alux" 1 0
713   (and (eq_attr "cpu" "k6")
714        (eq_attr "type" "ishift,alu1,negnot,cld"))
715   1 1)
717 ;; The QI mode arithmetic is issued to X pipe only.
718 (define_function_unit "k6_alux" 1 0
719   (and (eq_attr "cpu" "k6")
720        (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
721             (match_operand:QI 0 "general_operand" "")))
722   1 1)
724 (define_function_unit "k6_alu" 2 0
725   (and (eq_attr "cpu" "k6")
726        (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
727   1 1)
729 (define_function_unit "k6_alu" 2 0
730   (and (eq_attr "cpu" "k6")
731        (and (eq_attr "type" "imov")
732             (eq_attr "memory" "none")))
733   1 1)
735 (define_function_unit "k6_branch" 1 0
736   (and (eq_attr "cpu" "k6")
737        (eq_attr "type" "call,callv,ibr"))
738   1 1)
740 ;; Load unit have two cycle latency, but we take care for it in adjust_cost
741 (define_function_unit "k6_load" 1 0
742   (and (eq_attr "cpu" "k6")
743        (ior (eq_attr "type" "pop")
744             (eq_attr "memory" "load,both")))
745   1 1)
747 (define_function_unit "k6_load" 1 0
748   (and (eq_attr "cpu" "k6")
749        (and (eq_attr "type" "str")
750             (eq_attr "memory" "load,both")))
751   10 10)
753 ;; Lea have two instructions, so latency is probably 2
754 (define_function_unit "k6_store" 1 0
755   (and (eq_attr "cpu" "k6")
756        (eq_attr "type" "lea"))
757   2 1)
759 (define_function_unit "k6_store" 1 0
760   (and (eq_attr "cpu" "k6")
761        (eq_attr "type" "str"))
762   10 10)
764 (define_function_unit "k6_store" 1 0
765   (and (eq_attr "cpu" "k6")
766        (ior (eq_attr "type" "push")
767             (eq_attr "memory" "store,both")))
768   1 1)
770 (define_function_unit "k6_fpu" 1 1
771   (and (eq_attr "cpu" "k6")
772        (eq_attr "type" "fop,fop1,fmov,fcmp"))
773   2 2)
775 (define_function_unit "k6_fpu" 1 1
776   (and (eq_attr "cpu" "k6")
777        (eq_attr "type" "fmul"))
778   2 2)
780 ;; ??? Guess
781 (define_function_unit "k6_fpu" 1 1
782   (and (eq_attr "cpu" "k6")
783        (eq_attr "type" "fdiv,fpspc"))
784   56 56)
786 (define_function_unit "k6_alu" 2 0
787   (and (eq_attr "cpu" "k6")
788        (eq_attr "type" "imul"))
789   2 2)
791 (define_function_unit "k6_alux" 1 0
792   (and (eq_attr "cpu" "k6")
793        (eq_attr "type" "imul"))
794   2 2)
796 ;; ??? Guess
797 (define_function_unit "k6_alu" 2 0
798   (and (eq_attr "cpu" "k6")
799        (eq_attr "type" "idiv"))
800   17 17)
802 (define_function_unit "k6_alux" 1 0
803   (and (eq_attr "cpu" "k6")
804        (eq_attr "type" "idiv"))
805   17 17)
807 ;; AMD Athlon Scheduling
809 ;; The Athlon does contain three pipelined FP units, three integer units and
810 ;; three address generation units. 
812 ;; The predecode logic is determining boundaries of instructions in the 64
813 ;; byte cache line. So the cache line straddling problem of K6 might be issue
814 ;; here as well, but it is not noted in the documentation.
816 ;; Three DirectPath instructions decoders and only one VectorPath decoder
817 ;; is available. They can decode three DirectPath instructions or one VectorPath
818 ;; instruction per cycle.
819 ;; Decoded macro instructions are then passed to 72 entry instruction control
820 ;; unit, that passes
821 ;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
823 ;; The load/store queue unit is not attached to the schedulers but
824 ;; communicates with all the execution units seperately instead.
826 (define_attr "athlon_decode" "direct,vector"
827   (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
828            (const_string "vector")
829          (and (eq_attr "type" "push")
830               (match_operand 1 "memory_operand" ""))
831            (const_string "vector")
832          (and (eq_attr "type" "fmov")
833               (and (eq_attr "memory" "load,store")
834                    (eq_attr "mode" "XF")))
835            (const_string "vector")]
836         (const_string "direct")))
838 (define_function_unit "athlon_vectordec" 1 0
839   (and (eq_attr "cpu" "athlon")
840        (eq_attr "athlon_decode" "vector"))
841   1 1)
843 (define_function_unit "athlon_directdec" 3 0
844   (and (eq_attr "cpu" "athlon")
845        (eq_attr "athlon_decode" "direct"))
846   1 1)
848 (define_function_unit "athlon_vectordec" 1 0
849   (and (eq_attr "cpu" "athlon")
850        (eq_attr "athlon_decode" "direct"))
851   1 1 [(eq_attr "athlon_decode" "vector")])
853 (define_function_unit "athlon_ieu" 3 0
854   (and (eq_attr "cpu" "athlon")
855        (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
856   1 1)
858 (define_function_unit "athlon_ieu" 3 0
859   (and (eq_attr "cpu" "athlon")
860        (eq_attr "type" "str"))
861   15 15)
863 (define_function_unit "athlon_ieu" 3 0
864   (and (eq_attr "cpu" "athlon")
865        (eq_attr "type" "imul"))
866   5 0)
868 (define_function_unit "athlon_ieu" 3 0
869   (and (eq_attr "cpu" "athlon")
870        (eq_attr "type" "idiv"))
871   42 0)
873 (define_function_unit "athlon_muldiv" 1 0
874   (and (eq_attr "cpu" "athlon")
875        (eq_attr "type" "imul"))
876   5 0)
878 (define_function_unit "athlon_muldiv" 1 0
879   (and (eq_attr "cpu" "athlon")
880        (eq_attr "type" "idiv"))
881   42 42)
883 (define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
884   (cond [(eq_attr "type" "fop,fop1,fcmp")
885            (const_string "add")
886          (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
887            (const_string "mul")
888          (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
889            (const_string "store")
890          (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
891            (const_string "any")
892          (and (eq_attr "type" "fmov")
893               (ior (match_operand:SI 1 "register_operand" "")
894                    (match_operand 1 "immediate_operand" "")))
895            (const_string "store")
896          (eq_attr "type" "fmov")
897            (const_string "muladd")]
898         (const_string "none")))
900 ;; We use latencies 1 for definitions.  This is OK to model colisions
901 ;; in execution units.  The real latencies are modeled in the "fp" pipeline.
903 ;; fsin, fcos: 96-192
904 ;; fsincos: 107-211
905 ;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
906 (define_function_unit "athlon_fp" 3 0
907   (and (eq_attr "cpu" "athlon")
908        (eq_attr "type" "fpspc"))
909   100 1)
911 ;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
912 (define_function_unit "athlon_fp" 3 0
913   (and (eq_attr "cpu" "athlon")
914        (eq_attr "type" "fdiv"))
915   24 1)
917 (define_function_unit "athlon_fp" 3 0
918   (and (eq_attr "cpu" "athlon")
919        (eq_attr "type" "fop,fop1,fmul"))
920   4 1)
922 ;; XFmode loads are slow.
923 ;; XFmode store is slow too (8 cycles), but we don't need to model it, because
924 ;; there are no dependent instructions.
926 (define_function_unit "athlon_fp" 3 0
927   (and (eq_attr "cpu" "athlon")
928        (and (eq_attr "type" "fmov")
929             (and (eq_attr "memory" "load")
930                  (eq_attr "mode" "XF"))))
931   10 1)
933 (define_function_unit "athlon_fp" 3 0
934   (and (eq_attr "cpu" "athlon")
935        (eq_attr "type" "fmov,fsgn"))
936   2 1)
938 ;; fcmp and ftst instructions
939 (define_function_unit "athlon_fp" 3 0
940   (and (eq_attr "cpu" "athlon")
941        (and (eq_attr "type" "fcmp")
942             (eq_attr "athlon_decode" "direct")))
943   3 1)
945 ;; fcmpi instructions.
946 (define_function_unit "athlon_fp" 3 0
947   (and (eq_attr "cpu" "athlon")
948        (and (eq_attr "type" "fcmp")
949             (eq_attr "athlon_decode" "vector")))
950   3 1)
952 (define_function_unit "athlon_fp" 3 0
953   (and (eq_attr "cpu" "athlon")
954        (eq_attr "type" "fcmov"))
955   7 1)
957 (define_function_unit "athlon_fp_mul" 1 0
958   (and (eq_attr "cpu" "athlon")
959        (eq_attr "athlon_fpunits" "mul"))
960   1 1)
962 (define_function_unit "athlon_fp_add" 1 0
963   (and (eq_attr "cpu" "athlon")
964        (eq_attr "athlon_fpunits" "add"))
965   1 1)
967 (define_function_unit "athlon_fp_muladd" 2 0
968   (and (eq_attr "cpu" "athlon")
969        (eq_attr "athlon_fpunits" "muladd,mul,add"))
970   1 1)
972 (define_function_unit "athlon_fp_store" 1 0
973   (and (eq_attr "cpu" "athlon")
974        (eq_attr "athlon_fpunits" "store"))
975   1 1)
977 ;; We don't need to model the Adress Generation Unit, since we don't model
978 ;; the re-order buffer yet and thus we never schedule more than three operations
979 ;; at time.  Later we may want to experiment with MD_SCHED macros modeling the
980 ;; decoders independently on the functional units.
982 ;(define_function_unit "athlon_agu" 3 0
983 ;  (and (eq_attr "cpu" "athlon")
984 ;       (and (eq_attr "memory" "!none")
985 ;            (eq_attr "athlon_fpunits" "none")))
986 ;  1 1)
988 ;; Model load unit to avoid too long sequences of loads.  We don't need to
989 ;; model store queue, since it is hardly going to be bottleneck.
991 (define_function_unit "athlon_load" 2 0
992   (and (eq_attr "cpu" "athlon")
993        (eq_attr "memory" "load,both"))
994   1 1)
997 ;; Compare instructions.
999 ;; All compare insns have expanders that save the operands away without
1000 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
1001 ;; after the cmp) will actually emit the cmpM.
1003 (define_expand "cmpdi"
1004   [(set (reg:CC 17)
1005         (compare:CC (match_operand:DI 0 "general_operand" "")
1006                     (match_operand:DI 1 "general_operand" "")))]
1007   ""
1008   "
1010   if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1011       || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1012     operands[0] = force_reg (DImode, operands[0]);
1013   ix86_compare_op0 = operands[0];
1014   ix86_compare_op1 = operands[1];
1015   DONE;
1018 (define_expand "cmpsi"
1019   [(set (reg:CC 17)
1020         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
1021                     (match_operand:SI 1 "general_operand" "")))]
1022   ""
1023   "
1025   if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1026       || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1027     operands[0] = force_reg (SImode, operands[0]);
1028   ix86_compare_op0 = operands[0];
1029   ix86_compare_op1 = operands[1];
1030   DONE;
1033 (define_expand "cmphi"
1034   [(set (reg:CC 17)
1035         (compare:CC (match_operand:HI 0 "general_operand" "")
1036                     (match_operand:HI 1 "general_operand" "")))]
1037   ""
1038   "
1040   if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1041       || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1042     operands[0] = force_reg (HImode, operands[0]);
1043   ix86_compare_op0 = operands[0];
1044   ix86_compare_op1 = operands[1];
1045   DONE;
1048 (define_expand "cmpqi"
1049   [(set (reg:CC 17)
1050         (compare:CC (match_operand:QI 0 "general_operand" "")
1051                     (match_operand:QI 1 "general_operand" "")))]
1052   "TARGET_QIMODE_MATH"
1053   "
1055   if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1056       || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1057     operands[0] = force_reg (QImode, operands[0]);
1058   ix86_compare_op0 = operands[0];
1059   ix86_compare_op1 = operands[1];
1060   DONE;
1063 (define_insn "*cmpsi_ccno_1"
1064   [(set (reg 17)
1065         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1066                  (match_operand:SI 1 "const0_operand" "n,n")))]
1067   "ix86_match_ccmode (insn, CCNOmode)"
1068   "@
1069    test{l}\\t{%0, %0|%0, %0}
1070    cmp{l}\\t{%1, %0|%0, %1}"
1071   [(set_attr "type" "test,icmp")
1072    (set_attr "length_immediate" "0,1")
1073    (set_attr "mode" "SI")])
1075 (define_insn "*cmpsi_minus_1"
1076   [(set (reg 17)
1077         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1078                            (match_operand:SI 1 "general_operand" "ri,mr"))
1079                  (const_int 0)))]
1080   "ix86_match_ccmode (insn, CCGOCmode)"
1081   "cmp{l}\\t{%1, %0|%0, %1}"
1082   [(set_attr "type" "icmp")
1083    (set_attr "mode" "SI")])
1085 (define_expand "cmpsi_1"
1086   [(set (reg:CC 17)
1087         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1088                     (match_operand:SI 1 "general_operand" "ri,mr")))]
1089   ""
1090   "")
1092 (define_insn "*cmpsi_1_insn"
1093   [(set (reg 17)
1094         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1095                  (match_operand:SI 1 "general_operand" "ri,mr")))]
1096   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1097     && ix86_match_ccmode (insn, CCmode)"
1098   "cmp{l}\\t{%1, %0|%0, %1}"
1099   [(set_attr "type" "icmp")
1100    (set_attr "mode" "SI")])
1102 (define_insn "*cmphi_ccno_1"
1103   [(set (reg 17)
1104         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1105                  (match_operand:HI 1 "const0_operand" "n,n")))]
1106   "ix86_match_ccmode (insn, CCNOmode)"
1107   "@
1108    test{w}\\t{%0, %0|%0, %0}
1109    cmp{w}\\t{%1, %0|%0, %1}"
1110   [(set_attr "type" "test,icmp")
1111    (set_attr "length_immediate" "0,1")
1112    (set_attr "mode" "HI")])
1114 (define_insn "*cmphi_minus_1"
1115   [(set (reg 17)
1116         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1117                            (match_operand:HI 1 "general_operand" "ri,mr"))
1118                  (const_int 0)))]
1119   "ix86_match_ccmode (insn, CCGOCmode)"
1120   "cmp{w}\\t{%1, %0|%0, %1}"
1121   [(set_attr "type" "icmp")
1122    (set_attr "mode" "HI")])
1124 (define_insn "*cmphi_1"
1125   [(set (reg 17)
1126         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1127                  (match_operand:HI 1 "general_operand" "ri,mr")))]
1128   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1129    && ix86_match_ccmode (insn, CCmode)"
1130   "cmp{w}\\t{%1, %0|%0, %1}"
1131   [(set_attr "type" "icmp")
1132    (set_attr "mode" "HI")])
1134 (define_insn "*cmpqi_ccno_1"
1135   [(set (reg 17)
1136         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1137                  (match_operand:QI 1 "const0_operand" "n,n")))]
1138   "ix86_match_ccmode (insn, CCNOmode)"
1139   "@
1140    test{b}\\t{%0, %0|%0, %0}
1141    cmp{b}\\t{$0, %0|%0, 0}"
1142   [(set_attr "type" "test,icmp")
1143    (set_attr "length_immediate" "0,1")
1144    (set_attr "mode" "QI")])
1146 (define_insn "*cmpqi_1"
1147   [(set (reg 17)
1148         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1149                  (match_operand:QI 1 "general_operand" "qi,mq")))]
1150   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1151     && ix86_match_ccmode (insn, CCmode)"
1152   "cmp{b}\\t{%1, %0|%0, %1}"
1153   [(set_attr "type" "icmp")
1154    (set_attr "mode" "QI")])
1156 (define_insn "*cmpqi_minus_1"
1157   [(set (reg 17)
1158         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1159                            (match_operand:QI 1 "general_operand" "qi,mq"))
1160                  (const_int 0)))]
1161   "ix86_match_ccmode (insn, CCGOCmode)"
1162   "cmp{b}\\t{%1, %0|%0, %1}"
1163   [(set_attr "type" "icmp")
1164    (set_attr "mode" "QI")])
1166 (define_insn "*cmpqi_ext_1"
1167   [(set (reg 17)
1168         (compare
1169           (match_operand:QI 0 "general_operand" "qm")
1170           (subreg:QI
1171             (zero_extract:SI
1172               (match_operand 1 "ext_register_operand" "q")
1173               (const_int 8)
1174               (const_int 8)) 0)))]
1175   "ix86_match_ccmode (insn, CCmode)"
1176   "cmp{b}\\t{%h1, %0|%0, %h1}"
1177   [(set_attr "type" "icmp")
1178    (set_attr "mode" "QI")])
1180 (define_insn "*cmpqi_ext_2"
1181   [(set (reg 17)
1182         (compare
1183           (subreg:QI
1184             (zero_extract:SI
1185               (match_operand 0 "ext_register_operand" "q")
1186               (const_int 8)
1187               (const_int 8)) 0)
1188           (match_operand:QI 1 "const0_operand" "n")))]
1189   "ix86_match_ccmode (insn, CCNOmode)"
1190   "test{b}\\t%h0, %h0"
1191   [(set_attr "type" "test")
1192    (set_attr "length_immediate" "0")
1193    (set_attr "mode" "QI")])
1195 (define_expand "cmpqi_ext_3"
1196   [(set (reg:CC 17)
1197         (compare:CC
1198           (subreg:QI
1199             (zero_extract:SI
1200               (match_operand 0 "ext_register_operand" "q")
1201               (const_int 8)
1202               (const_int 8)) 0)
1203           (match_operand:QI 1 "general_operand" "qmn")))]
1204   ""
1205   "")
1207 (define_insn "cmpqi_ext_3_insn"
1208   [(set (reg 17)
1209         (compare
1210           (subreg:QI
1211             (zero_extract:SI
1212               (match_operand 0 "ext_register_operand" "q")
1213               (const_int 8)
1214               (const_int 8)) 0)
1215           (match_operand:QI 1 "general_operand" "qmn")))]
1216   "ix86_match_ccmode (insn, CCmode)"
1217   "cmp{b}\\t{%1, %h0|%h0, %1}"
1218   [(set_attr "type" "icmp")
1219    (set_attr "mode" "QI")])
1221 (define_insn "*cmpqi_ext_4"
1222   [(set (reg 17)
1223         (compare
1224           (subreg:QI
1225             (zero_extract:SI
1226               (match_operand 0 "ext_register_operand" "q")
1227               (const_int 8)
1228               (const_int 8)) 0)
1229           (subreg:QI
1230             (zero_extract:SI
1231               (match_operand 1 "ext_register_operand" "q")
1232               (const_int 8)
1233               (const_int 8)) 0)))]
1234   "ix86_match_ccmode (insn, CCmode)"
1235   "cmp{b}\\t{%h1, %h0|%h0, %h1}"
1236   [(set_attr "type" "icmp")
1237    (set_attr "mode" "QI")])
1239 ;; These implement float point compares.
1240 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1241 ;; which would allow mix and match FP modes on the compares.  Which is what
1242 ;; the old patterns did, but with many more of them.
1244 (define_expand "cmpxf"
1245   [(set (reg:CC 17)
1246         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1247                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1248   "TARGET_80387"
1249   "
1251   ix86_compare_op0 = operands[0];
1252   ix86_compare_op1 = operands[1];
1253   DONE;
1256 (define_expand "cmptf"
1257   [(set (reg:CC 17)
1258         (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
1259                     (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
1260   "TARGET_80387"
1261   "
1263   ix86_compare_op0 = operands[0];
1264   ix86_compare_op1 = operands[1];
1265   DONE;
1268 (define_expand "cmpdf"
1269   [(set (reg:CC 17)
1270         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1271                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
1272   "TARGET_80387"
1273   "
1275   ix86_compare_op0 = operands[0];
1276   ix86_compare_op1 = operands[1];
1277   DONE;
1280 (define_expand "cmpsf"
1281   [(set (reg:CC 17)
1282         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1283                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
1284   "TARGET_80387"
1285   "
1287   ix86_compare_op0 = operands[0];
1288   ix86_compare_op1 = operands[1];
1289   DONE;
1292 ;; FP compares, step 1:
1293 ;; Set the FP condition codes.
1295 ;; CCFPmode     compare with exceptions
1296 ;; CCFPUmode    compare with no exceptions
1298 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1299 ;; and that fp moves clobber the condition codes, and that there is
1300 ;; currently no way to describe this fact to reg-stack.  So there are
1301 ;; no splitters yet for this.
1303 ;; %%% YIKES!  This scheme does not retain a strong connection between 
1304 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1305 ;; work!  Only allow tos/mem with tos in op 0.
1307 ;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
1308 ;; things aren't as bad as they sound...
1310 (define_insn "*cmpfp_0"
1311   [(set (match_operand:HI 0 "register_operand" "=a")
1312         (unspec:HI
1313           [(compare:CCFP (match_operand 1 "register_operand" "f")
1314                          (match_operand 2 "const0_operand" "X"))] 9))]
1315   "TARGET_80387
1316    && FLOAT_MODE_P (GET_MODE (operands[1]))
1317    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1318   "*
1320   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1321     return \"ftst\;fnstsw\\t%0\;fstp\\t%y0\";
1322   else
1323     return \"ftst\;fnstsw\\t%0\";
1325   [(set_attr "type" "multi")
1326    (set_attr "mode" "unknownfp")])
1328 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1329 ;; used to manage the reg stack popping would not be preserved.
1331 (define_insn "*cmpfp_2_sf"
1332   [(set (reg:CCFP 18)
1333         (compare:CCFP
1334           (match_operand:SF 0 "register_operand" "f")
1335           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1336   "TARGET_80387"
1337   "* return output_fp_compare (insn, operands, 0, 0);"
1338   [(set_attr "type" "fcmp")
1339    (set_attr "mode" "SF")])
1341 (define_insn "*cmpfp_2_sf_1"
1342   [(set (match_operand:HI 0 "register_operand" "=a")
1343         (unspec:HI
1344           [(compare:CCFP
1345              (match_operand:SF 1 "register_operand" "f")
1346              (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
1347   "TARGET_80387"
1348   "* return output_fp_compare (insn, operands, 2, 0);"
1349   [(set_attr "type" "fcmp")
1350    (set_attr "mode" "SF")])
1352 (define_insn "*cmpfp_2_df"
1353   [(set (reg:CCFP 18)
1354         (compare:CCFP
1355           (match_operand:DF 0 "register_operand" "f")
1356           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1357   "TARGET_80387"
1358   "* return output_fp_compare (insn, operands, 0, 0);"
1359   [(set_attr "type" "fcmp")
1360    (set_attr "mode" "DF")])
1362 (define_insn "*cmpfp_2_df_1"
1363   [(set (match_operand:HI 0 "register_operand" "=a")
1364         (unspec:HI
1365           [(compare:CCFP
1366              (match_operand:DF 1 "register_operand" "f")
1367              (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
1368   "TARGET_80387"
1369   "* return output_fp_compare (insn, operands, 2, 0);"
1370   [(set_attr "type" "multi")
1371    (set_attr "mode" "DF")])
1373 (define_insn "*cmpfp_2_xf"
1374   [(set (reg:CCFP 18)
1375         (compare:CCFP
1376           (match_operand:XF 0 "register_operand" "f")
1377           (match_operand:XF 1 "register_operand" "f")))]
1378   "TARGET_80387"
1379   "* return output_fp_compare (insn, operands, 0, 0);"
1380   [(set_attr "type" "fcmp")
1381    (set_attr "mode" "XF")])
1383 (define_insn "*cmpfp_2_tf"
1384   [(set (reg:CCFP 18)
1385         (compare:CCFP
1386           (match_operand:TF 0 "register_operand" "f")
1387           (match_operand:TF 1 "register_operand" "f")))]
1388   "TARGET_80387"
1389   "* return output_fp_compare (insn, operands, 0, 0);"
1390   [(set_attr "type" "fcmp")
1391    (set_attr "mode" "XF")])
1393 (define_insn "*cmpfp_2_xf_1"
1394   [(set (match_operand:HI 0 "register_operand" "=a")
1395         (unspec:HI
1396           [(compare:CCFP
1397              (match_operand:XF 1 "register_operand" "f")
1398              (match_operand:XF 2 "register_operand" "f"))] 9))]
1399   "TARGET_80387"
1400   "* return output_fp_compare (insn, operands, 2, 0);"
1401   [(set_attr "type" "multi")
1402    (set_attr "mode" "XF")])
1404 (define_insn "*cmpfp_2_tf_1"
1405   [(set (match_operand:HI 0 "register_operand" "=a")
1406         (unspec:HI
1407           [(compare:CCFP
1408              (match_operand:TF 1 "register_operand" "f")
1409              (match_operand:TF 2 "register_operand" "f"))] 9))]
1410   "TARGET_80387"
1411   "* return output_fp_compare (insn, operands, 2, 0);"
1412   [(set_attr "type" "multi")
1413    (set_attr "mode" "XF")])
1415 (define_insn "*cmpfp_2u"
1416   [(set (reg:CCFPU 18)
1417         (compare:CCFPU
1418           (match_operand 0 "register_operand" "f")
1419           (match_operand 1 "register_operand" "f")))]
1420   "TARGET_80387
1421    && FLOAT_MODE_P (GET_MODE (operands[0]))
1422    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1423   "* return output_fp_compare (insn, operands, 0, 1);"
1424   [(set_attr "type" "fcmp")
1425    (set_attr "mode" "unknownfp")])
1427 (define_insn "*cmpfp_2u_1"
1428   [(set (match_operand:HI 0 "register_operand" "=a")
1429         (unspec:HI
1430           [(compare:CCFPU
1431              (match_operand 1 "register_operand" "f")
1432              (match_operand 2 "register_operand" "f"))] 9))]
1433   "TARGET_80387
1434    && FLOAT_MODE_P (GET_MODE (operands[1]))
1435    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1436   "* return output_fp_compare (insn, operands, 2, 1);"
1437   [(set_attr "type" "multi")
1438    (set_attr "mode" "unknownfp")])
1440 ;; Patterns to match the SImode-in-memory ficom instructions.
1442 ;; %%% Play games with accepting gp registers, as otherwise we have to
1443 ;; force them to memory during rtl generation, which is no good.  We
1444 ;; can get rid of this once we teach reload to do memory input reloads 
1445 ;; via pushes.
1447 (define_insn "*ficom_1"
1448   [(set (reg:CCFP 18)
1449         (compare:CCFP
1450           (match_operand 0 "register_operand" "f,f")
1451           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1452   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1453    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1454   "#")
1456 ;; Split the not-really-implemented gp register case into a
1457 ;; push-op-pop sequence.
1459 ;; %%% This is most efficient, but am I gonna get in trouble
1460 ;; for separating cc0_setter and cc0_user?
1462 (define_split
1463   [(set (reg:CCFP 18)
1464         (compare:CCFP
1465           (match_operand:SF 0 "register_operand" "")
1466           (float (match_operand:SI 1 "register_operand" ""))))]
1467   "0 && TARGET_80387 && reload_completed"
1468   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1469    (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1470    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1471               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1472   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1473    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1475 ;; FP compares, step 2
1476 ;; Move the fpsw to ax.
1478 (define_insn "x86_fnstsw_1"
1479   [(set (match_operand:HI 0 "register_operand" "=a")
1480         (unspec:HI [(reg 18)] 9))]
1481   "TARGET_80387"
1482   "fnstsw\\t%0"
1483   [(set_attr "length" "2")
1484    (set_attr "mode" "SI")
1485    (set_attr "i387" "1")
1486    (set_attr "ppro_uops" "few")])
1488 ;; FP compares, step 3
1489 ;; Get ax into flags, general case.
1491 (define_insn "x86_sahf_1"
1492   [(set (reg:CC 17)
1493         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1494   ""
1495   "sahf"
1496   [(set_attr "length" "1")
1497    (set_attr "athlon_decode" "vector")
1498    (set_attr "mode" "SI")
1499    (set_attr "ppro_uops" "one")])
1501 ;; Pentium Pro can do steps 1 through 3 in one go.
1503 (define_insn "*cmpfp_i"
1504   [(set (reg:CCFP 17)
1505         (compare:CCFP (match_operand 0 "register_operand" "f")
1506                       (match_operand 1 "register_operand" "f")))]
1507   "TARGET_80387 && TARGET_CMOVE
1508    && FLOAT_MODE_P (GET_MODE (operands[0]))
1509    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1510   "* return output_fp_compare (insn, operands, 1, 0);"
1511   [(set_attr "type" "fcmp")
1512    (set_attr "mode" "unknownfp")
1513    (set_attr "athlon_decode" "vector")])
1515 (define_insn "*cmpfp_iu"
1516   [(set (reg:CCFPU 17)
1517         (compare:CCFPU (match_operand 0 "register_operand" "f")
1518                        (match_operand 1 "register_operand" "f")))]
1519   "TARGET_80387 && TARGET_CMOVE
1520    && FLOAT_MODE_P (GET_MODE (operands[0]))
1521    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1522   "* return output_fp_compare (insn, operands, 1, 1);"
1523   [(set_attr "type" "fcmp")
1524    (set_attr "mode" "unknownfp")
1525    (set_attr "athlon_decode" "vector")])
1527 ;; Move instructions.
1529 ;; General case of fullword move.
1531 (define_expand "movsi"
1532   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1533         (match_operand:SI 1 "general_operand" ""))]
1534   ""
1535   "ix86_expand_move (SImode, operands); DONE;")
1537 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1538 ;; general_operand.
1540 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1541 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1542 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1543 ;; targets without our curiosities, and it is just as easy to represent
1544 ;; this differently.
1546 (define_insn "*pushsi2"
1547   [(set (match_operand:SI 0 "push_operand" "=<")
1548         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1549   ""
1550   "push{l}\\t%1"
1551   [(set_attr "type" "push")
1552    (set_attr "mode" "SI")])
1554 (define_insn "*pushsi2_prologue"
1555   [(set (match_operand:SI 0 "push_operand" "=<")
1556         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1557    (set (reg:SI 6) (reg:SI 6))]
1558   ""
1559   "push{l}\\t%1"
1560   [(set_attr "type" "push")
1561    (set_attr "mode" "SI")])
1563 (define_insn "*popsi1_epilogue"
1564   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1565         (mem:SI (reg:SI 7)))
1566    (set (reg:SI 7)
1567         (plus:SI (reg:SI 7) (const_int 4)))
1568    (set (reg:SI 6) (reg:SI 6))]
1569   ""
1570   "pop{l}\\t%0"
1571   [(set_attr "type" "pop")
1572    (set_attr "mode" "SI")])
1574 (define_insn "popsi1"
1575   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1576         (mem:SI (reg:SI 7)))
1577    (set (reg:SI 7)
1578         (plus:SI (reg:SI 7) (const_int 4)))]
1579   ""
1580   "pop{l}\\t%0"
1581   [(set_attr "type" "pop")
1582    (set_attr "mode" "SI")])
1584 (define_insn "*movsi_xor"
1585   [(set (match_operand:SI 0 "register_operand" "=r")
1586         (match_operand:SI 1 "const0_operand" "i"))
1587    (clobber (reg:CC 17))]
1588   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1589   "xor{l}\\t{%0, %0|%0, %0}"
1590   [(set_attr "type" "alu1")
1591    (set_attr "mode" "SI")
1592    (set_attr "length_immediate" "0")])
1594 (define_insn "*movsi_or"
1595   [(set (match_operand:SI 0 "register_operand" "=r")
1596         (match_operand:SI 1 "immediate_operand" "i"))
1597    (clobber (reg:CC 17))]
1598   "reload_completed && GET_CODE (operands[1]) == CONST_INT
1599    && INTVAL (operands[1]) == -1
1600    && (TARGET_PENTIUM || optimize_size)"
1601   "*
1603   operands[1] = constm1_rtx;
1604   return \"or{l}\\t{%1, %0|%0, %1}\";
1606   [(set_attr "type" "alu1")
1607    (set_attr "mode" "SI")
1608    (set_attr "length_immediate" "1")])
1610 (define_insn "*movsi_1"
1611   [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!r")
1612         (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,r,*y"))]
1613   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1614   "*
1616   switch (get_attr_type (insn))
1617     {
1618     case TYPE_MMX:
1619       return \"movd\\t{%1, %0|%0, %1}\";
1621     case TYPE_LEA:
1622       return \"lea{l}\\t{%1, %0|%0, %1}\";
1624     default:
1625       if (flag_pic && SYMBOLIC_CONST (operands[1]))
1626         abort();
1627       return \"mov{l}\\t{%1, %0|%0, %1}\";
1628     }
1630   [(set (attr "type")
1631      (cond [(ior (match_operand:SI 0 "mmx_reg_operand" "")
1632                  (match_operand:SI 1 "mmx_reg_operand" ""))
1633               (const_string "mmx")
1634             (and (ne (symbol_ref "flag_pic") (const_int 0))
1635                  (match_operand:SI 1 "symbolic_operand" ""))
1636               (const_string "lea")
1637            ]
1638            (const_string "imov")))
1639    (set_attr "modrm" "0,*,0,*,*,*")
1640    (set_attr "mode" "SI")])
1642 (define_insn "*swapsi"
1643   [(set (match_operand:SI 0 "register_operand" "+r")
1644         (match_operand:SI 1 "register_operand" "+r"))
1645    (set (match_dup 1)
1646         (match_dup 0))]
1647   ""
1648   "xchg{l}\\t%1, %0"
1649   [(set_attr "type" "imov")
1650    (set_attr "pent_pair" "np")
1651    (set_attr "athlon_decode" "vector")
1652    (set_attr "mode" "SI")
1653    (set_attr "modrm" "0")
1654    (set_attr "ppro_uops" "few")])
1656 (define_expand "movhi"
1657   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1658         (match_operand:HI 1 "general_operand" ""))]
1659   ""
1660   "ix86_expand_move (HImode, operands); DONE;")
1662 (define_insn "*pushhi2"
1663   [(set (match_operand:HI 0 "push_operand" "=<,<")
1664         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1665   ""
1666   "@
1667    push{w}\\t{|WORD PTR }%1
1668    push{w}\\t%1"
1669   [(set_attr "type" "push")
1670    (set_attr "mode" "HI")])
1672 (define_insn "*pophi1"
1673   [(set (match_operand:HI 0 "nonimmediate_operand" "=r*m")
1674         (mem:HI (reg:SI 7)))
1675    (set (reg:SI 7)
1676         (plus:SI (reg:SI 7) (const_int 2)))]
1677   ""
1678   "pop{w}\\t%0"
1679   [(set_attr "type" "pop")
1680    (set_attr "mode" "HI")])
1682 (define_insn "*movhi_1"
1683   [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
1684         (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1685   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1686   "*
1688   switch (get_attr_type (insn))
1689     {
1690     case TYPE_IMOVX:
1691       /* movzwl is faster than movw on p2 due to partial word stalls,
1692          though not as fast as an aligned movl.  */
1693       return \"movz{wl|x}\\t{%1, %k0|%k0, %1}\";
1694     default:
1695       if (get_attr_mode (insn) == MODE_SI)
1696         return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1697       else
1698         return \"mov{w}\\t{%1, %0|%0, %1}\";
1699     }
1701   [(set (attr "type")
1702      (cond [(and (eq_attr "alternative" "0,1")
1703                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1704                           (const_int 0))
1705                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1706                           (const_int 0))))
1707               (const_string "imov")
1708             (and (eq_attr "alternative" "2,3,4")
1709                  (match_operand:HI 1 "aligned_operand" ""))
1710               (const_string "imov")
1711             (and (ne (symbol_ref "TARGET_MOVX")
1712                      (const_int 0))
1713                  (eq_attr "alternative" "0,1,3,4"))
1714               (const_string "imovx")
1715            ]
1716            (const_string "imov")))
1717     (set (attr "mode")
1718       (cond [(eq_attr "type" "imovx")
1719                (const_string "SI")
1720              (and (eq_attr "alternative" "2,3,4")
1721                   (match_operand:HI 1 "aligned_operand" ""))
1722                (const_string "SI")
1723              (and (eq_attr "alternative" "0,1")
1724                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1725                            (const_int 0))
1726                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1727                            (const_int 0))))
1728                (const_string "SI")
1729             ]
1730             (const_string "HI")))
1731    (set_attr "modrm" "0,*,*,0,*,*")])
1733 (define_insn "*swaphi_1"
1734   [(set (match_operand:HI 0 "register_operand" "+r")
1735         (match_operand:HI 1 "register_operand" "+r"))
1736    (set (match_dup 1)
1737         (match_dup 0))]
1738   "TARGET_PARTIAL_REG_STALL"
1739   "xchg{w}\\t%1, %0"
1740   [(set_attr "type" "imov")
1741    (set_attr "pent_pair" "np")
1742    (set_attr "mode" "HI")
1743    (set_attr "modrm" "0")
1744    (set_attr "ppro_uops" "few")])
1746 (define_insn "*swaphi_2"
1747   [(set (match_operand:HI 0 "register_operand" "+r")
1748         (match_operand:HI 1 "register_operand" "+r"))
1749    (set (match_dup 1)
1750         (match_dup 0))]
1751   "! TARGET_PARTIAL_REG_STALL"
1752   "xchg{l}\\t%k1, %k0"
1753   [(set_attr "type" "imov")
1754    (set_attr "pent_pair" "np")
1755    (set_attr "mode" "SI")
1756    (set_attr "modrm" "0")
1757    (set_attr "ppro_uops" "few")])
1759 (define_expand "movstricthi"
1760   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1761         (match_operand:HI 1 "general_operand" ""))]
1762   "! TARGET_PARTIAL_REG_STALL"
1763   "
1765   /* Don't generate memory->memory moves, go through a register */
1766   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1767     operands[1] = force_reg (HImode, operands[1]);
1770 (define_insn "*movstricthi_1"
1771   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1772         (match_operand:HI 1 "general_operand" "rn,m"))]
1773   "! TARGET_PARTIAL_REG_STALL
1774    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1775   "mov{w}\\t{%1, %0|%0, %1}"
1776   [(set_attr "type" "imov")
1777    (set_attr "mode" "HI")])
1779 (define_insn "*movstricthi_xor"
1780   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1781         (match_operand:HI 1 "const0_operand" "i"))
1782    (clobber (reg:CC 17))]
1783   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1784   "xor{w}\\t{%0, %0|%0, %0}"
1785   [(set_attr "type" "alu1")
1786    (set_attr "mode" "HI")
1787    (set_attr "length_immediate" "0")])
1789 (define_expand "movqi"
1790   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1791         (match_operand:QI 1 "general_operand" ""))]
1792   ""
1793   "ix86_expand_move (QImode, operands); DONE;")
1795 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1796 ;; "push a byte".  But actually we use pushw, which has the effect
1797 ;; of rounding the amount pushed up to a halfword.
1799 (define_insn "*pushqi2"
1800   [(set (match_operand:QI 0 "push_operand" "=<,<")
1801         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1802   ""
1803   "@
1804    push{w}\\t{|word ptr }%1
1805    push{w}\\t%w1"
1806   [(set_attr "type" "push")
1807    (set_attr "mode" "HI")])
1809 (define_insn "*popqi1"
1810   [(set (match_operand:QI 0 "nonimmediate_operand" "=r*m")
1811         (mem:QI (reg:SI 7)))
1812    (set (reg:SI 7)
1813         (plus:SI (reg:SI 7) (const_int 2)))]
1814   ""
1815   "pop{w}\\t%0"
1816   [(set_attr "type" "pop")
1817    (set_attr "mode" "HI")])
1819 ;; Situation is quite tricky about when to choose full sized (SImode) move
1820 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1821 ;; partial register dependency machines (such as AMD Athlon), where QImode
1822 ;; moves issue extra dependency and for partial register stalls machines
1823 ;; that don't use QImode patterns (and QImode move cause stall on the next
1824 ;; instruction).
1826 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1827 ;; register stall machines with, where we use QImode instructions, since
1828 ;; partial register stall can be caused there.  Then we use movzx.
1829 (define_insn "*movqi_1"
1830   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1831         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1832   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1833   "*
1835   switch (get_attr_type (insn))
1836     {
1837     case TYPE_IMOVX:
1838       if (!QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1839         abort ();
1840       return \"movz{bl|x}\\t{%1, %k0|%k0, %1}\";
1841     default:
1842       if (get_attr_mode (insn) == MODE_SI)
1843         return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1844       else
1845         return \"mov{b}\\t{%1, %0|%0, %1}\";
1846     }
1848   [(set (attr "type")
1849      (cond [(and (eq_attr "alternative" "3")
1850                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1851                           (const_int 0))
1852                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1853                           (const_int 0))))
1854               (const_string "imov")
1855             (eq_attr "alternative" "3,5")
1856               (const_string "imovx")
1857             (and (ne (symbol_ref "TARGET_MOVX")
1858                      (const_int 0))
1859                  (eq_attr "alternative" "2"))
1860               (const_string "imovx")
1861            ]
1862            (const_string "imov")))
1863    (set (attr "mode")
1864       (cond [(eq_attr "alternative" "3,4,5")
1865                (const_string "SI")
1866              (eq_attr "alternative" "6")
1867                (const_string "QI")
1868              (eq_attr "type" "imovx")
1869                (const_string "SI")
1870              (and (eq_attr "type" "imov")
1871                   (and (eq_attr "alternative" "0,1,2")
1872                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1873                            (const_int 0))))
1874                (const_string "SI")
1875              ;; Avoid partial register stalls when not using QImode arithmetic
1876              (and (eq_attr "type" "imov")
1877                   (and (eq_attr "alternative" "0,1,2")
1878                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1879                                 (const_int 0))
1880                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1881                                 (const_int 0)))))
1882                (const_string "SI")
1883            ]
1884            (const_string "QI")))])
1886 (define_expand "reload_outqi"
1887   [(parallel [(match_operand:QI 0 "" "=m")
1888               (match_operand:QI 1 "register_operand" "r")
1889               (match_operand:QI 2 "register_operand" "=&q")])]
1890   ""
1891   "
1893   rtx op0, op1, op2;
1894   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1896   if (reg_overlap_mentioned_p (op2, op0))
1897     abort ();
1898   if (! q_regs_operand (op1, QImode))
1899     {
1900       emit_insn (gen_movqi (op2, op1));
1901       op1 = op2;
1902     }
1903   emit_insn (gen_movqi (op0, op1));
1904   DONE;
1907 (define_insn "*swapqi"
1908   [(set (match_operand:QI 0 "register_operand" "+r")
1909         (match_operand:QI 1 "register_operand" "+r"))
1910    (set (match_dup 1)
1911         (match_dup 0))]
1912   ""
1913   "xchg{b}\\t%1, %0"
1914   [(set_attr "type" "imov")
1915    (set_attr "pent_pair" "np")
1916    (set_attr "mode" "QI")
1917    (set_attr "modrm" "0")
1918    (set_attr "ppro_uops" "few")])
1920 (define_expand "movstrictqi"
1921   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1922         (match_operand:QI 1 "general_operand" ""))]
1923   "! TARGET_PARTIAL_REG_STALL"
1924   "
1926   /* Don't generate memory->memory moves, go through a register */
1927   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1928     operands[1] = force_reg (QImode, operands[1]);
1931 (define_insn "*movstrictqi_1"
1932   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1933         (match_operand:QI 1 "general_operand" "*qn,m"))]
1934   "! TARGET_PARTIAL_REG_STALL
1935    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1936   "mov{b}\\t{%1, %0|%0, %1}"
1937   [(set_attr "type" "imov")
1938    (set_attr "mode" "QI")])
1940 (define_insn "*movstrictqi_xor"
1941   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1942         (match_operand:QI 1 "const0_operand" "i"))
1943    (clobber (reg:CC 17))]
1944   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1945   "xor{b}\\t{%0, %0|%0, %0}"
1946   [(set_attr "type" "alu1")
1947    (set_attr "mode" "QI")
1948    (set_attr "length_immediate" "0")])
1950 (define_insn "*movsi_extv_1"
1951   [(set (match_operand:SI 0 "register_operand" "=r")
1952         (sign_extract:SI (match_operand:SI 1 "register_operand" "q")
1953                          (const_int 8)
1954                          (const_int 8)))]
1955   ""
1956   "movs{bl|x}\\t{%h1, %0|%0, %h1}"
1957   [(set_attr "type" "imovx")
1958    (set_attr "mode" "SI")])
1960 (define_insn "*movhi_extv_1"
1961   [(set (match_operand:HI 0 "register_operand" "=r")
1962         (sign_extract:HI (match_operand:SI 1 "register_operand" "q")
1963                          (const_int 8)
1964                          (const_int 8)))]
1965   ""
1966   "movs{bl|x}\\t{%h1, %k0|%k0, %h1}"
1967   [(set_attr "type" "imovx")
1968    (set_attr "mode" "SI")])
1970 (define_insn "*movqi_extv_1"
1971   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
1972         (sign_extract:QI (match_operand:SI 1 "register_operand" "q,q")
1973                          (const_int 8)
1974                          (const_int 8)))]
1975   ""
1976   "*
1978   switch (get_attr_type (insn))
1979     {
1980     case TYPE_IMOVX:
1981       return \"movs{bl|x}\\t{%h1, %k0|%k0, %h1}\";
1982     default:
1983       return \"mov{b}\\t{%h1, %0|%0, %h1}\";
1984     }
1986   [(set (attr "type")
1987      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1988                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1989                              (ne (symbol_ref "TARGET_MOVX")
1990                                  (const_int 0))))
1991         (const_string "imovx")
1992         (const_string "imov")))
1993    (set (attr "mode")
1994      (if_then_else (eq_attr "type" "imovx")
1995         (const_string "SI")
1996         (const_string "QI")))])
1998 (define_insn "*movsi_extzv_1"
1999   [(set (match_operand:SI 0 "register_operand" "=r")
2000         (zero_extract:SI (match_operand 1 "ext_register_operand" "q")
2001                          (const_int 8)
2002                          (const_int 8)))]
2003   ""
2004   "movz{bl|x}\\t{%h1, %0|%0, %h1}"
2005   [(set_attr "type" "imovx")
2006    (set_attr "mode" "SI")])
2008 (define_insn "*movqi_extzv_1"
2009   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
2010         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "q,q")
2011                                     (const_int 8)
2012                                     (const_int 8)) 0))]
2013   ""
2014   "*
2016   switch (get_attr_type (insn))
2017     {
2018     case TYPE_IMOVX:
2019       return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\";
2020     default:
2021       return \"mov{b}\\t{%h1, %0|%0, %h1}\";
2022     }
2024   [(set (attr "type")
2025      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2026                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2027                              (ne (symbol_ref "TARGET_MOVX")
2028                                  (const_int 0))))
2029         (const_string "imovx")
2030         (const_string "imov")))
2031    (set (attr "mode")
2032      (if_then_else (eq_attr "type" "imovx")
2033         (const_string "SI")
2034         (const_string "QI")))])
2036 (define_insn "*movsi_insv_1"
2037   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
2038                          (const_int 8)
2039                          (const_int 8))
2040         (match_operand:SI 1 "nonimmediate_operand" "qm"))]
2041   ""
2042   "mov{b}\\t{%b1, %h0|%h0, %b1}"
2043   [(set_attr "type" "imov")
2044    (set_attr "mode" "QI")])
2046 (define_insn "*movqi_insv_2"
2047   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
2048                          (const_int 8)
2049                          (const_int 8))
2050         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "q")
2051                              (const_int 8))
2052                 (const_int 255)))]
2053   ""
2054   "mov{b}\\t{%h1, %h0|%h0, %h1}"
2055   [(set_attr "type" "imov")
2056    (set_attr "mode" "QI")])
2058 (define_expand "movdi"
2059   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2060         (match_operand:DI 1 "general_operand" ""))]
2061   ""
2062   "ix86_expand_move (DImode, operands); DONE;")
2064 (define_insn "*pushdi"
2065   [(set (match_operand:DI 0 "push_operand" "=<")
2066         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2067   ""
2068   "#")
2070 (define_insn "*movdi_2"
2071   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y")
2072         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m"))]
2073   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
2074   "@
2075    #
2076    #
2077    movq\\t{%1, %0|%0, %1}
2078    movq\\t{%1, %0|%0, %1}"
2079   [(set_attr "type" "*,*,mmx,mmx")])
2081 (define_split
2082   [(set (match_operand:DI 0 "push_operand" "")
2083         (match_operand:DI 1 "general_operand" ""))]
2084   "reload_completed && ! MMX_REG_P (operands[1])"
2085   [(const_int 0)]
2086   "if (!ix86_split_long_move (operands)) abort (); DONE;")
2088 ;; %%% This multiword shite has got to go.
2089 (define_split
2090   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2091         (match_operand:DI 1 "general_operand" ""))]
2092   "reload_completed && ! MMX_REG_P (operands[0]) && ! MMX_REG_P (operands[1])"
2093   [(set (match_dup 2) (match_dup 5))
2094    (set (match_dup 3) (match_dup 6))]
2095   "if (ix86_split_long_move (operands)) DONE;")
2096   
2097 (define_expand "movsf"
2098   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2099         (match_operand:SF 1 "general_operand" ""))]
2100   ""
2101   "ix86_expand_move (SFmode, operands); DONE;")
2103 (define_insn "*pushsf"
2104   [(set (match_operand:SF 0 "push_operand" "=<,<")
2105         (match_operand:SF 1 "general_no_elim_operand" "f#r,rFm#f"))]
2106   ""
2107   "*
2109   switch (which_alternative)
2110     {
2111     case 0:
2112       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2113       operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2114       operands[2] = stack_pointer_rtx;
2115       operands[3] = GEN_INT (4);
2116       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2117         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2118       else
2119         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2121     case 1:
2122       return \"push{l}\\t%1\";
2124     default:
2125       abort ();
2126     }
2128   [(set_attr "type" "multi,push")
2129    (set_attr "mode" "SF,SI")])
2131 (define_split
2132   [(set (match_operand:SF 0 "push_operand" "")
2133         (match_operand:SF 1 "memory_operand" ""))]
2134   "reload_completed
2135    && GET_CODE (operands[1]) == MEM
2136    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2137    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2138   [(set (match_dup 0)
2139         (match_dup 1))]
2140   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2143 ;; %%% Kill this when call knows how to work this out.
2144 (define_split
2145   [(set (match_operand:SF 0 "push_operand" "")
2146         (match_operand:SF 1 "register_operand" ""))]
2147   "FP_REGNO_P (REGNO (operands[1]))"
2148   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2149    (set (mem:SF (reg:SI 7)) (match_dup 1))])
2151 (define_insn "*movsf_1"
2152   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,m")
2153         (match_operand:SF 1 "general_operand" "fm#r,f#r,G,rmF#f,Fr#f"))]
2154   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2155    && (reload_in_progress || reload_completed
2156        || GET_CODE (operands[1]) != CONST_DOUBLE
2157        || memory_operand (operands[0], SFmode))" 
2158   "*
2160   switch (which_alternative)
2161     {
2162     case 0:
2163       if (REG_P (operands[1])
2164           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2165         return \"fstp\\t%y0\";
2166       else if (STACK_TOP_P (operands[0]))
2167         return \"fld%z1\\t%y1\";
2168       else
2169         return \"fst\\t%y0\";
2171     case 1:
2172       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2173         return \"fstp%z0\\t%y0\";
2174       else
2175         return \"fst%z0\\t%y0\";
2177     case 2:
2178       switch (standard_80387_constant_p (operands[1]))
2179         {
2180         case 1:
2181           return \"fldz\";
2182         case 2:
2183           return \"fld1\";
2184         }
2185       abort();
2187     case 3:
2188     case 4:
2189       return \"mov{l}\\t{%1, %0|%0, %1}\";
2191     default:
2192       abort();
2193     }
2195   [(set_attr "type" "fmov,fmov,fmov,imov,imov")
2196    (set_attr "mode" "SF,SF,SF,SI,SI")])
2198 (define_split
2199   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2200         (match_operand:SF 1 "memory_operand" ""))]
2201   "reload_completed
2202    && GET_CODE (operands[1]) == MEM
2203    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2204    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2205    && (!(FP_REG_P (operands[0]) || 
2206          (GET_CODE (operands[0]) == SUBREG
2207           && FP_REG_P (SUBREG_REG (operands[0]))))
2208        || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
2209   [(set (match_dup 0)
2210         (match_dup 1))]
2211   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2213 (define_insn "*swapsf"
2214   [(set (match_operand:SF 0 "register_operand" "+f")
2215         (match_operand:SF 1 "register_operand" "+f"))
2216    (set (match_dup 1)
2217         (match_dup 0))]
2218   ""
2219   "*
2221   if (STACK_TOP_P (operands[0]))
2222     return \"fxch\\t%1\";
2223   else
2224     return \"fxch\\t%0\";
2226   [(set_attr "type" "fxch")
2227    (set_attr "mode" "SF")])
2229 (define_expand "movdf"
2230   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2231         (match_operand:DF 1 "general_operand" ""))]
2232   ""
2233   "ix86_expand_move (DFmode, operands); DONE;")
2235 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2236 ;; Size of pushdf using integer insturctions is 2+2*memory operand size
2237 ;; On the average, pushdf using integers can be still shorter.  Allow this
2238 ;; pattern for optimize_size too.
2240 (define_insn "*pushdf_nointeger"
2241   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2242         (match_operand:DF 1 "general_no_elim_operand" "f,Fo#f,*r#f"))]
2243   "!TARGET_INTEGER_DFMODE_MOVES"
2244   "*
2246   switch (which_alternative)
2247     {
2248     case 0:
2249       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2250       operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2251       operands[2] = stack_pointer_rtx;
2252       operands[3] = GEN_INT (8);
2253       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2254         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2255       else
2256         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2258     case 1:
2259     case 2:
2260       return \"#\";
2262     default:
2263       abort ();
2264     }
2266   [(set_attr "type" "multi")
2267    (set_attr "mode" "DF,SI,SI")])
2269 (define_insn "*pushdf_integer"
2270   [(set (match_operand:DF 0 "push_operand" "=<,<")
2271         (match_operand:DF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2272   "TARGET_INTEGER_DFMODE_MOVES"
2273   "*
2275   switch (which_alternative)
2276     {
2277     case 0:
2278       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2279       operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2280       operands[2] = stack_pointer_rtx;
2281       operands[3] = GEN_INT (8);
2282       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2283         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2284       else
2285         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2287     case 1:
2288       return \"#\";
2290     default:
2291       abort ();
2292     }
2294   [(set_attr "type" "multi")
2295    (set_attr "mode" "DF,SI")])
2297 ;; %%% Kill this when call knows how to work this out.
2298 (define_split
2299   [(set (match_operand:DF 0 "push_operand" "")
2300         (match_operand:DF 1 "register_operand" ""))]
2301   "reload_completed && FP_REGNO_P (REGNO (operands[1]))"
2302   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2303    (set (mem:DF (reg:SI 7)) (match_dup 1))]
2304   "")
2306 (define_split
2307   [(set (match_operand:DF 0 "push_operand" "")
2308         (match_operand:DF 1 "general_operand" ""))]
2309   "reload_completed"
2310   [(const_int 0)]
2311   "if (!ix86_split_long_move (operands)) abort (); DONE;")
2313 ;; Moving is usually shorter when only FP registers are used. This separate
2314 ;; movdf pattern avoids the use of integer registers for FP operations
2315 ;; when optimizing for size.
2317 (define_insn "*movdf_nointeger"
2318   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2319         (match_operand:DF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2320   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2321    && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2322    && (reload_in_progress || reload_completed
2323        || GET_CODE (operands[1]) != CONST_DOUBLE
2324        || memory_operand (operands[0], DFmode))" 
2325   "*
2327   switch (which_alternative)
2328     {
2329     case 0:
2330       if (REG_P (operands[1])
2331           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2332         return \"fstp\\t%y0\";
2333       else if (STACK_TOP_P (operands[0]))
2334         return \"fld%z1\\t%y1\";
2335       else
2336         return \"fst\\t%y0\";
2338     case 1:
2339       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2340         return \"fstp%z0\\t%y0\";
2341       else
2342         return \"fst%z0\\t%y0\";
2344     case 2:
2345       switch (standard_80387_constant_p (operands[1]))
2346         {
2347         case 1:
2348           return \"fldz\";
2349         case 2:
2350           return \"fld1\";
2351         }
2352       abort();
2354     case 3:
2355     case 4:
2356       return \"#\";
2358     default:
2359       abort();
2360     }
2362   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2363    (set_attr "mode" "DF,DF,DF,SI,SI")])
2365 (define_insn "*movdf_integer"
2366   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2367         (match_operand:DF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2368   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2369    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2370    && (reload_in_progress || reload_completed
2371        || GET_CODE (operands[1]) != CONST_DOUBLE
2372        || memory_operand (operands[0], DFmode))" 
2373   "*
2375   switch (which_alternative)
2376     {
2377     case 0:
2378       if (REG_P (operands[1])
2379           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2380         return \"fstp\\t%y0\";
2381       else if (STACK_TOP_P (operands[0]))
2382         return \"fld%z1\\t%y1\";
2383       else
2384         return \"fst\\t%y0\";
2386     case 1:
2387       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2388         return \"fstp%z0\\t%y0\";
2389       else
2390         return \"fst%z0\\t%y0\";
2392     case 2:
2393       switch (standard_80387_constant_p (operands[1]))
2394         {
2395         case 1:
2396           return \"fldz\";
2397         case 2:
2398           return \"fld1\";
2399         }
2400       abort();
2402     case 3:
2403     case 4:
2404       return \"#\";
2406     default:
2407       abort();
2408     }
2410   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2411    (set_attr "mode" "DF,DF,DF,SI,SI")])
2413 (define_split
2414   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2415         (match_operand:DF 1 "general_operand" ""))]
2416   "reload_completed
2417    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2418    && ! (FP_REG_P (operands[0]) || 
2419          (GET_CODE (operands[0]) == SUBREG
2420           && FP_REG_P (SUBREG_REG (operands[0]))))
2421    && ! (FP_REG_P (operands[1]) || 
2422          (GET_CODE (operands[1]) == SUBREG
2423           && FP_REG_P (SUBREG_REG (operands[1]))))"
2424   [(set (match_dup 2) (match_dup 5))
2425    (set (match_dup 3) (match_dup 6))]
2426   "if (ix86_split_long_move (operands)) DONE;")
2428 (define_split
2429   [(set (match_operand:DF 0 "register_operand" "")
2430         (match_operand:DF 1 "memory_operand" ""))]
2431   "reload_completed
2432    && GET_CODE (operands[1]) == MEM
2433    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2434    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2435    && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
2436   [(set (match_dup 0)
2437         (match_dup 1))]
2438   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2440 (define_insn "*swapdf"
2441   [(set (match_operand:DF 0 "register_operand" "+f")
2442         (match_operand:DF 1 "register_operand" "+f"))
2443    (set (match_dup 1)
2444         (match_dup 0))]
2445   ""
2446   "*
2448   if (STACK_TOP_P (operands[0]))
2449     return \"fxch\\t%1\";
2450   else
2451     return \"fxch\\t%0\";
2453   [(set_attr "type" "fxch")
2454    (set_attr "mode" "DF")])
2456 (define_expand "movxf"
2457   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2458         (match_operand:XF 1 "general_operand" ""))]
2459   ""
2460   "ix86_expand_move (XFmode, operands); DONE;")
2462 (define_expand "movtf"
2463   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2464         (match_operand:TF 1 "general_operand" ""))]
2465   ""
2466   "ix86_expand_move (TFmode, operands); DONE;")
2468 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2469 ;; Size of pushdf using integer insturctions is 3+3*memory operand size
2470 ;; Pushing using integer instructions is longer except for constants
2471 ;; and direct memory references.
2472 ;; (assuming that any given constant is pushed only once, but this ought to be
2473 ;;  handled elsewhere).
2475 (define_insn "*pushxf_nointeger"
2476   [(set (match_operand:XF 0 "push_operand" "=<,<,<")
2477         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2478   "optimize_size"
2479   "*
2481   switch (which_alternative)
2482     {
2483     case 0:
2484       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2485       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2486       operands[2] = stack_pointer_rtx;
2487       operands[3] = GEN_INT (12);
2488       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2489         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2490       else
2491         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2493     case 1:
2494     case 2:
2495       return \"#\";
2497     default:
2498       abort ();
2499     }
2501   [(set_attr "type" "multi")
2502    (set_attr "mode" "XF,SI,SI")])
2504 (define_insn "*pushtf_nointeger"
2505   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2506         (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2507   "optimize_size"
2508   "*
2510   switch (which_alternative)
2511     {
2512     case 0:
2513       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2514       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2515       operands[2] = stack_pointer_rtx;
2516       operands[3] = GEN_INT (16);
2517       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2518         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2519       else
2520         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2522     case 1:
2523     case 2:
2524       return \"#\";
2526     default:
2527       abort ();
2528     }
2530   [(set_attr "type" "multi")
2531    (set_attr "mode" "XF,SI,SI")])
2533 (define_insn "*pushxf_integer"
2534   [(set (match_operand:XF 0 "push_operand" "=<,<")
2535         (match_operand:XF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2536   "!optimize_size"
2537   "*
2539   switch (which_alternative)
2540     {
2541     case 0:
2542       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2543       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2544       operands[2] = stack_pointer_rtx;
2545       operands[3] = GEN_INT (12);
2546       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2547         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2548       else
2549         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2551     case 1:
2552       return \"#\";
2554     default:
2555       abort ();
2556     }
2558   [(set_attr "type" "multi")
2559    (set_attr "mode" "XF,SI")])
2561 (define_insn "*pushtf_integer"
2562   [(set (match_operand:TF 0 "push_operand" "=<,<")
2563         (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2564   "!optimize_size"
2565   "*
2567   switch (which_alternative)
2568     {
2569     case 0:
2570       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
2571       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2572       operands[2] = stack_pointer_rtx;
2573       operands[3] = GEN_INT (16);
2574       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2575         return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2576       else
2577         return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2579     case 1:
2580       return \"#\";
2582     default:
2583       abort ();
2584     }
2586   [(set_attr "type" "multi")
2587    (set_attr "mode" "XF,SI")])
2589 (define_split
2590   [(set (match_operand 0 "push_operand" "")
2591         (match_operand 1 "general_operand" ""))]
2592   "reload_completed
2593    && (GET_MODE (operands[0]) == XFmode
2594        || GET_MODE (operands[0]) == TFmode
2595        || GET_MODE (operands[0]) == DFmode)
2596    && (!REG_P (operands[1]) || !FP_REGNO_P (REGNO (operands[1])))"
2597   [(const_int 0)]
2598   "if (!ix86_split_long_move (operands)) abort (); DONE;")
2600 (define_split
2601   [(set (match_operand:XF 0 "push_operand" "")
2602         (match_operand:XF 1 "register_operand" ""))]
2603   "FP_REGNO_P (REGNO (operands[1]))"
2604   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2605    (set (mem:XF (reg:SI 7)) (match_dup 1))])
2607 (define_split
2608   [(set (match_operand:TF 0 "push_operand" "")
2609         (match_operand:TF 1 "register_operand" ""))]
2610   "FP_REGNO_P (REGNO (operands[1]))"
2611   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2612    (set (mem:TF (reg:SI 7)) (match_dup 1))])
2614 ;; Do not use integer registers when optimizing for size
2615 (define_insn "*movxf_nointeger"
2616   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2617         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2618   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2619    && optimize_size
2620    && (reload_in_progress || reload_completed
2621        || GET_CODE (operands[1]) != CONST_DOUBLE
2622        || memory_operand (operands[0], XFmode))" 
2623   "*
2625   switch (which_alternative)
2626     {
2627     case 0:
2628       if (REG_P (operands[1])
2629           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2630         return \"fstp\\t%y0\";
2631       else if (STACK_TOP_P (operands[0]))
2632         return \"fld%z1\\t%y1\";
2633       else
2634         return \"fst\\t%y0\";
2636     case 1:
2637       /* There is no non-popping store to memory for XFmode.  So if
2638          we need one, follow the store with a load.  */
2639       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2640         return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2641       else
2642         return \"fstp%z0\\t%y0\";
2644     case 2:
2645       switch (standard_80387_constant_p (operands[1]))
2646         {
2647         case 1:
2648           return \"fldz\";
2649         case 2:
2650           return \"fld1\";
2651         }
2652       break;
2654     case 3: case 4:
2655       return \"#\";
2656     }
2657   abort();
2659   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2660    (set_attr "mode" "XF,XF,XF,SI,SI")])
2662 (define_insn "*movtf_nointeger"
2663   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2664         (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2665   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2666    && optimize_size
2667    && (reload_in_progress || reload_completed
2668        || GET_CODE (operands[1]) != CONST_DOUBLE
2669        || memory_operand (operands[0], TFmode))" 
2670   "*
2672   switch (which_alternative)
2673     {
2674     case 0:
2675       if (REG_P (operands[1])
2676           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2677         return \"fstp\\t%y0\";
2678       else if (STACK_TOP_P (operands[0]))
2679         return \"fld%z1\\t%y1\";
2680       else
2681         return \"fst\\t%y0\";
2683     case 1:
2684       /* There is no non-popping store to memory for XFmode.  So if
2685          we need one, follow the store with a load.  */
2686       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2687         return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2688       else
2689         return \"fstp%z0\\t%y0\";
2691     case 2:
2692       switch (standard_80387_constant_p (operands[1]))
2693         {
2694         case 1:
2695           return \"fldz\";
2696         case 2:
2697           return \"fld1\";
2698         }
2699       break;
2701     case 3: case 4:
2702       return \"#\";
2703     }
2704   abort();
2706   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2707    (set_attr "mode" "XF,XF,XF,SI,SI")])
2709 (define_insn "*movxf_integer"
2710   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2711         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2712   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2713    && !optimize_size
2714    && (reload_in_progress || reload_completed
2715        || GET_CODE (operands[1]) != CONST_DOUBLE
2716        || memory_operand (operands[0], XFmode))" 
2717   "*
2719   switch (which_alternative)
2720     {
2721     case 0:
2722       if (REG_P (operands[1])
2723           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2724         return \"fstp\\t%y0\";
2725       else if (STACK_TOP_P (operands[0]))
2726         return \"fld%z1\\t%y1\";
2727       else
2728         return \"fst\\t%y0\";
2730     case 1:
2731       /* There is no non-popping store to memory for XFmode.  So if
2732          we need one, follow the store with a load.  */
2733       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2734         return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2735       else
2736         return \"fstp%z0\\t%y0\";
2738     case 2:
2739       switch (standard_80387_constant_p (operands[1]))
2740         {
2741         case 1:
2742           return \"fldz\";
2743         case 2:
2744           return \"fld1\";
2745         }
2746       break;
2748     case 3: case 4:
2749       return \"#\";
2750     }
2751   abort();
2753   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2754    (set_attr "mode" "XF,XF,XF,SI,SI")])
2756 (define_insn "*movtf_integer"
2757   [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2758         (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2759   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2760    && !optimize_size
2761    && (reload_in_progress || reload_completed
2762        || GET_CODE (operands[1]) != CONST_DOUBLE
2763        || memory_operand (operands[0], TFmode))" 
2764   "*
2766   switch (which_alternative)
2767     {
2768     case 0:
2769       if (REG_P (operands[1])
2770           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2771         return \"fstp\\t%y0\";
2772       else if (STACK_TOP_P (operands[0]))
2773         return \"fld%z1\\t%y1\";
2774       else
2775         return \"fst\\t%y0\";
2777     case 1:
2778       /* There is no non-popping store to memory for XFmode.  So if
2779          we need one, follow the store with a load.  */
2780       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2781         return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2782       else
2783         return \"fstp%z0\\t%y0\";
2785     case 2:
2786       switch (standard_80387_constant_p (operands[1]))
2787         {
2788         case 1:
2789           return \"fldz\";
2790         case 2:
2791           return \"fld1\";
2792         }
2793       break;
2795     case 3: case 4:
2796       return \"#\";
2797     }
2798   abort();
2800   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2801    (set_attr "mode" "XF,XF,XF,SI,SI")])
2803 (define_split
2804   [(set (match_operand 0 "nonimmediate_operand" "")
2805         (match_operand 1 "general_operand" ""))]
2806   "reload_completed
2807    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2808    && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
2809    && ! (FP_REG_P (operands[0]) || 
2810          (GET_CODE (operands[0]) == SUBREG
2811           && FP_REG_P (SUBREG_REG (operands[0]))))
2812    && ! (FP_REG_P (operands[1]) || 
2813          (GET_CODE (operands[1]) == SUBREG
2814           && FP_REG_P (SUBREG_REG (operands[1]))))"
2815   [(set (match_dup 2) (match_dup 5))
2816    (set (match_dup 3) (match_dup 6))
2817    (set (match_dup 4) (match_dup 7))]
2818   "if (ix86_split_long_move (operands)) DONE;")
2820 (define_split
2821   [(set (match_operand 0 "register_operand" "")
2822         (match_operand 1 "memory_operand" ""))]
2823   "reload_completed
2824    && GET_CODE (operands[1]) == MEM
2825    && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
2826    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2827    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2828    && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
2829   [(set (match_dup 0)
2830         (match_dup 1))]
2831   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2833 (define_insn "swapxf"
2834   [(set (match_operand:XF 0 "register_operand" "+f")
2835         (match_operand:XF 1 "register_operand" "+f"))
2836    (set (match_dup 1)
2837         (match_dup 0))]
2838   ""
2839   "*
2841   if (STACK_TOP_P (operands[0]))
2842     return \"fxch\\t%1\";
2843   else
2844     return \"fxch\\t%0\";
2846   [(set_attr "type" "fxch")
2847    (set_attr "mode" "XF")])
2849 (define_insn "swaptf"
2850   [(set (match_operand:TF 0 "register_operand" "+f")
2851         (match_operand:TF 1 "register_operand" "+f"))
2852    (set (match_dup 1)
2853         (match_dup 0))]
2854   ""
2855   "*
2857   if (STACK_TOP_P (operands[0]))
2858     return \"fxch\\t%1\";
2859   else
2860     return \"fxch\\t%0\";
2862   [(set_attr "type" "fxch")
2863    (set_attr "mode" "XF")])
2865 ;; Zero extension instructions
2867 (define_expand "zero_extendhisi2"
2868   [(set (match_operand:SI 0 "register_operand" "")
2869      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2870   ""
2871   "
2873   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2874     {
2875       operands[1] = force_reg (HImode, operands[1]);
2876       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2877       DONE;
2878     }
2881 (define_insn "zero_extendhisi2_and"
2882   [(set (match_operand:SI 0 "register_operand" "=r")
2883      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2884    (clobber (reg:CC 17))]
2885   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2886   "#"
2887   [(set_attr "type" "alu1")
2888    (set_attr "mode" "SI")])
2890 (define_split
2891   [(set (match_operand:SI 0 "register_operand" "")
2892         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2893    (clobber (reg:CC 17))]
2894   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2895   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2896               (clobber (reg:CC 17))])]
2897   "")
2899 (define_insn "*zero_extendhisi2_movzwl"
2900   [(set (match_operand:SI 0 "register_operand" "=r")
2901      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2902   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2903   "movz{wl|x}\\t{%1, %0|%0, %1}"
2904   [(set_attr "type" "imovx")
2905    (set_attr "mode" "SI")])
2907 (define_expand "zero_extendqihi2"
2908   [(parallel
2909     [(set (match_operand:HI 0 "register_operand" "")
2910        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2911      (clobber (reg:CC 17))])]
2912   ""
2913   "")
2915 (define_insn "*zero_extendqihi2_and"
2916   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2917      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2918    (clobber (reg:CC 17))]
2919   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2920   "#"
2921   [(set_attr "type" "alu1")
2922    (set_attr "mode" "HI")])
2924 (define_insn "*zero_extendqihi2_movzbw_and"
2925   [(set (match_operand:HI 0 "register_operand" "=r,r")
2926      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2927    (clobber (reg:CC 17))]
2928   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2929   "#"
2930   [(set_attr "type" "imovx,alu1")
2931    (set_attr "mode" "HI")])
2933 (define_insn "*zero_extendqihi2_movzbw"
2934   [(set (match_operand:HI 0 "register_operand" "=r")
2935      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2936   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2937   "movz{bw|x}\\t{%1, %0|%0, %1}"
2938   [(set_attr "type" "imovx")
2939    (set_attr "mode" "HI")])
2941 ;; For the movzbw case strip only the clobber
2942 (define_split
2943   [(set (match_operand:HI 0 "register_operand" "")
2944         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2945    (clobber (reg:CC 17))]
2946   "reload_completed 
2947    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2948    && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
2949   [(set (match_operand:HI 0 "register_operand" "")
2950         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2952 ;; When source and destination does not overlap, clear destination
2953 ;; first and then do the movb
2954 (define_split
2955   [(set (match_operand:HI 0 "register_operand" "")
2956         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2957    (clobber (reg:CC 17))]
2958   "reload_completed
2959    && QI_REG_P (operands[0])
2960    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2961    && !reg_overlap_mentioned_p (operands[0], operands[1])"
2962   [(set (match_dup 0) (const_int 0))
2963    (set (strict_low_part (match_dup 2)) (match_dup 1))]
2964   "operands[2] = gen_lowpart (QImode, operands[0]);")
2966 ;; Rest is handled by single and.
2967 (define_split
2968   [(set (match_operand:HI 0 "register_operand" "")
2969         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2970    (clobber (reg:CC 17))]
2971   "reload_completed
2972    && true_regnum (operands[0]) == true_regnum (operands[1])"
2973   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2974               (clobber (reg:CC 17))])]
2975   "")
2977 (define_expand "zero_extendqisi2"
2978   [(parallel
2979     [(set (match_operand:SI 0 "register_operand" "")
2980        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2981      (clobber (reg:CC 17))])]
2982   ""
2983   "")
2985 (define_insn "*zero_extendqisi2_and"
2986   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2987      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2988    (clobber (reg:CC 17))]
2989   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2990   "#"
2991   [(set_attr "type" "alu1")
2992    (set_attr "mode" "SI")])
2994 (define_insn "*zero_extendqisi2_movzbw_and"
2995   [(set (match_operand:SI 0 "register_operand" "=r,r")
2996      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2997    (clobber (reg:CC 17))]
2998   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2999   "#"
3000   [(set_attr "type" "imovx,alu1")
3001    (set_attr "mode" "SI")])
3003 (define_insn "*zero_extendqisi2_movzbw"
3004   [(set (match_operand:SI 0 "register_operand" "=r")
3005      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3006   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3007   "movz{bl|x}\\t{%1, %0|%0, %1}"
3008   [(set_attr "type" "imovx")
3009    (set_attr "mode" "SI")])
3011 ;; For the movzbl case strip only the clobber
3012 (define_split
3013   [(set (match_operand:SI 0 "register_operand" "")
3014         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3015    (clobber (reg:CC 17))]
3016   "reload_completed 
3017    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3018    && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
3019   [(set (match_dup 0)
3020         (zero_extend:SI (match_dup 1)))])
3022 ;; When source and destination does not overlap, clear destination
3023 ;; first and then do the movb
3024 (define_split
3025   [(set (match_operand:SI 0 "register_operand" "")
3026         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3027    (clobber (reg:CC 17))]
3028   "reload_completed
3029    && QI_REG_P (operands[0])
3030    && (QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3031    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3032    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3033   [(set (match_dup 0) (const_int 0))
3034    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3035   "operands[2] = gen_lowpart (QImode, operands[0]);")
3037 ;; Rest is handled by single and.
3038 (define_split
3039   [(set (match_operand:SI 0 "register_operand" "")
3040         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3041    (clobber (reg:CC 17))]
3042   "reload_completed
3043    && true_regnum (operands[0]) == true_regnum (operands[1])"
3044   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3045               (clobber (reg:CC 17))])]
3046   "")
3048 ;; %%% Kill me once multi-word ops are sane.
3049 (define_insn "zero_extendsidi2"
3050   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3051         (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))
3052    (clobber (reg:CC 17))]
3053   ""
3054   "#"
3055   [(set_attr "mode" "SI")])
3057 (define_split 
3058   [(set (match_operand:DI 0 "register_operand" "")
3059         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3060    (clobber (reg:CC 17))]
3061   "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
3062   [(set (match_dup 4) (const_int 0))]
3063   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3065 (define_split 
3066   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3067         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3068    (clobber (reg:CC 17))]
3069   "reload_completed"
3070   [(set (match_dup 3) (match_dup 1))
3071    (set (match_dup 4) (const_int 0))]
3072   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3074 ;; Sign extension instructions
3076 (define_insn "extendsidi2"
3077   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3078         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3079    (clobber (reg:CC 17))
3080    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3081   ""
3082   "#")
3084 ;; Extend to memory case when source register does die.
3085 (define_split 
3086   [(set (match_operand:DI 0 "memory_operand" "")
3087         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3088    (clobber (reg:CC 17))
3089    (clobber (match_operand:SI 2 "register_operand" ""))]
3090   "(reload_completed
3091     && dead_or_set_p (insn, operands[1])
3092     && !reg_mentioned_p (operands[1], operands[0]))"
3093   [(set (match_dup 3) (match_dup 1))
3094    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3095               (clobber (reg:CC 17))])
3096    (set (match_dup 4) (match_dup 1))]
3097   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3099 ;; Extend to memory case when source register does not die.
3100 (define_split 
3101   [(set (match_operand:DI 0 "memory_operand" "")
3102         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3103    (clobber (reg:CC 17))
3104    (clobber (match_operand:SI 2 "register_operand" ""))]
3105   "reload_completed"
3106   [(const_int 0)]
3107   "
3109   split_di (&operands[0], 1, &operands[3], &operands[4]);
3111   emit_move_insn (operands[3], operands[1]);
3113   /* Generate a cltd if possible and doing so it profitable.  */
3114   if (true_regnum (operands[1]) == 0
3115       && true_regnum (operands[2]) == 1
3116       && (optimize_size || TARGET_USE_CLTD))
3117     {
3118       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3119     }
3120   else
3121     {
3122       emit_move_insn (operands[2], operands[1]);
3123       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3124     }
3125   emit_move_insn (operands[4], operands[2]);
3126   DONE;
3129 ;; Extend to register case.  Optimize case where source and destination
3130 ;; registers match and cases where we can use cltd.
3131 (define_split 
3132   [(set (match_operand:DI 0 "register_operand" "")
3133         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3134    (clobber (reg:CC 17))
3135    (clobber (match_scratch:SI 2 ""))]
3136   "reload_completed"
3137   [(const_int 0)]
3138   "
3140   split_di (&operands[0], 1, &operands[3], &operands[4]);
3142   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3143     emit_move_insn (operands[3], operands[1]);
3145   /* Generate a cltd if possible and doing so it profitable.  */
3146   if (true_regnum (operands[3]) == 0
3147       && (optimize_size || TARGET_USE_CLTD))
3148     {
3149       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3150       DONE;
3151     }
3153   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3154     emit_move_insn (operands[4], operands[1]);
3156   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3157   DONE;
3160 (define_insn "extendhisi2"
3161   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3162         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3163   ""
3164   "*
3166   switch (get_attr_prefix_0f (insn))
3167     {
3168     case 0:
3169       return \"{cwtl|cwde}\";
3170     default:
3171       return \"movs{wl|x}\\t{%1,%0|%0, %1}\";
3172     }
3174   [(set_attr "type" "imovx")
3175    (set_attr "mode" "SI")
3176    (set (attr "prefix_0f")
3177      ;; movsx is short decodable while cwtl is vector decoded.
3178      (if_then_else (and (eq_attr "cpu" "!k6")
3179                         (eq_attr "alternative" "0"))
3180         (const_string "0")
3181         (const_string "1")))
3182    (set (attr "modrm")
3183      (if_then_else (eq_attr "prefix_0f" "0")
3184         (const_string "0")
3185         (const_string "1")))])
3187 (define_insn "extendqihi2"
3188   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3189         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3190   ""
3191   "*
3193   switch (get_attr_prefix_0f (insn))
3194     {
3195     case 0:
3196       return \"{cbtw|cbw}\";
3197     default:
3198       return \"movs{bw|x}\\t{%1,%0|%0, %1}\";
3199     }
3201   [(set_attr "type" "imovx")
3202    (set_attr "mode" "HI")
3203    (set (attr "prefix_0f")
3204      ;; movsx is short decodable while cwtl is vector decoded.
3205      (if_then_else (and (eq_attr "cpu" "!k6")
3206                         (eq_attr "alternative" "0"))
3207         (const_string "0")
3208         (const_string "1")))
3209    (set (attr "modrm")
3210      (if_then_else (eq_attr "prefix_0f" "0")
3211         (const_string "0")
3212         (const_string "1")))])
3214 (define_insn "extendqisi2"
3215   [(set (match_operand:SI 0 "register_operand" "=r")
3216         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3217   ""
3218   "movs{bl|x}\\t{%1,%0|%0, %1}"
3219    [(set_attr "type" "imovx")
3220     (set_attr "mode" "SI")])
3222 ;; Conversions between float and double.
3224 ;; These are all no-ops in the model used for the 80387.  So just
3225 ;; emit moves.
3227 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3228 (define_insn "*dummy_extendsfdf2"
3229   [(set (match_operand:DF 0 "push_operand" "=<")
3230         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3231   "0"
3232   "#")
3234 (define_split
3235   [(set (match_operand:DF 0 "push_operand" "")
3236         (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3237   "FP_REGNO_P (REGNO (operands[1]))"
3238   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3239    (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3241 (define_insn "*dummy_extendsfxf2"
3242   [(set (match_operand:XF 0 "push_operand" "=<")
3243         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3244   "0"
3245   "#")
3247 (define_split
3248   [(set (match_operand:XF 0 "push_operand" "")
3249         (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
3250   "FP_REGNO_P (REGNO (operands[1]))"
3251   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3252    (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3254 (define_insn "*dummy_extendsftf2"
3255   [(set (match_operand:TF 0 "push_operand" "=<")
3256         (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3257   "0"
3258   "#")
3260 (define_split
3261   [(set (match_operand:TF 0 "push_operand" "")
3262         (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3263   "FP_REGNO_P (REGNO (operands[1]))"
3264   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3265    (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3267 (define_insn "*dummy_extenddfxf2"
3268   [(set (match_operand:XF 0 "push_operand" "=<")
3269         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3270   "0"
3271   "#")
3273 (define_split
3274   [(set (match_operand:XF 0 "push_operand" "")
3275         (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
3276   "FP_REGNO_P (REGNO (operands[1]))"
3277   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3278    (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3280 (define_insn "*dummy_extenddftf2"
3281   [(set (match_operand:TF 0 "push_operand" "=<")
3282         (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3283   "0"
3284   "#")
3286 (define_split
3287   [(set (match_operand:TF 0 "push_operand" "")
3288         (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
3289   "FP_REGNO_P (REGNO (operands[1]))"
3290   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3291    (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3293 (define_expand "extendsfdf2"
3294   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3295         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
3296   "TARGET_80387"
3297   "
3299   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3300     operands[1] = force_reg (SFmode, operands[1]);
3303 (define_insn "*extendsfdf2_1"
3304   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3305         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3306   "TARGET_80387
3307    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3308   "*
3310   switch (which_alternative)
3311     {
3312     case 0:
3313       if (REG_P (operands[1])
3314           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3315         return \"fstp\\t%y0\";
3316       else if (STACK_TOP_P (operands[0]))
3317         return \"fld%z1\\t%y1\";
3318       else
3319         return \"fst\\t%y0\";
3321     case 1:
3322       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3323         return \"fstp%z0\\t%y0\";
3325       else
3326         return \"fst%z0\\t%y0\";
3328     default:
3329       abort ();
3330     }
3332   [(set_attr "type" "fmov")
3333    (set_attr "mode" "SF,XF")])
3335 (define_expand "extendsfxf2"
3336   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3337         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
3338   "TARGET_80387"
3339   "
3341   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3342     operands[1] = force_reg (SFmode, operands[1]);
3345 (define_insn "*extendsfxf2_1"
3346   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3347         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3348   "TARGET_80387
3349    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3350   "*
3352   switch (which_alternative)
3353     {
3354     case 0:
3355       if (REG_P (operands[1])
3356           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3357         return \"fstp\\t%y0\";
3358       else if (STACK_TOP_P (operands[0]))
3359         return \"fld%z1\\t%y1\";
3360       else
3361         return \"fst\\t%y0\";
3363     case 1:
3364       /* There is no non-popping store to memory for XFmode.  So if
3365          we need one, follow the store with a load.  */
3366       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3367         return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3368       else
3369         return \"fstp%z0\\t%y0\";
3371     default:
3372       abort ();
3373     }
3375   [(set_attr "type" "fmov")
3376    (set_attr "mode" "SF,XF")])
3378 (define_expand "extendsftf2"
3379   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3380         (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
3381   "TARGET_80387"
3382   "
3384   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3385     operands[1] = force_reg (SFmode, operands[1]);
3388 (define_insn "*extendsftf2_1"
3389   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3390         (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3391   "TARGET_80387
3392    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3393   "*
3395   switch (which_alternative)
3396     {
3397     case 0:
3398       if (REG_P (operands[1])
3399           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3400         return \"fstp\\t%y0\";
3401       else if (STACK_TOP_P (operands[0]))
3402         return \"fld%z1\\t%y1\";
3403       else
3404         return \"fst\\t%y0\";
3406     case 1:
3407       /* There is no non-popping store to memory for XFmode.  So if
3408          we need one, follow the store with a load.  */
3409       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3410         return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3411       else
3412         return \"fstp%z0\\t%y0\";
3414     default:
3415       abort ();
3416     }
3418   [(set_attr "type" "fmov")
3419    (set_attr "mode" "SF,XF")])
3421 (define_expand "extenddfxf2"
3422   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3423         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
3424   "TARGET_80387"
3425   "
3427   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3428     operands[1] = force_reg (DFmode, operands[1]);
3431 (define_insn "*extenddfxf2_1"
3432   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3433         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3434   "TARGET_80387
3435    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3436   "*
3438   switch (which_alternative)
3439     {
3440     case 0:
3441       if (REG_P (operands[1])
3442           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3443         return \"fstp\\t%y0\";
3444       else if (STACK_TOP_P (operands[0]))
3445         return \"fld%z1\\t%y1\";
3446       else
3447         return \"fst\\t%y0\";
3449     case 1:
3450       /* There is no non-popping store to memory for XFmode.  So if
3451          we need one, follow the store with a load.  */
3452       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3453         return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3454       else
3455         return \"fstp%z0\\t%y0\";
3457     default:
3458       abort ();
3459     }
3461   [(set_attr "type" "fmov")
3462    (set_attr "mode" "DF,XF")])
3464 (define_expand "extenddftf2"
3465   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3466         (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
3467   "TARGET_80387"
3468   "
3470   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3471     operands[1] = force_reg (DFmode, operands[1]);
3474 (define_insn "*extenddftf2_1"
3475   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3476         (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3477   "TARGET_80387
3478    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3479   "*
3481   switch (which_alternative)
3482     {
3483     case 0:
3484       if (REG_P (operands[1])
3485           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3486         return \"fstp\\t%y0\";
3487       else if (STACK_TOP_P (operands[0]))
3488         return \"fld%z1\\t%y1\";
3489       else
3490         return \"fst\\t%y0\";
3492     case 1:
3493       /* There is no non-popping store to memory for XFmode.  So if
3494          we need one, follow the store with a load.  */
3495       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3496         return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3497       else
3498         return \"fstp%z0\\t%y0\";
3500     default:
3501       abort ();
3502     }
3504   [(set_attr "type" "fmov")
3505    (set_attr "mode" "DF,XF")])
3507 ;; %%% This seems bad bad news.
3508 ;; This cannot output into an f-reg because there is no way to be sure
3509 ;; of truncating in that case.  Otherwise this is just like a simple move
3510 ;; insn.  So we pretend we can output to a reg in order to get better
3511 ;; register preferencing, but we really use a stack slot.
3513 (define_expand "truncdfsf2"
3514   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3515                    (float_truncate:SF
3516                     (match_operand:DF 1 "register_operand" "")))
3517               (clobber (match_dup 2))])]
3518   "TARGET_80387"
3519   "operands[2] = assign_386_stack_local (SFmode, 0);")
3521 (define_insn "*truncdfsf2_1"
3522   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3523         (float_truncate:SF
3524          (match_operand:DF 1 "register_operand" "f,0")))
3525    (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3526   "TARGET_80387"
3527   "*
3529   switch (which_alternative)
3530     {
3531     case 0:
3532       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3533         return \"fstp%z0\\t%y0\";
3534       else
3535         return \"fst%z0\\t%y0\";
3536     case 1:
3537       return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3538     }
3539   abort ();
3541   [(set_attr "type" "fmov,multi")
3542    (set_attr "mode" "SF")])
3544 (define_insn "*truncdfsf2_2"
3545   [(set (match_operand:SF 0 "memory_operand" "=m")
3546         (float_truncate:SF
3547          (match_operand:DF 1 "register_operand" "f")))]
3548   "TARGET_80387"
3549   "*
3551   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3552     return \"fstp%z0\\t%y0\";
3553   else
3554     return \"fst%z0\\t%y0\";
3556   [(set_attr "type" "fmov")
3557    (set_attr "mode" "SF")])
3559 (define_split
3560   [(set (match_operand:SF 0 "memory_operand" "")
3561         (float_truncate:SF
3562          (match_operand:DF 1 "register_operand" "")))
3563    (clobber (match_operand:SF 2 "memory_operand" ""))]
3564   "TARGET_80387"
3565   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3566   "")
3568 (define_split
3569   [(set (match_operand:SF 0 "register_operand" "")
3570         (float_truncate:SF
3571          (match_operand:DF 1 "register_operand" "")))
3572    (clobber (match_operand:SF 2 "memory_operand" ""))]
3573   "TARGET_80387 && reload_completed"
3574   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3575    (set (match_dup 0) (match_dup 2))]
3576   "")
3578 (define_expand "truncxfsf2"
3579   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3580                    (float_truncate:SF
3581                     (match_operand:XF 1 "register_operand" "")))
3582               (clobber (match_dup 2))])]
3583   "TARGET_80387"
3584   "operands[2] = assign_386_stack_local (SFmode, 0);")
3586 (define_insn "*truncxfsf2_1"
3587   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3588         (float_truncate:SF
3589          (match_operand:XF 1 "register_operand" "f,0")))
3590    (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3591   "TARGET_80387"
3592   "*
3594   switch (which_alternative)
3595     {
3596     case 0:
3597       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3598         return \"fstp%z0\\t%y0\";
3599       else
3600         return \"fst%z0\\t%y0\";
3601     case 1:
3602       return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3603     }
3604   abort ();
3606   [(set_attr "type" "fmov,multi")
3607    (set_attr "mode" "SF")])
3609 (define_insn "*truncxfsf2_2"
3610   [(set (match_operand:SF 0 "memory_operand" "=m")
3611         (float_truncate:SF
3612          (match_operand:XF 1 "register_operand" "f")))]
3613   "TARGET_80387"
3614   "*
3616   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3617     return \"fstp%z0\\t%y0\";
3618   else
3619     return \"fst%z0\\t%y0\";
3621   [(set_attr "type" "fmov")
3622    (set_attr "mode" "SF")])
3624 (define_split
3625   [(set (match_operand:SF 0 "memory_operand" "")
3626         (float_truncate:SF
3627          (match_operand:XF 1 "register_operand" "")))
3628    (clobber (match_operand:SF 2 "memory_operand" ""))]
3629   "TARGET_80387"
3630   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3631   "")
3633 (define_split
3634   [(set (match_operand:SF 0 "register_operand" "")
3635         (float_truncate:SF
3636          (match_operand:XF 1 "register_operand" "")))
3637    (clobber (match_operand:SF 2 "memory_operand" ""))]
3638   "TARGET_80387 && reload_completed"
3639   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3640    (set (match_dup 0) (match_dup 2))]
3641   "")
3643 (define_expand "trunctfsf2"
3644   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3645                    (float_truncate:SF
3646                     (match_operand:TF 1 "register_operand" "")))
3647               (clobber (match_dup 2))])]
3648   "TARGET_80387"
3649   "operands[2] = assign_386_stack_local (SFmode, 0);")
3651 (define_insn "*trunctfsf2_1"
3652   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3653         (float_truncate:SF
3654          (match_operand:TF 1 "register_operand" "f,0")))
3655    (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3656   "TARGET_80387"
3657   "*
3659   switch (which_alternative)
3660     {
3661     case 0:
3662       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3663         return \"fstp%z0\\t%y0\";
3664       else
3665         return \"fst%z0\\t%y0\";
3666     case 1:
3667       return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3668     }
3669   abort ();
3671   [(set_attr "type" "fmov,multi")
3672    (set_attr "mode" "SF")])
3674 (define_insn "*truncxfsf2_2"
3675   [(set (match_operand:SF 0 "memory_operand" "=m")
3676         (float_truncate:SF
3677          (match_operand:TF 1 "register_operand" "f")))]
3678   "TARGET_80387"
3679   "*
3681   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3682     return \"fstp%z0\\t%y0\";
3683   else
3684     return \"fst%z0\\t%y0\";
3686   [(set_attr "type" "fmov")
3687    (set_attr "mode" "SF")])
3689 (define_split
3690   [(set (match_operand:SF 0 "memory_operand" "")
3691         (float_truncate:SF
3692          (match_operand:TF 1 "register_operand" "")))
3693    (clobber (match_operand:SF 2 "memory_operand" ""))]
3694   "TARGET_80387"
3695   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3696   "")
3698 (define_split
3699   [(set (match_operand:SF 0 "register_operand" "")
3700         (float_truncate:SF
3701          (match_operand:TF 1 "register_operand" "")))
3702    (clobber (match_operand:SF 2 "memory_operand" ""))]
3703   "TARGET_80387 && reload_completed"
3704   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3705    (set (match_dup 0) (match_dup 2))]
3706   "")
3709 (define_expand "truncxfdf2"
3710   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3711                    (float_truncate:DF
3712                     (match_operand:XF 1 "register_operand" "")))
3713               (clobber (match_dup 2))])]
3714   "TARGET_80387"
3715   "operands[2] = assign_386_stack_local (DFmode, 0);")
3717 (define_insn "*truncxfdf2_1"
3718   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
3719         (float_truncate:DF
3720          (match_operand:XF 1 "register_operand" "f,0")))
3721    (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
3722   "TARGET_80387"
3723   "*
3725   switch (which_alternative)
3726     {
3727     case 0:
3728       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3729         return \"fstp%z0\\t%y0\";
3730       else
3731         return \"fst%z0\\t%y0\";
3732     case 1:
3733       return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3734     }
3735   abort ();
3737   [(set_attr "type" "fmov,multi")
3738    (set_attr "mode" "DF")])
3740 (define_insn "*truncxfdf2_2"
3741   [(set (match_operand:DF 0 "memory_operand" "=m")
3742         (float_truncate:DF
3743           (match_operand:XF 1 "register_operand" "f")))]
3744   "TARGET_80387"
3745   "*
3747   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3748     return \"fstp%z0\\t%y0\";
3749   else
3750     return \"fst%z0\\t%y0\";
3752   [(set_attr "type" "fmov")
3753    (set_attr "mode" "DF")])
3755 (define_split
3756   [(set (match_operand:DF 0 "memory_operand" "")
3757         (float_truncate:DF
3758          (match_operand:XF 1 "register_operand" "")))
3759    (clobber (match_operand:DF 2 "memory_operand" ""))]
3760   "TARGET_80387"
3761   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3762   "")
3764 (define_split
3765   [(set (match_operand:DF 0 "register_operand" "")
3766         (float_truncate:DF
3767          (match_operand:XF 1 "register_operand" "")))
3768    (clobber (match_operand:DF 2 "memory_operand" ""))]
3769   "TARGET_80387 && reload_completed"
3770   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3771    (set (match_dup 0) (match_dup 2))]
3772   "")
3774 (define_expand "trunctfdf2"
3775   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3776                    (float_truncate:DF
3777                     (match_operand:TF 1 "register_operand" "")))
3778               (clobber (match_dup 2))])]
3779   "TARGET_80387"
3780   "operands[2] = assign_386_stack_local (DFmode, 0);")
3782 (define_insn "*trunctfdf2_1"
3783   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
3784         (float_truncate:DF
3785          (match_operand:TF 1 "register_operand" "f,0")))
3786    (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
3787   "TARGET_80387"
3788   "*
3790   switch (which_alternative)
3791     {
3792     case 0:
3793       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3794         return \"fstp%z0\\t%y0\";
3795       else
3796         return \"fst%z0\\t%y0\";
3797     case 1:
3798       return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3799     }
3800   abort ();
3802   [(set_attr "type" "fmov,multi")
3803    (set_attr "mode" "DF")])
3805 (define_insn "*truncxfdf2_2"
3806   [(set (match_operand:DF 0 "memory_operand" "=m")
3807         (float_truncate:DF
3808           (match_operand:TF 1 "register_operand" "f")))]
3809   "TARGET_80387"
3810   "*
3812   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3813     return \"fstp%z0\\t%y0\";
3814   else
3815     return \"fst%z0\\t%y0\";
3817   [(set_attr "type" "fmov")
3818    (set_attr "mode" "DF")])
3820 (define_split
3821   [(set (match_operand:DF 0 "memory_operand" "")
3822         (float_truncate:DF
3823          (match_operand:TF 1 "register_operand" "")))
3824    (clobber (match_operand:DF 2 "memory_operand" ""))]
3825   "TARGET_80387"
3826   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3827   "")
3829 (define_split
3830   [(set (match_operand:DF 0 "register_operand" "")
3831         (float_truncate:DF
3832          (match_operand:TF 1 "register_operand" "")))
3833    (clobber (match_operand:DF 2 "memory_operand" ""))]
3834   "TARGET_80387 && reload_completed"
3835   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3836    (set (match_dup 0) (match_dup 2))]
3837   "")
3840 ;; %%% Break up all these bad boys.
3842 ;; Signed conversion to DImode.
3844 (define_expand "fix_truncxfdi2"
3845   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3846                    (fix:DI (match_operand:XF 1 "register_operand" "")))
3847               (clobber (match_dup 2))
3848               (clobber (match_dup 3))
3849               (clobber (match_scratch:SI 4 ""))
3850               (clobber (match_scratch:XF 5 ""))])]
3851   "TARGET_80387"
3852   "operands[2] = assign_386_stack_local (SImode, 0);
3853    operands[3] = assign_386_stack_local (DImode, 1);")
3855 (define_expand "fix_trunctfdi2"
3856   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3857                    (fix:DI (match_operand:TF 1 "register_operand" "")))
3858               (clobber (match_dup 2))
3859               (clobber (match_dup 3))
3860               (clobber (match_scratch:SI 4 ""))
3861               (clobber (match_scratch:TF 5 ""))])]
3862   "TARGET_80387"
3863   "operands[2] = assign_386_stack_local (SImode, 0);
3864    operands[3] = assign_386_stack_local (DImode, 1);")
3866 (define_expand "fix_truncdfdi2"
3867   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3868                    (fix:DI (match_operand:DF 1 "register_operand" "")))
3869               (clobber (match_dup 2))
3870               (clobber (match_dup 3))
3871               (clobber (match_scratch:SI 4 ""))
3872               (clobber (match_scratch:DF 5 ""))])]
3873   "TARGET_80387"
3874   "operands[2] = assign_386_stack_local (SImode, 0);
3875    operands[3] = assign_386_stack_local (DImode, 1);")
3877 (define_expand "fix_truncsfdi2"
3878   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3879                    (fix:DI (match_operand:SF 1 "register_operand" "")))
3880               (clobber (match_dup 2))
3881               (clobber (match_dup 3))
3882               (clobber (match_scratch:SI 4 ""))
3883               (clobber (match_scratch:SF 5 ""))])]
3884   "TARGET_80387"
3885   "operands[2] = assign_386_stack_local (SImode, 0);
3886    operands[3] = assign_386_stack_local (DImode, 1);")
3888 (define_insn "*fix_truncdi_1"
3889   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
3890         (fix:DI (match_operand 1 "register_operand" "f,f")))
3891    (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3892    (clobber (match_operand:DI 3 "memory_operand" "=m,m"))
3893    (clobber (match_scratch:SI 4 "=&r,&r"))
3894    (clobber (match_scratch 5 "=&f,&f"))]
3895   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3896   "* return output_fix_trunc (insn, operands);"
3897   [(set_attr "type" "multi")])
3899 (define_split 
3900   [(set (match_operand:DI 0 "register_operand" "")
3901         (fix:DI (match_operand 1 "register_operand" "")))
3902    (clobber (match_operand:SI 2 "memory_operand" ""))
3903    (clobber (match_operand:DI 3 "memory_operand" ""))
3904    (clobber (match_scratch:SI 4 ""))
3905    (clobber (match_scratch 5 ""))]
3906   "reload_completed && !reg_overlap_mentioned_p (operands[4], operands[3])"
3907   [(parallel [(set (match_dup 3) (fix:DI (match_dup 1)))
3908               (clobber (match_dup 2))
3909               (clobber (match_dup 3))
3910               (clobber (match_dup 4))
3911               (clobber (match_dup 5))])
3912    (set (match_dup 0) (match_dup 3))]
3913   "")
3915 ;; Signed conversion to SImode.
3917 (define_expand "fix_truncxfsi2"
3918   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3919                    (fix:SI (match_operand:XF 1 "register_operand" "")))
3920               (clobber (match_dup 2))
3921               (clobber (match_dup 3))
3922               (clobber (match_scratch:SI 4 ""))])]
3923   "TARGET_80387"
3924   "operands[2] = assign_386_stack_local (SImode, 0);
3925    operands[3] = assign_386_stack_local (SImode, 1);")
3927 (define_expand "fix_trunctfsi2"
3928   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3929                    (fix:SI (match_operand:TF 1 "register_operand" "")))
3930               (clobber (match_dup 2))
3931               (clobber (match_dup 3))
3932               (clobber (match_scratch:SI 4 ""))])]
3933   "TARGET_80387"
3934   "operands[2] = assign_386_stack_local (SImode, 0);
3935    operands[3] = assign_386_stack_local (SImode, 1);")
3937 (define_expand "fix_truncdfsi2"
3938   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3939                    (fix:SI (match_operand:DF 1 "register_operand" "")))
3940               (clobber (match_dup 2))
3941               (clobber (match_dup 3))
3942               (clobber (match_scratch:SI 4 ""))])]
3943   "TARGET_80387"
3944   "operands[2] = assign_386_stack_local (SImode, 0);
3945    operands[3] = assign_386_stack_local (SImode, 1);")
3947 (define_expand "fix_truncsfsi2"
3948   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3949                    (fix:SI (match_operand:SF 1 "register_operand" "")))
3950               (clobber (match_dup 2))
3951               (clobber (match_dup 3))
3952               (clobber (match_scratch:SI 4 ""))])]
3953   "TARGET_80387"
3954   "operands[2] = assign_386_stack_local (SImode, 0);
3955    operands[3] = assign_386_stack_local (SImode, 1);")
3957 (define_insn "*fix_truncsi_1"
3958   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
3959         (fix:SI (match_operand 1 "register_operand" "f,f")))
3960    (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3961    (clobber (match_operand:SI 3 "memory_operand" "=m,m"))
3962    (clobber (match_scratch:SI 4 "=&r,r"))]
3963   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3964   "* return output_fix_trunc (insn, operands);"
3965   [(set_attr "type" "multi")])
3967 (define_split 
3968   [(set (match_operand:SI 0 "register_operand" "")
3969         (fix:SI (match_operand 1 "register_operand" "")))
3970    (clobber (match_operand:SI 2 "memory_operand" ""))
3971    (clobber (match_operand:SI 3 "memory_operand" ""))
3972    (clobber (match_scratch:SI 4 ""))]
3973   "reload_completed"
3974   [(parallel [(set (match_dup 3) (fix:SI (match_dup 1)))
3975               (clobber (match_dup 2))
3976               (clobber (match_dup 3))
3977               (clobber (match_dup 4))])
3978    (set (match_dup 0) (match_dup 3))]
3979   "")
3981 ;; Signed conversion to HImode.
3983 (define_expand "fix_truncxfhi2"
3984   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3985                    (fix:HI (match_operand:XF 1 "register_operand" "")))
3986               (clobber (match_dup 2))
3987               (clobber (match_dup 3))
3988               (clobber (match_scratch:SI 4 ""))])]
3989   "TARGET_80387"
3990   "operands[2] = assign_386_stack_local (SImode, 0);
3991    operands[3] = assign_386_stack_local (HImode, 1);")
3993 (define_expand "fix_trunctfhi2"
3994   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3995                    (fix:HI (match_operand:TF 1 "register_operand" "")))
3996               (clobber (match_dup 2))
3997               (clobber (match_dup 3))
3998               (clobber (match_scratch:SI 4 ""))])]
3999   "TARGET_80387"
4000   "operands[2] = assign_386_stack_local (SImode, 0);
4001    operands[3] = assign_386_stack_local (HImode, 1);")
4003 (define_expand "fix_truncdfhi2"
4004   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4005                    (fix:HI (match_operand:DF 1 "register_operand" "")))
4006               (clobber (match_dup 2))
4007               (clobber (match_dup 3))
4008               (clobber (match_scratch:SI 4 ""))])]
4009   "TARGET_80387"
4010   "operands[2] = assign_386_stack_local (SImode, 0);
4011    operands[3] = assign_386_stack_local (HImode, 1);")
4013 (define_expand "fix_truncsfhi2"
4014   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4015                    (fix:HI (match_operand:SF 1 "register_operand" "")))
4016               (clobber (match_dup 2))
4017               (clobber (match_dup 3))
4018               (clobber (match_scratch:SI 4 ""))])]
4019   "TARGET_80387"
4020   "operands[2] = assign_386_stack_local (SImode, 0);
4021    operands[3] = assign_386_stack_local (HImode, 1);")
4023 (define_insn "*fix_trunchi_1"
4024   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4025         (fix:HI (match_operand 1 "register_operand" "f,f")))
4026    (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4027    (clobber (match_operand:HI 3 "memory_operand" "=m,m"))
4028    (clobber (match_scratch:SI 4 "=&r,r"))]
4029   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
4030   "* return output_fix_trunc (insn, operands);"
4031   [(set_attr "type" "multi")])
4033 (define_split 
4034   [(set (match_operand:HI 0 "register_operand" "")
4035         (fix:HI (match_operand 1 "register_operand" "")))
4036    (clobber (match_operand:SI 2 "memory_operand" ""))
4037    (clobber (match_operand:HI 3 "memory_operand" ""))
4038    (clobber (match_scratch:SI 4 ""))]
4039   "reload_completed"
4040   [(parallel [(set (match_dup 3) (fix:HI (match_dup 1)))
4041               (clobber (match_dup 2))
4042               (clobber (match_dup 3))
4043               (clobber (match_dup 4))])
4044    (set (match_dup 0) (match_dup 3))]
4045   "")
4047 ;; %% Not used yet.
4048 (define_insn "x86_fnstcw_1"
4049   [(set (match_operand:HI 0 "memory_operand" "=m")
4050         (unspec:HI [(reg:HI 18)] 11))]
4051   "TARGET_80387"
4052   "fnstcw\\t%0"
4053   [(set_attr "length" "2")
4054    (set_attr "mode" "HI")
4055    (set_attr "i387" "1")
4056    (set_attr "ppro_uops" "few")])
4058 (define_insn "x86_fldcw_1"
4059   [(set (reg:HI 18)
4060         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
4061   "TARGET_80387"
4062   "fldcw\\t%0"
4063   [(set_attr "length" "2")
4064    (set_attr "mode" "HI")
4065    (set_attr "i387" "1")
4066    (set_attr "athlon_decode" "vector")
4067    (set_attr "ppro_uops" "few")])
4069 ;; Conversion between fixed point and floating point.
4071 ;; Even though we only accept memory inputs, the backend _really_
4072 ;; wants to be able to do this between registers.
4074 (define_insn "floathisf2"
4075   [(set (match_operand:SF 0 "register_operand" "=f,f")
4076         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4077   "TARGET_80387"
4078   "@
4079    fild%z1\\t%1
4080    #"
4081   [(set_attr "type" "fmov,multi")
4082    (set_attr "mode" "SF")
4083    (set_attr "fp_int_src" "true")])
4085 (define_insn "floatsisf2"
4086   [(set (match_operand:SF 0 "register_operand" "=f,f")
4087         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4088   "TARGET_80387"
4089   "@
4090    fild%z1\\t%1
4091    #"
4092   [(set_attr "type" "fmov,multi")
4093    (set_attr "mode" "SF")
4094    (set_attr "fp_int_src" "true")])
4096 (define_insn "floatdisf2"
4097   [(set (match_operand:SF 0 "register_operand" "=f,f")
4098         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4099   "TARGET_80387"
4100   "@
4101    fild%z1\\t%1
4102    #"
4103   [(set_attr "type" "fmov,multi")
4104    (set_attr "mode" "SF")
4105    (set_attr "fp_int_src" "true")])
4107 (define_insn "floathidf2"
4108   [(set (match_operand:DF 0 "register_operand" "=f,f")
4109         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4110   "TARGET_80387"
4111   "@
4112    fild%z1\\t%1
4113    #"
4114   [(set_attr "type" "fmov,multi")
4115    (set_attr "mode" "DF")
4116    (set_attr "fp_int_src" "true")])
4118 (define_insn "floatsidf2"
4119   [(set (match_operand:DF 0 "register_operand" "=f,f")
4120         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4121   "TARGET_80387"
4122   "@
4123    fild%z1\\t%1
4124    #"
4125   [(set_attr "type" "fmov,multi")
4126    (set_attr "mode" "DF")
4127    (set_attr "fp_int_src" "true")])
4129 (define_insn "floatdidf2"
4130   [(set (match_operand:DF 0 "register_operand" "=f,f")
4131         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4132   "TARGET_80387"
4133   "@
4134    fild%z1\\t%1
4135    #"
4136   [(set_attr "type" "fmov,multi")
4137    (set_attr "mode" "DF")
4138    (set_attr "fp_int_src" "true")])
4140 (define_insn "floathixf2"
4141   [(set (match_operand:XF 0 "register_operand" "=f,f")
4142         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4143   "TARGET_80387"
4144   "@
4145    fild%z1\\t%1
4146    #"
4147   [(set_attr "type" "fmov,multi")
4148    (set_attr "mode" "XF")
4149    (set_attr "fp_int_src" "true")])
4151 (define_insn "floathitf2"
4152   [(set (match_operand:TF 0 "register_operand" "=f,f")
4153         (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4154   "TARGET_80387"
4155   "@
4156    fild%z1\\t%1
4157    #"
4158   [(set_attr "type" "fmov,multi")
4159    (set_attr "mode" "XF")
4160    (set_attr "fp_int_src" "true")])
4162 (define_insn "floatsixf2"
4163   [(set (match_operand:XF 0 "register_operand" "=f,f")
4164         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4165   "TARGET_80387"
4166   "@
4167    fild%z1\\t%1
4168    #"
4169   [(set_attr "type" "fmov,multi")
4170    (set_attr "mode" "XF")
4171    (set_attr "fp_int_src" "true")])
4173 (define_insn "floatsitf2"
4174   [(set (match_operand:TF 0 "register_operand" "=f,f")
4175         (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4176   "TARGET_80387"
4177   "@
4178    fild%z1\\t%1
4179    #"
4180   [(set_attr "type" "fmov,multi")
4181    (set_attr "mode" "XF")
4182    (set_attr "fp_int_src" "true")])
4184 (define_insn "floatdixf2"
4185   [(set (match_operand:XF 0 "register_operand" "=f,f")
4186         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4187   "TARGET_80387"
4188   "@
4189    fild%z1\\t%1
4190    #"
4191   [(set_attr "type" "fmov,multi")
4192    (set_attr "mode" "XF")
4193    (set_attr "fp_int_src" "true")])
4195 (define_insn "floatditf2"
4196   [(set (match_operand:TF 0 "register_operand" "=f,f")
4197         (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4198   "TARGET_80387"
4199   "@
4200    fild%z1\\t%1
4201    #"
4202   [(set_attr "type" "fmov,multi")
4203    (set_attr "mode" "XF")
4204    (set_attr "fp_int_src" "true")])
4206 ;; %%% Kill these when reload knows how to do it.
4207 (define_split
4208   [(set (match_operand 0 "register_operand" "")
4209         (float (match_operand 1 "register_operand" "")))]
4210   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4211   [(const_int 0)]
4212   "
4214   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4215   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4216   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4217   ix86_free_from_memory (GET_MODE (operands[1]));
4218   DONE;
4221 ;; Add instructions
4223 ;; %%% define_expand from the very first?
4224 ;; %%% splits for addsidi3
4225 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4226 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4227 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4229 (define_insn "adddi3"
4230   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4231         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4232                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4233    (clobber (reg:CC 17))]
4234   ""
4235   "#")
4237 (define_split
4238   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4239         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4240                  (match_operand:DI 2 "general_operand" "")))
4241    (clobber (reg:CC 17))]
4242   "reload_completed"
4243   [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
4244               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4245    (parallel [(set (match_dup 3)
4246                    (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4247                                      (match_dup 4))
4248                             (match_dup 5)))
4249               (clobber (reg:CC 17))])]
4250   "split_di (operands+0, 1, operands+0, operands+3);
4251    split_di (operands+1, 1, operands+1, operands+4);
4252    split_di (operands+2, 1, operands+2, operands+5);")
4254 (define_insn "*addsi3_carry"
4255   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4256           (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4257                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4258                    (match_operand:SI 2 "general_operand" "ri,rm")))
4259    (clobber (reg:CC 17))]
4260   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4261   "adc{l}\\t{%2, %0|%0, %2}"
4262   [(set_attr "type" "alu")
4263    (set_attr "pent_pair" "pu")
4264    (set_attr "mode" "SI")
4265    (set_attr "ppro_uops" "few")])
4267 (define_insn "*addsi3_cc"
4268   [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4269                                 (match_operand:SI 2 "general_operand" "ri,rm")] 12))
4270    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4271         (plus:SI (match_dup 1) (match_dup 2)))]
4272   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4273   "add{l}\\t{%2, %0|%0, %2}"
4274   [(set_attr "type" "alu")
4275    (set_attr "mode" "SI")])
4277 (define_insn "addqi3_cc"
4278   [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4279                                 (match_operand:QI 2 "general_operand" "qi,qm")] 12))
4280    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4281         (plus:QI (match_dup 1) (match_dup 2)))]
4282   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4283   "add{b}\\t{%2, %0|%0, %2}"
4284   [(set_attr "type" "alu")
4285    (set_attr "mode" "QI")])
4287 (define_expand "addsi3"
4288   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4289                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4290                             (match_operand:SI 2 "general_operand" "")))
4291               (clobber (reg:CC 17))])]
4292   ""
4293   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4295 (define_insn "*lea_0"
4296   [(set (match_operand:SI 0 "register_operand" "=r")
4297         (match_operand:SI 1 "address_operand" "p"))]
4298   ""
4299   "lea{l}\\t{%a1, %0|%0, %a1}"
4300   [(set_attr "type" "lea")
4301    (set_attr "mode" "SI")])
4303 ;; The lea patterns for non-Pmodes needs to be matched by several
4304 ;; insns converted to real lea by splitters.
4306 (define_insn_and_split "*lea_general_1"
4307   [(set (match_operand 0 "register_operand" "=r")
4308         (plus (plus (match_operand 1 "register_operand" "r")
4309                     (match_operand 2 "register_operand" "r"))
4310               (match_operand 3 "immediate_operand" "i")))]
4311   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
4312    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4313    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4314    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4315    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4316        || GET_MODE (operands[3]) == VOIDmode)"
4317   "#"
4318   "&& reload_completed"
4319   [(const_int 0)]
4320   "
4322   rtx pat;
4323   operands[0] = gen_lowpart (SImode, operands[0]);
4324   operands[1] = gen_lowpart (Pmode, operands[1]);
4325   operands[2] = gen_lowpart (Pmode, operands[2]);
4326   operands[3] = gen_lowpart (Pmode, operands[3]);
4327   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4328                       operands[3]);
4329   if (Pmode != SImode)
4330     pat = gen_rtx_SUBREG (SImode, pat, 0);
4331   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4332   DONE;
4334   [(set_attr "type" "lea")
4335    (set_attr "mode" "SI")])
4337 (define_insn_and_split "*lea_general_2"
4338   [(set (match_operand 0 "register_operand" "=r")
4339         (plus (mult (match_operand 1 "register_operand" "r")
4340                     (match_operand 2 "const248_operand" "i"))
4341               (match_operand 3 "nonmemory_operand" "ri")))]
4342   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
4343    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4344    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4345    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4346        || GET_MODE (operands[3]) == VOIDmode)"
4347   "#"
4348   "&& reload_completed"
4349   [(const_int 0)]
4350   "
4352   rtx pat;
4353   operands[0] = gen_lowpart (SImode, operands[0]);
4354   operands[1] = gen_lowpart (Pmode, operands[1]);
4355   operands[3] = gen_lowpart (Pmode, operands[3]);
4356   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4357                       operands[3]);
4358   if (Pmode != SImode)
4359     pat = gen_rtx_SUBREG (SImode, pat, 0);
4360   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4361   DONE;
4363   [(set_attr "type" "lea")
4364    (set_attr "mode" "SI")])
4366 (define_insn_and_split "*lea_general_3"
4367   [(set (match_operand 0 "register_operand" "=r")
4368         (plus (plus (mult (match_operand 1 "register_operand" "r")
4369                           (match_operand 2 "const248_operand" "i"))
4370                     (match_operand 3 "register_operand" "r"))
4371               (match_operand 4 "immediate_operand" "i")))]
4372   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
4373    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4374    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4375    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4376   "#"
4377   "&& reload_completed"
4378   [(const_int 0)]
4379   "
4381   rtx pat;
4382   operands[0] = gen_lowpart (SImode, operands[0]);
4383   operands[1] = gen_lowpart (Pmode, operands[1]);
4384   operands[3] = gen_lowpart (Pmode, operands[3]);
4385   operands[4] = gen_lowpart (Pmode, operands[4]);
4386   pat = gen_rtx_PLUS (Pmode,
4387                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
4388                                                          operands[2]),
4389                                     operands[3]),
4390                       operands[4]);
4391   if (Pmode != SImode)
4392     pat = gen_rtx_SUBREG (SImode, pat, 0);
4393   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4394   DONE;
4396   [(set_attr "type" "lea")
4397    (set_attr "mode" "SI")])
4399 (define_insn "*addsi_1"
4400   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
4401         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
4402                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
4403    (clobber (reg:CC 17))]
4404   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4405   "*
4407   switch (get_attr_type (insn))
4408     {
4409     case TYPE_LEA:
4410       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
4411       return \"lea{l}\\t{%a2, %0|%0, %a2}\";
4413     case TYPE_INCDEC:
4414       if (! rtx_equal_p (operands[0], operands[1]))
4415         abort ();
4416       if (operands[2] == const1_rtx)
4417         return \"inc{l}\\t%0\";
4418       else if (operands[2] == constm1_rtx)
4419         return \"dec{l}\\t%0\";
4420       else
4421         abort();
4423     default:
4424       if (! rtx_equal_p (operands[0], operands[1]))
4425         abort ();
4427       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4428          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4429       if (GET_CODE (operands[2]) == CONST_INT
4430           && (INTVAL (operands[2]) == 128
4431               || (INTVAL (operands[2]) < 0
4432                   && INTVAL (operands[2]) != -128)))
4433         {
4434           operands[2] = GEN_INT (-INTVAL (operands[2]));
4435           return \"sub{l}\\t{%2, %0|%0, %2}\";
4436         }
4437       return \"add{l}\\t{%2, %0|%0, %2}\";
4438     }
4440   [(set (attr "type")
4441      (cond [(eq_attr "alternative" "2")
4442               (const_string "lea")
4443             ; Current assemblers are broken and do not allow @GOTOFF in
4444             ; ought but a memory context.
4445             (match_operand:SI 2 "pic_symbolic_operand" "")
4446               (const_string "lea")
4447             (match_operand:SI 2 "incdec_operand" "")
4448               (const_string "incdec")
4449            ]
4450            (const_string "alu")))
4451    (set_attr "mode" "SI")])
4453 ;; Convert lea to the lea pattern to avoid flags dependency.
4454 (define_split
4455   [(set (match_operand 0 "register_operand" "")
4456         (plus (match_operand 1 "register_operand" "")
4457               (match_operand 2 "nonmemory_operand" "")))
4458    (clobber (reg:CC 17))]
4459   "reload_completed
4460    && true_regnum (operands[0]) != true_regnum (operands[1])"
4461   [(const_int 0)]
4462   "
4464   rtx pat;
4465   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
4466      may confuse gen_lowpart.  */
4467   if (GET_MODE (operands[0]) != Pmode)
4468     {
4469       operands[1] = gen_lowpart (Pmode, operands[1]);
4470       operands[2] = gen_lowpart (Pmode, operands[2]);
4471     }
4472   operands[0] = gen_lowpart (SImode, operands[0]);
4473   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
4474   if (Pmode != SImode)
4475     pat = gen_rtx_SUBREG (SImode, pat, 0);
4476   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4477   DONE;
4480 (define_insn "*addsi_2"
4481   [(set (reg 17)
4482         (compare
4483           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4484                    (match_operand:SI 2 "general_operand" "rmni,rni"))
4485           (const_int 0)))                       
4486    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4487         (plus:SI (match_dup 1) (match_dup 2)))]
4488   "ix86_match_ccmode (insn, CCGOCmode)
4489    && ix86_binary_operator_ok (PLUS, SImode, operands)
4490    /* Current assemblers are broken and do not allow @GOTOFF in
4491       ought but a memory context. */
4492    && ! pic_symbolic_operand (operands[2], VOIDmode)"
4493   "*
4495   switch (get_attr_type (insn))
4496     {
4497     case TYPE_INCDEC:
4498       if (! rtx_equal_p (operands[0], operands[1]))
4499         abort ();
4500       if (operands[2] == const1_rtx)
4501         return \"inc{l}\\t%0\";
4502       else if (operands[2] == constm1_rtx)
4503         return \"dec{l}\\t%0\";
4504       else
4505         abort();
4507     default:
4508       if (! rtx_equal_p (operands[0], operands[1]))
4509         abort ();
4510       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4511          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4512       if (GET_CODE (operands[2]) == CONST_INT
4513           && (INTVAL (operands[2]) == 128
4514               || (INTVAL (operands[2]) < 0
4515                   && INTVAL (operands[2]) != -128)))
4516         {
4517           operands[2] = GEN_INT (-INTVAL (operands[2]));
4518           return \"sub{l}\\t{%2, %0|%0, %2}\";
4519         }
4520       return \"add{l}\\t{%2, %0|%0, %2}\";
4521     }
4523   [(set (attr "type")
4524      (if_then_else (match_operand:SI 2 "incdec_operand" "")
4525         (const_string "incdec")
4526         (const_string "alu")))
4527    (set_attr "mode" "SI")])
4529 (define_insn "*addsi_3"
4530   [(set (reg 17)
4531         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
4532                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
4533    (clobber (match_scratch:SI 0 "=r"))]
4534   "ix86_match_ccmode (insn, CCZmode)
4535    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
4536    /* Current assemblers are broken and do not allow @GOTOFF in
4537       ought but a memory context. */
4538    && ! pic_symbolic_operand (operands[2], VOIDmode)"
4539   "*
4541   switch (get_attr_type (insn))
4542     {
4543     case TYPE_INCDEC:
4544       if (! rtx_equal_p (operands[0], operands[1]))
4545         abort ();
4546       if (operands[2] == const1_rtx)
4547         return \"inc{l}\\t%0\";
4548       else if (operands[2] == constm1_rtx)
4549         return \"dec{l}\\t%0\";
4550       else
4551         abort();
4553     default:
4554       if (! rtx_equal_p (operands[0], operands[1]))
4555         abort ();
4556       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4557          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4558       if (GET_CODE (operands[2]) == CONST_INT
4559           && (INTVAL (operands[2]) == 128
4560               || (INTVAL (operands[2]) < 0
4561                   && INTVAL (operands[2]) != -128)))
4562         {
4563           operands[2] = GEN_INT (-INTVAL (operands[2]));
4564           return \"sub{l}\\t{%2, %0|%0, %2}\";
4565         }
4566       return \"add{l}\\t{%2, %0|%0, %2}\";
4567     }
4569   [(set (attr "type")
4570      (if_then_else (match_operand:SI 2 "incdec_operand" "")
4571         (const_string "incdec")
4572         (const_string "alu")))
4573    (set_attr "mode" "SI")])
4575 ; For comparisons agains 1, -1 and 128, we may generate better code
4576 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
4577 ; is matched then.  We can't accept general immediate, because for
4578 ; case of overflows,  the result is messed up.
4579 ; This pattern also don't hold of 0x80000000, since the value overflows
4580 ; when negated.
4581 ; Also carry flag is reversed compared to cmp, so this converison is valid
4582 ; only for comparisons not depending on it.
4583 (define_insn "*addsi_4"
4584   [(set (reg 17)
4585         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
4586                  (match_operand:SI 2 "const_int_operand" "n")))
4587    (clobber (match_scratch:SI 0 "=rm"))]
4588   "ix86_match_ccmode (insn, CCGCmode)
4589    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
4590   "*
4592   switch (get_attr_type (insn))
4593     {
4594     case TYPE_INCDEC:
4595       if (operands[2] == constm1_rtx)
4596         return \"inc{l}\\t%0\";
4597       else if (operands[2] == const1_rtx)
4598         return \"dec{l}\\t%0\";
4599       else
4600         abort();
4602     default:
4603       if (! rtx_equal_p (operands[0], operands[1]))
4604         abort ();
4605       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4606          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4607       if ((INTVAL (operands[2]) == -128
4608            || (INTVAL (operands[2]) > 0
4609                && INTVAL (operands[2]) != 128)))
4610         return \"sub{l}\\t{%2, %0|%0, %2}\";
4611       operands[2] = GEN_INT (-INTVAL (operands[2]));
4612       return \"add{l}\\t{%2, %0|%0, %2}\";
4613     }
4615   [(set (attr "type")
4616      (if_then_else (match_operand:SI 2 "incdec_operand" "")
4617         (const_string "incdec")
4618         (const_string "alu")))
4619    (set_attr "mode" "SI")])
4621 (define_insn "*addsi_5"
4622   [(set (reg 17)
4623         (compare
4624           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
4625                    (match_operand:SI 2 "general_operand" "rmni"))
4626           (const_int 0)))                       
4627    (clobber (match_scratch:SI 0 "=r"))]
4628   "ix86_match_ccmode (insn, CCGOCmode)
4629    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
4630    /* Current assemblers are broken and do not allow @GOTOFF in
4631       ought but a memory context. */
4632    && ! pic_symbolic_operand (operands[2], VOIDmode)"
4633   "*
4635   switch (get_attr_type (insn))
4636     {
4637     case TYPE_INCDEC:
4638       if (! rtx_equal_p (operands[0], operands[1]))
4639         abort ();
4640       if (operands[2] == const1_rtx)
4641         return \"inc{l}\\t%0\";
4642       else if (operands[2] == constm1_rtx)
4643         return \"dec{l}\\t%0\";
4644       else
4645         abort();
4647     default:
4648       if (! rtx_equal_p (operands[0], operands[1]))
4649         abort ();
4650       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4651          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4652       if (GET_CODE (operands[2]) == CONST_INT
4653           && (INTVAL (operands[2]) == 128
4654               || (INTVAL (operands[2]) < 0
4655                   && INTVAL (operands[2]) != -128)))
4656         {
4657           operands[2] = GEN_INT (-INTVAL (operands[2]));
4658           return \"sub{l}\\t{%2, %0|%0, %2}\";
4659         }
4660       return \"add{l}\\t{%2, %0|%0, %2}\";
4661     }
4663   [(set (attr "type")
4664      (if_then_else (match_operand:SI 2 "incdec_operand" "")
4665         (const_string "incdec")
4666         (const_string "alu")))
4667    (set_attr "mode" "SI")])
4669 (define_expand "addhi3"
4670   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4671                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
4672                             (match_operand:HI 2 "general_operand" "")))
4673               (clobber (reg:CC 17))])]
4674   "TARGET_HIMODE_MATH"
4675   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
4677 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
4678 ;; type optimizations enabled by define-splits.  This is not important
4679 ;; for PII, and in fact harmful because of partial register stalls.
4681 (define_insn "*addhi_1_lea"
4682   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
4683         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
4684                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
4685    (clobber (reg:CC 17))]
4686   "!TARGET_PARTIAL_REG_STALL
4687    && ix86_binary_operator_ok (PLUS, HImode, operands)"
4688   "*
4690   switch (get_attr_type (insn))
4691     {
4692     case TYPE_LEA:
4693       return \"#\";
4694     case TYPE_INCDEC:
4695       if (operands[2] == const1_rtx)
4696         return \"inc{w}\\t%0\";
4697       else if (operands[2] == constm1_rtx
4698                || (GET_CODE (operands[2]) == CONST_INT
4699                    && INTVAL (operands[2]) == 65535))
4700         return \"dec{w}\\t%0\";
4701       abort();
4703     default:
4704       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4705          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4706       if (GET_CODE (operands[2]) == CONST_INT
4707           && (INTVAL (operands[2]) == 128
4708               || (INTVAL (operands[2]) < 0
4709                   && INTVAL (operands[2]) != -128)))
4710         {
4711           operands[2] = GEN_INT (-INTVAL (operands[2]));
4712           return \"sub{w}\\t{%2, %0|%0, %2}\";
4713         }
4714       return \"add{w}\\t{%2, %0|%0, %2}\";
4715     }
4717   [(set (attr "type")
4718      (if_then_else (eq_attr "alternative" "2")
4719         (const_string "lea")
4720         (if_then_else (match_operand:HI 2 "incdec_operand" "")
4721            (const_string "incdec")
4722            (const_string "alu"))))
4723    (set_attr "mode" "HI,HI,SI")])
4725 (define_insn "*addhi_1"
4726   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4727         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4728                  (match_operand:HI 2 "general_operand" "ri,rm")))
4729    (clobber (reg:CC 17))]
4730   "TARGET_PARTIAL_REG_STALL
4731    && ix86_binary_operator_ok (PLUS, HImode, operands)"
4732   "*
4734   switch (get_attr_type (insn))
4735     {
4736     case TYPE_INCDEC:
4737       if (operands[2] == const1_rtx)
4738         return \"inc{w}\\t%0\";
4739       else if (operands[2] == constm1_rtx
4740                || (GET_CODE (operands[2]) == CONST_INT
4741                    && INTVAL (operands[2]) == 65535))
4742         return \"dec{w}\\t%0\";
4743       abort();
4745     default:
4746       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4747          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4748       if (GET_CODE (operands[2]) == CONST_INT
4749           && (INTVAL (operands[2]) == 128
4750               || (INTVAL (operands[2]) < 0
4751                   && INTVAL (operands[2]) != -128)))
4752         {
4753           operands[2] = GEN_INT (-INTVAL (operands[2]));
4754           return \"sub{w}\\t{%2, %0|%0, %2}\";
4755         }
4756       return \"add{w}\\t{%2, %0|%0, %2}\";
4757     }
4759   [(set (attr "type")
4760      (if_then_else (match_operand:HI 2 "incdec_operand" "")
4761         (const_string "incdec")
4762         (const_string "alu")))
4763    (set_attr "mode" "HI")])
4765 (define_insn "*addhi_2"
4766   [(set (reg 17)
4767         (compare
4768           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4769                    (match_operand:HI 2 "general_operand" "rmni,rni"))
4770           (const_int 0)))                       
4771    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
4772         (plus:HI (match_dup 1) (match_dup 2)))]
4773   "ix86_match_ccmode (insn, CCGOCmode)
4774    && ix86_binary_operator_ok (PLUS, HImode, operands)"
4775   "*
4777   switch (get_attr_type (insn))
4778     {
4779     case TYPE_INCDEC:
4780       if (operands[2] == const1_rtx)
4781         return \"inc{w}\\t%0\";
4782       else if (operands[2] == constm1_rtx
4783                || (GET_CODE (operands[2]) == CONST_INT
4784                    && INTVAL (operands[2]) == 65535))
4785         return \"dec{w}\\t%0\";
4786       abort();
4788     default:
4789       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4790          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4791       if (GET_CODE (operands[2]) == CONST_INT
4792           && (INTVAL (operands[2]) == 128
4793               || (INTVAL (operands[2]) < 0
4794                   && INTVAL (operands[2]) != -128)))
4795         {
4796           operands[2] = GEN_INT (-INTVAL (operands[2]));
4797           return \"sub{w}\\t{%2, %0|%0, %2}\";
4798         }
4799       return \"add{w}\\t{%2, %0|%0, %2}\";
4800     }
4802   [(set (attr "type")
4803      (if_then_else (match_operand:HI 2 "incdec_operand" "")
4804         (const_string "incdec")
4805         (const_string "alu")))
4806    (set_attr "mode" "HI")])
4808 (define_insn "*addhi_3"
4809   [(set (reg 17)
4810         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
4811                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
4812    (clobber (match_scratch:HI 0 "=r"))]
4813   "ix86_match_ccmode (insn, CCZmode)
4814    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
4815   "*
4817   switch (get_attr_type (insn))
4818     {
4819     case TYPE_INCDEC:
4820       if (operands[2] == const1_rtx)
4821         return \"inc{w}\\t%0\";
4822       else if (operands[2] == constm1_rtx
4823                || (GET_CODE (operands[2]) == CONST_INT
4824                    && INTVAL (operands[2]) == 65535))
4825         return \"dec{w}\\t%0\";
4826       abort();
4828     default:
4829       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4830          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4831       if (GET_CODE (operands[2]) == CONST_INT
4832           && (INTVAL (operands[2]) == 128
4833               || (INTVAL (operands[2]) < 0
4834                   && INTVAL (operands[2]) != -128)))
4835         {
4836           operands[2] = GEN_INT (-INTVAL (operands[2]));
4837           return \"sub{w}\\t{%2, %0|%0, %2}\";
4838         }
4839       return \"add{w}\\t{%2, %0|%0, %2}\";
4840     }
4842   [(set (attr "type")
4843      (if_then_else (match_operand:HI 2 "incdec_operand" "")
4844         (const_string "incdec")
4845         (const_string "alu")))
4846    (set_attr "mode" "HI")])
4848 ; See comments above addsi_3_imm for details.
4849 (define_insn "*addhi_4"
4850   [(set (reg 17)
4851         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
4852                  (match_operand:HI 2 "const_int_operand" "n")))
4853    (clobber (match_scratch:HI 0 "=rm"))]
4854   "ix86_match_ccmode (insn, CCGCmode)
4855    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
4856   "*
4858   switch (get_attr_type (insn))
4859     {
4860     case TYPE_INCDEC:
4861       if (operands[2] == constm1_rtx
4862           || (GET_CODE (operands[2]) == CONST_INT
4863               && INTVAL (operands[2]) == 65535))
4864         return \"inc{w}\\t%0\";
4865       else if (operands[2] == const1_rtx)
4866         return \"dec{w}\\t%0\";
4867       else
4868         abort();
4870     default:
4871       if (! rtx_equal_p (operands[0], operands[1]))
4872         abort ();
4873       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4874          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4875       if ((INTVAL (operands[2]) == -128
4876            || (INTVAL (operands[2]) > 0
4877                && INTVAL (operands[2]) != 128)))
4878         return \"sub{w}\\t{%2, %0|%0, %2}\";
4879       operands[2] = GEN_INT (-INTVAL (operands[2]));
4880       return \"add{w}\\t{%2, %0|%0, %2}\";
4881     }
4883   [(set (attr "type")
4884      (if_then_else (match_operand:HI 2 "incdec_operand" "")
4885         (const_string "incdec")
4886         (const_string "alu")))
4887    (set_attr "mode" "SI")])
4890 (define_insn "*addhi_5"
4891   [(set (reg 17)
4892         (compare
4893           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
4894                    (match_operand:HI 2 "general_operand" "rmni"))
4895           (const_int 0)))                       
4896    (clobber (match_scratch:HI 0 "=r"))]
4897   "ix86_match_ccmode (insn, CCGOCmode)
4898    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
4899   "*
4901   switch (get_attr_type (insn))
4902     {
4903     case TYPE_INCDEC:
4904       if (operands[2] == const1_rtx)
4905         return \"inc{w}\\t%0\";
4906       else if (operands[2] == constm1_rtx
4907                || (GET_CODE (operands[2]) == CONST_INT
4908                    && INTVAL (operands[2]) == 65535))
4909         return \"dec{w}\\t%0\";
4910       abort();
4912     default:
4913       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4914          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4915       if (GET_CODE (operands[2]) == CONST_INT
4916           && (INTVAL (operands[2]) == 128
4917               || (INTVAL (operands[2]) < 0
4918                   && INTVAL (operands[2]) != -128)))
4919         {
4920           operands[2] = GEN_INT (-INTVAL (operands[2]));
4921           return \"sub{w}\\t{%2, %0|%0, %2}\";
4922         }
4923       return \"add{w}\\t{%2, %0|%0, %2}\";
4924     }
4926   [(set (attr "type")
4927      (if_then_else (match_operand:HI 2 "incdec_operand" "")
4928         (const_string "incdec")
4929         (const_string "alu")))
4930    (set_attr "mode" "HI")])
4932 (define_expand "addqi3"
4933   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
4934                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
4935                             (match_operand:QI 2 "general_operand" "")))
4936               (clobber (reg:CC 17))])]
4937   "TARGET_QIMODE_MATH"
4938   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
4940 ;; %%% Potential partial reg stall on alternative 2.  What to do?
4941 (define_insn "*addqi_1_lea"
4942   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
4943         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
4944                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
4945    (clobber (reg:CC 17))]
4946   "!TARGET_PARTIAL_REG_STALL
4947    && ix86_binary_operator_ok (PLUS, QImode, operands)"
4948   "*
4950   int widen = (which_alternative == 2);
4951   switch (get_attr_type (insn))
4952     {
4953     case TYPE_LEA:
4954       return \"#\";
4955     case TYPE_INCDEC:
4956       if (operands[2] == const1_rtx)
4957         return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
4958       else if (operands[2] == constm1_rtx
4959                || (GET_CODE (operands[2]) == CONST_INT
4960                    && INTVAL (operands[2]) == 255))
4961         return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
4962       abort();
4964     default:
4965       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4966          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
4967       if (GET_CODE (operands[2]) == CONST_INT
4968           && (INTVAL (operands[2]) == 128
4969               || (INTVAL (operands[2]) < 0
4970                   && INTVAL (operands[2]) != -128)))
4971         {
4972           operands[2] = GEN_INT (-INTVAL (operands[2]));
4973           if (widen)
4974             return \"sub{l}\\t{%2, %k0|%k0, %2}\";
4975           else
4976             return \"sub{b}\\t{%2, %0|%0, %2}\";
4977         }
4978       if (widen)
4979         return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
4980       else
4981         return \"add{b}\\t{%2, %0|%0, %2}\";
4982     }
4984   [(set (attr "type")
4985      (if_then_else (eq_attr "alternative" "3")
4986         (const_string "lea")
4987         (if_then_else (match_operand:QI 2 "incdec_operand" "")
4988            (const_string "incdec")
4989            (const_string "alu"))))
4990    (set_attr "mode" "QI,QI,SI,SI")])
4992 (define_insn "*addqi_1"
4993   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
4994         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
4995                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
4996    (clobber (reg:CC 17))]
4997   "TARGET_PARTIAL_REG_STALL
4998    && ix86_binary_operator_ok (PLUS, QImode, operands)"
4999   "*
5001   int widen = (which_alternative == 2);
5002   switch (get_attr_type (insn))
5003     {
5004     case TYPE_INCDEC:
5005       if (operands[2] == const1_rtx)
5006         return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
5007       else if (operands[2] == constm1_rtx
5008                || (GET_CODE (operands[2]) == CONST_INT
5009                    && INTVAL (operands[2]) == 255))
5010         return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
5011       abort();
5013     default:
5014       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5015          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5016       if (GET_CODE (operands[2]) == CONST_INT
5017           && (INTVAL (operands[2]) == 128
5018               || (INTVAL (operands[2]) < 0
5019                   && INTVAL (operands[2]) != -128)))
5020         {
5021           operands[2] = GEN_INT (-INTVAL (operands[2]));
5022           if (widen)
5023             return \"sub{l}\\t{%2, %k0|%k0, %2}\";
5024           else
5025             return \"sub{b}\\t{%2, %0|%0, %2}\";
5026         }
5027       if (widen)
5028         return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
5029       else
5030         return \"add{b}\\t{%2, %0|%0, %2}\";
5031     }
5033   [(set (attr "type")
5034      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5035         (const_string "incdec")
5036         (const_string "alu")))
5037    (set_attr "mode" "QI,QI,SI")])
5039 (define_insn "*addqi_2"
5040   [(set (reg 17)
5041         (compare
5042           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
5043                    (match_operand:QI 2 "general_operand" "qmni,qni"))
5044           (const_int 0)))
5045    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
5046         (plus:QI (match_dup 1) (match_dup 2)))]
5047   "ix86_match_ccmode (insn, CCGOCmode)
5048    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5049   "*
5051   switch (get_attr_type (insn))
5052     {
5053     case TYPE_INCDEC:
5054       if (operands[2] == const1_rtx)
5055         return \"inc{b}\\t%0\";
5056       else if (operands[2] == constm1_rtx
5057                || (GET_CODE (operands[2]) == CONST_INT
5058                    && INTVAL (operands[2]) == 255))
5059         return \"dec{b}\\t%0\";
5060       abort();
5062     default:
5063       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
5064       if (GET_CODE (operands[2]) == CONST_INT
5065           && INTVAL (operands[2]) < 0)
5066         {
5067           operands[2] = GEN_INT (-INTVAL (operands[2]));
5068           return \"sub{b}\\t{%2, %0|%0, %2}\";
5069         }
5070       return \"add{b}\\t{%2, %0|%0, %2}\";
5071     }
5073   [(set (attr "type")
5074      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5075         (const_string "incdec")
5076         (const_string "alu")))
5077    (set_attr "mode" "QI")])
5079 (define_insn "*addqi_3"
5080   [(set (reg 17)
5081         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
5082                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
5083    (clobber (match_scratch:QI 0 "=q"))]
5084   "ix86_match_ccmode (insn, CCZmode)
5085    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5086   "*
5088   switch (get_attr_type (insn))
5089     {
5090     case TYPE_INCDEC:
5091       if (operands[2] == const1_rtx)
5092         return \"inc{b}\\t%0\";
5093       else if (operands[2] == constm1_rtx
5094                || (GET_CODE (operands[2]) == CONST_INT
5095                    && INTVAL (operands[2]) == 255))
5096         return \"dec{b}\\t%0\";
5097       abort();
5099     default:
5100       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
5101       if (GET_CODE (operands[2]) == CONST_INT
5102           && INTVAL (operands[2]) < 0)
5103         {
5104           operands[2] = GEN_INT (-INTVAL (operands[2]));
5105           return \"sub{b}\\t{%2, %0|%0, %2}\";
5106         }
5107       return \"add{b}\\t{%2, %0|%0, %2}\";
5108     }
5110   [(set (attr "type")
5111      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5112         (const_string "incdec")
5113         (const_string "alu")))
5114    (set_attr "mode" "QI")])
5116 ; See comments above addsi_3_imm for details.
5117 (define_insn "*addqi_4"
5118   [(set (reg 17)
5119         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
5120                  (match_operand:QI 2 "const_int_operand" "n")))
5121    (clobber (match_scratch:QI 0 "=qm"))]
5122   "ix86_match_ccmode (insn, CCGCmode)
5123    && (INTVAL (operands[2]) & 0xff) != 0x80"
5124   "*
5126   switch (get_attr_type (insn))
5127     {
5128     case TYPE_INCDEC:
5129       if (operands[2] == constm1_rtx
5130           || (GET_CODE (operands[2]) == CONST_INT
5131               && INTVAL (operands[2]) == 255))
5132         return \"inc{b}\\t%0\";
5133       else if (operands[2] == const1_rtx)
5134         return \"dec{b}\\t%0\";
5135       else
5136         abort();
5138     default:
5139       if (! rtx_equal_p (operands[0], operands[1]))
5140         abort ();
5141       if (INTVAL (operands[2]) < 0)
5142         {
5143           operands[2] = GEN_INT (-INTVAL (operands[2]));
5144           return \"add{b}\\t{%2, %0|%0, %2}\";
5145         }
5146       return \"sub{b}\\t{%2, %0|%0, %2}\";
5147     }
5149   [(set (attr "type")
5150      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5151         (const_string "incdec")
5152         (const_string "alu")))
5153    (set_attr "mode" "QI")])
5156 (define_insn "*addqi_5"
5157   [(set (reg 17)
5158         (compare
5159           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
5160                    (match_operand:QI 2 "general_operand" "qmni"))
5161           (const_int 0)))
5162    (clobber (match_scratch:QI 0 "=q"))]
5163   "ix86_match_ccmode (insn, CCGOCmode)
5164    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5165   "*
5167   switch (get_attr_type (insn))
5168     {
5169     case TYPE_INCDEC:
5170       if (operands[2] == const1_rtx)
5171         return \"inc{b}\\t%0\";
5172       else if (operands[2] == constm1_rtx
5173                || (GET_CODE (operands[2]) == CONST_INT
5174                    && INTVAL (operands[2]) == 255))
5175         return \"dec{b}\\t%0\";
5176       abort();
5178     default:
5179       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
5180       if (GET_CODE (operands[2]) == CONST_INT
5181           && INTVAL (operands[2]) < 0)
5182         {
5183           operands[2] = GEN_INT (-INTVAL (operands[2]));
5184           return \"sub{b}\\t{%2, %0|%0, %2}\";
5185         }
5186       return \"add{b}\\t{%2, %0|%0, %2}\";
5187     }
5189   [(set (attr "type")
5190      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5191         (const_string "incdec")
5192         (const_string "alu")))
5193    (set_attr "mode" "QI")])
5196 (define_insn "addqi_ext_1"
5197   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5198                          (const_int 8)
5199                          (const_int 8))
5200         (plus:SI
5201           (zero_extract:SI
5202             (match_operand 1 "ext_register_operand" "0")
5203             (const_int 8)
5204             (const_int 8))
5205           (match_operand:QI 2 "general_operand" "qmn")))
5206    (clobber (reg:CC 17))]
5207   ""
5208   "*
5210   switch (get_attr_type (insn))
5211     {
5212     case TYPE_INCDEC:
5213       if (operands[2] == const1_rtx)
5214         return \"inc{b}\\t%h0\";
5215       else if (operands[2] == constm1_rtx
5216                || (GET_CODE (operands[2]) == CONST_INT
5217                    && INTVAL (operands[2]) == 255))
5218         return \"dec{b}\\t%h0\";
5219       abort();
5221     default:
5222       return \"add{b}\\t{%2, %h0|%h0, %2}\";
5223     }
5225   [(set (attr "type")
5226      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5227         (const_string "incdec")
5228         (const_string "alu")))
5229    (set_attr "mode" "QI")])
5231 (define_insn "*addqi_ext_2"
5232   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5233                          (const_int 8)
5234                          (const_int 8))
5235         (plus:SI
5236           (zero_extract:SI
5237             (match_operand 1 "ext_register_operand" "%0")
5238             (const_int 8)
5239             (const_int 8))
5240           (zero_extract:SI
5241             (match_operand 2 "ext_register_operand" "q")
5242             (const_int 8)
5243             (const_int 8))))
5244    (clobber (reg:CC 17))]
5245   ""
5246   "add{b}\\t{%h2, %h0|%h0, %h2}"
5247   [(set_attr "type" "alu")
5248    (set_attr "mode" "QI")])
5250 ;; The patterns that match these are at the end of this file.
5252 (define_expand "addxf3"
5253   [(set (match_operand:XF 0 "register_operand" "")
5254         (plus:XF (match_operand:XF 1 "register_operand" "")
5255                  (match_operand:XF 2 "register_operand" "")))]
5256   "TARGET_80387"
5257   "")
5259 (define_expand "addtf3"
5260   [(set (match_operand:TF 0 "register_operand" "")
5261         (plus:TF (match_operand:TF 1 "register_operand" "")
5262                  (match_operand:TF 2 "register_operand" "")))]
5263   "TARGET_80387"
5264   "")
5266 (define_expand "adddf3"
5267   [(set (match_operand:DF 0 "register_operand" "")
5268         (plus:DF (match_operand:DF 1 "register_operand" "")
5269                  (match_operand:DF 2 "nonimmediate_operand" "")))]
5270   "TARGET_80387"
5271   "")
5273 (define_expand "addsf3"
5274   [(set (match_operand:SF 0 "register_operand" "")
5275         (plus:SF (match_operand:SF 1 "register_operand" "")
5276                  (match_operand:SF 2 "nonimmediate_operand" "")))]
5277   "TARGET_80387"
5278   "")
5280 ;; Subtract instructions
5282 ;; %%% define_expand from the very first?
5283 ;; %%% splits for subsidi3
5285 (define_insn "subdi3"
5286   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5287         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
5288                   (match_operand:DI 2 "general_operand" "roiF,riF")))
5289    (clobber (reg:CC 17))]
5290   ""
5291   "#")
5293 (define_split
5294   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5295         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5296                   (match_operand:DI 2 "general_operand" "")))
5297    (clobber (reg:CC 17))]
5298   "reload_completed"
5299   [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
5300               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
5301    (parallel [(set (match_dup 3)
5302                    (minus:SI (match_dup 4)
5303                              (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5304                                       (match_dup 5))))
5305               (clobber (reg:CC 17))])]
5306   "split_di (operands+0, 1, operands+0, operands+3);
5307    split_di (operands+1, 1, operands+1, operands+4);
5308    split_di (operands+2, 1, operands+2, operands+5);")
5310 (define_insn "subsi3_carry"
5311   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5312           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5313             (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5314                (match_operand:SI 2 "general_operand" "ri,rm"))))
5315    (clobber (reg:CC 17))]
5316   "ix86_binary_operator_ok (MINUS, SImode, operands)"
5317   "sbb{l}\\t{%2, %0|%0, %2}"
5318   [(set_attr "type" "alu")
5319    (set_attr "pent_pair" "pu")
5320    (set_attr "ppro_uops" "few")
5321    (set_attr "mode" "SI")])
5323 (define_expand "subsi3"
5324   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5325                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5326                              (match_operand:SI 2 "general_operand" "")))
5327               (clobber (reg:CC 17))])]
5328   ""
5329   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
5331 (define_insn "*subsi_1"
5332   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5333         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5334                   (match_operand:SI 2 "general_operand" "ri,rm")))
5335    (clobber (reg:CC 17))]
5336   "ix86_binary_operator_ok (MINUS, SImode, operands)"
5337   "sub{l}\\t{%2, %0|%0, %2}"
5338   [(set_attr "type" "alu")
5339    (set_attr "mode" "SI")])
5341 (define_insn "*subsi_2"
5342   [(set (reg 17)
5343         (compare
5344           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5345                     (match_operand:SI 2 "general_operand" "ri,rm"))
5346           (const_int 0)))
5347    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5348         (minus:SI (match_dup 1) (match_dup 2)))]
5349   "ix86_match_ccmode (insn, CCGOCmode)
5350    && ix86_binary_operator_ok (MINUS, SImode, operands)"
5351   "sub{l}\\t{%2, %0|%0, %2}"
5352   [(set_attr "type" "alu")
5353    (set_attr "mode" "SI")])
5355 (define_insn "*subsi_3"
5356   [(set (reg 17)
5357         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
5358                  (match_operand:SI 2 "general_operand" "ri,rm")))
5359    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5360         (minus:SI (match_dup 1) (match_dup 2)))]
5361   "ix86_match_ccmode (insn, CCmode)
5362    && ix86_binary_operator_ok (MINUS, SImode, operands)"
5363   "sub{l}\\t{%2, %0|%0, %2}"
5364   [(set_attr "type" "alu")
5365    (set_attr "mode" "SI")])
5367 (define_expand "subhi3"
5368   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5369                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5370                              (match_operand:HI 2 "general_operand" "")))
5371               (clobber (reg:CC 17))])]
5372   "TARGET_HIMODE_MATH"
5373   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
5375 (define_insn "*subhi_1"
5376   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5377         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
5378                   (match_operand:HI 2 "general_operand" "ri,rm")))
5379    (clobber (reg:CC 17))]
5380   "ix86_binary_operator_ok (MINUS, HImode, operands)"
5381   "sub{w}\\t{%2, %0|%0, %2}"
5382   [(set_attr "type" "alu")
5383    (set_attr "mode" "HI")])
5385 (define_insn "*subhi_2"
5386   [(set (reg 17)
5387         (compare
5388           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
5389                     (match_operand:HI 2 "general_operand" "ri,rm"))
5390           (const_int 0)))
5391    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5392         (minus:HI (match_dup 1) (match_dup 2)))]
5393   "ix86_match_ccmode (insn, CCGOCmode)
5394    && ix86_binary_operator_ok (MINUS, HImode, operands)"
5395   "sub{w}\\t{%2, %0|%0, %2}"
5396   [(set_attr "type" "alu")
5397    (set_attr "mode" "HI")])
5399 (define_insn "*subhi_3"
5400   [(set (reg 17)
5401         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
5402                  (match_operand:HI 2 "general_operand" "ri,rm")))
5403    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5404         (minus:HI (match_dup 1) (match_dup 2)))]
5405   "ix86_match_ccmode (insn, CCmode)
5406    && ix86_binary_operator_ok (MINUS, HImode, operands)"
5407   "sub{w}\\t{%2, %0|%0, %2}"
5408   [(set_attr "type" "alu")
5409    (set_attr "mode" "HI")])
5411 (define_expand "subqi3"
5412   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5413                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5414                              (match_operand:QI 2 "general_operand" "")))
5415               (clobber (reg:CC 17))])]
5416   "TARGET_QIMODE_MATH"
5417   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
5419 (define_insn "*subqi_1"
5420   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5421         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
5422                   (match_operand:QI 2 "general_operand" "qn,qmn")))
5423    (clobber (reg:CC 17))]
5424   "ix86_binary_operator_ok (MINUS, QImode, operands)"
5425   "sub{b}\\t{%2, %0|%0, %2}"
5426   [(set_attr "type" "alu")
5427    (set_attr "mode" "QI")])
5429 (define_insn "*subqi_2"
5430   [(set (reg 17)
5431         (compare
5432           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
5433                     (match_operand:QI 2 "general_operand" "qi,qm"))
5434           (const_int 0)))
5435    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
5436         (minus:HI (match_dup 1) (match_dup 2)))]
5437   "ix86_match_ccmode (insn, CCGOCmode)
5438    && ix86_binary_operator_ok (MINUS, QImode, operands)"
5439   "sub{b}\\t{%2, %0|%0, %2}"
5440   [(set_attr "type" "alu")
5441    (set_attr "mode" "QI")])
5443 (define_insn "*subqi_3"
5444   [(set (reg 17)
5445         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
5446                  (match_operand:QI 2 "general_operand" "qi,qm")))
5447    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
5448         (minus:HI (match_dup 1) (match_dup 2)))]
5449   "ix86_match_ccmode (insn, CCmode)
5450    && ix86_binary_operator_ok (MINUS, QImode, operands)"
5451   "sub{b}\\t{%2, %0|%0, %2}"
5452   [(set_attr "type" "alu")
5453    (set_attr "mode" "QI")])
5455 ;; The patterns that match these are at the end of this file.
5457 (define_expand "subxf3"
5458   [(set (match_operand:XF 0 "register_operand" "")
5459         (minus:XF (match_operand:XF 1 "register_operand" "")
5460                   (match_operand:XF 2 "register_operand" "")))]
5461   "TARGET_80387"
5462   "")
5464 (define_expand "subtf3"
5465   [(set (match_operand:TF 0 "register_operand" "")
5466         (minus:TF (match_operand:TF 1 "register_operand" "")
5467                   (match_operand:TF 2 "register_operand" "")))]
5468   "TARGET_80387"
5469   "")
5471 (define_expand "subdf3"
5472   [(set (match_operand:DF 0 "register_operand" "")
5473         (minus:DF (match_operand:DF 1 "register_operand" "")
5474                   (match_operand:DF 2 "nonimmediate_operand" "")))]
5475   "TARGET_80387"
5476   "")
5478 (define_expand "subsf3"
5479   [(set (match_operand:SF 0 "register_operand" "")
5480         (minus:SF (match_operand:SF 1 "register_operand" "")
5481                   (match_operand:SF 2 "nonimmediate_operand" "")))]
5482   "TARGET_80387"
5483   "")
5485 ;; Multiply instructions
5487 (define_expand "mulsi3"
5488   [(parallel [(set (match_operand:SI 0 "register_operand" "")
5489                    (mult:SI (match_operand:SI 1 "register_operand" "")
5490                             (match_operand:SI 2 "general_operand" "")))
5491               (clobber (reg:CC 17))])]
5492   ""
5493   "")
5495 (define_insn "*mulsi3_1"
5496   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
5497         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
5498                  (match_operand:SI 2 "general_operand" "K,i,mr")))
5499    (clobber (reg:CC 17))]
5500   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
5501   ; For the {r,0,i} alternative (i.e., register <- register * immediate),
5502   ; there are two ways of writing the exact same machine instruction
5503   ; in assembly language.  One, for example, is:
5504   ;
5505   ;   imul $12, %eax
5506   ;
5507   ; while the other is:
5508   ;
5509   ;   imul $12, %eax, %eax
5510   ;
5511   ; The first is simply short-hand for the latter.  But, some assemblers,
5512   ; like the SCO OSR5 COFF assembler, don't handle the first form.
5513   "@
5514    imul{l}\\t{%2, %1, %0|%0, %1, %2}
5515    imul{l}\\t{%2, %1, %0|%0, %1, %2}
5516    imul{l}\\t{%2, %0|%0, %2}"
5517   [(set_attr "type" "imul")
5518    (set_attr "prefix_0f" "0,0,1")
5519    (set_attr "mode" "SI")])
5521 (define_expand "mulhi3"
5522   [(parallel [(set (match_operand:HI 0 "register_operand" "")
5523                    (mult:HI (match_operand:HI 1 "register_operand" "")
5524                             (match_operand:HI 2 "general_operand" "")))
5525               (clobber (reg:CC 17))])]
5526   "TARGET_HIMODE_MATH"
5527   "")
5529 (define_insn "*mulhi3_1"
5530   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
5531         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
5532                  (match_operand:HI 2 "general_operand" "K,i,mr")))
5533    (clobber (reg:CC 17))]
5534   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
5535   ; %%% There was a note about "Assembler has weird restrictions",
5536   ; concerning alternative 1 when op1 == op0.  True?
5537   "@
5538    imul{w}\\t{%2, %1, %0|%0, %1, %2}
5539    imul{w}\\t{%2, %1, %0|%0, %1, %2}
5540    imul{w}\\t{%2, %0|%0, %2}"
5541   [(set_attr "type" "imul")
5542    (set_attr "prefix_0f" "0,0,1")
5543    (set_attr "mode" "HI")])
5545 (define_insn "mulqi3"
5546   [(set (match_operand:QI 0 "register_operand" "=a")
5547         (mult:QI (match_operand:QI 1 "register_operand" "%0")
5548                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
5549    (clobber (reg:CC 17))]
5550   "TARGET_QIMODE_MATH"
5551   "mul{b}\\t%2"
5552   [(set_attr "type" "imul")
5553    (set_attr "length_immediate" "0")
5554    (set_attr "mode" "QI")])
5556 (define_insn "umulqihi3"
5557   [(set (match_operand:HI 0 "register_operand" "=a")
5558         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
5559                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
5560    (clobber (reg:CC 17))]
5561   "TARGET_QIMODE_MATH"
5562   "mul{b}\\t%2"
5563   [(set_attr "type" "imul")
5564    (set_attr "length_immediate" "0")
5565    (set_attr "mode" "QI")])
5567 (define_insn "mulqihi3"
5568   [(set (match_operand:HI 0 "register_operand" "=a")
5569         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
5570                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
5571    (clobber (reg:CC 17))]
5572   "TARGET_QIMODE_MATH"
5573   "imul{b}\\t%2"
5574   [(set_attr "type" "imul")
5575    (set_attr "length_immediate" "0")
5576    (set_attr "mode" "QI")])
5578 (define_insn "umulsidi3"
5579   [(set (match_operand:DI 0 "register_operand" "=A")
5580         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
5581                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
5582    (clobber (reg:CC 17))]
5583   ""
5584   "mul{l}\\t%2"
5585   [(set_attr "type" "imul")
5586    (set_attr "ppro_uops" "few")
5587    (set_attr "length_immediate" "0")
5588    (set_attr "mode" "SI")])
5590 (define_insn "mulsidi3"
5591   [(set (match_operand:DI 0 "register_operand" "=A")
5592         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
5593                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
5594    (clobber (reg:CC 17))]
5595   ""
5596   "imul{l}\\t%2"
5597   [(set_attr "type" "imul")
5598    (set_attr "length_immediate" "0")
5599    (set_attr "mode" "SI")])
5601 (define_insn "umulsi3_highpart"
5602   [(set (match_operand:SI 0 "register_operand" "=d")
5603         (truncate:SI
5604           (lshiftrt:DI
5605             (mult:DI (zero_extend:DI
5606                        (match_operand:SI 1 "register_operand" "%a"))
5607                      (zero_extend:DI
5608                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
5609             (const_int 32))))
5610    (clobber (match_scratch:SI 3 "=a"))
5611    (clobber (reg:CC 17))]
5612   ""
5613   "mul{l}\\t%2"
5614   [(set_attr "type" "imul")
5615    (set_attr "ppro_uops" "few")
5616    (set_attr "length_immediate" "0")
5617    (set_attr "mode" "SI")])
5619 (define_insn "smulsi3_highpart"
5620   [(set (match_operand:SI 0 "register_operand" "=d")
5621         (truncate:SI
5622           (lshiftrt:DI
5623             (mult:DI (sign_extend:DI
5624                        (match_operand:SI 1 "register_operand" "%a"))
5625                      (sign_extend:DI
5626                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
5627             (const_int 32))))
5628    (clobber (match_scratch:SI 3 "=a"))
5629    (clobber (reg:CC 17))]
5630   ""
5631   "imul{l}\\t%2"
5632   [(set_attr "type" "imul")
5633    (set_attr "ppro_uops" "few")
5634    (set_attr "mode" "SI")])
5636 ;; The patterns that match these are at the end of this file.
5638 (define_expand "mulxf3"
5639   [(set (match_operand:XF 0 "register_operand" "")
5640         (mult:XF (match_operand:XF 1 "register_operand" "")
5641                  (match_operand:XF 2 "register_operand" "")))]
5642   "TARGET_80387"
5643   "")
5645 (define_expand "multf3"
5646   [(set (match_operand:TF 0 "register_operand" "")
5647         (mult:TF (match_operand:TF 1 "register_operand" "")
5648                  (match_operand:TF 2 "register_operand" "")))]
5649   "TARGET_80387"
5650   "")
5652 (define_expand "muldf3"
5653   [(set (match_operand:DF 0 "register_operand" "")
5654         (mult:DF (match_operand:DF 1 "register_operand" "")
5655                  (match_operand:DF 2 "nonimmediate_operand" "")))]
5656   "TARGET_80387"
5657   "")
5659 (define_expand "mulsf3"
5660   [(set (match_operand:SF 0 "register_operand" "")
5661         (mult:SF (match_operand:SF 1 "register_operand" "")
5662                  (match_operand:SF 2 "nonimmediate_operand" "")))]
5663   "TARGET_80387"
5664   "")
5666 ;; Divide instructions
5668 (define_insn "divqi3"
5669   [(set (match_operand:QI 0 "register_operand" "=a")
5670         (div:QI (match_operand:HI 1 "register_operand" "0")
5671                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
5672    (clobber (reg:CC 17))]
5673   "TARGET_QIMODE_MATH"
5674   "idiv{b}\\t%2"
5675   [(set_attr "type" "idiv")
5676    (set_attr "mode" "QI")
5677    (set_attr "ppro_uops" "few")])
5679 (define_insn "udivqi3"
5680   [(set (match_operand:QI 0 "register_operand" "=a")
5681         (udiv:QI (match_operand:HI 1 "register_operand" "0")
5682                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
5683    (clobber (reg:CC 17))]
5684   "TARGET_QIMODE_MATH"
5685   "div{b}\\t%2"
5686   [(set_attr "type" "idiv")
5687    (set_attr "mode" "QI")
5688    (set_attr "ppro_uops" "few")])
5690 ;; The patterns that match these are at the end of this file.
5692 (define_expand "divxf3"
5693   [(set (match_operand:XF 0 "register_operand" "")
5694         (div:XF (match_operand:XF 1 "register_operand" "")
5695                 (match_operand:XF 2 "register_operand" "")))]
5696   "TARGET_80387"
5697   "")
5699 (define_expand "divtf3"
5700   [(set (match_operand:TF 0 "register_operand" "")
5701         (div:TF (match_operand:TF 1 "register_operand" "")
5702                 (match_operand:TF 2 "register_operand" "")))]
5703   "TARGET_80387"
5704   "")
5706 (define_expand "divdf3"
5707   [(set (match_operand:DF 0 "register_operand" "")
5708         (div:DF (match_operand:DF 1 "register_operand" "")
5709                 (match_operand:DF 2 "nonimmediate_operand" "")))]
5710    "TARGET_80387"
5711    "")
5713 (define_expand "divsf3"
5714   [(set (match_operand:SF 0 "register_operand" "")
5715         (div:SF (match_operand:SF 1 "register_operand" "")
5716                 (match_operand:SF 2 "nonimmediate_operand" "")))]
5717   "TARGET_80387"
5718   "")
5720 ;; Remainder instructions.
5721 (define_expand "divmodsi4"
5722   [(parallel [(set (match_operand:SI 0 "register_operand" "")
5723                    (div:SI (match_operand:SI 1 "register_operand" "")
5724                            (match_operand:SI 2 "nonimmediate_operand" "")))
5725               (set (match_operand:SI 3 "register_operand" "")
5726                    (mod:SI (match_dup 1) (match_dup 2)))
5727               (clobber (reg:CC 17))])]
5728   ""
5729   "")
5731 ;; Allow to come the parameter in eax or edx to avoid extra moves.
5732 ;; Penalize eax case sligthly because it results in worse scheduling
5733 ;; of code.
5734 (define_insn "*divmodsi4_nocltd"
5735   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
5736         (div:SI (match_operand:SI 2 "register_operand" "1,0")
5737                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
5738    (set (match_operand:SI 1 "register_operand" "=&d,&d")
5739         (mod:SI (match_dup 2) (match_dup 3)))
5740    (clobber (reg:CC 17))]
5741   "!optimize_size && !TARGET_USE_CLTD"
5742   "#"
5743   [(set_attr "type" "multi")])
5745 (define_insn "*divmodsi4_cltd"
5746   [(set (match_operand:SI 0 "register_operand" "=a")
5747         (div:SI (match_operand:SI 2 "register_operand" "a")
5748                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
5749    (set (match_operand:SI 1 "register_operand" "=&d")
5750         (mod:SI (match_dup 2) (match_dup 3)))
5751    (clobber (reg:CC 17))]
5752   "optimize_size || TARGET_USE_CLTD"
5753   "#"
5754   [(set_attr "type" "multi")])
5756 (define_insn "*divmodsi_noext"
5757   [(set (match_operand:SI 0 "register_operand" "=a")
5758         (div:SI (match_operand:SI 1 "register_operand" "0")
5759                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
5760    (set (match_operand:SI 3 "register_operand" "=d")
5761         (mod:SI (match_dup 1) (match_dup 2)))
5762    (use (match_operand:SI 4 "register_operand" "3"))
5763    (clobber (reg:CC 17))]
5764   ""
5765   "idiv{l}\\t%2"
5766   [(set_attr "type" "idiv")
5767    (set_attr "mode" "SI")
5768    (set_attr "ppro_uops" "few")])
5770 (define_split
5771   [(set (match_operand:SI 0 "register_operand" "")
5772         (div:SI (match_operand:SI 1 "register_operand" "")
5773                 (match_operand:SI 2 "nonimmediate_operand" "")))
5774    (set (match_operand:SI 3 "register_operand" "")
5775         (mod:SI (match_dup 1) (match_dup 2)))
5776    (clobber (reg:CC 17))]
5777   "reload_completed"
5778   [(parallel [(set (match_dup 3)
5779                    (ashiftrt:SI (match_dup 4) (const_int 31)))
5780               (clobber (reg:CC 17))])
5781    (parallel [(set (match_dup 0)
5782                    (div:SI (reg:SI 0) (match_dup 2)))
5783               (set (match_dup 3)
5784                    (mod:SI (reg:SI 0) (match_dup 2)))
5785               (use (match_dup 3))
5786               (clobber (reg:CC 17))])]
5787   "
5789   /* Avoid use of cltd in favour of a mov+shift.  */
5790   if (!TARGET_USE_CLTD && !optimize_size)
5791     {
5792       if (true_regnum (operands[1]))
5793         emit_move_insn (operands[0], operands[1]);
5794       else
5795         emit_move_insn (operands[3], operands[1]);
5796       operands[4] = operands[3];
5797     }
5798   else
5799     {
5800       if (true_regnum (operands[1]))
5801         abort();
5802       operands[4] = operands[1];
5803     }
5805 ;; %%% Split me.
5806 (define_insn "divmodhi4"
5807   [(set (match_operand:HI 0 "register_operand" "=a")
5808         (div:HI (match_operand:HI 1 "register_operand" "0")
5809                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
5810    (set (match_operand:HI 3 "register_operand" "=&d")
5811         (mod:HI (match_dup 1) (match_dup 2)))
5812    (clobber (reg:CC 17))]
5813   "TARGET_HIMODE_MATH"
5814   "cwtd\;idiv{w}\\t%2"
5815   [(set_attr "type" "multi")
5816    (set_attr "length_immediate" "0")
5817    (set_attr "mode" "SI")])
5819 (define_insn "udivmodsi4"
5820   [(set (match_operand:SI 0 "register_operand" "=a")
5821         (udiv:SI (match_operand:SI 1 "register_operand" "0")
5822                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
5823    (set (match_operand:SI 3 "register_operand" "=&d")
5824         (umod:SI (match_dup 1) (match_dup 2)))
5825    (clobber (reg:CC 17))]
5826   ""
5827   "xor{l}\\t%3, %3\;div{l}\\t%2"
5828   [(set_attr "type" "multi")
5829    (set_attr "length_immediate" "0")
5830    (set_attr "mode" "SI")])
5832 (define_insn "*udivmodsi4_noext"
5833   [(set (match_operand:SI 0 "register_operand" "=a")
5834         (udiv:SI (match_operand:SI 1 "register_operand" "0")
5835                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
5836    (set (match_operand:SI 3 "register_operand" "=d")
5837         (umod:SI (match_dup 1) (match_dup 2)))
5838    (use (match_dup 3))
5839    (clobber (reg:CC 17))]
5840   ""
5841   "div{l}\\t%2"
5842   [(set_attr "type" "idiv")
5843    (set_attr "ppro_uops" "few")
5844    (set_attr "mode" "SI")])
5846 (define_split
5847   [(set (match_operand:SI 0 "register_operand" "")
5848         (udiv:SI (match_operand:SI 1 "register_operand" "")
5849                  (match_operand:SI 2 "nonimmediate_operand" "")))
5850    (set (match_operand:SI 3 "register_operand" "")
5851         (umod:SI (match_dup 1) (match_dup 2)))
5852    (clobber (reg:CC 17))]
5853   "reload_completed"
5854   [(set (match_dup 3) (const_int 0))
5855    (parallel [(set (match_dup 0)
5856                    (udiv:SI (match_dup 1) (match_dup 2)))
5857               (set (match_dup 3)
5858                    (umod:SI (match_dup 1) (match_dup 2)))
5859               (use (match_dup 3))
5860               (clobber (reg:CC 17))])]
5861   "")
5863 (define_expand "udivmodhi4"
5864   [(set (match_dup 4) (const_int 0))
5865    (parallel [(set (match_operand:HI 0 "register_operand" "")
5866                    (udiv:HI (match_operand:HI 1 "register_operand" "")
5867                             (match_operand:HI 2 "nonimmediate_operand" "")))
5868               (set (match_operand:HI 3 "register_operand" "")
5869                    (umod:HI (match_dup 1) (match_dup 2)))
5870               (use (match_dup 4))
5871               (clobber (reg:CC 17))])]
5872   "TARGET_HIMODE_MATH"
5873   "operands[4] = gen_reg_rtx (HImode);")
5875 (define_insn "*udivmodhi_noext"
5876   [(set (match_operand:HI 0 "register_operand" "=a")
5877         (udiv:HI (match_operand:HI 1 "register_operand" "0")
5878                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
5879    (set (match_operand:HI 3 "register_operand" "=d")
5880         (umod:HI (match_dup 1) (match_dup 2)))
5881    (use (match_operand:HI 4 "register_operand" "3"))
5882    (clobber (reg:CC 17))]
5883   ""
5884   "div{w}\\t%2"
5885   [(set_attr "type" "idiv")
5886    (set_attr "mode" "HI")
5887    (set_attr "ppro_uops" "few")])
5889 ;; We can not use div/idiv for double division, because it causes
5890 ;; "division by zero" on the overflow and that's not what we expect
5891 ;; from truncate.  Because true (non truncating) double division is
5892 ;; never generated, we can't create this insn anyway.
5894 ;(define_insn ""
5895 ;  [(set (match_operand:SI 0 "register_operand" "=a")
5896 ;       (truncate:SI
5897 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
5898 ;                  (zero_extend:DI
5899 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
5900 ;   (set (match_operand:SI 3 "register_operand" "=d")
5901 ;       (truncate:SI
5902 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
5903 ;   (clobber (reg:CC 17))]
5904 ;  ""
5905 ;  "div{l}\\t{%2, %0|%0, %2}"
5906 ;  [(set_attr "type" "idiv")
5907 ;   (set_attr "ppro_uops" "few")])
5909 ;;- Logical AND instructions
5911 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
5912 ;; Note that this excludes ah.
5915 (define_insn "testsi_1"
5916   [(set (reg 17)
5917         (compare
5918           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
5919                   (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
5920           (const_int 0)))]
5921   "ix86_match_ccmode (insn, CCNOmode)"
5922   "test{l}\\t{%1, %0|%0, %1}"
5923   [(set_attr "type" "test")
5924    (set_attr "modrm" "0,1,1")
5925    (set_attr "mode" "SI")
5926    (set_attr "pent_pair" "uv,np,uv")])
5928 (define_expand "testsi_ccno_1"
5929   [(set (reg:CCNO 17)
5930         (compare:CCNO
5931           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
5932                   (match_operand:SI 1 "nonmemory_operand" ""))
5933           (const_int 0)))]
5934   ""
5935   "")
5937 (define_insn "*testhi_1"
5938   [(set (reg 17)
5939         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
5940                          (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
5941                  (const_int 0)))]
5942   "ix86_match_ccmode (insn, CCNOmode)"
5943   "test{w}\\t{%1, %0|%0, %1}"
5944   [(set_attr "type" "test")
5945    (set_attr "modrm" "0,1,1")
5946    (set_attr "mode" "HI")
5947    (set_attr "pent_pair" "uv,np,uv")])
5949 (define_expand "testqi_ccz_1"
5950   [(set (reg:CCZ 17)
5951         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
5952                              (match_operand:QI 1 "nonmemory_operand" ""))
5953                  (const_int 0)))]
5954   ""
5955   "")
5957 (define_insn "*testqi_1"
5958   [(set (reg 17)
5959         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
5960                          (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
5961                  (const_int 0)))]
5962   "ix86_match_ccmode (insn, CCNOmode)"
5963   "*
5965   if (which_alternative == 3)
5966     {
5967       if (GET_CODE (operands[1]) == CONST_INT
5968           && (INTVAL (operands[1]) & 0xffffff00))
5969         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
5970       return \"test{l}\\t{%1, %k0|%k0, %1}\";
5971     }
5972   return \"test{b}\\t{%1, %0|%0, %1}\";
5974   [(set_attr "type" "test")
5975    (set_attr "modrm" "0,1,1,1")
5976    (set_attr "mode" "QI,QI,QI,SI")
5977    (set_attr "pent_pair" "uv,np,uv,np")])
5979 (define_expand "testqi_ext_ccno_0"
5980   [(set (reg:CCNO 17)
5981         (compare:CCNO
5982           (and:SI
5983             (zero_extract:SI
5984               (match_operand 0 "ext_register_operand" "")
5985               (const_int 8)
5986               (const_int 8))
5987             (match_operand 1 "const_int_operand" ""))
5988           (const_int 0)))]
5989   ""
5990   "")
5992 (define_insn "*testqi_ext_0"
5993   [(set (reg 17)
5994         (compare
5995           (and:SI
5996             (zero_extract:SI
5997               (match_operand 0 "ext_register_operand" "q")
5998               (const_int 8)
5999               (const_int 8))
6000             (match_operand 1 "const_int_operand" "n"))
6001           (const_int 0)))]
6002   "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
6003    && ix86_match_ccmode (insn, CCNOmode)"
6004   "test{b}\\t{%1, %h0|%h0, %1}"
6005   [(set_attr "type" "test")
6006    (set_attr "mode" "QI")
6007    (set_attr "length_immediate" "1")
6008    (set_attr "pent_pair" "np")])
6010 (define_insn "*testqi_ext_1"
6011   [(set (reg 17)
6012         (compare
6013           (and:SI
6014             (zero_extract:SI
6015               (match_operand 0 "ext_register_operand" "q")
6016               (const_int 8)
6017               (const_int 8))
6018             (zero_extend:SI
6019               (match_operand:QI 1 "nonimmediate_operand" "qm")))
6020           (const_int 0)))]
6021   "ix86_match_ccmode (insn, CCNOmode)"
6022   "test{b}\\t{%1, %h0|%h0, %1}"
6023   [(set_attr "type" "test")
6024    (set_attr "mode" "QI")])
6026 (define_insn "*testqi_ext_2"
6027   [(set (reg 17)
6028         (compare
6029           (and:SI
6030             (zero_extract:SI
6031               (match_operand 0 "ext_register_operand" "q")
6032               (const_int 8)
6033               (const_int 8))
6034             (zero_extract:SI
6035               (match_operand 1 "ext_register_operand" "q")
6036               (const_int 8)
6037               (const_int 8)))
6038           (const_int 0)))]
6039   "ix86_match_ccmode (insn, CCNOmode)"
6040   "test{b}\\t{%h1, %h0|%h0, %h1}"
6041   [(set_attr "type" "test")
6042    (set_attr "mode" "QI")])
6044 ;; Combine likes to form bit extractions for some tests.  Humor it.
6045 (define_insn "*testqi_ext_3"
6046   [(set (reg 17)
6047         (compare (zero_extract:SI
6048                    (match_operand 0 "nonimmediate_operand" "rm")
6049                    (match_operand:SI 1 "const_int_operand" "")
6050                    (match_operand:SI 2 "const_int_operand" ""))
6051                  (const_int 0)))]
6052   "ix86_match_ccmode (insn, CCNOmode)
6053    && (GET_MODE (operands[0]) == SImode
6054        || GET_MODE (operands[0]) == HImode
6055        || GET_MODE (operands[0]) == QImode)"
6056   "#")
6058 (define_split
6059   [(set (reg 17)
6060         (compare (zero_extract:SI
6061                    (match_operand 0 "nonimmediate_operand" "rm")
6062                    (match_operand:SI 1 "const_int_operand" "")
6063                    (match_operand:SI 2 "const_int_operand" ""))
6064                  (const_int 0)))]
6065   "ix86_match_ccmode (insn, CCNOmode)"
6066   [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
6067   "
6069   HOST_WIDE_INT len = INTVAL (operands[1]);
6070   HOST_WIDE_INT pos = INTVAL (operands[2]);
6071   HOST_WIDE_INT mask;
6072   enum machine_mode mode;
6074   mode = GET_MODE (operands[0]);
6075   if (GET_CODE (operands[0]) == MEM)
6076     {
6077       /* ??? Combine likes to put non-volatile mem extractions in QImode
6078          no matter the size of the test.  So find a mode that works.  */
6079       if (! MEM_VOLATILE_P (operands[0]))
6080         {
6081           mode = smallest_mode_for_size (pos + len, MODE_INT);
6082           operands[0] = change_address (operands[0], mode, NULL_RTX);
6083         }
6084     }
6085   else if (mode == HImode && pos + len <= 8)
6086     {
6087       /* Small HImode tests can be converted to QImode.  */
6088       mode = QImode;
6089       operands[0] = gen_lowpart (QImode, operands[0]);
6090     }
6092   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
6093   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
6095   operands[3] = gen_rtx_AND (mode, operands[0], GEN_INT (mask));
6098 ;; %%% This used to optimize known byte-wide and operations to memory,
6099 ;; and sometimes to QImode registers.  If this is considered useful,
6100 ;; it should be done with splitters.
6102 (define_expand "andsi3"
6103   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6104         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
6105                 (match_operand:SI 2 "general_operand" "")))
6106    (clobber (reg:CC 17))]
6107   ""
6108   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
6110 (define_insn "*andsi_1"
6111   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
6112         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
6113                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
6114    (clobber (reg:CC 17))]
6115   "ix86_binary_operator_ok (AND, SImode, operands)"
6116   "*
6118   switch (get_attr_type (insn))
6119     {
6120     case TYPE_IMOVX:
6121       {
6122         enum machine_mode mode;
6124         if (GET_CODE (operands[2]) != CONST_INT)
6125           abort ();
6126         if (INTVAL (operands[2]) == 0xff)
6127           mode = QImode;
6128         else if (INTVAL (operands[2]) == 0xffff)
6129           mode = HImode;
6130         else
6131           abort ();
6132         
6133         operands[1] = gen_lowpart (mode, operands[1]);
6134         if (mode == QImode)
6135           return \"movz{bl|x}\\t{%1,%0|%0, %1}\";
6136         else
6137           return \"movz{wl|x}\\t{%1,%0|%0, %1}\";
6138       }
6140     default:
6141       if (! rtx_equal_p (operands[0], operands[1]))
6142         abort ();
6143       return \"and{l}\\t{%2, %0|%0, %2}\";
6144     }
6146   [(set_attr "type" "alu,alu,imovx")
6147    (set_attr "length_immediate" "*,*,0")
6148    (set_attr "mode" "SI")])
6150 (define_split
6151   [(set (match_operand:SI 0 "register_operand" "")
6152         (and:SI (match_dup 0)
6153                 (const_int -65536)))
6154    (clobber (reg:CC 17))]
6155   "optimize_size"
6156   [(set (strict_low_part (match_dup 1)) (const_int 0))]
6157   "operands[1] = gen_lowpart (HImode, operands[0]);")
6159 (define_split
6160   [(set (match_operand 0 "q_regs_operand" "")
6161         (and (match_dup 0)
6162                 (const_int -256)))
6163    (clobber (reg:CC 17))]
6164   "(optimize_size || !TARGET_PARTIAL_REG_STALL)
6165    && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)"
6166   [(set (strict_low_part (match_dup 1)) (const_int 0))]
6167   "operands[1] = gen_lowpart (QImode, operands[0]);")
6169 (define_split
6170   [(set (match_operand 0 "q_regs_operand" "")
6171         (and (match_dup 0)
6172              (const_int -65281)))
6173    (clobber (reg:CC 17))]
6174   "(optimize_size || !TARGET_PARTIAL_REG_STALL)
6175    && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)"
6176   [(parallel [(set (zero_extract:SI (match_dup 0)
6177                                     (const_int 8)
6178                                     (const_int 8))
6179                    (xor:SI 
6180                      (zero_extract:SI (match_dup 0)
6181                                       (const_int 8)
6182                                       (const_int 8))
6183                      (zero_extract:SI (match_dup 0)
6184                                       (const_int 8)
6185                                       (const_int 8))))
6186               (clobber (reg:CC 17))])]
6187   "operands[0] = gen_lowpart (SImode, operands[0]);")
6189 (define_insn "*andsi_2"
6190   [(set (reg 17)
6191         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6192                          (match_operand:SI 2 "general_operand" "rim,ri"))
6193                  (const_int 0)))
6194    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6195         (and:SI (match_dup 1) (match_dup 2)))]
6196   "ix86_match_ccmode (insn, CCNOmode)
6197    && ix86_binary_operator_ok (AND, SImode, operands)"
6198   "and{l}\\t{%2, %0|%0, %2}"
6199   [(set_attr "type" "alu")
6200    (set_attr "mode" "SI")])
6202 (define_expand "andhi3"
6203   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6204         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
6205                 (match_operand:HI 2 "general_operand" "")))
6206    (clobber (reg:CC 17))]
6207   "TARGET_HIMODE_MATH"
6208   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
6210 (define_insn "*andhi_1"
6211   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6212         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
6213                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
6214    (clobber (reg:CC 17))]
6215   "ix86_binary_operator_ok (AND, HImode, operands)"
6216   "*
6218   switch (get_attr_type (insn))
6219     {
6220     case TYPE_IMOVX:
6221       if (GET_CODE (operands[2]) != CONST_INT)
6222         abort ();
6223       if (INTVAL (operands[2]) == 0xff)
6224         return \"movz{bl|x}\\t{%b1, %k0|%k0, %b1}\";
6225       abort ();
6227     default:
6228       if (! rtx_equal_p (operands[0], operands[1]))
6229         abort ();
6231       return \"and{w}\\t{%2, %0|%0, %2}\";
6232     }
6234   [(set_attr "type" "alu,alu,imovx")
6235    (set_attr "length_immediate" "*,*,0")
6236    (set_attr "mode" "HI,HI,SI")])
6238 (define_insn "*andhi_2"
6239   [(set (reg 17)
6240         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6241                          (match_operand:HI 2 "general_operand" "rim,ri"))
6242                  (const_int 0)))
6243    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6244         (and:HI (match_dup 1) (match_dup 2)))]
6245   "ix86_match_ccmode (insn, CCNOmode)
6246    && ix86_binary_operator_ok (AND, HImode, operands)"
6247   "and{w}\\t{%2, %0|%0, %2}"
6248   [(set_attr "type" "alu")
6249    (set_attr "mode" "HI")])
6251 (define_expand "andqi3"
6252   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6253         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
6254                 (match_operand:QI 2 "general_operand" "")))
6255    (clobber (reg:CC 17))]
6256   "TARGET_QIMODE_MATH"
6257   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
6259 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6260 (define_insn "*andqi_1"
6261   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6262         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6263                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
6264    (clobber (reg:CC 17))]
6265   "ix86_binary_operator_ok (AND, QImode, operands)"
6266   "@
6267    and{b}\\t{%2, %0|%0, %2}
6268    and{b}\\t{%2, %0|%0, %2}
6269    and{l}\\t{%k2, %k0|%k0, %k2}"
6270   [(set_attr "type" "alu")
6271    (set_attr "mode" "QI,QI,SI")])
6273 (define_insn "*andqi_1_slp"
6274   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6275         (and:QI (match_dup 0)
6276                 (match_operand:QI 1 "general_operand" "qi,qmi")))
6277    (clobber (reg:CC 17))]
6278   ""
6279   "and{b}\\t{%1, %0|%0, %1}"
6280   [(set_attr "type" "alu1")
6281    (set_attr "mode" "QI")])
6283 (define_insn "*andqi_2"
6284   [(set (reg 17)
6285         (compare (and:QI
6286                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6287                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
6288                  (const_int 0)))
6289    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
6290         (and:QI (match_dup 1) (match_dup 2)))]
6291   "ix86_match_ccmode (insn, CCNOmode)
6292    && ix86_binary_operator_ok (AND, QImode, operands)"
6293   "*
6295   if (which_alternative == 2)
6296     {
6297       if (GET_CODE (operands[2]) == CONST_INT
6298           && (INTVAL (operands[2]) & 0xffffff00))
6299         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
6300       return \"and{l}\\t{%2, %k0|%k0, %2}\";
6301     }
6302   return \"and{b}\\t{%2, %0|%0, %2}\";
6304   [(set_attr "type" "alu")
6305    (set_attr "mode" "QI,QI,SI")])
6307 (define_insn "*andqi_2_slp"
6308   [(set (reg 17)
6309         (compare (and:QI
6310                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
6311                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
6312                  (const_int 0)))
6313    (set (strict_low_part (match_dup 0))
6314         (and:QI (match_dup 0) (match_dup 1)))]
6315   "ix86_match_ccmode (insn, CCNOmode)"
6316   "and{b}\\t{%1, %0|%0, %1}"
6317   [(set_attr "type" "alu1")
6318    (set_attr "mode" "QI")])
6320 ;; ??? A bug in recog prevents it from recognizing a const_int as an
6321 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
6322 ;; for a QImode operand, which of course failed.
6324 (define_insn "andqi_ext_0"
6325   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6326                          (const_int 8)
6327                          (const_int 8))
6328         (and:SI 
6329           (zero_extract:SI
6330             (match_operand 1 "ext_register_operand" "0")
6331             (const_int 8)
6332             (const_int 8))
6333           (match_operand 2 "const_int_operand" "n")))
6334    (clobber (reg:CC 17))]
6335   "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
6336   "and{b}\\t{%2, %h0|%h0, %2}"
6337   [(set_attr "type" "alu")
6338    (set_attr "length_immediate" "1")
6339    (set_attr "mode" "QI")])
6341 ;; Generated by peephole translating test to and.  This shows up
6342 ;; often in fp comparisons.
6344 (define_insn "*andqi_ext_0_cc"
6345   [(set (reg 17)
6346         (compare
6347           (and:SI
6348             (zero_extract:SI
6349               (match_operand 1 "ext_register_operand" "0")
6350               (const_int 8)
6351               (const_int 8))
6352             (match_operand 2 "const_int_operand" "n"))
6353           (const_int 0)))
6354    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6355                          (const_int 8)
6356                          (const_int 8))
6357         (and:SI 
6358           (zero_extract:SI
6359             (match_dup 1)
6360             (const_int 8)
6361             (const_int 8))
6362           (match_dup 2)))]
6363   "ix86_match_ccmode (insn, CCNOmode)
6364    && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
6365   "and{b}\\t{%2, %h0|%h0, %2}"
6366   [(set_attr "type" "alu")
6367    (set_attr "length_immediate" "1")
6368    (set_attr "mode" "QI")])
6370 (define_insn "*andqi_ext_1"
6371   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6372                          (const_int 8)
6373                          (const_int 8))
6374         (and:SI 
6375           (zero_extract:SI
6376             (match_operand 1 "ext_register_operand" "0")
6377             (const_int 8)
6378             (const_int 8))
6379           (zero_extend:SI
6380             (match_operand:QI 2 "general_operand" "qm"))))
6381    (clobber (reg:CC 17))]
6382   ""
6383   "and{b}\\t{%2, %h0|%h0, %2}"
6384   [(set_attr "type" "alu")
6385    (set_attr "length_immediate" "0")
6386    (set_attr "mode" "QI")])
6388 (define_insn "*andqi_ext_2"
6389   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6390                          (const_int 8)
6391                          (const_int 8))
6392         (and:SI
6393           (zero_extract:SI
6394             (match_operand 1 "ext_register_operand" "%0")
6395             (const_int 8)
6396             (const_int 8))
6397           (zero_extract:SI
6398             (match_operand 2 "ext_register_operand" "q")
6399             (const_int 8)
6400             (const_int 8))))
6401    (clobber (reg:CC 17))]
6402   ""
6403   "and{b}\\t{%h2, %h0|%h0, %h2}"
6404   [(set_attr "type" "alu")
6405    (set_attr "length_immediate" "0")
6406    (set_attr "mode" "QI")])
6408 ;; Logical inclusive OR instructions
6410 ;; %%% This used to optimize known byte-wide and operations to memory.
6411 ;; If this is considered useful, it should be done with splitters.
6413 (define_expand "iorsi3"
6414   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6415         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
6416                 (match_operand:SI 2 "general_operand" "")))
6417    (clobber (reg:CC 17))]
6418   ""
6419   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
6421 (define_insn "*iorsi_1"
6422   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6423         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6424                 (match_operand:SI 2 "general_operand" "ri,rmi")))
6425    (clobber (reg:CC 17))]
6426   "ix86_binary_operator_ok (IOR, SImode, operands)"
6427   "or{l}\\t{%2, %0|%0, %2}"
6428   [(set_attr "type" "alu")
6429    (set_attr "mode" "SI")])
6431 (define_insn "*iorsi_2"
6432   [(set (reg 17)
6433         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6434                          (match_operand:SI 2 "general_operand" "rim,ri"))
6435                  (const_int 0)))
6436    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6437         (ior:SI (match_dup 1) (match_dup 2)))]
6438   "ix86_match_ccmode (insn, CCNOmode)
6439    && ix86_binary_operator_ok (IOR, SImode, operands)"
6440   "or{l}\\t{%2, %0|%0, %2}"
6441   [(set_attr "type" "alu")
6442    (set_attr "mode" "SI")])
6444 (define_insn "*iorsi_3"
6445   [(set (reg 17)
6446         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6447                          (match_operand:SI 2 "general_operand" "rim"))
6448                  (const_int 0)))
6449    (clobber (match_scratch:SI 0 "=r"))]
6450   "ix86_match_ccmode (insn, CCNOmode)
6451    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6452   "or{l}\\t{%2, %0|%0, %2}"
6453   [(set_attr "type" "alu")
6454    (set_attr "mode" "SI")])
6456 (define_expand "iorhi3"
6457   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6458         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
6459                 (match_operand:HI 2 "general_operand" "")))
6460    (clobber (reg:CC 17))]
6461   "TARGET_HIMODE_MATH"
6462   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
6464 (define_insn "*iorhi_1"
6465   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
6466         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6467                 (match_operand:HI 2 "general_operand" "rmi,ri")))
6468    (clobber (reg:CC 17))]
6469   "ix86_binary_operator_ok (IOR, HImode, operands)"
6470   "or{w}\\t{%2, %0|%0, %2}"
6471   [(set_attr "type" "alu")
6472    (set_attr "mode" "HI")])
6474 (define_insn "*iorhi_2"
6475   [(set (reg 17)
6476         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6477                          (match_operand:HI 2 "general_operand" "rim,ri"))
6478                  (const_int 0)))
6479    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6480         (ior:HI (match_dup 1) (match_dup 2)))]
6481   "ix86_match_ccmode (insn, CCNOmode)
6482    && ix86_binary_operator_ok (IOR, HImode, operands)"
6483   "or{w}\\t{%2, %0|%0, %2}"
6484   [(set_attr "type" "alu")
6485    (set_attr "mode" "HI")])
6487 (define_insn "*iorhi_3"
6488   [(set (reg 17)
6489         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6490                          (match_operand:HI 2 "general_operand" "rim"))
6491                  (const_int 0)))
6492    (clobber (match_scratch:HI 0 "=r"))]
6493   "ix86_match_ccmode (insn, CCNOmode)
6494    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6495   "or{w}\\t{%2, %0|%0, %2}"
6496   [(set_attr "type" "alu")
6497    (set_attr "mode" "HI")])
6499 (define_expand "iorqi3"
6500   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6501         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
6502                 (match_operand:QI 2 "general_operand" "")))
6503    (clobber (reg:CC 17))]
6504   "TARGET_QIMODE_MATH"
6505   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
6507 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6508 (define_insn "*iorqi_1"
6509   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
6510         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6511                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
6512    (clobber (reg:CC 17))]
6513   "ix86_binary_operator_ok (IOR, QImode, operands)"
6514   "@
6515    or{b}\\t{%2, %0|%0, %2}
6516    or{b}\\t{%2, %0|%0, %2}
6517    or{l}\\t{%k2, %k0|%k0, %k2}"
6518   [(set_attr "type" "alu")
6519    (set_attr "mode" "QI,QI,SI")])
6521 (define_insn "*iorqi_1_slp"
6522   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
6523         (ior:QI (match_dup 0)
6524                 (match_operand:QI 1 "general_operand" "qmi,qi")))
6525    (clobber (reg:CC 17))]
6526   ""
6527   "or{b}\\t{%1, %0|%0, %1}"
6528   [(set_attr "type" "alu1")
6529    (set_attr "mode" "QI")])
6531 (define_insn "*iorqi_2"
6532   [(set (reg 17)
6533         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6534                          (match_operand:QI 2 "general_operand" "qim,qi"))
6535                  (const_int 0)))
6536    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6537         (ior:QI (match_dup 1) (match_dup 2)))]
6538   "ix86_match_ccmode (insn, CCNOmode)
6539    && ix86_binary_operator_ok (IOR, QImode, operands)"
6540   "or{b}\\t{%2, %0|%0, %2}"
6541   [(set_attr "type" "alu")
6542    (set_attr "mode" "QI")])
6544 (define_insn "*iorqi_2_slp"
6545   [(set (reg 17)
6546         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
6547                          (match_operand:QI 1 "general_operand" "qim,qi"))
6548                  (const_int 0)))
6549    (set (strict_low_part (match_dup 0))
6550         (ior:QI (match_dup 0) (match_dup 1)))]
6551   "ix86_match_ccmode (insn, CCNOmode)"
6552   "or{b}\\t{%1, %0|%0, %1}"
6553   [(set_attr "type" "alu1")
6554    (set_attr "mode" "QI")])
6556 (define_insn "*iorqi_3"
6557   [(set (reg 17)
6558         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6559                          (match_operand:QI 2 "general_operand" "qim"))
6560                  (const_int 0)))
6561    (clobber (match_scratch:QI 0 "=q"))]
6562   "ix86_match_ccmode (insn, CCNOmode)
6563    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6564   "or{b}\\t{%2, %0|%0, %2}"
6565   [(set_attr "type" "alu")
6566    (set_attr "mode" "QI")])
6569 ;; Logical XOR instructions
6571 ;; %%% This used to optimize known byte-wide and operations to memory.
6572 ;; If this is considered useful, it should be done with splitters.
6574 (define_expand "xorsi3"
6575   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6576         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
6577                 (match_operand:SI 2 "general_operand" "")))
6578    (clobber (reg:CC 17))]
6579   ""
6580   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
6582 (define_insn "*xorsi_1"
6583   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6584         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6585                 (match_operand:SI 2 "general_operand" "ri,rm")))
6586    (clobber (reg:CC 17))]
6587   "ix86_binary_operator_ok (XOR, SImode, operands)"
6588   "xor{l}\\t{%2, %0|%0, %2}"
6589   [(set_attr "type" "alu")
6590    (set_attr "mode" "SI")])
6592 (define_insn "*xorsi_2"
6593   [(set (reg 17)
6594         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6595                          (match_operand:SI 2 "general_operand" "rim,ri"))
6596                  (const_int 0)))
6597    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6598         (xor:SI (match_dup 1) (match_dup 2)))]
6599   "ix86_match_ccmode (insn, CCNOmode)
6600    && ix86_binary_operator_ok (XOR, SImode, operands)"
6601   "xor{l}\\t{%2, %0|%0, %2}"
6602   [(set_attr "type" "alu")
6603    (set_attr "mode" "SI")])
6605 (define_insn "*xorsi_3"
6606   [(set (reg 17)
6607         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6608                          (match_operand:SI 2 "general_operand" "rim"))
6609                  (const_int 0)))
6610    (clobber (match_scratch:SI 0 "=r"))]
6611   "ix86_match_ccmode (insn, CCNOmode)
6612    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6613   "xor{l}\\t{%2, %0|%0, %2}"
6614   [(set_attr "type" "alu")
6615    (set_attr "mode" "SI")])
6617 (define_expand "xorhi3"
6618   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6619         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
6620                 (match_operand:HI 2 "general_operand" "")))
6621    (clobber (reg:CC 17))]
6622   "TARGET_HIMODE_MATH"
6623   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
6625 (define_insn "*xorhi_1"
6626   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
6627         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6628                 (match_operand:HI 2 "general_operand" "rmi,ri")))
6629    (clobber (reg:CC 17))]
6630   "ix86_binary_operator_ok (XOR, HImode, operands)"
6631   "xor{w}\\t{%2, %0|%0, %2}"
6632   [(set_attr "type" "alu")
6633    (set_attr "mode" "HI")])
6635 (define_insn "*xorhi_2"
6636   [(set (reg 17)
6637         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6638                          (match_operand:HI 2 "general_operand" "rim,ri"))
6639                  (const_int 0)))
6640    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6641         (xor:HI (match_dup 1) (match_dup 2)))]
6642   "ix86_match_ccmode (insn, CCNOmode)
6643    && ix86_binary_operator_ok (XOR, HImode, operands)"
6644   "xor{w}\\t{%2, %0|%0, %2}"
6645   [(set_attr "type" "alu")
6646    (set_attr "mode" "HI")])
6648 (define_insn "*xorhi_3"
6649   [(set (reg 17)
6650         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6651                          (match_operand:HI 2 "general_operand" "rim"))
6652                  (const_int 0)))
6653    (clobber (match_scratch:HI 0 "=r"))]
6654   "ix86_match_ccmode (insn, CCNOmode)
6655    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6656   "xor{w}\\t{%2, %0|%0, %2}"
6657   [(set_attr "type" "alu")
6658    (set_attr "mode" "HI")])
6660 (define_expand "xorqi3"
6661   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6662         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
6663                 (match_operand:QI 2 "general_operand" "")))
6664    (clobber (reg:CC 17))]
6665   "TARGET_QIMODE_MATH"
6666   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
6668 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6669 (define_insn "*xorqi_1"
6670   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
6671         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6672                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
6673    (clobber (reg:CC 17))]
6674   "ix86_binary_operator_ok (XOR, QImode, operands)"
6675   "@
6676    xor{b}\\t{%2, %0|%0, %2}
6677    xor{b}\\t{%2, %0|%0, %2}
6678    xor{l}\\t{%k2, %k0|%k0, %k2}"
6679   [(set_attr "type" "alu")
6680    (set_attr "mode" "QI,QI,SI")])
6682 (define_insn "*xorqi_ext_1"
6683   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6684                          (const_int 8)
6685                          (const_int 8))
6686         (xor:SI 
6687           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
6688                            (const_int 8)
6689                            (const_int 8))
6690           (zero_extract:SI (match_operand 2 "ext_register_operand" "q")
6691                            (const_int 8)
6692                            (const_int 8))))
6693    (clobber (reg:CC 17))]
6694   ""
6695   "xor{b}\\t{%h2, %h0|%h0, %h2}"
6696   [(set_attr "type" "alu")
6697    (set_attr "length_immediate" "0")
6698    (set_attr "mode" "QI")])
6700 (define_insn "*xorqi_cc_1"
6701   [(set (reg 17)
6702         (compare
6703           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6704                   (match_operand:QI 2 "general_operand" "qim,qi"))
6705           (const_int 0)))
6706    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6707         (xor:QI (match_dup 1) (match_dup 2)))]
6708   "ix86_match_ccmode (insn, CCNOmode)
6709    && ix86_binary_operator_ok (XOR, QImode, operands)"
6710   "xor{b}\\t{%2, %0|%0, %2}"
6711   [(set_attr "type" "alu")
6712    (set_attr "mode" "QI")])
6714 (define_insn "*xorqi_cc_2"
6715   [(set (reg 17)
6716         (compare
6717           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6718                   (match_operand:QI 2 "general_operand" "qim"))
6719           (const_int 0)))
6720    (clobber (match_scratch:QI 0 "=q"))]
6721   "ix86_match_ccmode (insn, CCNOmode)
6722    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6723   "xor{b}\\t{%2, %0|%0, %2}"
6724   [(set_attr "type" "alu")
6725    (set_attr "mode" "QI")])
6727 (define_insn "*xorqi_cc_ext_1"
6728   [(set (reg 17)
6729         (compare
6730           (xor:SI
6731             (zero_extract:SI
6732               (match_operand 1 "ext_register_operand" "0")
6733               (const_int 8)
6734               (const_int 8))
6735             (match_operand:QI 2 "general_operand" "qmn"))
6736           (const_int 0)))
6737    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6738                          (const_int 8)
6739                          (const_int 8))
6740         (xor:SI 
6741           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
6742           (match_dup 2)))]
6743   "ix86_match_ccmode (insn, CCNOmode)"
6744   "xor{b}\\t{%2, %h0|%h0, %2}"
6745   [(set_attr "type" "alu")
6746    (set_attr "mode" "QI")])
6748 (define_expand "xorqi_cc_ext_1"
6749   [(parallel [
6750      (set (reg:CCNO 17)
6751           (compare:CCNO
6752             (xor:SI
6753               (zero_extract:SI
6754                 (match_operand 1 "ext_register_operand" "")
6755                 (const_int 8)
6756                 (const_int 8))
6757               (match_operand:QI 2 "general_operand" ""))
6758             (const_int 0)))
6759      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
6760                            (const_int 8)
6761                            (const_int 8))
6762           (xor:SI 
6763             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
6764             (match_dup 2)))])]
6765   ""
6766   "")
6768 ;; Negation instructions
6770 ;; %%% define_expand from the very first?
6772 (define_expand "negdi2"
6773   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6774                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
6775               (clobber (reg:CC 17))])]
6776   ""
6777   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
6779 (define_insn "*negdi2_1"
6780   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
6781         (neg:DI (match_operand:DI 1 "general_operand" "0")))
6782    (clobber (reg:CC 17))]
6783   "ix86_unary_operator_ok (NEG, DImode, operands)"
6784   "#")
6786 (define_split
6787   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6788         (neg:DI (match_operand:DI 1 "general_operand" "")))
6789    (clobber (reg:CC 17))]
6790   "reload_completed"
6791   [(parallel
6792     [(set (reg:CCZ 17)
6793           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
6794      (set (match_dup 0) (neg:SI (match_dup 2)))])
6795    (parallel
6796     [(set (match_dup 1)
6797           (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6798                             (match_dup 3))
6799                    (const_int 0)))
6800      (clobber (reg:CC 17))])
6801    (parallel
6802     [(set (match_dup 1)
6803           (neg:SI (match_dup 1)))
6804      (clobber (reg:CC 17))])]
6805   "split_di (operands+1, 1, operands+2, operands+3);
6806    split_di (operands+0, 1, operands+0, operands+1);")
6808 (define_expand "negsi2"
6809   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6810                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
6811               (clobber (reg:CC 17))])]
6812   ""
6813   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
6815 (define_insn "*negsi2_1"
6816   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6817         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
6818    (clobber (reg:CC 17))]
6819   "ix86_unary_operator_ok (NEG, SImode, operands)"
6820   "neg{l}\\t%0"
6821   [(set_attr "type" "negnot")
6822    (set_attr "mode" "SI")])
6824 ;; The problem with neg is that it does not perform (compare x 0),
6825 ;; it really performs (compare 0 x), which leaves us with the zero
6826 ;; flag being the only useful item.
6828 (define_insn "*negsi2_cmpz"
6829   [(set (reg:CCZ 17)
6830         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
6831                      (const_int 0)))
6832    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6833         (neg:SI (match_dup 1)))]
6834   "ix86_unary_operator_ok (NEG, SImode, operands)"
6835   "neg{l}\\t%0"
6836   [(set_attr "type" "negnot")
6837    (set_attr "mode" "SI")])
6839 (define_expand "neghi2"
6840   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6841                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
6842               (clobber (reg:CC 17))])]
6843   "TARGET_HIMODE_MATH"
6844   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
6846 (define_insn "*neghi2_1"
6847   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6848         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
6849    (clobber (reg:CC 17))]
6850   "ix86_unary_operator_ok (NEG, HImode, operands)"
6851   "neg{w}\\t%0"
6852   [(set_attr "type" "negnot")
6853    (set_attr "mode" "HI")])
6855 (define_insn "*neghi2_cmpz"
6856   [(set (reg:CCZ 17)
6857         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
6858                      (const_int 0)))
6859    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6860         (neg:HI (match_dup 1)))]
6861   "ix86_unary_operator_ok (NEG, HImode, operands)"
6862   "neg{w}\\t%0"
6863   [(set_attr "type" "negnot")
6864    (set_attr "mode" "HI")])
6866 (define_expand "negqi2"
6867   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6868                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
6869               (clobber (reg:CC 17))])]
6870   "TARGET_QIMODE_MATH"
6871   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
6873 (define_insn "*negqi2_1"
6874   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6875         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
6876    (clobber (reg:CC 17))]
6877   "ix86_unary_operator_ok (NEG, QImode, operands)"
6878   "neg{b}\\t%0"
6879   [(set_attr "type" "negnot")
6880    (set_attr "mode" "QI")])
6882 (define_insn "*negqi2_cmpz"
6883   [(set (reg:CCZ 17)
6884         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
6885                      (const_int 0)))
6886    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6887         (neg:QI (match_dup 1)))]
6888   "ix86_unary_operator_ok (NEG, QImode, operands)"
6889   "neg{b}\\t%0"
6890   [(set_attr "type" "negnot")
6891    (set_attr "mode" "QI")])
6893 ;; Changing of sign for FP values is doable using integer unit too.
6895 (define_expand "negsf2"
6896   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
6897                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
6898               (clobber (reg:CC 17))])]
6899   "TARGET_80387"
6900   "ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
6902 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
6903 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
6904 ;; to itself.
6905 (define_insn "*negsf2_if"
6906   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
6907         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
6908    (clobber (reg:CC 17))]
6909   "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
6910   "#")
6912 (define_split
6913   [(set (match_operand:SF 0 "register_operand" "")
6914         (neg:SF (match_operand:SF 1 "register_operand" "")))
6915    (clobber (reg:CC 17))]
6916   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
6917   [(set (match_dup 0)
6918         (neg:SF (match_dup 1)))]
6919   "")
6921 (define_split
6922   [(set (match_operand:SF 0 "register_operand" "")
6923         (neg:SF (match_operand:SF 1 "register_operand" "")))
6924    (clobber (reg:CC 17))]
6925   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
6926   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
6927               (clobber (reg:CC 17))])]
6928   "operands[1] = GEN_INT (0x80000000);
6929    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
6931 (define_split
6932   [(set (match_operand 0 "memory_operand" "")
6933         (neg (match_operand 1 "memory_operand" "")))
6934    (clobber (reg:CC 17))]
6935   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
6936   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
6937               (clobber (reg:CC 17))])]
6938   "
6940   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
6942   /* XFmode's size is 12, but only 10 bytes are used.  */
6943   if (size == 12)
6944     size = 10;
6945   operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
6946   operands[0] = adj_offsettable_operand (operands[0], size - 1);
6947   operands[1] = GEN_INT (0x80);
6950 (define_expand "negdf2"
6951   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
6952                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
6953               (clobber (reg:CC 17))])]
6954   "TARGET_80387"
6955   "ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
6957 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
6958 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
6959 ;; to itself.
6960 (define_insn "*negdf2_if"
6961   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
6962         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
6963    (clobber (reg:CC 17))]
6964   "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
6965   "#")
6967 (define_split
6968   [(set (match_operand:DF 0 "register_operand" "")
6969         (neg:DF (match_operand:DF 1 "register_operand" "")))
6970    (clobber (reg:CC 17))]
6971   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
6972   [(set (match_dup 0)
6973         (neg:DF (match_dup 1)))]
6974   "")
6976 (define_split
6977   [(set (match_operand:DF 0 "register_operand" "")
6978         (neg:DF (match_operand:DF 1 "register_operand" "")))
6979    (clobber (reg:CC 17))]
6980   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
6981   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
6982               (clobber (reg:CC 17))])]
6983   "operands[4] = GEN_INT (0x80000000);
6984    split_di (operands+0, 1, operands+2, operands+3);")
6986 (define_expand "negxf2"
6987   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
6988                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
6989               (clobber (reg:CC 17))])]
6990   "TARGET_80387"
6991   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
6993 (define_expand "negtf2"
6994   [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
6995                    (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
6996               (clobber (reg:CC 17))])]
6997   "TARGET_80387"
6998   "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
7000 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7001 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7002 ;; to itself.
7003 (define_insn "*negxf2_if"
7004   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
7005         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
7006    (clobber (reg:CC 17))]
7007   "TARGET_80387 && ix86_unary_operator_ok (NEG, XFmode, operands)"
7008   "#")
7010 (define_split
7011   [(set (match_operand:XF 0 "register_operand" "")
7012         (neg:XF (match_operand:XF 1 "register_operand" "")))
7013    (clobber (reg:CC 17))]
7014   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7015   [(set (match_dup 0)
7016         (neg:XF (match_dup 1)))]
7017   "")
7019 (define_split
7020   [(set (match_operand:XF 0 "register_operand" "")
7021         (neg:XF (match_operand:XF 1 "register_operand" "")))
7022    (clobber (reg:CC 17))]
7023   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7024   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
7025               (clobber (reg:CC 17))])]
7026   "operands[1] = GEN_INT (0x8000);
7027    operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7029 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7030 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7031 ;; to itself.
7032 (define_insn "*negtf2_if"
7033   [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
7034         (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
7035    (clobber (reg:CC 17))]
7036   "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
7037   "#")
7039 (define_split
7040   [(set (match_operand:TF 0 "register_operand" "")
7041         (neg:TF (match_operand:TF 1 "register_operand" "")))
7042    (clobber (reg:CC 17))]
7043   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7044   [(set (match_dup 0)
7045         (neg:TF (match_dup 1)))]
7046   "")
7048 (define_split
7049   [(set (match_operand:TF 0 "register_operand" "")
7050         (neg:TF (match_operand:TF 1 "register_operand" "")))
7051    (clobber (reg:CC 17))]
7052   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7053   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
7054               (clobber (reg:CC 17))])]
7055   "operands[1] = GEN_INT (0x8000);
7056    operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7058 ;; Conditionize these after reload. If they matches before reload, we 
7059 ;; lose the clobber and ability to use integer instructions.
7061 (define_insn "*negsf2_1"
7062   [(set (match_operand:SF 0 "register_operand" "=f")
7063         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
7064   "TARGET_80387 && reload_completed"
7065   "fchs"
7066   [(set_attr "type" "fsgn")
7067    (set_attr "mode" "SF")
7068    (set_attr "ppro_uops" "few")])
7070 (define_insn "*negdf2_1"
7071   [(set (match_operand:DF 0 "register_operand" "=f")
7072         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
7073   "TARGET_80387 && reload_completed"
7074   "fchs"
7075   [(set_attr "type" "fsgn")
7076    (set_attr "mode" "DF")
7077    (set_attr "ppro_uops" "few")])
7079 (define_insn "*negextendsfdf2"
7080   [(set (match_operand:DF 0 "register_operand" "=f")
7081         (neg:DF (float_extend:DF
7082                   (match_operand:SF 1 "register_operand" "0"))))]
7083   "TARGET_80387"
7084   "fchs"
7085   [(set_attr "type" "fsgn")
7086    (set_attr "mode" "DF")
7087    (set_attr "ppro_uops" "few")])
7089 (define_insn "*negxf2_1"
7090   [(set (match_operand:XF 0 "register_operand" "=f")
7091         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
7092   "TARGET_80387 && reload_completed"
7093   "fchs"
7094   [(set_attr "type" "fsgn")
7095    (set_attr "mode" "XF")
7096    (set_attr "ppro_uops" "few")])
7098 (define_insn "*negextenddfxf2"
7099   [(set (match_operand:XF 0 "register_operand" "=f")
7100         (neg:XF (float_extend:XF
7101                   (match_operand:DF 1 "register_operand" "0"))))]
7102   "TARGET_80387"
7103   "fchs"
7104   [(set_attr "type" "fsgn")
7105    (set_attr "mode" "XF")
7106    (set_attr "ppro_uops" "few")])
7108 (define_insn "*negextendsfxf2"
7109   [(set (match_operand:XF 0 "register_operand" "=f")
7110         (neg:XF (float_extend:XF
7111                   (match_operand:SF 1 "register_operand" "0"))))]
7112   "TARGET_80387"
7113   "fchs"
7114   [(set_attr "type" "fsgn")
7115    (set_attr "mode" "XF")
7116    (set_attr "ppro_uops" "few")])
7118 (define_insn "*negtf2_1"
7119   [(set (match_operand:TF 0 "register_operand" "=f")
7120         (neg:TF (match_operand:TF 1 "register_operand" "0")))]
7121   "TARGET_80387 && reload_completed"
7122   "fchs"
7123   [(set_attr "type" "fsgn")
7124    (set_attr "mode" "XF")
7125    (set_attr "ppro_uops" "few")])
7127 (define_insn "*negextenddftf2"
7128   [(set (match_operand:TF 0 "register_operand" "=f")
7129         (neg:TF (float_extend:TF
7130                   (match_operand:DF 1 "register_operand" "0"))))]
7131   "TARGET_80387"
7132   "fchs"
7133   [(set_attr "type" "fsgn")
7134    (set_attr "mode" "XF")
7135    (set_attr "ppro_uops" "few")])
7137 (define_insn "*negextendsftf2"
7138   [(set (match_operand:TF 0 "register_operand" "=f")
7139         (neg:TF (float_extend:TF
7140                   (match_operand:SF 1 "register_operand" "0"))))]
7141   "TARGET_80387"
7142   "fchs"
7143   [(set_attr "type" "fsgn")
7144    (set_attr "mode" "XF")
7145    (set_attr "ppro_uops" "few")])
7147 ;; Absolute value instructions
7149 (define_expand "abssf2"
7150   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
7151                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
7152               (clobber (reg:CC 17))])]
7153   "TARGET_80387"
7154   "ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
7156 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7157 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7158 ;; to itself.
7159 (define_insn "*abssf2_if"
7160   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
7161         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
7162    (clobber (reg:CC 17))]
7163   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
7164   "#")
7166 (define_split
7167   [(set (match_operand:SF 0 "register_operand" "")
7168         (abs:SF (match_operand:SF 1 "register_operand" "")))
7169    (clobber (reg:CC 17))]
7170   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
7171   [(set (match_dup 0)
7172         (abs:SF (match_dup 1)))]
7173   "")
7175 (define_split
7176   [(set (match_operand:SF 0 "register_operand" "")
7177         (abs:SF (match_operand:SF 1 "register_operand" "")))
7178    (clobber (reg:CC 17))]
7179   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7180   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
7181               (clobber (reg:CC 17))])]
7182   "operands[1] = GEN_INT (~0x80000000);
7183    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
7185 (define_split
7186   [(set (match_operand 0 "memory_operand" "")
7187         (abs (match_operand 1 "memory_operand" "")))
7188    (clobber (reg:CC 17))]
7189   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
7190   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7191               (clobber (reg:CC 17))])]
7192   "
7194   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
7196   /* XFmode's size is 12, but only 10 bytes are used.  */
7197   if (size == 12)
7198     size = 10;
7199   operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
7200   operands[0] = adj_offsettable_operand (operands[0], size - 1);
7201   operands[1] = GEN_INT (~0x80);
7204 (define_expand "absdf2"
7205   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
7206                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
7207               (clobber (reg:CC 17))])]
7208   "TARGET_80387"
7209   "ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
7211 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7212 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7213 ;; to itself.
7214 (define_insn "*absdf2_if"
7215   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
7216         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
7217    (clobber (reg:CC 17))]
7218   "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
7219   "#")
7221 (define_split
7222   [(set (match_operand:DF 0 "register_operand" "")
7223         (abs:DF (match_operand:DF 1 "register_operand" "")))
7224    (clobber (reg:CC 17))]
7225   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7226   [(set (match_dup 0)
7227         (abs:DF (match_dup 1)))]
7228   "")
7230 (define_split
7231   [(set (match_operand:DF 0 "register_operand" "")
7232         (abs:DF (match_operand:DF 1 "register_operand" "")))
7233    (clobber (reg:CC 17))]
7234   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7235   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
7236               (clobber (reg:CC 17))])]
7237   "operands[4] = GEN_INT (~0x80000000);
7238    split_di (operands+0, 1, operands+2, operands+3);")
7240 (define_expand "absxf2"
7241   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
7242                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
7243               (clobber (reg:CC 17))])]
7244   "TARGET_80387"
7245   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
7247 (define_expand "abstf2"
7248   [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
7249                    (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
7250               (clobber (reg:CC 17))])]
7251   "TARGET_80387"
7252   "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
7254 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7255 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7256 ;; to itself.
7257 (define_insn "*absxf2_if"
7258   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
7259         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
7260    (clobber (reg:CC 17))]
7261   "TARGET_80387 && ix86_unary_operator_ok (ABS, XFmode, operands)"
7262   "#")
7264 (define_split
7265   [(set (match_operand:XF 0 "register_operand" "")
7266         (abs:XF (match_operand:XF 1 "register_operand" "")))
7267    (clobber (reg:CC 17))]
7268   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7269   [(set (match_dup 0)
7270         (abs:XF (match_dup 1)))]
7271   "")
7273 (define_split
7274   [(set (match_operand:XF 0 "register_operand" "")
7275         (abs:XF (match_operand:XF 1 "register_operand" "")))
7276    (clobber (reg:CC 17))]
7277   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7278   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
7279               (clobber (reg:CC 17))])]
7280   "operands[1] = GEN_INT (~0x8000);
7281    operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7283 (define_insn "*abstf2_if"
7284   [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
7285         (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
7286    (clobber (reg:CC 17))]
7287   "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
7288   "#")
7290 (define_split
7291   [(set (match_operand:TF 0 "register_operand" "")
7292         (abs:TF (match_operand:TF 1 "register_operand" "")))
7293    (clobber (reg:CC 17))]
7294   "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7295   [(set (match_dup 0)
7296         (abs:TF (match_dup 1)))]
7297   "")
7299 (define_split
7300   [(set (match_operand:TF 0 "register_operand" "")
7301         (abs:TF (match_operand:TF 1 "register_operand" "")))
7302    (clobber (reg:CC 17))]
7303   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7304   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
7305               (clobber (reg:CC 17))])]
7306   "operands[1] = GEN_INT (~0x8000);
7307    operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7309 (define_insn "*abssf2_1"
7310   [(set (match_operand:SF 0 "register_operand" "=f")
7311         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
7312   "TARGET_80387 && reload_completed"
7313   "fabs"
7314   [(set_attr "type" "fsgn")
7315    (set_attr "mode" "SF")])
7317 (define_insn "*absdf2_1"
7318   [(set (match_operand:DF 0 "register_operand" "=f")
7319         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
7320   "TARGET_80387 && reload_completed"
7321   "fabs"
7322   [(set_attr "type" "fsgn")
7323    (set_attr "mode" "DF")])
7325 (define_insn "*absextendsfdf2"
7326   [(set (match_operand:DF 0 "register_operand" "=f")
7327         (abs:DF (float_extend:DF
7328                   (match_operand:SF 1 "register_operand" "0"))))]
7329   "TARGET_80387"
7330   "fabs"
7331   [(set_attr "type" "fsgn")
7332    (set_attr "mode" "DF")])
7334 (define_insn "*absxf2_1"
7335   [(set (match_operand:XF 0 "register_operand" "=f")
7336         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
7337   "TARGET_80387 && reload_completed"
7338   "fabs"
7339   [(set_attr "type" "fsgn")
7340    (set_attr "mode" "DF")])
7342 (define_insn "*absextenddfxf2"
7343   [(set (match_operand:XF 0 "register_operand" "=f")
7344         (abs:XF (float_extend:XF
7345           (match_operand:DF 1 "register_operand" "0"))))]
7346   "TARGET_80387"
7347   "fabs"
7348   [(set_attr "type" "fsgn")
7349    (set_attr "mode" "XF")])
7351 (define_insn "*absextendsfxf2"
7352   [(set (match_operand:XF 0 "register_operand" "=f")
7353         (abs:XF (float_extend:XF
7354           (match_operand:SF 1 "register_operand" "0"))))]
7355   "TARGET_80387"
7356   "fabs"
7357   [(set_attr "type" "fsgn")
7358    (set_attr "mode" "XF")])
7360 (define_insn "*abstf2_1"
7361   [(set (match_operand:TF 0 "register_operand" "=f")
7362         (abs:TF (match_operand:TF 1 "register_operand" "0")))]
7363   "TARGET_80387 && reload_completed"
7364   "fabs"
7365   [(set_attr "type" "fsgn")
7366    (set_attr "mode" "DF")])
7368 (define_insn "*absextenddftf2"
7369   [(set (match_operand:TF 0 "register_operand" "=f")
7370         (abs:TF (float_extend:TF
7371           (match_operand:DF 1 "register_operand" "0"))))]
7372   "TARGET_80387"
7373   "fabs"
7374   [(set_attr "type" "fsgn")
7375    (set_attr "mode" "XF")])
7377 (define_insn "*absextendsftf2"
7378   [(set (match_operand:TF 0 "register_operand" "=f")
7379         (abs:TF (float_extend:TF
7380           (match_operand:SF 1 "register_operand" "0"))))]
7381   "TARGET_80387"
7382   "fabs"
7383   [(set_attr "type" "fsgn")
7384    (set_attr "mode" "XF")])
7386 ;; One complement instructions
7388 (define_expand "one_cmplsi2"
7389   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7390         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
7391   ""
7392   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
7394 (define_insn "*one_cmplsi2_1"
7395   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7396         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
7397   "ix86_unary_operator_ok (NOT, SImode, operands)"
7398   "not{l}\\t%0"
7399   [(set_attr "type" "negnot")
7400    (set_attr "mode" "SI")])
7402 (define_insn "*one_cmplsi2_2"
7403   [(set (reg 17)
7404         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
7405                  (const_int 0)))
7406    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7407         (not:SI (match_dup 1)))]
7408   "ix86_match_ccmode (insn, CCNOmode)
7409    && ix86_unary_operator_ok (NOT, SImode, operands)"
7410   "#"
7411   [(set_attr "type" "alu1")
7412    (set_attr "mode" "SI")])
7414 (define_split
7415   [(set (reg 17)
7416         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
7417                  (const_int 0)))
7418    (set (match_operand:SI 0 "nonimmediate_operand" "")
7419         (not:SI (match_dup 1)))]
7420   "ix86_match_ccmode (insn, CCNOmode)"
7421   [(parallel [(set (reg:CCNO 17)
7422                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
7423                                  (const_int 0)))
7424               (set (match_dup 0)
7425                    (xor:SI (match_dup 1) (const_int -1)))])]
7426   "")
7428 (define_expand "one_cmplhi2"
7429   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7430         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
7431   "TARGET_HIMODE_MATH"
7432   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
7434 (define_insn "*one_cmplhi2_1"
7435   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7436         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
7437   "ix86_unary_operator_ok (NOT, HImode, operands)"
7438   "not{w}\\t%0"
7439   [(set_attr "type" "negnot")
7440    (set_attr "mode" "HI")])
7442 (define_insn "*one_cmplhi2_2"
7443   [(set (reg 17)
7444         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
7445                  (const_int 0)))
7446    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7447         (not:HI (match_dup 1)))]
7448   "ix86_match_ccmode (insn, CCNOmode)
7449    && ix86_unary_operator_ok (NEG, HImode, operands)"
7450   "#"
7451   [(set_attr "type" "alu1")
7452    (set_attr "mode" "HI")])
7454 (define_split
7455   [(set (reg 17)
7456         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
7457                  (const_int 0)))
7458    (set (match_operand:HI 0 "nonimmediate_operand" "")
7459         (not:HI (match_dup 1)))]
7460   "ix86_match_ccmode (insn, CCNOmode)"
7461   [(parallel [(set (reg:CCNO 17)
7462                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
7463                                  (const_int 0)))
7464               (set (match_dup 0)
7465                    (xor:HI (match_dup 1) (const_int -1)))])]
7466   "")
7468 ;; %%% Potential partial reg stall on alternative 1.  What to do?
7469 (define_expand "one_cmplqi2"
7470   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7471         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
7472   "TARGET_QIMODE_MATH"
7473   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
7475 (define_insn "*one_cmplqi2_1"
7476   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
7477         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
7478   "ix86_unary_operator_ok (NOT, QImode, operands)"
7479   "@
7480    not{b}\\t%0
7481    not{l}\\t%k0"
7482   [(set_attr "type" "negnot")
7483    (set_attr "mode" "QI,SI")])
7485 (define_insn "*one_cmplqi2_2"
7486   [(set (reg 17)
7487         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
7488                  (const_int 0)))
7489    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7490         (not:QI (match_dup 1)))]
7491   "ix86_match_ccmode (insn, CCNOmode)
7492    && ix86_unary_operator_ok (NOT, QImode, operands)"
7493   "#"
7494   [(set_attr "type" "alu1")
7495    (set_attr "mode" "QI")])
7497 (define_split
7498   [(set (reg 17)
7499         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
7500                  (const_int 0)))
7501    (set (match_operand:QI 0 "nonimmediate_operand" "")
7502         (not:QI (match_dup 1)))]
7503   "ix86_match_ccmode (insn, CCNOmode)"
7504   [(parallel [(set (reg:CCNO 17)
7505                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
7506                                  (const_int 0)))
7507               (set (match_dup 0)
7508                    (xor:QI (match_dup 1) (const_int -1)))])]
7509   "")
7511 ;; Arithmetic shift instructions
7513 ;; DImode shifts are implemented using the i386 "shift double" opcode,
7514 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
7515 ;; is variable, then the count is in %cl and the "imm" operand is dropped
7516 ;; from the assembler input.
7518 ;; This instruction shifts the target reg/mem as usual, but instead of
7519 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
7520 ;; is a left shift double, bits are taken from the high order bits of
7521 ;; reg, else if the insn is a shift right double, bits are taken from the
7522 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
7523 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
7525 ;; Since sh[lr]d does not change the `reg' operand, that is done
7526 ;; separately, making all shifts emit pairs of shift double and normal
7527 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
7528 ;; support a 63 bit shift, each shift where the count is in a reg expands
7529 ;; to a pair of shifts, a branch, a shift by 32 and a label.
7531 ;; If the shift count is a constant, we need never emit more than one
7532 ;; shift pair, instead using moves and sign extension for counts greater
7533 ;; than 31.
7535 (define_expand "ashldi3"
7536   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
7537                    (ashift:DI (match_operand:DI 1 "register_operand" "0")
7538                               (match_operand:QI 2 "nonmemory_operand" "Jc")))
7539               (clobber (reg:CC 17))])]
7540   ""
7541   "
7543   if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
7544     {
7545       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
7546       DONE;
7547     }
7550 (define_insn "ashldi3_1"
7551   [(set (match_operand:DI 0 "register_operand" "=r")
7552         (ashift:DI (match_operand:DI 1 "register_operand" "0")
7553                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
7554    (clobber (match_scratch:SI 3 "=&r"))
7555    (clobber (reg:CC 17))]
7556   "TARGET_CMOVE"
7557   "#"
7558   [(set_attr "type" "multi")])
7560 (define_insn "*ashldi3_2"
7561   [(set (match_operand:DI 0 "register_operand" "=r")
7562         (ashift:DI (match_operand:DI 1 "register_operand" "0")
7563                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
7564    (clobber (reg:CC 17))]
7565   ""
7566   "#"
7567   [(set_attr "type" "multi")])
7569 (define_split
7570   [(set (match_operand:DI 0 "register_operand" "")
7571         (ashift:DI (match_operand:DI 1 "register_operand" "")
7572                    (match_operand:QI 2 "nonmemory_operand" "")))
7573    (clobber (match_scratch:SI 3 ""))
7574    (clobber (reg:CC 17))]
7575   "TARGET_CMOVE && reload_completed"
7576   [(const_int 0)]
7577   "ix86_split_ashldi (operands, operands[3]); DONE;")
7579 (define_split
7580   [(set (match_operand:DI 0 "register_operand" "")
7581         (ashift:DI (match_operand:DI 1 "register_operand" "")
7582                    (match_operand:QI 2 "nonmemory_operand" "")))
7583    (clobber (reg:CC 17))]
7584   "reload_completed"
7585   [(const_int 0)]
7586   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
7588 (define_insn "x86_shld_1"
7589   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
7590         (ior:SI (ashift:SI (match_dup 0)
7591                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
7592                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
7593                   (minus:QI (const_int 32) (match_dup 2)))))
7594    (clobber (reg:CC 17))]
7595   ""
7596   "@
7597    shld{l}\\t{%2, %1, %0|%0, %1, %2}
7598    shld{l}\\t{%s2%1, %0|%0, %1, %2}"
7599   [(set_attr "type" "ishift")
7600    (set_attr "prefix_0f" "1")
7601    (set_attr "mode" "SI")
7602    (set_attr "pent_pair" "np")
7603    (set_attr "athlon_decode" "vector")
7604    (set_attr "ppro_uops" "few")])
7606 (define_expand "x86_shift_adj_1"
7607   [(set (reg:CCZ 17)
7608         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
7609                              (const_int 32))
7610                      (const_int 0)))
7611    (set (match_operand:SI 0 "register_operand" "")
7612         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
7613                          (match_operand:SI 1 "register_operand" "")
7614                          (match_dup 0)))
7615    (set (match_dup 1)
7616         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
7617                          (match_operand:SI 3 "register_operand" "r")
7618                          (match_dup 1)))]
7619   "TARGET_CMOVE"
7620   "")
7622 (define_expand "x86_shift_adj_2"
7623   [(use (match_operand:SI 0 "register_operand" ""))
7624    (use (match_operand:SI 1 "register_operand" ""))
7625    (use (match_operand:QI 2 "register_operand" ""))]
7626   ""
7627   "
7629   rtx label = gen_label_rtx ();
7630   rtx tmp;
7632   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
7634   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
7635   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
7636   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
7637                               gen_rtx_LABEL_REF (VOIDmode, label),
7638                               pc_rtx);
7639   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
7640   JUMP_LABEL (tmp) = label;
7642   emit_move_insn (operands[0], operands[1]);
7643   emit_move_insn (operands[1], const0_rtx);
7645   emit_label (label);
7646   LABEL_NUSES (label) = 1;
7648   DONE;
7651 (define_expand "ashlsi3"
7652   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7653         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
7654                    (match_operand:QI 2 "nonmemory_operand" "")))
7655    (clobber (reg:CC 17))]
7656   ""
7657   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
7659 (define_insn "*ashlsi3_1"
7660   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7661         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
7662                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
7663    (clobber (reg:CC 17))]
7664   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
7665   "*
7667   switch (get_attr_type (insn))
7668     {
7669     case TYPE_ALU:
7670       if (operands[2] != const1_rtx)
7671         abort ();
7672       if (!rtx_equal_p (operands[0], operands[1]))
7673         abort ();
7674       return \"add{l}\\t{%0, %0|%0, %0}\";
7676     case TYPE_LEA:
7677       if (GET_CODE (operands[2]) != CONST_INT
7678           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
7679         abort ();
7680       operands[1] = gen_rtx_MULT (SImode, operands[1],
7681                                   GEN_INT (1 << INTVAL (operands[2])));
7682       return \"lea{l}\\t{%a1, %0|%0, %a1}\";
7684     default:
7685       if (REG_P (operands[2]))
7686         return \"sal{l}\\t{%b2, %0|%0, %b2}\";
7687       else if (GET_CODE (operands[2]) == CONST_INT
7688                && INTVAL (operands[2]) == 1
7689                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
7690         return \"sal{l}\\t%0\";
7691       else
7692         return \"sal{l}\\t{%2, %0|%0, %2}\";
7693     }
7695   [(set (attr "type")
7696      (cond [(eq_attr "alternative" "1")
7697               (const_string "lea")
7698             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
7699                           (const_int 0))
7700                       (match_operand 0 "register_operand" ""))
7701                  (match_operand 2 "const1_operand" ""))
7702               (const_string "alu")
7703            ]
7704            (const_string "ishift")))
7705    (set_attr "mode" "SI")])
7707 ;; Convert lea to the lea pattern to avoid flags dependency.
7708 (define_split
7709   [(set (match_operand 0 "register_operand" "")
7710         (ashift (match_operand 1 "register_operand" "")
7711                 (match_operand:QI 2 "const_int_operand" "")))
7712    (clobber (reg:CC 17))]
7713   "reload_completed
7714    && true_regnum (operands[0]) != true_regnum (operands[1])"
7715   [(const_int 0)]
7716   "
7718   rtx pat;
7719   operands[0] = gen_lowpart (SImode, operands[0]);
7720   operands[1] = gen_lowpart (Pmode, operands[1]);
7721   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7722   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
7723   if (Pmode != SImode)
7724     pat = gen_rtx_SUBREG (SImode, pat, 0);
7725   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7726   DONE;
7729 ;; This pattern can't accept a variable shift count, since shifts by
7730 ;; zero don't affect the flags.  We assume that shifts by constant
7731 ;; zero are optimized away.
7732 (define_insn "*ashlsi3_cmp"
7733   [(set (reg 17)
7734         (compare
7735           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
7736                      (match_operand:QI 2 "immediate_operand" "I"))
7737           (const_int 0)))
7738    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7739         (ashift:SI (match_dup 1) (match_dup 2)))]
7740   "ix86_match_ccmode (insn, CCGOCmode)
7741    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
7742   "*
7744   switch (get_attr_type (insn))
7745     {
7746     case TYPE_ALU:
7747       if (operands[2] != const1_rtx)
7748         abort ();
7749       return \"add{l}\\t{%0, %0|%0, %0}\";
7751     default:
7752       if (REG_P (operands[2]))
7753         return \"sal{l}\\t{%b2, %0|%0, %b2}\";
7754       else if (GET_CODE (operands[2]) == CONST_INT
7755                && INTVAL (operands[2]) == 1
7756                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
7757         return \"sal{l}\\t%0\";
7758       else
7759         return \"sal{l}\\t{%2, %0|%0, %2}\";
7760     }
7762   [(set (attr "type")
7763      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
7764                           (const_int 0))
7765                       (match_operand 0 "register_operand" ""))
7766                  (match_operand 2 "const1_operand" ""))
7767               (const_string "alu")
7768            ]
7769            (const_string "ishift")))
7770    (set_attr "mode" "SI")])
7772 (define_expand "ashlhi3"
7773   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7774         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
7775                    (match_operand:QI 2 "nonmemory_operand" "")))
7776    (clobber (reg:CC 17))]
7777   "TARGET_HIMODE_MATH"
7778   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
7780 (define_insn "*ashlhi3_1_lea"
7781   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7782         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
7783                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
7784    (clobber (reg:CC 17))]
7785   "!TARGET_PARTIAL_REG_STALL
7786    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
7787   "*
7789   switch (get_attr_type (insn))
7790     {
7791     case TYPE_LEA:
7792       return \"#\";
7793     case TYPE_ALU:
7794       if (operands[2] != const1_rtx)
7795         abort ();
7796       return \"add{w}\\t{%0, %0|%0, %0}\";
7798     default:
7799       if (REG_P (operands[2]))
7800         return \"sal{w}\\t{%b2, %0|%0, %b2}\";
7801       else if (GET_CODE (operands[2]) == CONST_INT
7802                && INTVAL (operands[2]) == 1
7803                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
7804         return \"sal{w}\\t%0\";
7805       else
7806         return \"sal{w}\\t{%2, %0|%0, %2}\";
7807     }
7809   [(set (attr "type")
7810      (cond [(eq_attr "alternative" "1")
7811               (const_string "lea")
7812             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
7813                           (const_int 0))
7814                       (match_operand 0 "register_operand" ""))
7815                  (match_operand 2 "const1_operand" ""))
7816               (const_string "alu")
7817            ]
7818            (const_string "ishift")))
7819    (set_attr "mode" "HI,SI")])
7821 (define_insn "*ashlhi3_1"
7822   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7823         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
7824                    (match_operand:QI 2 "nonmemory_operand" "cI")))
7825    (clobber (reg:CC 17))]
7826   "TARGET_PARTIAL_REG_STALL
7827    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
7828   "*
7830   switch (get_attr_type (insn))
7831     {
7832     case TYPE_ALU:
7833       if (operands[2] != const1_rtx)
7834         abort ();
7835       return \"add{w}\\t{%0, %0|%0, %0}\";
7837     default:
7838       if (REG_P (operands[2]))
7839         return \"sal{w}\\t{%b2, %0|%0, %b2}\";
7840       else if (GET_CODE (operands[2]) == CONST_INT
7841                && INTVAL (operands[2]) == 1
7842                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
7843         return \"sal{w}\\t%0\";
7844       else
7845         return \"sal{w}\\t{%2, %0|%0, %2}\";
7846     }
7848   [(set (attr "type")
7849      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
7850                           (const_int 0))
7851                       (match_operand 0 "register_operand" ""))
7852                  (match_operand 2 "const1_operand" ""))
7853               (const_string "alu")
7854            ]
7855            (const_string "ishift")))
7856    (set_attr "mode" "HI")])
7858 ;; This pattern can't accept a variable shift count, since shifts by
7859 ;; zero don't affect the flags.  We assume that shifts by constant
7860 ;; zero are optimized away.
7861 (define_insn "*ashlhi3_cmp"
7862   [(set (reg 17)
7863         (compare
7864           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
7865                      (match_operand:QI 2 "immediate_operand" "I"))
7866           (const_int 0)))
7867    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7868         (ashift:HI (match_dup 1) (match_dup 2)))]
7869   "ix86_match_ccmode (insn, CCGOCmode)
7870    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
7871   "*
7873   switch (get_attr_type (insn))
7874     {
7875     case TYPE_ALU:
7876       if (operands[2] != const1_rtx)
7877         abort ();
7878       return \"add{w}\\t{%0, %0|%0, %0}\";
7880     default:
7881       if (REG_P (operands[2]))
7882         return \"sal{w}\\t{%b2, %0|%0, %b2}\";
7883       else if (GET_CODE (operands[2]) == CONST_INT
7884                && INTVAL (operands[2]) == 1
7885                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
7886         return \"sal{w}\\t%0\";
7887       else
7888         return \"sal{w}\\t{%2, %0|%0, %2}\";
7889     }
7891   [(set (attr "type")
7892      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
7893                           (const_int 0))
7894                       (match_operand 0 "register_operand" ""))
7895                  (match_operand 2 "const1_operand" ""))
7896               (const_string "alu")
7897            ]
7898            (const_string "ishift")))
7899    (set_attr "mode" "HI")])
7901 (define_expand "ashlqi3"
7902   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7903         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
7904                    (match_operand:QI 2 "nonmemory_operand" "")))
7905    (clobber (reg:CC 17))]
7906   "TARGET_QIMODE_MATH"
7907   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
7909 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7911 (define_insn "*ashlqi3_1_lea"
7912   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
7913         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
7914                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
7915    (clobber (reg:CC 17))]
7916   "!TARGET_PARTIAL_REG_STALL
7917    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
7918   "*
7920   switch (get_attr_type (insn))
7921     {
7922     case TYPE_LEA:
7923       return \"#\";
7924     case TYPE_ALU:
7925       if (operands[2] != const1_rtx)
7926         abort ();
7927       if (NON_QI_REG_P (operands[1]))
7928         return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
7929       else
7930         return \"add{b}\\t{%0, %0|%0, %0}\";
7932     default:
7933       if (REG_P (operands[2]))
7934         {
7935           if (get_attr_mode (insn) == MODE_SI)
7936             return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
7937           else
7938             return \"sal{b}\\t{%b2, %0|%0, %b2}\";
7939         }
7940       else if (GET_CODE (operands[2]) == CONST_INT
7941                && INTVAL (operands[2]) == 1
7942                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
7943         {
7944           if (get_attr_mode (insn) == MODE_SI)
7945             return \"sal{l}\\t%0\";
7946           else
7947             return \"sal{b}\\t%0\";
7948         }
7949       else
7950         {
7951           if (get_attr_mode (insn) == MODE_SI)
7952             return \"sal{l}\\t{%2, %k0|%k0, %2}\";
7953           else
7954             return \"sal{b}\\t{%2, %0|%0, %2}\";
7955         }
7956     }
7958   [(set (attr "type")
7959      (cond [(eq_attr "alternative" "2")
7960               (const_string "lea")
7961             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
7962                           (const_int 0))
7963                       (match_operand 0 "register_operand" ""))
7964                  (match_operand 2 "const1_operand" ""))
7965               (const_string "alu")
7966            ]
7967            (const_string "ishift")))
7968    (set_attr "mode" "QI,SI,SI")])
7970 (define_insn "*ashlqi3_1"
7971   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
7972         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7973                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
7974    (clobber (reg:CC 17))]
7975   "TARGET_PARTIAL_REG_STALL
7976    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
7977   "*
7979   switch (get_attr_type (insn))
7980     {
7981     case TYPE_ALU:
7982       if (operands[2] != const1_rtx)
7983         abort ();
7984       if (NON_QI_REG_P (operands[1]))
7985         return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
7986       else
7987         return \"add{b}\\t{%0, %0|%0, %0}\";
7989     default:
7990       if (REG_P (operands[2]))
7991         {
7992           if (NON_QI_REG_P (operands[1]))
7993             return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
7994           else
7995             return \"sal{b}\\t{%b2, %0|%0, %b2}\";
7996         }
7997       else if (GET_CODE (operands[2]) == CONST_INT
7998                && INTVAL (operands[2]) == 1
7999                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8000         {
8001           if (NON_QI_REG_P (operands[1]))
8002             return \"sal{l}\\t%0\";
8003           else
8004             return \"sal{b}\\t%0\";
8005         }
8006       else
8007         {
8008           if (NON_QI_REG_P (operands[1]))
8009             return \"sal{l}\\t{%2, %k0|%k0, %2}\";
8010           else
8011             return \"sal{b}\\t{%2, %0|%0, %2}\";
8012         }
8013     }
8015   [(set (attr "type")
8016      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8017                           (const_int 0))
8018                       (match_operand 0 "register_operand" ""))
8019                  (match_operand 2 "const1_operand" ""))
8020               (const_string "alu")
8021            ]
8022            (const_string "ishift")))
8023    (set_attr "mode" "QI,SI")])
8025 ;; This pattern can't accept a variable shift count, since shifts by
8026 ;; zero don't affect the flags.  We assume that shifts by constant
8027 ;; zero are optimized away.
8028 (define_insn "*ashlqi3_cmp"
8029   [(set (reg 17)
8030         (compare
8031           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8032                      (match_operand:QI 2 "immediate_operand" "I"))
8033           (const_int 0)))
8034    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8035         (ashift:QI (match_dup 1) (match_dup 2)))]
8036   "ix86_match_ccmode (insn, CCGOCmode)
8037    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8038   "*
8040   switch (get_attr_type (insn))
8041     {
8042     case TYPE_ALU:
8043       if (operands[2] != const1_rtx)
8044         abort ();
8045       return \"add{b}\\t{%0, %0|%0, %0}\";
8047     default:
8048       if (REG_P (operands[2]))
8049         return \"sal{b}\\t{%b2, %0|%0, %b2}\";
8050       else if (GET_CODE (operands[2]) == CONST_INT
8051                && INTVAL (operands[2]) == 1
8052                && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8053         return \"sal{b}\\t%0\";
8054       else
8055         return \"sal{b}\\t{%2, %0|%0, %2}\";
8056     }
8058   [(set (attr "type")
8059      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8060                           (const_int 0))
8061                       (match_operand 0 "register_operand" ""))
8062                  (match_operand 2 "const1_operand" ""))
8063               (const_string "alu")
8064            ]
8065            (const_string "ishift")))
8066    (set_attr "mode" "QI")])
8068 ;; See comment above `ashldi3' about how this works.
8070 (define_expand "ashrdi3"
8071   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
8072                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8073                                 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8074               (clobber (reg:CC 17))])]
8075   ""
8076   "
8078   if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
8079     {
8080       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
8081       DONE;
8082     }
8085 (define_insn "ashrdi3_1"
8086   [(set (match_operand:DI 0 "register_operand" "=r")
8087         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8088                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
8089    (clobber (match_scratch:SI 3 "=&r"))
8090    (clobber (reg:CC 17))]
8091   "TARGET_CMOVE"
8092   "#"
8093   [(set_attr "type" "multi")])
8095 (define_insn "*ashrdi3_2"
8096   [(set (match_operand:DI 0 "register_operand" "=r")
8097         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8098                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
8099    (clobber (reg:CC 17))]
8100   ""
8101   "#"
8102   [(set_attr "type" "multi")])
8104 (define_split
8105   [(set (match_operand:DI 0 "register_operand" "")
8106         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
8107                      (match_operand:QI 2 "nonmemory_operand" "")))
8108    (clobber (match_scratch:SI 3 ""))
8109    (clobber (reg:CC 17))]
8110   "TARGET_CMOVE && reload_completed"
8111   [(const_int 0)]
8112   "ix86_split_ashrdi (operands, operands[3]); DONE;")
8114 (define_split
8115   [(set (match_operand:DI 0 "register_operand" "")
8116         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
8117                      (match_operand:QI 2 "nonmemory_operand" "")))
8118    (clobber (reg:CC 17))]
8119   "reload_completed"
8120   [(const_int 0)]
8121   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
8123 (define_insn "x86_shrd_1"
8124   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
8125         (ior:SI (ashiftrt:SI (match_dup 0)
8126                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
8127                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
8128                   (minus:QI (const_int 32) (match_dup 2)))))
8129    (clobber (reg:CC 17))]
8130   ""
8131   "@
8132    shrd{l}\\t{%2, %1, %0|%0, %1, %2}
8133    shrd{l}\\t{%s2%1, %0|%0, %1, %2}"
8134   [(set_attr "type" "ishift")
8135    (set_attr "prefix_0f" "1")
8136    (set_attr "pent_pair" "np")
8137    (set_attr "ppro_uops" "few")
8138    (set_attr "mode" "SI")])
8140 (define_expand "x86_shift_adj_3"
8141   [(use (match_operand:SI 0 "register_operand" ""))
8142    (use (match_operand:SI 1 "register_operand" ""))
8143    (use (match_operand:QI 2 "register_operand" ""))]
8144   ""
8145   "
8147   rtx label = gen_label_rtx ();
8148   rtx tmp;
8150   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
8152   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8153   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8154   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8155                               gen_rtx_LABEL_REF (VOIDmode, label),
8156                               pc_rtx);
8157   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8158   JUMP_LABEL (tmp) = label;
8160   emit_move_insn (operands[0], operands[1]);
8161   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
8163   emit_label (label);
8164   LABEL_NUSES (label) = 1;
8166   DONE;
8169 (define_insn "ashrsi3_31"
8170   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
8171         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
8172                      (match_operand:SI 2 "const_int_operand" "i,i")))
8173    (clobber (reg:CC 17))]
8174   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
8175    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8176   "@
8177    {cltd|cdq}
8178    sar{l}\\t{%2, %0|%0, %2}"
8179   [(set_attr "type" "imovx,ishift")
8180    (set_attr "prefix_0f" "0,*")
8181    (set_attr "length_immediate" "0,*")
8182    (set_attr "modrm" "0,1")
8183    (set_attr "mode" "SI")])
8185 (define_expand "ashrsi3"
8186   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8187         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
8188                      (match_operand:QI 2 "nonmemory_operand" "")))
8189    (clobber (reg:CC 17))]
8190   ""
8191   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
8193 (define_insn "*ashrsi3_1_one_bit"
8194   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8195         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8196                      (match_operand:QI 2 "const_int_1_operand" "")))
8197    (clobber (reg:CC 17))]
8198   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
8199    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8200   "sar{l}\\t%0"
8201   [(set_attr "type" "ishift")
8202    (set (attr "length") 
8203      (if_then_else (match_operand:SI 0 "register_operand" "") 
8204         (const_string "2")
8205         (const_string "*")))])
8207 (define_insn "*ashrsi3_1"
8208   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8209         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8210                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
8211    (clobber (reg:CC 17))]
8212   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8213   "@
8214    sar{l}\\t{%2, %0|%0, %2}
8215    sar{l}\\t{%b2, %0|%0, %b2}"
8216   [(set_attr "type" "ishift")
8217    (set_attr "mode" "SI")])
8219 ;; This pattern can't accept a variable shift count, since shifts by
8220 ;; zero don't affect the flags.  We assume that shifts by constant
8221 ;; zero are optimized away.
8222 (define_insn "*ashrsi3_one_bit_cmp"
8223   [(set (reg 17)
8224         (compare
8225           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8226                        (match_operand:QI 2 "const_int_1_operand" ""))
8227           (const_int 0)))
8228    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8229         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
8230   "ix86_match_ccmode (insn, CCGOCmode)
8231    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8232    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8233   "sar{l}\\t%0"
8234   [(set_attr "type" "ishift")
8235    (set (attr "length") 
8236      (if_then_else (match_operand:SI 0 "register_operand" "") 
8237         (const_string "2")
8238         (const_string "*")))])
8240 ;; This pattern can't accept a variable shift count, since shifts by
8241 ;; zero don't affect the flags.  We assume that shifts by constant
8242 ;; zero are optimized away.
8243 (define_insn "*ashrsi3_cmp"
8244   [(set (reg 17)
8245         (compare
8246           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8247                        (match_operand:QI 2 "immediate_operand" "I"))
8248           (const_int 0)))
8249    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8250         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
8251   "ix86_match_ccmode (insn, CCGOCmode)
8252    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8253   "sar{l}\\t{%2, %0|%0, %2}"
8254   [(set_attr "type" "ishift")
8255    (set_attr "mode" "SI")])
8257 (define_expand "ashrhi3"
8258   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8259         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
8260                      (match_operand:QI 2 "nonmemory_operand" "")))
8261    (clobber (reg:CC 17))]
8262   "TARGET_HIMODE_MATH"
8263   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
8265 (define_insn "*ashrhi3_1_one_bit"
8266   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8267         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8268                      (match_operand:QI 2 "const_int_1_operand" "")))
8269    (clobber (reg:CC 17))]
8270   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
8271    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8272   "sar{w}\\t%0"
8273   [(set_attr "type" "ishift")
8274    (set (attr "length") 
8275      (if_then_else (match_operand:SI 0 "register_operand" "") 
8276         (const_string "2")
8277         (const_string "*")))])
8279 (define_insn "*ashrhi3_1"
8280   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
8281         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8282                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
8283    (clobber (reg:CC 17))]
8284   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
8285   "@
8286    sar{w}\\t{%2, %0|%0, %2}
8287    sar{w}\\t{%b2, %0|%0, %b2}"
8288   [(set_attr "type" "ishift")
8289    (set_attr "mode" "HI")])
8291 ;; This pattern can't accept a variable shift count, since shifts by
8292 ;; zero don't affect the flags.  We assume that shifts by constant
8293 ;; zero are optimized away.
8294 (define_insn "*ashrhi3_one_bit_cmp"
8295   [(set (reg 17)
8296         (compare
8297           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8298                        (match_operand:QI 2 "const_int_1_operand" ""))
8299           (const_int 0)))
8300    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8301         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
8302   "ix86_match_ccmode (insn, CCGOCmode)
8303    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8304    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
8305   "sar{w}\\t%0"
8306   [(set_attr "type" "ishift")
8307    (set (attr "length") 
8308      (if_then_else (match_operand:SI 0 "register_operand" "") 
8309         (const_string "2")
8310         (const_string "*")))])
8312 ;; This pattern can't accept a variable shift count, since shifts by
8313 ;; zero don't affect the flags.  We assume that shifts by constant
8314 ;; zero are optimized away.
8315 (define_insn "*ashrhi3_cmp"
8316   [(set (reg 17)
8317         (compare
8318           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8319                        (match_operand:QI 2 "immediate_operand" "I"))
8320           (const_int 0)))
8321    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8322         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
8323   "ix86_match_ccmode (insn, CCGOCmode)
8324    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
8325   "sar{w}\\t{%2, %0|%0, %2}"
8326   [(set_attr "type" "ishift")
8327    (set_attr "mode" "HI")])
8329 (define_expand "ashrqi3"
8330   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8331         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
8332                      (match_operand:QI 2 "nonmemory_operand" "")))
8333    (clobber (reg:CC 17))]
8334   "TARGET_QIMODE_MATH"
8335   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
8337 (define_insn "*ashrqi3_1_one_bit"
8338   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8339         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8340                      (match_operand:QI 2 "const_int_1_operand" "")))
8341    (clobber (reg:CC 17))]
8342   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
8343    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8344   "sar{b}\\t%0"
8345   [(set_attr "type" "ishift")
8346    (set (attr "length") 
8347      (if_then_else (match_operand:SI 0 "register_operand" "") 
8348         (const_string "2")
8349         (const_string "*")))])
8351 (define_insn "*ashrqi3_1"
8352   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
8353         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8354                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
8355    (clobber (reg:CC 17))]
8356   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
8357   "@
8358    sar{b}\\t{%2, %0|%0, %2}
8359    sar{b}\\t{%b2, %0|%0, %b2}"
8360   [(set_attr "type" "ishift")
8361    (set_attr "mode" "QI")])
8363 ;; This pattern can't accept a variable shift count, since shifts by
8364 ;; zero don't affect the flags.  We assume that shifts by constant
8365 ;; zero are optimized away.
8366 (define_insn "*ashrqi3_one_bit_cmp"
8367   [(set (reg 17)
8368         (compare
8369           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8370                        (match_operand:QI 2 "const_int_1_operand" "I"))
8371           (const_int 0)))
8372    (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
8373         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
8374   "ix86_match_ccmode (insn, CCGOCmode)
8375    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8376    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
8377   "sar{b}\\t%0"
8378   [(set_attr "type" "ishift")
8379    (set (attr "length") 
8380      (if_then_else (match_operand:SI 0 "register_operand" "") 
8381         (const_string "2")
8382         (const_string "*")))])
8384 ;; This pattern can't accept a variable shift count, since shifts by
8385 ;; zero don't affect the flags.  We assume that shifts by constant
8386 ;; zero are optimized away.
8387 (define_insn "*ashrqi3_cmp"
8388   [(set (reg 17)
8389         (compare
8390           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8391                        (match_operand:QI 2 "immediate_operand" "I"))
8392           (const_int 0)))
8393    (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
8394         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
8395   "ix86_match_ccmode (insn, CCGOCmode)
8396    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
8397   "sar{b}\\t{%2, %0|%0, %2}"
8398   [(set_attr "type" "ishift")
8399    (set_attr "mode" "QI")])
8401 ;; Logical shift instructions
8403 ;; See comment above `ashldi3' about how this works.
8405 (define_expand "lshrdi3"
8406   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
8407                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8408                                 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8409               (clobber (reg:CC 17))])]
8410   ""
8411   "
8413   if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
8414     {
8415       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
8416       DONE;
8417     }
8420 (define_insn "lshrdi3_1"
8421   [(set (match_operand:DI 0 "register_operand" "=r")
8422         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8423                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
8424    (clobber (match_scratch:SI 3 "=&r"))
8425    (clobber (reg:CC 17))]
8426   "TARGET_CMOVE"
8427   "#"
8428   [(set_attr "type" "multi")])
8430 (define_insn "*lshrdi3_2"
8431   [(set (match_operand:DI 0 "register_operand" "=r")
8432         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8433                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
8434    (clobber (reg:CC 17))]
8435   ""
8436   "#"
8437   [(set_attr "type" "multi")])
8439 (define_split 
8440   [(set (match_operand:DI 0 "register_operand" "")
8441         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
8442                      (match_operand:QI 2 "nonmemory_operand" "")))
8443    (clobber (match_scratch:SI 3 ""))
8444    (clobber (reg:CC 17))]
8445   "TARGET_CMOVE && reload_completed"
8446   [(const_int 0)]
8447   "ix86_split_lshrdi (operands, operands[3]); DONE;")
8449 (define_split 
8450   [(set (match_operand:DI 0 "register_operand" "")
8451         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
8452                      (match_operand:QI 2 "nonmemory_operand" "")))
8453    (clobber (reg:CC 17))]
8454   "reload_completed"
8455   [(const_int 0)]
8456   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
8458 (define_expand "lshrsi3"
8459   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8460         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
8461                      (match_operand:QI 2 "nonmemory_operand" "")))
8462    (clobber (reg:CC 17))]
8463   ""
8464   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
8466 (define_insn "*lshrsi3_1_one_bit"
8467   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8468         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8469                      (match_operand:QI 2 "const_int_1_operand" "")))
8470    (clobber (reg:CC 17))]
8471   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
8472    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8473   "shr{l}\\t%0"
8474   [(set_attr "type" "ishift")
8475    (set (attr "length") 
8476      (if_then_else (match_operand:SI 0 "register_operand" "") 
8477         (const_string "2")
8478         (const_string "*")))])
8480 (define_insn "*lshrsi3_1"
8481   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8482         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8483                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
8484    (clobber (reg:CC 17))]
8485   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8486   "@
8487    shr{l}\\t{%2, %0|%0, %2}
8488    shr{l}\\t{%b2, %0|%0, %b2}"
8489   [(set_attr "type" "ishift")
8490    (set_attr "mode" "SI")])
8492 ;; This pattern can't accept a variable shift count, since shifts by
8493 ;; zero don't affect the flags.  We assume that shifts by constant
8494 ;; zero are optimized away.
8495 (define_insn "*lshrsi3_one_bit_cmp"
8496   [(set (reg 17)
8497         (compare
8498           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8499                        (match_operand:QI 2 "const_int_1_operand" ""))
8500           (const_int 0)))
8501    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8502         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
8503   "ix86_match_ccmode (insn, CCGOCmode)
8504    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8505    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8506   "shr{l}\\t%0"
8507   [(set_attr "type" "ishift")
8508    (set (attr "length") 
8509      (if_then_else (match_operand:SI 0 "register_operand" "") 
8510         (const_string "2")
8511         (const_string "*")))])
8513 ;; This pattern can't accept a variable shift count, since shifts by
8514 ;; zero don't affect the flags.  We assume that shifts by constant
8515 ;; zero are optimized away.
8516 (define_insn "*lshrsi3_cmp"
8517   [(set (reg 17)
8518         (compare
8519           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8520                        (match_operand:QI 2 "immediate_operand" "I"))
8521           (const_int 0)))
8522    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8523         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
8524   "ix86_match_ccmode (insn, CCGOCmode)
8525    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8526   "shr{l}\\t{%2, %0|%0, %2}"
8527   [(set_attr "type" "ishift")
8528    (set_attr "mode" "SI")])
8530 (define_expand "lshrhi3"
8531   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8532         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
8533                      (match_operand:QI 2 "nonmemory_operand" "")))
8534    (clobber (reg:CC 17))]
8535   "TARGET_HIMODE_MATH"
8536   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
8538 (define_insn "*lshrhi3_1_one_bit"
8539   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8540         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8541                      (match_operand:QI 2 "const_int_1_operand" "")))
8542    (clobber (reg:CC 17))]
8543   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
8544    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8545   "shr{w}\\t%0"
8546   [(set_attr "type" "ishift")
8547    (set (attr "length") 
8548      (if_then_else (match_operand:SI 0 "register_operand" "") 
8549         (const_string "2")
8550         (const_string "*")))])
8552 (define_insn "*lshrhi3_1"
8553   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
8554         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8555                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
8556    (clobber (reg:CC 17))]
8557   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8558   "@
8559    shr{w}\\t{%2, %0|%0, %2}
8560    shr{w}\\t{%b2, %0|%0, %b2}"
8561   [(set_attr "type" "ishift")
8562    (set_attr "mode" "HI")])
8564 ;; This pattern can't accept a variable shift count, since shifts by
8565 ;; zero don't affect the flags.  We assume that shifts by constant
8566 ;; zero are optimized away.
8567 (define_insn "*lshrhi3_one_bit_cmp"
8568   [(set (reg 17)
8569         (compare
8570           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8571                        (match_operand:QI 2 "const_int_1_operand" ""))
8572           (const_int 0)))
8573    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8574         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
8575   "ix86_match_ccmode (insn, CCGOCmode)
8576    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8577    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8578   "shr{w}\\t%0"
8579   [(set_attr "type" "ishift")
8580    (set (attr "length") 
8581      (if_then_else (match_operand:SI 0 "register_operand" "") 
8582         (const_string "2")
8583         (const_string "*")))])
8585 ;; This pattern can't accept a variable shift count, since shifts by
8586 ;; zero don't affect the flags.  We assume that shifts by constant
8587 ;; zero are optimized away.
8588 (define_insn "*lshrhi3_cmp"
8589   [(set (reg 17)
8590         (compare
8591           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8592                        (match_operand:QI 2 "immediate_operand" "I"))
8593           (const_int 0)))
8594    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8595         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
8596   "ix86_match_ccmode (insn, CCGOCmode)
8597    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8598   "shr{w}\\t{%2, %0|%0, %2}"
8599   [(set_attr "type" "ishift")
8600    (set_attr "mode" "HI")])
8602 (define_expand "lshrqi3"
8603   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8604         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
8605                      (match_operand:QI 2 "nonmemory_operand" "")))
8606    (clobber (reg:CC 17))]
8607   "TARGET_QIMODE_MATH"
8608   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
8610 (define_insn "*lshrqi3_1_one_bit"
8611   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8612         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8613                      (match_operand:QI 2 "const_int_1_operand" "")))
8614    (clobber (reg:CC 17))]
8615   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
8616    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8617   "shr{b}\\t%0"
8618   [(set_attr "type" "ishift")
8619    (set (attr "length") 
8620      (if_then_else (match_operand:SI 0 "register_operand" "") 
8621         (const_string "2")
8622         (const_string "*")))])
8624 (define_insn "*lshrqi3_1"
8625   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
8626         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8627                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
8628    (clobber (reg:CC 17))]
8629   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
8630   "@
8631    shr{b}\\t{%2, %0|%0, %2}
8632    shr{b}\\t{%b2, %0|%0, %b2}"
8633   [(set_attr "type" "ishift")
8634    (set_attr "mode" "QI")])
8636 ;; This pattern can't accept a variable shift count, since shifts by
8637 ;; zero don't affect the flags.  We assume that shifts by constant
8638 ;; zero are optimized away.
8639 (define_insn "*lshrqi2_one_bit_cmp"
8640   [(set (reg 17)
8641         (compare
8642           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8643                        (match_operand:QI 2 "const_int_1_operand" ""))
8644           (const_int 0)))
8645    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8646         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
8647   "ix86_match_ccmode (insn, CCGOCmode)
8648    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8649    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
8650   "shr{b}\\t%0"
8651   [(set_attr "type" "ishift")
8652    (set (attr "length") 
8653      (if_then_else (match_operand:SI 0 "register_operand" "") 
8654         (const_string "2")
8655         (const_string "*")))])
8657 ;; This pattern can't accept a variable shift count, since shifts by
8658 ;; zero don't affect the flags.  We assume that shifts by constant
8659 ;; zero are optimized away.
8660 (define_insn "*lshrqi2_cmp"
8661   [(set (reg 17)
8662         (compare
8663           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8664                        (match_operand:QI 2 "immediate_operand" "I"))
8665           (const_int 0)))
8666    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8667         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
8668   "ix86_match_ccmode (insn, CCGOCmode)
8669    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
8670   "shr{b}\\t{%2, %0|%0, %2}"
8671   [(set_attr "type" "ishift")
8672    (set_attr "mode" "QI")])
8674 ;; Rotate instructions
8676 (define_expand "rotlsi3"
8677   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8678         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
8679                    (match_operand:QI 2 "nonmemory_operand" "")))
8680    (clobber (reg:CC 17))]
8681   ""
8682   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
8684 (define_insn "*rotlsi3_1_one_bit"
8685   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8686         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8687                    (match_operand:QI 2 "const_int_1_operand" "")))
8688    (clobber (reg:CC 17))]
8689   "ix86_binary_operator_ok (ROTATE, SImode, operands)
8690    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8691   "rol{l}\\t%0"
8692   [(set_attr "type" "ishift")
8693    (set (attr "length") 
8694      (if_then_else (match_operand:SI 0 "register_operand" "") 
8695         (const_string "2")
8696         (const_string "*")))])
8698 (define_insn "*rotlsi3_1"
8699   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8700         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8701                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
8702    (clobber (reg:CC 17))]
8703   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
8704   "@
8705    rol{l}\\t{%2, %0|%0, %2}
8706    rol{l}\\t{%b2, %0|%0, %b2}"
8707   [(set_attr "type" "ishift")
8708    (set_attr "mode" "SI")])
8710 (define_expand "rotlhi3"
8711   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8712         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
8713                    (match_operand:QI 2 "nonmemory_operand" "")))
8714    (clobber (reg:CC 17))]
8715   "TARGET_HIMODE_MATH"
8716   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
8718 (define_insn "*rotlhi3_1_one_bit"
8719   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8720         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8721                    (match_operand:QI 2 "const_int_1_operand" "")))
8722    (clobber (reg:CC 17))]
8723   "ix86_binary_operator_ok (ROTATE, HImode, operands)
8724    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8725   "rol{w}\\t%0"
8726   [(set_attr "type" "ishift")
8727    (set (attr "length") 
8728      (if_then_else (match_operand:SI 0 "register_operand" "") 
8729         (const_string "2")
8730         (const_string "*")))])
8732 (define_insn "*rotlhi3_1"
8733   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
8734         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8735                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
8736    (clobber (reg:CC 17))]
8737   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
8738   "@
8739    rol{w}\\t{%2, %0|%0, %2}
8740    rol{w}\\t{%b2, %0|%0, %b2}"
8741   [(set_attr "type" "ishift")
8742    (set_attr "mode" "HI")])
8744 (define_expand "rotlqi3"
8745   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8746         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
8747                    (match_operand:QI 2 "nonmemory_operand" "")))
8748    (clobber (reg:CC 17))]
8749   "TARGET_QIMODE_MATH"
8750   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
8752 (define_insn "*rotlqi3_1_one_bit"
8753   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8754         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8755                    (match_operand:QI 2 "const_int_1_operand" "")))
8756    (clobber (reg:CC 17))]
8757   "ix86_binary_operator_ok (ROTATE, QImode, operands)
8758    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8759   "rol{b}\\t%0"
8760   [(set_attr "type" "ishift")
8761    (set (attr "length") 
8762      (if_then_else (match_operand:SI 0 "register_operand" "") 
8763         (const_string "2")
8764         (const_string "*")))])
8766 (define_insn "*rotlqi3_1"
8767   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
8768         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8769                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
8770    (clobber (reg:CC 17))]
8771   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
8772   "@
8773    rol{b}\\t{%2, %0|%0, %2}
8774    rol{b}\\t{%b2, %0|%0, %b2}"
8775   [(set_attr "type" "ishift")
8776    (set_attr "mode" "QI")])
8778 (define_expand "rotrsi3"
8779   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8780         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
8781                      (match_operand:QI 2 "nonmemory_operand" "")))
8782    (clobber (reg:CC 17))]
8783   ""
8784   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
8786 (define_insn "*rotrsi3_1_one_bit"
8787   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8788         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8789                      (match_operand:QI 2 "const_int_1_operand" "")))
8790    (clobber (reg:CC 17))]
8791   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
8792    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8793   "ror{l}\\t%0"
8794   [(set_attr "type" "ishift")
8795    (set (attr "length") 
8796      (if_then_else (match_operand:SI 0 "register_operand" "") 
8797         (const_string "2")
8798         (const_string "*")))])
8800 (define_insn "*rotrsi3_1"
8801   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8802         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8803                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
8804    (clobber (reg:CC 17))]
8805   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
8806   "@
8807    ror{l}\\t{%2, %0|%0, %2}
8808    ror{l}\\t{%b2, %0|%0, %b2}"
8809   [(set_attr "type" "ishift")
8810    (set_attr "mode" "SI")])
8812 (define_expand "rotrhi3"
8813   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8814         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
8815                      (match_operand:QI 2 "nonmemory_operand" "")))
8816    (clobber (reg:CC 17))]
8817   "TARGET_HIMODE_MATH"
8818   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
8820 (define_insn "*rotrhi3_one_bit"
8821   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8822         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8823                      (match_operand:QI 2 "const_int_1_operand" "")))
8824    (clobber (reg:CC 17))]
8825   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
8826    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8827   "ror{w}\\t%0"
8828   [(set_attr "type" "ishift")
8829    (set (attr "length") 
8830      (if_then_else (match_operand:SI 0 "register_operand" "") 
8831         (const_string "2")
8832         (const_string "*")))])
8834 (define_insn "*rotrhi3"
8835   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
8836         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8837                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
8838    (clobber (reg:CC 17))]
8839   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
8840   "@
8841    ror{w}\\t{%2, %0|%0, %2}
8842    ror{w}\\t{%b2, %0|%0, %b2}"
8843   [(set_attr "type" "ishift")
8844    (set_attr "mode" "HI")])
8846 (define_expand "rotrqi3"
8847   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8848         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
8849                      (match_operand:QI 2 "nonmemory_operand" "")))
8850    (clobber (reg:CC 17))]
8851   "TARGET_QIMODE_MATH"
8852   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
8854 (define_insn "*rotrqi3_1_one_bit"
8855   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8856         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8857                      (match_operand:QI 2 "const_int_1_operand" "")))
8858    (clobber (reg:CC 17))]
8859   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
8860    && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8861   "ror{b}\\t%0"
8862   [(set_attr "type" "ishift")
8863    (set (attr "length") 
8864      (if_then_else (match_operand:SI 0 "register_operand" "") 
8865         (const_string "2")
8866         (const_string "*")))])
8868 (define_insn "*rotrqi3_1"
8869   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
8870         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8871                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
8872    (clobber (reg:CC 17))]
8873   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
8874   "@
8875    ror{b}\\t{%2, %0|%0, %2}
8876    ror{b}\\t{%b2, %0|%0, %b2}"
8877   [(set_attr "type" "ishift")
8878    (set_attr "mode" "QI")])
8880 ;; Bit set / bit test instructions
8882 (define_expand "extv"
8883   [(set (match_operand:SI 0 "register_operand" "")
8884         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
8885                          (match_operand:SI 2 "immediate_operand" "")
8886                          (match_operand:SI 3 "immediate_operand" "")))]
8887   ""
8888   "
8890   /* Handle extractions from %ah et al.  */
8891   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
8892     FAIL;
8894   /* From mips.md: extract_bit_field doesn't verify that our source
8895      matches the predicate, so check it again here.  */
8896   if (! register_operand (operands[1], VOIDmode))
8897     FAIL;
8900 (define_expand "extzv"
8901   [(set (match_operand:SI 0 "register_operand" "")
8902         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
8903                          (match_operand:SI 2 "immediate_operand" "")
8904                          (match_operand:SI 3 "immediate_operand" "")))]
8905   ""
8906   "
8908   /* Handle extractions from %ah et al.  */
8909   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
8910     FAIL;
8912   /* From mips.md: extract_bit_field doesn't verify that our source
8913      matches the predicate, so check it again here.  */
8914   if (! register_operand (operands[1], VOIDmode))
8915     FAIL;
8918 (define_expand "insv"
8919   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8920                          (match_operand:SI 1 "immediate_operand" "")
8921                          (match_operand:SI 2 "immediate_operand" ""))
8922         (match_operand:SI 3 "register_operand" ""))]
8923   ""
8924   "
8926   /* Handle extractions from %ah et al.  */
8927   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
8928     FAIL;
8930   /* From mips.md: insert_bit_field doesn't verify that our source
8931      matches the predicate, so check it again here.  */
8932   if (! register_operand (operands[0], VOIDmode))
8933     FAIL;
8936 ;; %%% bts, btr, btc, bt.
8938 ;; Store-flag instructions.
8940 ;; For all sCOND expanders, also expand the compare or test insn that
8941 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
8943 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
8944 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
8945 ;; way, which can later delete the movzx if only QImode is needed.
8947 (define_expand "seq"
8948   [(set (match_operand:SI 0 "register_operand" "")
8949         (eq:SI (reg:CC 17) (const_int 0)))]
8950   ""
8951   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
8953 (define_expand "sne"
8954   [(set (match_operand:SI 0 "register_operand" "")
8955         (ne:SI (reg:CC 17) (const_int 0)))]
8956   ""
8957   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
8959 (define_expand "sgt"
8960   [(set (match_operand:SI 0 "register_operand" "")
8961         (gt:SI (reg:CC 17) (const_int 0)))]
8962   ""
8963   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
8965 (define_expand "sgtu"
8966   [(set (match_operand:SI 0 "register_operand" "")
8967         (gtu:SI (reg:CC 17) (const_int 0)))]
8968   ""
8969   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
8971 (define_expand "slt"
8972   [(set (match_operand:SI 0 "register_operand" "")
8973         (lt:SI (reg:CC 17) (const_int 0)))]
8974   ""
8975   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
8977 (define_expand "sltu"
8978   [(set (match_operand:SI 0 "register_operand" "")
8979         (ltu:SI (reg:CC 17) (const_int 0)))]
8980   ""
8981   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
8983 (define_expand "sge"
8984   [(set (match_operand:SI 0 "register_operand" "")
8985         (ge:SI (reg:CC 17) (const_int 0)))]
8986   ""
8987   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
8989 (define_expand "sgeu"
8990   [(set (match_operand:SI 0 "register_operand" "")
8991         (geu:SI (reg:CC 17) (const_int 0)))]
8992   ""
8993   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
8995 (define_expand "sle"
8996   [(set (match_operand:SI 0 "register_operand" "")
8997         (le:SI (reg:CC 17) (const_int 0)))]
8998   ""
8999   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
9001 (define_expand "sleu"
9002   [(set (match_operand:SI 0 "register_operand" "")
9003         (leu:SI (reg:CC 17) (const_int 0)))]
9004   ""
9005   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
9007 (define_expand "sunordered"
9008   [(set (match_operand:SI 0 "register_operand" "")
9009         (unordered:SI (reg:CC 17) (const_int 0)))]
9010   "TARGET_80387"
9011   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
9013 (define_expand "sordered"
9014   [(set (match_operand:SI 0 "register_operand" "")
9015         (ordered:SI (reg:CC 17) (const_int 0)))]
9016   "TARGET_80387"
9017   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
9019 (define_expand "suneq"
9020   [(set (match_operand:SI 0 "register_operand" "")
9021         (uneq:SI (reg:CC 17) (const_int 0)))]
9022   "TARGET_80387"
9023   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
9025 (define_expand "sunge"
9026   [(set (match_operand:SI 0 "register_operand" "")
9027         (unge:SI (reg:CC 17) (const_int 0)))]
9028   "TARGET_80387"
9029   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
9031 (define_expand "sungt"
9032   [(set (match_operand:SI 0 "register_operand" "")
9033         (ungt:SI (reg:CC 17) (const_int 0)))]
9034   "TARGET_80387"
9035   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
9037 (define_expand "sunle"
9038   [(set (match_operand:SI 0 "register_operand" "")
9039         (unle:SI (reg:CC 17) (const_int 0)))]
9040   "TARGET_80387"
9041   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
9043 (define_expand "sunlt"
9044   [(set (match_operand:SI 0 "register_operand" "")
9045         (unlt:SI (reg:CC 17) (const_int 0)))]
9046   "TARGET_80387"
9047   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
9049 (define_expand "sltgt"
9050   [(set (match_operand:SI 0 "register_operand" "")
9051         (ltgt:SI (reg:CC 17) (const_int 0)))]
9052   "TARGET_80387"
9053   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
9055 (define_insn "*setcc_1"
9056   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9057         (match_operator:QI 1 "ix86_comparison_operator"
9058           [(reg 17) (const_int 0)]))]
9059   ""
9060   "set%C1\\t%0"
9061   [(set_attr "type" "setcc")
9062    (set_attr "mode" "QI")])
9064 (define_insn "setcc_2"
9065   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9066         (match_operator:QI 1 "ix86_comparison_operator"
9067           [(reg 17) (const_int 0)]))]
9068   ""
9069   "set%C1\\t%0"
9070   [(set_attr "type" "setcc")
9071    (set_attr "mode" "QI")])
9074 ;; Basic conditional jump instructions.
9075 ;; We ignore the overflow flag for signed branch instructions.
9077 ;; For all bCOND expanders, also expand the compare or test insn that
9078 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
9080 (define_expand "beq"
9081   [(set (pc)
9082         (if_then_else (match_dup 1)
9083                       (label_ref (match_operand 0 "" ""))
9084                       (pc)))]
9085   ""
9086   "ix86_expand_branch (EQ, operands[0]); DONE;")
9088 (define_expand "bne"
9089   [(set (pc)
9090         (if_then_else (match_dup 1)
9091                       (label_ref (match_operand 0 "" ""))
9092                       (pc)))]
9093   ""
9094   "ix86_expand_branch (NE, operands[0]); DONE;")
9096 (define_expand "bgt"
9097   [(set (pc)
9098         (if_then_else (match_dup 1)
9099                       (label_ref (match_operand 0 "" ""))
9100                       (pc)))]
9101   ""
9102   "ix86_expand_branch (GT, operands[0]); DONE;")
9104 (define_expand "bgtu"
9105   [(set (pc)
9106         (if_then_else (match_dup 1)
9107                       (label_ref (match_operand 0 "" ""))
9108                       (pc)))]
9109   ""
9110   "ix86_expand_branch (GTU, operands[0]); DONE;")
9112 (define_expand "blt"
9113   [(set (pc)
9114         (if_then_else (match_dup 1)
9115                       (label_ref (match_operand 0 "" ""))
9116                       (pc)))]
9117   ""
9118   "ix86_expand_branch (LT, operands[0]); DONE;")
9120 (define_expand "bltu"
9121   [(set (pc)
9122         (if_then_else (match_dup 1)
9123                       (label_ref (match_operand 0 "" ""))
9124                       (pc)))]
9125   ""
9126   "ix86_expand_branch (LTU, operands[0]); DONE;")
9128 (define_expand "bge"
9129   [(set (pc)
9130         (if_then_else (match_dup 1)
9131                       (label_ref (match_operand 0 "" ""))
9132                       (pc)))]
9133   ""
9134   "ix86_expand_branch (GE, operands[0]); DONE;")
9136 (define_expand "bgeu"
9137   [(set (pc)
9138         (if_then_else (match_dup 1)
9139                       (label_ref (match_operand 0 "" ""))
9140                       (pc)))]
9141   ""
9142   "ix86_expand_branch (GEU, operands[0]); DONE;")
9144 (define_expand "ble"
9145   [(set (pc)
9146         (if_then_else (match_dup 1)
9147                       (label_ref (match_operand 0 "" ""))
9148                       (pc)))]
9149   ""
9150   "ix86_expand_branch (LE, operands[0]); DONE;")
9152 (define_expand "bleu"
9153   [(set (pc)
9154         (if_then_else (match_dup 1)
9155                       (label_ref (match_operand 0 "" ""))
9156                       (pc)))]
9157   ""
9158   "ix86_expand_branch (LEU, operands[0]); DONE;")
9160 (define_expand "bunordered"
9161   [(set (pc)
9162         (if_then_else (match_dup 1)
9163                       (label_ref (match_operand 0 "" ""))
9164                       (pc)))]
9165   "TARGET_80387"
9166   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
9168 (define_expand "bordered"
9169   [(set (pc)
9170         (if_then_else (match_dup 1)
9171                       (label_ref (match_operand 0 "" ""))
9172                       (pc)))]
9173   "TARGET_80387"
9174   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
9176 (define_expand "buneq"
9177   [(set (pc)
9178         (if_then_else (match_dup 1)
9179                       (label_ref (match_operand 0 "" ""))
9180                       (pc)))]
9181   "TARGET_80387"
9182   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
9184 (define_expand "bunge"
9185   [(set (pc)
9186         (if_then_else (match_dup 1)
9187                       (label_ref (match_operand 0 "" ""))
9188                       (pc)))]
9189   "TARGET_80387"
9190   "ix86_expand_branch (UNGE, operands[0]); DONE;")
9192 (define_expand "bungt"
9193   [(set (pc)
9194         (if_then_else (match_dup 1)
9195                       (label_ref (match_operand 0 "" ""))
9196                       (pc)))]
9197   "TARGET_80387"
9198   "ix86_expand_branch (UNGT, operands[0]); DONE;")
9200 (define_expand "bunle"
9201   [(set (pc)
9202         (if_then_else (match_dup 1)
9203                       (label_ref (match_operand 0 "" ""))
9204                       (pc)))]
9205   "TARGET_80387"
9206   "ix86_expand_branch (UNLE, operands[0]); DONE;")
9208 (define_expand "bunlt"
9209   [(set (pc)
9210         (if_then_else (match_dup 1)
9211                       (label_ref (match_operand 0 "" ""))
9212                       (pc)))]
9213   "TARGET_80387"
9214   "ix86_expand_branch (UNLT, operands[0]); DONE;")
9216 (define_expand "bltgt"
9217   [(set (pc)
9218         (if_then_else (match_dup 1)
9219                       (label_ref (match_operand 0 "" ""))
9220                       (pc)))]
9221   "TARGET_80387"
9222   "ix86_expand_branch (LTGT, operands[0]); DONE;")
9224 (define_insn "*jcc_1"
9225   [(set (pc)
9226         (if_then_else (match_operator 1 "ix86_comparison_operator"
9227                                       [(reg 17) (const_int 0)])
9228                       (label_ref (match_operand 0 "" ""))
9229                       (pc)))]
9230   ""
9231   "j%C1\\t%l0"
9232   [(set_attr "type" "ibr")
9233    (set (attr "prefix_0f")
9234            (if_then_else (and (ge (minus (match_dup 0) (pc))
9235                                   (const_int -128))
9236                               (lt (minus (match_dup 0) (pc))
9237                                   (const_int 124)))
9238              (const_int 0)
9239              (const_int 1)))])
9241 (define_insn "*jcc_2"
9242   [(set (pc)
9243         (if_then_else (match_operator 1 "ix86_comparison_operator"
9244                                       [(reg 17) (const_int 0)])
9245                       (pc)
9246                       (label_ref (match_operand 0 "" ""))))]
9247   ""
9248   "j%c1\\t%l0"
9249   [(set_attr "type" "ibr")
9250    (set (attr "prefix_0f")
9251            (if_then_else (and (ge (minus (match_dup 0) (pc))
9252                                   (const_int -128))
9253                               (lt (minus (match_dup 0) (pc))
9254                                   (const_int 124)))
9255              (const_int 0)
9256              (const_int 1)))])
9258 ;; Define combination compare-and-branch fp compare instructions to use
9259 ;; during early optimization.  Splitting the operation apart early makes
9260 ;; for bad code when we want to reverse the operation.
9262 (define_insn "*fp_jcc_1"
9263   [(set (pc)
9264         (if_then_else (match_operator 0 "comparison_operator"
9265                         [(match_operand 1 "register_operand" "f")
9266                          (match_operand 2 "register_operand" "f")])
9267           (label_ref (match_operand 3 "" ""))
9268           (pc)))
9269    (clobber (reg:CCFP 18))
9270    (clobber (reg:CCFP 17))]
9271   "TARGET_CMOVE && TARGET_80387
9272    && FLOAT_MODE_P (GET_MODE (operands[1]))
9273    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9274   "#")
9276 (define_insn "*fp_jcc_2"
9277   [(set (pc)
9278         (if_then_else (match_operator 0 "comparison_operator"
9279                         [(match_operand 1 "register_operand" "f")
9280                          (match_operand 2 "register_operand" "f")])
9281           (pc)
9282           (label_ref (match_operand 3 "" ""))))
9283    (clobber (reg:CCFP 18))
9284    (clobber (reg:CCFP 17))]
9285   "TARGET_CMOVE && TARGET_80387
9286    && FLOAT_MODE_P (GET_MODE (operands[1]))
9287    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9288   "#")
9290 (define_insn "*fp_jcc_3"
9291   [(set (pc)
9292         (if_then_else (match_operator 0 "comparison_operator"
9293                         [(match_operand 1 "register_operand" "f")
9294                          (match_operand 2 "nonimmediate_operand" "fm")])
9295           (label_ref (match_operand 3 "" ""))
9296           (pc)))
9297    (clobber (reg:CCFP 18))
9298    (clobber (reg:CCFP 17))
9299    (clobber (match_scratch:HI 4 "=a"))]
9300   "TARGET_80387
9301    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
9302    && GET_MODE (operands[1]) == GET_MODE (operands[2])
9303    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
9304    && SELECT_CC_MODE (GET_CODE (operands[0]),
9305                       operands[1], operands[2]) == CCFPmode"
9306   "#")
9308 (define_insn "*fp_jcc_4"
9309   [(set (pc)
9310         (if_then_else (match_operator 0 "comparison_operator"
9311                         [(match_operand 1 "register_operand" "f")
9312                          (match_operand 2 "nonimmediate_operand" "fm")])
9313           (pc)
9314           (label_ref (match_operand 3 "" ""))))
9315    (clobber (reg:CCFP 18))
9316    (clobber (reg:CCFP 17))
9317    (clobber (match_scratch:HI 4 "=a"))]
9318   "TARGET_80387
9319    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
9320    && GET_MODE (operands[1]) == GET_MODE (operands[2])
9321    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
9322    && SELECT_CC_MODE (GET_CODE (operands[0]),
9323                       operands[1], operands[2]) == CCFPmode"
9324   "#")
9326 (define_insn "*fp_jcc_5"
9327   [(set (pc)
9328         (if_then_else (match_operator 0 "comparison_operator"
9329                         [(match_operand 1 "register_operand" "f")
9330                          (match_operand 2 "register_operand" "f")])
9331           (label_ref (match_operand 3 "" ""))
9332           (pc)))
9333    (clobber (reg:CCFP 18))
9334    (clobber (reg:CCFP 17))
9335    (clobber (match_scratch:HI 4 "=a"))]
9336   "TARGET_80387
9337    && FLOAT_MODE_P (GET_MODE (operands[1]))
9338    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9339   "#")
9341 (define_insn "*fp_jcc_6"
9342   [(set (pc)
9343         (if_then_else (match_operator 0 "comparison_operator"
9344                         [(match_operand 1 "register_operand" "f")
9345                          (match_operand 2 "register_operand" "f")])
9346           (pc)
9347           (label_ref (match_operand 3 "" ""))))
9348    (clobber (reg:CCFP 18))
9349    (clobber (reg:CCFP 17))
9350    (clobber (match_scratch:HI 4 "=a"))]
9351   "TARGET_80387
9352    && FLOAT_MODE_P (GET_MODE (operands[1]))
9353    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9354   "#")
9356 (define_split
9357   [(set (pc)
9358         (if_then_else (match_operator 0 "comparison_operator"
9359                         [(match_operand 1 "register_operand" "")
9360                          (match_operand 2 "nonimmediate_operand" "")])
9361           (match_operand 3 "" "")
9362           (match_operand 4 "" "")))
9363    (clobber (reg:CCFP 18))
9364    (clobber (reg:CCFP 17))]
9365   "reload_completed"
9366   [(const_int 0)]
9367   "
9369   ix86_split_fp_branch (operands[0], operands[1], operands[2],
9370                         operands[3], operands[4], NULL_RTX);
9371   DONE;
9374 (define_split
9375   [(set (pc)
9376         (if_then_else (match_operator 0 "comparison_operator"
9377                         [(match_operand 1 "register_operand" "")
9378                          (match_operand 2 "nonimmediate_operand" "")])
9379           (match_operand 3 "" "")
9380           (match_operand 4 "" "")))
9381    (clobber (reg:CCFP 18))
9382    (clobber (reg:CCFP 17))
9383    (clobber (match_scratch:HI 5 "=a"))]
9384   "reload_completed"
9385   [(set (pc)
9386         (if_then_else (match_dup 6)
9387           (match_dup 3)
9388           (match_dup 4)))]
9389   "
9391   ix86_split_fp_branch (operands[0], operands[1], operands[2],
9392                         operands[3], operands[4], operands[5]);
9393   DONE;
9396 ;; Unconditional and other jump instructions
9398 (define_insn "jump"
9399   [(set (pc)
9400         (label_ref (match_operand 0 "" "")))]
9401   ""
9402   "jmp\\t%l0"
9403   [(set_attr "type" "ibr")])
9405 (define_insn "indirect_jump"
9406   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
9407   ""
9408   "jmp\\t%A0"
9409   [(set_attr "type" "ibr")
9410    (set_attr "length_immediate" "0")])
9412 (define_insn "tablejump"
9413   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
9414    (use (label_ref (match_operand 1 "" "")))]
9415   "! flag_pic"
9416   "jmp\\t%A0"
9417   [(set_attr "type" "ibr")
9418    (set_attr "length_immediate" "0")])
9420 ;; Implement switch statements when generating PIC code.  Switches are
9421 ;; implemented by `tablejump' when not using -fpic.
9423 ;; Emit code here to do the range checking and make the index zero based.
9425 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
9426 ;; two rules below:
9427 ;; 
9428 ;;      .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
9429 ;; 
9430 ;; 1. An expression involving an external reference may only use the
9431 ;;    addition operator, and only with an assembly-time constant.
9432 ;;    The example above satisfies this because ".-.L2" is a constant.
9433 ;; 
9434 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
9435 ;;    given the value of "GOT - .", where GOT is the actual address of
9436 ;;    the Global Offset Table.  Therefore, the .long above actually
9437 ;;    stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2".  The
9438 ;;    expression "GOT - .L2" by itself would generate an error from as(1).
9439 ;; 
9440 ;; The pattern below emits code that looks like this:
9441 ;; 
9442 ;;      movl %ebx,reg
9443 ;;      subl TABLE@GOTOFF(%ebx,index,4),reg
9444 ;;      jmp reg
9445 ;; 
9446 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
9447 ;; the addr_diff_vec is known to be part of this module.
9448 ;; 
9449 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
9450 ;; evaluates to just ".L2".
9452 (define_expand "casesi"
9453   [(set (match_dup 5)
9454         (match_operand:SI 0 "general_operand" ""))
9455    (parallel [(set (match_dup 6)
9456                    (minus:SI (match_dup 5)
9457                              (match_operand:SI 1 "general_operand" "")))
9458               (clobber (reg:CC 17))])
9459    (set (reg:CC 17)
9460         (compare:CC (match_dup 6)
9461                     (match_operand:SI 2 "general_operand" "")))
9462    (set (pc)
9463         (if_then_else (gtu (reg:CC 17)
9464                            (const_int 0))
9465                       (label_ref (match_operand 4 "" ""))
9466                       (pc)))
9467    (parallel
9468      [(set (match_dup 7)
9469            (minus:SI (match_dup 8)
9470              (mem:SI (plus:SI (plus:SI (mult:SI (match_dup 6) (const_int 4))
9471                               (match_dup 8))
9472                      (const (unspec [(label_ref (match_operand 3 "" ""))] 7))))))
9473       (clobber (reg:CC 17))])
9474    (parallel [(set (pc) (match_dup 7))
9475               (use (label_ref (match_dup 3)))])]
9476   "flag_pic"
9477   "
9479   operands[5] = gen_reg_rtx (SImode);
9480   operands[6] = gen_reg_rtx (SImode);
9481   operands[7] = gen_reg_rtx (SImode);
9482   operands[8] = pic_offset_table_rtx;
9483   current_function_uses_pic_offset_table = 1;
9486 (define_insn "*tablejump_pic"
9487   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
9488    (use (label_ref (match_operand 1 "" "")))]
9489   ""
9490   "jmp\\t%A0"
9491   [(set_attr "type" "ibr")
9492    (set_attr "length_immediate" "0")])
9494 ;; Loop instruction
9496 ;; This is all complicated by the fact that since this is a jump insn
9497 ;; we must handle our own reloads.
9499 (define_expand "doloop_end"
9500   [(use (match_operand 0 "" ""))        ; loop pseudo
9501    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
9502    (use (match_operand 2 "" ""))        ; max iterations
9503    (use (match_operand 3 "" ""))        ; loop level 
9504    (use (match_operand 4 "" ""))]       ; label
9505   "TARGET_USE_LOOP"
9506   "                                 
9508   /* Only use cloop on innermost loops.  */
9509   if (INTVAL (operands[3]) > 1)
9510     FAIL;
9511   if (GET_MODE (operands[0]) != SImode)
9512     FAIL;
9513   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
9514                                            operands[0]));
9515   DONE;
9518 (define_insn "doloop_end_internal"
9519   [(set (pc)
9520         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
9521                           (const_int 1))
9522                       (label_ref (match_operand 0 "" ""))
9523                       (pc)))
9524    (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
9525         (plus:SI (match_dup 1)
9526                  (const_int -1)))
9527    (clobber (match_scratch:SI 3 "=X,X,r"))
9528    (clobber (reg:CC 17))]
9529   "TARGET_USE_LOOP"
9530   "*
9532   if (which_alternative != 0)
9533     return \"#\";
9534   if (get_attr_length (insn) == 2)
9535     return \"loop\\t%l0\";
9536   else
9537     return \"dec{l}\\t%1\;jne\\t%l0\";
9539   [(set_attr "ppro_uops" "many")
9540    (set (attr "type")
9541         (if_then_else (and (eq_attr "alternative" "0")
9542                            (and (ge (minus (match_dup 0) (pc))
9543                                     (const_int -128))
9544                                 (lt (minus (match_dup 0) (pc))
9545                                     (const_int 124))))
9546                       (const_string "ibr")
9547                       (const_string "multi")))])
9549 (define_split
9550   [(set (pc)
9551         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
9552                           (const_int 1))
9553                       (match_operand 0 "" "")
9554                       (pc)))
9555    (set (match_dup 1)
9556         (plus:SI (match_dup 1)
9557                  (const_int -1)))
9558    (clobber (match_scratch:SI 2 ""))
9559    (clobber (reg:CC 17))]
9560   "TARGET_USE_LOOP
9561    && reload_completed
9562    && REGNO (operands[1]) != 2"
9563   [(parallel [(set (reg:CCZ 17)
9564                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
9565                                  (const_int 0)))
9566               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
9567    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
9568                            (match_dup 0)
9569                            (pc)))]
9570   "")
9571   
9572 (define_split
9573   [(set (pc)
9574         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
9575                           (const_int 1))
9576                       (match_operand 0 "" "")
9577                       (pc)))
9578    (set (match_operand:SI 2 "nonimmediate_operand" "")
9579         (plus:SI (match_dup 1)
9580                  (const_int -1)))
9581    (clobber (match_scratch:SI 3 ""))
9582    (clobber (reg:CC 17))]
9583   "TARGET_USE_LOOP
9584    && reload_completed
9585    && (! REG_P (operands[2])
9586        || ! rtx_equal_p (operands[1], operands[2]))"
9587   [(set (match_dup 3) (match_dup 1))
9588    (parallel [(set (reg:CCZ 17)
9589                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
9590                                 (const_int 0)))
9591               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9592    (set (match_dup 2) (match_dup 3))
9593    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
9594                            (match_dup 0)
9595                            (pc)))]
9596   "")
9598 ;; Call instructions.
9600 ;; The predicates normally associated with named expanders are not properly
9601 ;; checked for calls.  This is a bug in the generic code, but it isn't that
9602 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
9604 ;; Call subroutine returning no value.
9606 (define_expand "call_pop"
9607   [(parallel [(call (match_operand:QI 0 "" "")
9608                     (match_operand:SI 1 "" ""))
9609               (set (reg:SI 7)
9610                    (plus:SI (reg:SI 7)
9611                             (match_operand:SI 3 "" "")))])]
9612   ""
9613   "
9615   if (operands[3] == const0_rtx)
9616     {
9617       emit_insn (gen_call (operands[0], operands[1]));
9618       DONE;
9619     }
9620   /* Static functions and indirect calls don't need
9621      current_function_uses_pic_offset_table.  */
9622   if (flag_pic
9623       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9624       && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
9625     current_function_uses_pic_offset_table = 1;
9626   if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
9627     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9630 (define_insn "*call_pop_0"
9631   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
9632          (match_operand:SI 1 "" ""))
9633    (set (reg:SI 7) (plus:SI (reg:SI 7)
9634                             (match_operand:SI 2 "immediate_operand" "")))]
9635   ""
9636   "*
9638   if (SIBLING_CALL_P (insn))
9639     return \"jmp\\t%P0\";
9640   else
9641     return \"call\\t%P0\";
9643   [(set_attr "type" "call")])
9644   
9645 (define_insn "*call_pop_1"
9646   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
9647          (match_operand:SI 1 "" ""))
9648    (set (reg:SI 7) (plus:SI (reg:SI 7)
9649                             (match_operand:SI 2 "immediate_operand" "i")))]
9650   ""
9651   "*
9653   if (constant_call_address_operand (operands[0], Pmode))
9654     {
9655       if (SIBLING_CALL_P (insn))
9656         return \"jmp\\t%P0\";
9657       else
9658         return \"call\\t%P0\";
9659     }
9660   if (SIBLING_CALL_P (insn))
9661     return \"jmp\\t%A0\";
9662   else
9663     return \"call\\t%A0\";
9665   [(set_attr "type" "call")])
9667 (define_expand "call"
9668   [(call (match_operand:QI 0 "" "")
9669          (match_operand:SI 1 "" ""))]
9670   ;; Operand 1 not used on the i386.
9671   ""
9672   "
9674   /* Static functions and indirect calls don't need
9675      current_function_uses_pic_offset_table.  */
9676   if (flag_pic
9677       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9678       && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
9679     current_function_uses_pic_offset_table = 1;
9680   if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
9681     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9684 (define_insn "*call_0"
9685   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
9686          (match_operand:SI 1 "" ""))]
9687   ""
9688   "*
9690   if (SIBLING_CALL_P (insn))
9691     return \"jmp\\t%P0\";
9692   else
9693     return \"call\\t%P0\";
9695   [(set_attr "type" "call")])
9697 (define_insn "*call_1"
9698   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
9699          (match_operand:SI 1 "" ""))]
9700   ""
9701   "*
9703   if (constant_call_address_operand (operands[0], QImode))
9704     {
9705       if (SIBLING_CALL_P (insn))
9706         return \"jmp\\t%P0\";
9707       else
9708         return \"call\\t%P0\";
9709     }
9710   if (SIBLING_CALL_P (insn))
9711     return \"jmp\\t%A0\";
9712   else
9713     return \"call\\t%A0\";
9715   [(set_attr "type" "call")])
9717 ;; Call subroutine, returning value in operand 0
9718 ;; (which must be a hard register).
9720 (define_expand "call_value_pop"
9721   [(parallel [(set (match_operand 0 "" "")
9722                    (call (match_operand:QI 1 "" "")
9723                          (match_operand:SI 2 "" "")))
9724               (set (reg:SI 7)
9725                    (plus:SI (reg:SI 7)
9726                             (match_operand:SI 4 "" "")))])]
9727   ""
9728   "
9730   if (operands[4] == const0_rtx)
9731     {
9732       emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
9733       DONE;
9734     }
9735   /* Static functions and indirect calls don't need
9736      current_function_uses_pic_offset_table.  */
9737   if (flag_pic
9738       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9739       && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
9740     current_function_uses_pic_offset_table = 1;
9741   if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
9742     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
9745 (define_expand "call_value"
9746   [(set (match_operand 0 "" "")
9747         (call (match_operand:QI 1 "" "")
9748               (match_operand:SI 2 "" "")))]
9749   ;; Operand 2 not used on the i386.
9750   ""
9751   "
9753   /* Static functions and indirect calls don't need
9754      current_function_uses_pic_offset_table.  */
9755   if (flag_pic
9756       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9757       && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
9758     current_function_uses_pic_offset_table = 1;
9759   if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
9760     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
9763 ;; Call subroutine returning any type.
9765 (define_expand "untyped_call"
9766   [(parallel [(call (match_operand 0 "" "")
9767                     (const_int 0))
9768               (match_operand 1 "" "")
9769               (match_operand 2 "" "")])]
9770   ""
9771   "
9773   int i;
9775   /* In order to give reg-stack an easier job in validating two
9776      coprocessor registers as containing a possible return value,
9777      simply pretend the untyped call returns a complex long double
9778      value.  */
9780   emit_call_insn (TARGET_80387
9781                   ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
9782                                     operands[0], const0_rtx)
9783                   : gen_call (operands[0], const0_rtx));
9785   for (i = 0; i < XVECLEN (operands[2], 0); i++)
9786     {
9787       rtx set = XVECEXP (operands[2], 0, i);
9788       emit_move_insn (SET_DEST (set), SET_SRC (set));
9789     }
9791   /* The optimizer does not know that the call sets the function value
9792      registers we stored in the result block.  We avoid problems by
9793      claiming that all hard registers are used and clobbered at this
9794      point.  */
9795   emit_insn (gen_blockage ());
9797   DONE;
9800 ;; Prologue and epilogue instructions
9802 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9803 ;; all of memory.  This blocks insns from being moved across this point.
9805 (define_insn "blockage"
9806   [(unspec_volatile [(const_int 0)] 0)]
9807   ""
9808   ""
9809   [(set_attr "length" "0")])
9811 ;; Insn emitted into the body of a function to return from a function.
9812 ;; This is only done if the function's epilogue is known to be simple.
9813 ;; See comments for ix86_can_use_return_insn_p in i386.c.
9815 (define_expand "return"
9816   [(return)]
9817   "ix86_can_use_return_insn_p ()"
9818   "
9820   if (current_function_pops_args)
9821     {
9822       rtx popc = GEN_INT (current_function_pops_args);
9823       emit_jump_insn (gen_return_pop_internal (popc));
9824       DONE;
9825     }
9828 (define_insn "return_internal"
9829   [(return)]
9830   "reload_completed"
9831   "ret"
9832   [(set_attr "length" "1")
9833    (set_attr "length_immediate" "0")
9834    (set_attr "modrm" "0")])
9836 (define_insn "return_pop_internal"
9837   [(return)
9838    (use (match_operand:SI 0 "const_int_operand" ""))]
9839   "reload_completed"
9840   "ret\\t%0"
9841   [(set_attr "length" "3")
9842    (set_attr "length_immediate" "2")
9843    (set_attr "modrm" "0")])
9845 (define_insn "return_indirect_internal"
9846   [(return)
9847    (use (match_operand:SI 0 "register_operand" "r"))]
9848   "reload_completed"
9849   "jmp\\t%A0"
9850   [(set_attr "type" "ibr")
9851    (set_attr "length_immediate" "0")])
9853 (define_insn "nop"
9854   [(const_int 0)]
9855   ""
9856   "nop"
9857   [(set_attr "length" "1")
9858    (set_attr "length_immediate" "0")
9859    (set_attr "modrm" "0")
9860    (set_attr "ppro_uops" "one")])
9862 (define_expand "prologue"
9863   [(const_int 1)]
9864   ""
9865   "ix86_expand_prologue (); DONE;")
9867 (define_insn "prologue_set_got"
9868   [(set (match_operand:SI 0 "register_operand" "=r")
9869         (unspec_volatile:SI
9870          [(plus:SI (match_dup 0)
9871                    (plus:SI (match_operand:SI 1 "symbolic_operand" "")
9872                             (minus:SI (pc) (match_operand 2 "" ""))))] 1))
9873    (clobber (reg:CC 17))]
9874   ""
9875   "*
9877   if (GET_CODE (operands[2]) == LABEL_REF)
9878      operands[2] = XEXP (operands[2], 0);
9879   if (TARGET_DEEP_BRANCH_PREDICTION) 
9880     return \"add{l}\\t{%1, %0|%0, %1}\";
9881   else  
9882     return \"add{l}\\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}\";
9884   [(set_attr "type" "alu")
9885    ; Since this insn may have two constant operands, we must set the
9886    ; length manually.
9887    (set_attr "length_immediate" "4")
9888    (set_attr "mode" "SI")])
9890 (define_insn "prologue_get_pc"
9891   [(set (match_operand:SI 0 "register_operand" "=r")
9892     (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
9893   ""
9894   "*
9896   if (GET_CODE (operands[1]) == LABEL_REF)
9897     operands[1] = XEXP (operands[1], 0);
9898   output_asm_insn (\"call\\t%X1\", operands);
9899   if (! TARGET_DEEP_BRANCH_PREDICTION)
9900     {
9901       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
9902                                  CODE_LABEL_NUMBER (operands[1]));
9903     }
9904   RET;
9906   [(set_attr "type" "multi")])
9908 (define_expand "epilogue"
9909   [(const_int 1)]
9910   ""
9911   "ix86_expand_epilogue (1); DONE;")
9913 (define_expand "sibcall_epilogue"
9914   [(const_int 1)]
9915   ""
9916   "ix86_expand_epilogue (0); DONE;")
9918 (define_expand "eh_return"
9919   [(use (match_operand 0 "register_operand" ""))
9920    (use (match_operand 1 "register_operand" ""))]
9921   ""
9922   "
9924   rtx tmp, sa = operands[0], ra = operands[1];
9926   /* Tricky bit: we write the address of the handler to which we will
9927      be returning into someone else's stack frame, one word below the
9928      stack address we wish to restore.  */
9929   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
9930   tmp = plus_constant (tmp, -UNITS_PER_WORD);
9931   tmp = gen_rtx_MEM (Pmode, tmp);
9932   emit_move_insn (tmp, ra);
9934   emit_insn (gen_eh_return_1 (sa));
9935   emit_barrier ();
9936   DONE;
9939 (define_insn_and_split "eh_return_1"
9940   [(unspec_volatile [(match_operand 0 "register_operand" "c")] 13)]
9941   ""
9942   "#"
9943   "reload_completed"
9944   [(const_int 1)]
9945   "ix86_expand_epilogue (2); DONE;")
9947 (define_insn "leave"
9948   [(set (reg:SI 7) (reg:SI 6))
9949    (set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))]
9950   ""
9951   "leave"
9952   [(set_attr "length_immediate" "0")
9953    (set_attr "length" "1")
9954    (set_attr "modrm" "0")
9955    (set_attr "modrm" "0")
9956    (set_attr "athlon_decode" "vector")
9957    (set_attr "ppro_uops" "few")])
9959 (define_expand "ffssi2"
9960   [(set (match_operand:SI 0 "nonimmediate_operand" "") 
9961         (ffs:SI (match_operand:SI 1 "general_operand" "")))]
9962   ""
9963   "
9965   rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
9966   rtx in = operands[1];
9968   if (TARGET_CMOVE)
9969     {
9970       emit_move_insn (tmp, constm1_rtx);
9971       emit_insn (gen_ffssi_1 (out, in));
9972       emit_insn (gen_rtx_SET (VOIDmode, out,
9973                   gen_rtx_IF_THEN_ELSE (SImode, 
9974                     gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
9975                                 const0_rtx),
9976                     tmp,
9977                     out)));
9978       emit_insn (gen_addsi3 (out, out, const1_rtx));
9979       emit_move_insn (operands[0], out);
9980     }
9982   /* Pentium bsf instruction is extremly slow.  The following code is
9983      recommended by the Intel Optimizing Manual as a reasonable replacement:
9984            TEST    EAX,EAX
9985            JZ      SHORT BS2
9986            XOR     ECX,ECX
9987            MOV     DWORD PTR [TEMP+4],ECX
9988            SUB     ECX,EAX
9989            AND     EAX,ECX
9990            MOV     DWORD PTR [TEMP],EAX
9991            FILD    QWORD PTR [TEMP]
9992            FSTP    QWORD PTR [TEMP]
9993            WAIT    ; WAIT only needed for compatibility with
9994                    ; earlier processors
9995            MOV     ECX, DWORD PTR [TEMP+4]
9996            SHR     ECX,20
9997            SUB     ECX,3FFH
9998            TEST    EAX,EAX       ; clear zero flag
9999        BS2:
10000      Following piece of code expand ffs to similar beast.
10001        */
10003   else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
10004     {
10005       rtx label = gen_label_rtx ();
10006       rtx lo, hi;
10007       rtx mem = assign_386_stack_local (DImode, 0);
10008       rtx fptmp = gen_reg_rtx (DFmode);
10009       split_di (&mem, 1, &lo, &hi);
10011       emit_move_insn (out, const0_rtx);
10013       emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label);
10015       emit_move_insn (hi, out);
10016       emit_insn (gen_subsi3 (out, out, in));
10017       emit_insn (gen_andsi3 (out, out, in));
10018       emit_move_insn (lo, out);
10019       emit_insn (gen_floatdidf2 (fptmp,mem));
10020       emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
10021       emit_move_insn (out, hi);
10022       emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
10023       emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
10025       emit_label (label);
10026       LABEL_NUSES (label) = 1;
10028       emit_move_insn (operands[0], out);
10029     }
10030   else
10031     {
10032       emit_move_insn (tmp, const0_rtx);
10033       emit_insn (gen_ffssi_1 (out, in));
10034       emit_insn (gen_rtx_SET (VOIDmode, 
10035                   gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
10036                   gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
10037                               const0_rtx)));
10038       emit_insn (gen_negsi2 (tmp, tmp));
10039       emit_insn (gen_iorsi3 (out, out, tmp));
10040       emit_insn (gen_addsi3 (out, out, const1_rtx));
10041       emit_move_insn (operands[0], out);
10042     }
10043   DONE;  
10046 (define_insn "ffssi_1"
10047   [(set (reg:CCZ 17)
10048         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
10049                      (const_int 0)))
10050    (set (match_operand:SI 0 "register_operand" "=r")
10051         (unspec:SI [(match_dup 1)] 5))]
10052   ""
10053   "bsf{l}\\t{%1, %0|%0, %1}"
10054   [(set_attr "prefix_0f" "1")
10055    (set_attr "ppro_uops" "few")])
10057 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
10058 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
10060 ;; These patterns match the binary 387 instructions for addM3, subM3,
10061 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
10062 ;; SFmode.  The first is the normal insn, the second the same insn but
10063 ;; with one operand a conversion, and the third the same insn but with
10064 ;; the other operand a conversion.  The conversion may be SFmode or
10065 ;; SImode if the target mode DFmode, but only SImode if the target mode
10066 ;; is SFmode.
10068 ;; Gcc is slightly more smart about handling normal two address instructions
10069 ;; so use special patterns for add and mull.
10070 (define_insn "*fop_sf_comm"
10071   [(set (match_operand:SF 0 "register_operand" "=f")
10072         (match_operator:SF 3 "binary_fp_operator"
10073                         [(match_operand:SF 1 "register_operand" "%0")
10074                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
10075   "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10076   "* return output_387_binary_op (insn, operands);"
10077   [(set (attr "type") 
10078         (if_then_else (match_operand:SF 3 "mult_operator" "") 
10079            (const_string "fmul")
10080            (const_string "fop")))
10081    (set_attr "mode" "SF")])
10083 (define_insn "*fop_df_comm"
10084   [(set (match_operand:DF 0 "register_operand" "=f")
10085         (match_operator:DF 3 "binary_fp_operator"
10086                         [(match_operand:DF 1 "register_operand" "%0")
10087                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
10088   "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10089   "* return output_387_binary_op (insn, operands);"
10090   [(set (attr "type") 
10091         (if_then_else (match_operand:DF 3 "mult_operator" "") 
10092            (const_string "fmul")
10093            (const_string "fop")))
10094    (set_attr "mode" "DF")])
10096 (define_insn "*fop_xf_comm"
10097   [(set (match_operand:XF 0 "register_operand" "=f")
10098         (match_operator:XF 3 "binary_fp_operator"
10099                         [(match_operand:XF 1 "register_operand" "%0")
10100                          (match_operand:XF 2 "register_operand" "f")]))]
10101   "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10102   "* return output_387_binary_op (insn, operands);"
10103   [(set (attr "type") 
10104         (if_then_else (match_operand:XF 3 "mult_operator" "") 
10105            (const_string "fmul")
10106            (const_string "fop")))
10107    (set_attr "mode" "XF")])
10109 (define_insn "*fop_tf_comm"
10110   [(set (match_operand:TF 0 "register_operand" "=f")
10111         (match_operator:TF 3 "binary_fp_operator"
10112                         [(match_operand:TF 1 "register_operand" "%0")
10113                          (match_operand:TF 2 "register_operand" "f")]))]
10114   "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10115   "* return output_387_binary_op (insn, operands);"
10116   [(set (attr "type") 
10117         (if_then_else (match_operand:TF 3 "mult_operator" "") 
10118            (const_string "fmul")
10119            (const_string "fop")))
10120    (set_attr "mode" "XF")])
10122 (define_insn "*fop_sf_1"
10123   [(set (match_operand:SF 0 "register_operand" "=f,f")
10124         (match_operator:SF 3 "binary_fp_operator"
10125                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
10126                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
10127   "TARGET_80387
10128    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
10129    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
10130   "* return output_387_binary_op (insn, operands);"
10131   [(set (attr "type") 
10132         (cond [(match_operand:SF 3 "mult_operator" "") 
10133                  (const_string "fmul")
10134                (match_operand:SF 3 "div_operator" "") 
10135                  (const_string "fdiv")
10136               ]
10137               (const_string "fop")))
10138    (set_attr "mode" "SF")])
10140 (define_insn "*fop_sf_2"
10141   [(set (match_operand:SF 0 "register_operand" "=f,f")
10142         (match_operator:SF 3 "binary_fp_operator"
10143           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10144            (match_operand:SF 2 "register_operand" "0,0")]))]
10145   "TARGET_80387 && TARGET_USE_FIOP"
10146   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10147   [(set (attr "type") 
10148         (cond [(match_operand:SF 3 "mult_operator" "") 
10149                  (const_string "fmul")
10150                (match_operand:SF 3 "div_operator" "") 
10151                  (const_string "fdiv")
10152               ]
10153               (const_string "fop")))
10154    (set_attr "fp_int_src" "true")
10155    (set_attr "ppro_uops" "many")
10156    (set_attr "mode" "SI")])
10158 (define_insn "*fop_sf_3"
10159   [(set (match_operand:SF 0 "register_operand" "=f,f")
10160         (match_operator:SF 3 "binary_fp_operator"
10161           [(match_operand:SF 1 "register_operand" "0,0")
10162            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
10163   "TARGET_80387 && TARGET_USE_FIOP"
10164   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10165   [(set (attr "type") 
10166         (cond [(match_operand:SF 3 "mult_operator" "") 
10167                  (const_string "fmul")
10168                (match_operand:SF 3 "div_operator" "") 
10169                  (const_string "fdiv")
10170               ]
10171               (const_string "fop")))
10172    (set_attr "fp_int_src" "true")
10173    (set_attr "ppro_uops" "many")
10174    (set_attr "mode" "SI")])
10176 (define_insn "*fop_df_1"
10177   [(set (match_operand:DF 0 "register_operand" "=f,f")
10178         (match_operator:DF 3 "binary_fp_operator"
10179                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
10180                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
10181   "TARGET_80387
10182    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
10183    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
10184   "* return output_387_binary_op (insn, operands);"
10185   [(set (attr "type") 
10186         (cond [(match_operand:DF 3 "mult_operator" "") 
10187                  (const_string "fmul")
10188                (match_operand:DF 3 "div_operator" "") 
10189                  (const_string "fdiv")
10190               ]
10191               (const_string "fop")))
10192    (set_attr "mode" "DF")])
10194 (define_insn "*fop_df_2"
10195   [(set (match_operand:DF 0 "register_operand" "=f,f")
10196         (match_operator:DF 3 "binary_fp_operator"
10197            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10198             (match_operand:DF 2 "register_operand" "0,0")]))]
10199   "TARGET_80387 && TARGET_USE_FIOP"
10200   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10201   [(set (attr "type") 
10202         (cond [(match_operand:DF 3 "mult_operator" "") 
10203                  (const_string "fmul")
10204                (match_operand:DF 3 "div_operator" "") 
10205                  (const_string "fdiv")
10206               ]
10207               (const_string "fop")))
10208    (set_attr "fp_int_src" "true")
10209    (set_attr "ppro_uops" "many")
10210    (set_attr "mode" "SI")])
10212 (define_insn "*fop_df_3"
10213   [(set (match_operand:DF 0 "register_operand" "=f,f")
10214         (match_operator:DF 3 "binary_fp_operator"
10215            [(match_operand:DF 1 "register_operand" "0,0")
10216             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
10217   "TARGET_80387 && TARGET_USE_FIOP"
10218   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10219   [(set (attr "type") 
10220         (cond [(match_operand:DF 3 "mult_operator" "") 
10221                  (const_string "fmul")
10222                (match_operand:DF 3 "div_operator" "") 
10223                  (const_string "fdiv")
10224               ]
10225               (const_string "fop")))
10226    (set_attr "fp_int_src" "true")
10227    (set_attr "ppro_uops" "many")
10228    (set_attr "mode" "SI")])
10230 (define_insn "*fop_df_4"
10231   [(set (match_operand:DF 0 "register_operand" "=f,f")
10232         (match_operator:DF 3 "binary_fp_operator"
10233            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
10234             (match_operand:DF 2 "register_operand" "0,f")]))]
10235   "TARGET_80387
10236    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
10237   "* return output_387_binary_op (insn, operands);"
10238   [(set (attr "type") 
10239         (cond [(match_operand:DF 3 "mult_operator" "") 
10240                  (const_string "fmul")
10241                (match_operand:DF 3 "div_operator" "") 
10242                  (const_string "fdiv")
10243               ]
10244               (const_string "fop")))
10245    (set_attr "mode" "SF")])
10247 (define_insn "*fop_df_5"
10248   [(set (match_operand:DF 0 "register_operand" "=f,f")
10249         (match_operator:DF 3 "binary_fp_operator"
10250           [(match_operand:DF 1 "register_operand" "0,f")
10251            (float_extend:DF
10252             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
10253   "TARGET_80387"
10254   "* return output_387_binary_op (insn, operands);"
10255   [(set (attr "type") 
10256         (cond [(match_operand:DF 3 "mult_operator" "") 
10257                  (const_string "fmul")
10258                (match_operand:DF 3 "div_operator" "") 
10259                  (const_string "fdiv")
10260               ]
10261               (const_string "fop")))
10262    (set_attr "mode" "SF")])
10264 (define_insn "*fop_xf_1"
10265   [(set (match_operand:XF 0 "register_operand" "=f,f")
10266         (match_operator:XF 3 "binary_fp_operator"
10267                         [(match_operand:XF 1 "register_operand" "0,f")
10268                          (match_operand:XF 2 "register_operand" "f,0")]))]
10269   "TARGET_80387
10270    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10271   "* return output_387_binary_op (insn, operands);"
10272   [(set (attr "type") 
10273         (cond [(match_operand:XF 3 "mult_operator" "") 
10274                  (const_string "fmul")
10275                (match_operand:XF 3 "div_operator" "") 
10276                  (const_string "fdiv")
10277               ]
10278               (const_string "fop")))
10279    (set_attr "mode" "XF")])
10281 (define_insn "*fop_tf_1"
10282   [(set (match_operand:TF 0 "register_operand" "=f,f")
10283         (match_operator:TF 3 "binary_fp_operator"
10284                         [(match_operand:TF 1 "register_operand" "0,f")
10285                          (match_operand:TF 2 "register_operand" "f,0")]))]
10286   "TARGET_80387
10287    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10288   "* return output_387_binary_op (insn, operands);"
10289   [(set (attr "type") 
10290         (cond [(match_operand:TF 3 "mult_operator" "") 
10291                  (const_string "fmul")
10292                (match_operand:TF 3 "div_operator" "") 
10293                  (const_string "fdiv")
10294               ]
10295               (const_string "fop")))
10296    (set_attr "mode" "XF")])
10298 (define_insn "*fop_xf_2"
10299   [(set (match_operand:XF 0 "register_operand" "=f,f")
10300         (match_operator:XF 3 "binary_fp_operator"
10301            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10302             (match_operand:XF 2 "register_operand" "0,0")]))]
10303   "TARGET_80387 && TARGET_USE_FIOP"
10304   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10305   [(set (attr "type") 
10306         (cond [(match_operand:XF 3 "mult_operator" "") 
10307                  (const_string "fmul")
10308                (match_operand:XF 3 "div_operator" "") 
10309                  (const_string "fdiv")
10310               ]
10311               (const_string "fop")))
10312    (set_attr "fp_int_src" "true")
10313    (set_attr "mode" "SI")
10314    (set_attr "ppro_uops" "many")])
10316 (define_insn "*fop_tf_2"
10317   [(set (match_operand:TF 0 "register_operand" "=f,f")
10318         (match_operator:TF 3 "binary_fp_operator"
10319            [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10320             (match_operand:TF 2 "register_operand" "0,0")]))]
10321   "TARGET_80387 && TARGET_USE_FIOP"
10322   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10323   [(set (attr "type") 
10324         (cond [(match_operand:TF 3 "mult_operator" "") 
10325                  (const_string "fmul")
10326                (match_operand:TF 3 "div_operator" "") 
10327                  (const_string "fdiv")
10328               ]
10329               (const_string "fop")))
10330    (set_attr "fp_int_src" "true")
10331    (set_attr "mode" "SI")
10332    (set_attr "ppro_uops" "many")])
10334 (define_insn "*fop_xf_3"
10335   [(set (match_operand:XF 0 "register_operand" "=f,f")
10336         (match_operator:XF 3 "binary_fp_operator"
10337           [(match_operand:XF 1 "register_operand" "0,0")
10338            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
10339   "TARGET_80387 && TARGET_USE_FIOP"
10340   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10341   [(set (attr "type") 
10342         (cond [(match_operand:XF 3 "mult_operator" "") 
10343                  (const_string "fmul")
10344                (match_operand:XF 3 "div_operator" "") 
10345                  (const_string "fdiv")
10346               ]
10347               (const_string "fop")))
10348    (set_attr "fp_int_src" "true")
10349    (set_attr "mode" "SI")
10350    (set_attr "ppro_uops" "many")])
10352 (define_insn "*fop_tf_3"
10353   [(set (match_operand:TF 0 "register_operand" "=f,f")
10354         (match_operator:TF 3 "binary_fp_operator"
10355           [(match_operand:TF 1 "register_operand" "0,0")
10356            (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
10357   "TARGET_80387 && TARGET_USE_FIOP"
10358   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10359   [(set (attr "type") 
10360         (cond [(match_operand:TF 3 "mult_operator" "") 
10361                  (const_string "fmul")
10362                (match_operand:TF 3 "div_operator" "") 
10363                  (const_string "fdiv")
10364               ]
10365               (const_string "fop")))
10366    (set_attr "fp_int_src" "true")
10367    (set_attr "mode" "SI")
10368    (set_attr "ppro_uops" "many")])
10370 (define_insn "*fop_xf_4"
10371   [(set (match_operand:XF 0 "register_operand" "=f,f")
10372         (match_operator:XF 3 "binary_fp_operator"
10373            [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
10374             (match_operand:XF 2 "register_operand" "0,f")]))]
10375   "TARGET_80387"
10376   "* return output_387_binary_op (insn, operands);"
10377   [(set (attr "type") 
10378         (cond [(match_operand:XF 3 "mult_operator" "") 
10379                  (const_string "fmul")
10380                (match_operand:XF 3 "div_operator" "") 
10381                  (const_string "fdiv")
10382               ]
10383               (const_string "fop")))
10384    (set_attr "mode" "SF")])
10386 (define_insn "*fop_tf_4"
10387   [(set (match_operand:TF 0 "register_operand" "=f,f")
10388         (match_operator:TF 3 "binary_fp_operator"
10389            [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
10390             (match_operand:TF 2 "register_operand" "0,f")]))]
10391   "TARGET_80387"
10392   "* return output_387_binary_op (insn, operands);"
10393   [(set (attr "type") 
10394         (cond [(match_operand:TF 3 "mult_operator" "") 
10395                  (const_string "fmul")
10396                (match_operand:TF 3 "div_operator" "") 
10397                  (const_string "fdiv")
10398               ]
10399               (const_string "fop")))
10400    (set_attr "mode" "SF")])
10402 (define_insn "*fop_xf_5"
10403   [(set (match_operand:XF 0 "register_operand" "=f,f")
10404         (match_operator:XF 3 "binary_fp_operator"
10405           [(match_operand:XF 1 "register_operand" "0,f")
10406            (float_extend:XF
10407             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
10408   "TARGET_80387"
10409   "* return output_387_binary_op (insn, operands);"
10410   [(set (attr "type") 
10411         (cond [(match_operand:XF 3 "mult_operator" "") 
10412                  (const_string "fmul")
10413                (match_operand:XF 3 "div_operator" "") 
10414                  (const_string "fdiv")
10415               ]
10416               (const_string "fop")))
10417    (set_attr "mode" "SF")])
10419 (define_insn "*fop_tf_5"
10420   [(set (match_operand:TF 0 "register_operand" "=f,f")
10421         (match_operator:TF 3 "binary_fp_operator"
10422           [(match_operand:TF 1 "register_operand" "0,f")
10423            (float_extend:TF
10424             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
10425   "TARGET_80387"
10426   "* return output_387_binary_op (insn, operands);"
10427   [(set (attr "type") 
10428         (cond [(match_operand:TF 3 "mult_operator" "") 
10429                  (const_string "fmul")
10430                (match_operand:TF 3 "div_operator" "") 
10431                  (const_string "fdiv")
10432               ]
10433               (const_string "fop")))
10434    (set_attr "mode" "SF")])
10436 (define_insn "*fop_xf_6"
10437   [(set (match_operand:XF 0 "register_operand" "=f,f")
10438         (match_operator:XF 3 "binary_fp_operator"
10439            [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
10440             (match_operand:XF 2 "register_operand" "0,f")]))]
10441   "TARGET_80387"
10442   "* return output_387_binary_op (insn, operands);"
10443   [(set (attr "type") 
10444         (cond [(match_operand:XF 3 "mult_operator" "") 
10445                  (const_string "fmul")
10446                (match_operand:XF 3 "div_operator" "") 
10447                  (const_string "fdiv")
10448               ]
10449               (const_string "fop")))
10450    (set_attr "mode" "DF")])
10452 (define_insn "*fop_tf_6"
10453   [(set (match_operand:TF 0 "register_operand" "=f,f")
10454         (match_operator:TF 3 "binary_fp_operator"
10455            [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
10456             (match_operand:TF 2 "register_operand" "0,f")]))]
10457   "TARGET_80387"
10458   "* return output_387_binary_op (insn, operands);"
10459   [(set (attr "type") 
10460         (cond [(match_operand:TF 3 "mult_operator" "") 
10461                  (const_string "fmul")
10462                (match_operand:TF 3 "div_operator" "") 
10463                  (const_string "fdiv")
10464               ]
10465               (const_string "fop")))
10466    (set_attr "mode" "DF")])
10468 (define_insn "*fop_xf_7"
10469   [(set (match_operand:XF 0 "register_operand" "=f,f")
10470         (match_operator:XF 3 "binary_fp_operator"
10471           [(match_operand:XF 1 "register_operand" "0,f")
10472            (float_extend:XF
10473             (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
10474   "TARGET_80387"
10475   "* return output_387_binary_op (insn, operands);"
10476   [(set (attr "type") 
10477         (cond [(match_operand:XF 3 "mult_operator" "") 
10478                  (const_string "fmul")
10479                (match_operand:XF 3 "div_operator" "") 
10480                  (const_string "fdiv")
10481               ]
10482               (const_string "fop")))
10483    (set_attr "mode" "DF")])
10485 (define_insn "*fop_tf_7"
10486   [(set (match_operand:TF 0 "register_operand" "=f,f")
10487         (match_operator:TF 3 "binary_fp_operator"
10488           [(match_operand:TF 1 "register_operand" "0,f")
10489            (float_extend:TF
10490             (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
10491   "TARGET_80387"
10492   "* return output_387_binary_op (insn, operands);"
10493   [(set (attr "type") 
10494         (cond [(match_operand:TF 3 "mult_operator" "") 
10495                  (const_string "fmul")
10496                (match_operand:TF 3 "div_operator" "") 
10497                  (const_string "fdiv")
10498               ]
10499               (const_string "fop")))
10500    (set_attr "mode" "DF")])
10502 (define_split
10503   [(set (match_operand 0 "register_operand" "")
10504         (match_operator 3 "binary_fp_operator"
10505            [(float (match_operand:SI 1 "register_operand" ""))
10506             (match_operand 2 "register_operand" "")]))]
10507   "TARGET_80387 && reload_completed
10508    && FLOAT_MODE_P (GET_MODE (operands[0]))"
10509   [(const_int 0)]
10510   "
10512   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
10513   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
10514   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
10515                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
10516                                           GET_MODE (operands[3]),
10517                                           operands[4],
10518                                           operands[2])));
10519   ix86_free_from_memory (GET_MODE (operands[1]));
10520   DONE;
10523 (define_split
10524   [(set (match_operand 0 "register_operand" "")
10525         (match_operator 3 "binary_fp_operator"
10526            [(match_operand 1 "register_operand" "")
10527             (float (match_operand:SI 2 "register_operand" ""))]))]
10528   "TARGET_80387 && reload_completed
10529    && FLOAT_MODE_P (GET_MODE (operands[0]))"
10530   [(const_int 0)]
10531   "
10533   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10534   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
10535   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
10536                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
10537                                           GET_MODE (operands[3]),
10538                                           operands[1],
10539                                           operands[4])));
10540   ix86_free_from_memory (GET_MODE (operands[2]));
10541   DONE;
10544 ;; FPU special functions.
10546 (define_insn "sqrtsf2"
10547   [(set (match_operand:SF 0 "register_operand" "=f")
10548         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
10549   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
10550   "fsqrt"
10551   [(set_attr "type" "fpspc")
10552    (set_attr "mode" "SF")
10553    (set_attr "athlon_decode" "direct")])
10555 (define_insn "sqrtdf2"
10556   [(set (match_operand:DF 0 "register_operand" "=f")
10557         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
10558   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10559    && (TARGET_IEEE_FP || flag_fast_math) "
10560   "fsqrt"
10561   [(set_attr "type" "fpspc")
10562    (set_attr "mode" "DF")
10563    (set_attr "athlon_decode" "direct")])
10565 (define_insn "*sqrtextendsfdf2"
10566   [(set (match_operand:DF 0 "register_operand" "=f")
10567         (sqrt:DF (float_extend:DF
10568                   (match_operand:SF 1 "register_operand" "0"))))]
10569   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
10570   "fsqrt"
10571   [(set_attr "type" "fpspc")
10572    (set_attr "mode" "DF")
10573    (set_attr "athlon_decode" "direct")])
10575 (define_insn "sqrtxf2"
10576   [(set (match_operand:XF 0 "register_operand" "=f")
10577         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
10578   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
10579    && (TARGET_IEEE_FP || flag_fast_math) "
10580   "fsqrt"
10581   [(set_attr "type" "fpspc")
10582    (set_attr "mode" "XF")
10583    (set_attr "athlon_decode" "direct")])
10585 (define_insn "sqrttf2"
10586   [(set (match_operand:TF 0 "register_operand" "=f")
10587         (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
10588   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
10589    && (TARGET_IEEE_FP || flag_fast_math) "
10590   "fsqrt"
10591   [(set_attr "type" "fpspc")
10592    (set_attr "mode" "XF")
10593    (set_attr "athlon_decode" "direct")])
10595 (define_insn "*sqrtextenddfxf2"
10596   [(set (match_operand:XF 0 "register_operand" "=f")
10597         (sqrt:XF (float_extend:XF
10598                   (match_operand:DF 1 "register_operand" "0"))))]
10599   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
10600   "fsqrt"
10601   [(set_attr "type" "fpspc")
10602    (set_attr "mode" "XF")
10603    (set_attr "athlon_decode" "direct")])
10605 (define_insn "*sqrtextenddftf2"
10606   [(set (match_operand:TF 0 "register_operand" "=f")
10607         (sqrt:TF (float_extend:TF
10608                   (match_operand:DF 1 "register_operand" "0"))))]
10609   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
10610   "fsqrt"
10611   [(set_attr "type" "fpspc")
10612    (set_attr "mode" "XF")
10613    (set_attr "athlon_decode" "direct")])
10615 (define_insn "*sqrtextendsfxf2"
10616   [(set (match_operand:XF 0 "register_operand" "=f")
10617         (sqrt:XF (float_extend:XF
10618                   (match_operand:SF 1 "register_operand" "0"))))]
10619   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
10620   "fsqrt"
10621   [(set_attr "type" "fpspc")
10622    (set_attr "mode" "XF")
10623    (set_attr "athlon_decode" "direct")])
10625 (define_insn "*sqrtextendsftf2"
10626   [(set (match_operand:TF 0 "register_operand" "=f")
10627         (sqrt:TF (float_extend:TF
10628                   (match_operand:SF 1 "register_operand" "0"))))]
10629   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
10630   "fsqrt"
10631   [(set_attr "type" "fpspc")
10632    (set_attr "mode" "XF")
10633    (set_attr "athlon_decode" "direct")])
10635 (define_insn "sindf2"
10636   [(set (match_operand:DF 0 "register_operand" "=f")
10637         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
10638   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
10639   "fsin"
10640   [(set_attr "type" "fpspc")
10641    (set_attr "mode" "DF")])
10643 (define_insn "sinsf2"
10644   [(set (match_operand:SF 0 "register_operand" "=f")
10645         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
10646   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
10647   "fsin"
10648   [(set_attr "type" "fpspc")
10649    (set_attr "mode" "SF")])
10651 (define_insn "*sinextendsfdf2"
10652   [(set (match_operand:DF 0 "register_operand" "=f")
10653         (unspec:DF [(float_extend:DF
10654                      (match_operand:SF 1 "register_operand" "0"))] 1))]
10655   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
10656   "fsin"
10657   [(set_attr "type" "fpspc")
10658    (set_attr "mode" "DF")])
10660 (define_insn "sinxf2"
10661   [(set (match_operand:XF 0 "register_operand" "=f")
10662         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
10663   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
10664   "fsin"
10665   [(set_attr "type" "fpspc")
10666    (set_attr "mode" "XF")])
10668 (define_insn "sintf2"
10669   [(set (match_operand:TF 0 "register_operand" "=f")
10670         (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
10671   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
10672   "fsin"
10673   [(set_attr "type" "fpspc")
10674    (set_attr "mode" "XF")])
10676 (define_insn "cosdf2"
10677   [(set (match_operand:DF 0 "register_operand" "=f")
10678         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
10679   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
10680   "fcos"
10681   [(set_attr "type" "fpspc")
10682    (set_attr "mode" "DF")])
10684 (define_insn "cossf2"
10685   [(set (match_operand:SF 0 "register_operand" "=f")
10686         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
10687   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
10688   "fcos"
10689   [(set_attr "type" "fpspc")
10690    (set_attr "mode" "SF")])
10692 (define_insn "*cosextendsfdf2"
10693   [(set (match_operand:DF 0 "register_operand" "=f")
10694         (unspec:DF [(float_extend:DF
10695                      (match_operand:SF 1 "register_operand" "0"))] 2))]
10696   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
10697   "fcos"
10698   [(set_attr "type" "fpspc")
10699    (set_attr "mode" "DF")])
10701 (define_insn "cosxf2"
10702   [(set (match_operand:XF 0 "register_operand" "=f")
10703         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
10704   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
10705   "fcos"
10706   [(set_attr "type" "fpspc")
10707    (set_attr "mode" "XF")])
10709 (define_insn "costf2"
10710   [(set (match_operand:TF 0 "register_operand" "=f")
10711         (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
10712   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
10713   "fcos"
10714   [(set_attr "type" "fpspc")
10715    (set_attr "mode" "XF")])
10717 ;; Block operation instructions
10719 (define_insn "cld"
10720  [(set (reg:SI 19) (const_int 0))]
10721  ""
10722  "cld"
10723   [(set_attr "type" "cld")])
10725 (define_expand "movstrsi"
10726   [(use (match_operand:BLK 0 "memory_operand" ""))
10727    (use (match_operand:BLK 1 "memory_operand" ""))
10728    (use (match_operand:SI 2 "nonmemory_operand" ""))
10729    (use (match_operand:SI 3 "const_int_operand" ""))]
10730   ""
10731   "
10733   rtx srcreg, destreg, countreg;
10734   int align = 0;
10735   int count = -1;
10736   rtx insns;
10738   start_sequence ();
10740   if (GET_CODE (operands[3]) == CONST_INT)
10741     align = INTVAL (operands[3]);
10743   /* This simple hack avoids all inlining code and simplifies code bellow.  */
10744   if (!TARGET_ALIGN_STRINGOPS)
10745     align = 32;
10747   if (GET_CODE (operands[2]) == CONST_INT)
10748     count = INTVAL (operands[2]);
10750   destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
10751   srcreg = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
10753   emit_insn (gen_cld ());
10755   /* When optimizing for size emit simple rep ; movsb instruction for
10756      counts not divisible by 4.  */
10758   if ((!optimize || optimize_size) 
10759       && (count < 0 || (count & 0x03)))
10760     {
10761       countreg = copy_to_mode_reg (SImode, operands[2]);
10762       emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
10763                                 destreg, srcreg, countreg));
10764     }
10766   /* For constant aligned (or small unaligned) copies use rep movsl
10767      followed by code copying the rest.  For PentiumPro ensure 8 byte
10768      alignment to allow rep movsl acceleration.  */
10770   else if (count >= 0 
10771            && (align >= 8
10772                || (!TARGET_PENTIUMPRO && align >= 4)
10773                || optimize_size || count < 64))
10774     {
10775       if (count & ~0x03)
10776         {
10777           countreg = copy_to_mode_reg (SImode,
10778                                        GEN_INT ((count >> 2)
10779                                                 & 0x3fffffff));
10780           emit_insn (gen_rep_movsi (destreg, srcreg, countreg,
10781                                     destreg, srcreg, countreg));
10782         }
10783       if (count & 0x02)
10784         emit_insn (gen_strmovhi (destreg, srcreg));
10785       if (count & 0x01)
10786         emit_insn (gen_strmovqi (destreg, srcreg));
10787     }
10788   /* The generic code based on the glibc implementation:
10789      - align destination to 4 bytes (8 byte alignment is used for PentiumPro
10790        allowing accelerated copying there)
10791      - copy the data using rep movsl
10792      - copy the rest.  */
10793   else
10794     {
10795       rtx countreg2;
10796       rtx label = NULL;
10798       /* In case we don't know anything about the alignment, default to
10799          library version, since it is usually equally fast and result in
10800          shorter code.  */
10801       if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
10802         {
10803           end_sequence ();
10804           FAIL;
10805         }
10807       if (TARGET_SINGLE_STRINGOP)
10808         emit_insn (gen_cld ());
10810       countreg2 = gen_reg_rtx (SImode);
10811       countreg = copy_to_mode_reg (SImode, operands[2]);
10813       /* We don't use loops to align destination and to copy parts smaller
10814          than 4 bytes, because gcc is able to optimize such code better (in
10815          the case the destination or the count really is aligned, gcc is often
10816          able to predict the branches) and also it is friendlier to the
10817          hardware branch prediction.  
10819          Using loops is benefical for generic case, because we can
10820          handle small counts using the loops.  Many CPUs (such as Athlon)
10821          have large REP prefix setup costs.
10823          This is quite costy.  Maybe we can revisit this decision later or
10824          add some customizability to this code.  */
10826       if (count < 0
10827           && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
10828         {
10829           label = gen_label_rtx ();
10830           emit_cmp_and_jump_insns (countreg, GEN_INT (3),
10831                                    LEU, 0, SImode, 1, 0, label);
10832         }
10833       if (align <= 1)
10834         {
10835           rtx label = gen_label_rtx ();
10836           rtx tmpcount = gen_reg_rtx (SImode);
10837           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
10838           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
10839                                    SImode, 1, 0, label);
10840           emit_insn (gen_strmovqi (destreg, srcreg));
10841           emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
10842           emit_label (label);
10843           LABEL_NUSES (label) = 1;
10844         }
10845       if (align <= 2)
10846         {
10847           rtx label = gen_label_rtx ();
10848           rtx tmpcount = gen_reg_rtx (SImode);
10849           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
10850           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
10851                                    SImode, 1, 0, label);
10852           emit_insn (gen_strmovhi (destreg, srcreg));
10853           emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
10854           emit_label (label);
10855           LABEL_NUSES (label) = 1;
10856         }
10857       if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
10858         {
10859           rtx label = gen_label_rtx ();
10860           rtx tmpcount = gen_reg_rtx (SImode);
10861           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
10862           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
10863                                    SImode, 1, 0, label);
10864           emit_insn (gen_strmovsi (destreg, srcreg));
10865           emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
10866           emit_label (label);
10867           LABEL_NUSES (label) = 1;
10868         }
10870       if (!TARGET_SINGLE_STRINGOP)
10871         emit_insn (gen_cld());
10872       emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
10873       emit_insn (gen_rep_movsi (destreg, srcreg, countreg2,
10874                                 destreg, srcreg, countreg2));
10876       if (label)
10877         {
10878           emit_label (label);
10879           LABEL_NUSES (label) = 1;
10880         }
10881       if (align > 2 && count > 0 && (count & 2))
10882         emit_insn (gen_strmovhi (destreg, srcreg));
10883       if (align <= 2 || count < 0)
10884         {
10885           rtx label = gen_label_rtx ();
10886           rtx tmpcount = gen_reg_rtx (SImode);
10887           emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
10888           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
10889                                    SImode, 1, 0, label);
10890           emit_insn (gen_strmovhi (destreg, srcreg));
10891           emit_label (label);
10892           LABEL_NUSES (label) = 1;
10893         }
10894       if (align > 1 && count > 0 && (count & 1))
10895         emit_insn (gen_strmovsi (destreg, srcreg));
10896       if (align <= 1 || count < 0)
10897         {
10898           rtx label = gen_label_rtx ();
10899           rtx tmpcount = gen_reg_rtx (SImode);
10900           emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
10901           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
10902                                    SImode, 1, 0, label);
10903           emit_insn (gen_strmovqi (destreg, srcreg));
10904           emit_label (label);
10905           LABEL_NUSES (label) = 1;
10906         }
10907     }
10909   insns = get_insns ();
10910   end_sequence ();
10912   ix86_set_move_mem_attrs (insns, operands[0], operands[1], destreg, srcreg);
10913   emit_insns (insns);
10914   DONE;
10917 ;; Most CPUs don't like single string operations
10918 ;; Handle this case here to simplify previous expander.
10920 (define_expand "strmovsi"
10921   [(set (match_dup 2)
10922         (mem:SI (match_operand:SI 1 "register_operand" "")))
10923    (set (mem:SI (match_operand:SI 0 "register_operand" ""))
10924         (match_dup 2))
10925    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
10926               (clobber (reg:CC 17))])
10927    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
10928               (clobber (reg:CC 17))])]
10929   ""
10930   "
10932   if (TARGET_SINGLE_STRINGOP || optimize_size)
10933     {
10934       emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
10935                                 operands[1]));
10936       DONE;
10937     }
10938   else 
10939     operands[2] = gen_reg_rtx (SImode);
10942 (define_expand "strmovhi"
10943   [(set (match_dup 2)
10944         (mem:HI (match_operand:SI 1 "register_operand" "")))
10945    (set (mem:HI (match_operand:SI 0 "register_operand" ""))
10946         (match_dup 2))
10947    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
10948               (clobber (reg:CC 17))])
10949    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
10950               (clobber (reg:CC 17))])]
10951   ""
10952   "
10954   if (TARGET_SINGLE_STRINGOP || optimize_size)
10955     {
10956       emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
10957                                 operands[1]));
10958       DONE;
10959     }
10960   else 
10961     operands[2] = gen_reg_rtx (HImode);
10964 (define_expand "strmovqi"
10965   [(set (match_dup 2)
10966         (mem:QI (match_operand:SI 1 "register_operand" "")))
10967    (set (mem:QI (match_operand:SI 0 "register_operand" ""))
10968         (match_dup 2))
10969    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
10970               (clobber (reg:CC 17))])
10971    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
10972               (clobber (reg:CC 17))])]
10973   ""
10974   "
10976   if (TARGET_SINGLE_STRINGOP || optimize_size)
10977     {
10978       emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
10979                                 operands[1]));
10980       DONE;
10981     }
10982   else 
10983     operands[2] = gen_reg_rtx (QImode);
10986 (define_insn "strmovsi_1"
10987   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
10988         (mem:SI (match_operand:SI 3 "register_operand" "1")))
10989    (set (match_operand:SI 0 "register_operand" "=D")
10990         (plus:SI (match_dup 2)
10991                  (const_int 4)))
10992    (set (match_operand:SI 1 "register_operand" "=S")
10993         (plus:SI (match_dup 3)
10994                  (const_int 4)))
10995    (use (reg:SI 19))]
10996   "TARGET_SINGLE_STRINGOP || optimize_size"
10997   "movsl"
10998   [(set_attr "type" "str")
10999    (set_attr "mode" "SI")
11000    (set_attr "memory" "both")])
11002 (define_insn "strmovhi_1"
11003   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
11004         (mem:HI (match_operand:SI 3 "register_operand" "1")))
11005    (set (match_operand:SI 0 "register_operand" "=D")
11006         (plus:SI (match_dup 2)
11007                  (const_int 2)))
11008    (set (match_operand:SI 1 "register_operand" "=S")
11009         (plus:SI (match_dup 3)
11010                  (const_int 2)))
11011    (use (reg:SI 19))]
11012   "TARGET_SINGLE_STRINGOP || optimize_size"
11013   "movsw"
11014   [(set_attr "type" "str")
11015    (set_attr "memory" "both")
11016    (set_attr "mode" "HI")])
11018 (define_insn "strmovqi_1"
11019   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
11020         (mem:QI (match_operand:SI 3 "register_operand" "1")))
11021    (set (match_operand:SI 0 "register_operand" "=D")
11022         (plus:SI (match_dup 2)
11023                  (const_int 1)))
11024    (set (match_operand:SI 1 "register_operand" "=S")
11025         (plus:SI (match_dup 3)
11026                  (const_int 1)))
11027    (use (reg:SI 19))]
11028   "TARGET_SINGLE_STRINGOP || optimize_size"
11029   "movsb"
11030   [(set_attr "type" "str")
11031    (set_attr "memory" "both")
11032    (set_attr "mode" "QI")])
11034 (define_insn "rep_movsi"
11035   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
11036    (set (match_operand:SI 0 "register_operand" "=D") 
11037         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
11038                             (const_int 2))
11039                  (match_operand:SI 3 "register_operand" "0")))
11040    (set (match_operand:SI 1 "register_operand" "=S") 
11041         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
11042                  (match_operand:SI 4 "register_operand" "1")))
11043    (set (mem:BLK (match_dup 3))
11044         (mem:BLK (match_dup 4)))
11045    (use (match_dup 5))
11046    (use (reg:SI 19))]
11047   ""
11048   "rep\;movsl|rep movsd"
11049   [(set_attr "type" "str")
11050    (set_attr "prefix_rep" "1")
11051    (set_attr "memory" "both")
11052    (set_attr "mode" "SI")])
11054 (define_insn "rep_movqi"
11055   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
11056    (set (match_operand:SI 0 "register_operand" "=D") 
11057         (plus:SI (match_operand:SI 3 "register_operand" "0")
11058                  (match_operand:SI 5 "register_operand" "2")))
11059    (set (match_operand:SI 1 "register_operand" "=S") 
11060         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
11061    (set (mem:BLK (match_dup 3))
11062         (mem:BLK (match_dup 4)))
11063    (use (match_dup 5))
11064    (use (reg:SI 19))]
11065   ""
11066   "rep\;movsb|rep movsb"
11067   [(set_attr "type" "str")
11068    (set_attr "prefix_rep" "1")
11069    (set_attr "memory" "both")
11070    (set_attr "mode" "SI")])
11072 (define_expand "clrstrsi"
11073    [(use (match_operand:BLK 0 "memory_operand" ""))
11074     (use (match_operand:SI 1 "nonmemory_operand" ""))
11075     (use (match_operand:SI 2 "const_int_operand" ""))]
11076   ""
11077   "
11079   /* See comments in movstr expanders.  The code is mostly identical.  */
11081   rtx destreg, zeroreg, countreg;
11082   int align = 0;
11083   int count = -1;
11084   rtx insns;
11086   start_sequence ();
11088   if (GET_CODE (operands[2]) == CONST_INT)
11089     align = INTVAL (operands[2]);
11091   /* This simple hack avoids all inlining code and simplifies code bellow.  */
11092   if (!TARGET_ALIGN_STRINGOPS)
11093     align = 32;
11095   if (GET_CODE (operands[1]) == CONST_INT)
11096     count = INTVAL (operands[1]);
11098   destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
11100   emit_insn (gen_cld ());
11102   /* When optimizing for size emit simple rep ; movsb instruction for
11103      counts not divisible by 4.  */
11105   if ((!optimize || optimize_size) 
11106       && (count < 0 || (count & 0x03)))
11107     {
11108       countreg = copy_to_mode_reg (SImode, operands[1]);
11109       zeroreg = copy_to_mode_reg (QImode, const0_rtx);
11110       emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg,
11111                                  destreg, countreg));
11112     }
11113   else if (count >= 0 
11114            && (align >= 8
11115                || (!TARGET_PENTIUMPRO && align >= 4)
11116                || optimize_size || count < 64))
11117     {
11118       zeroreg = copy_to_mode_reg (SImode, const0_rtx);
11119       if (INTVAL (operands[1]) & ~0x03)
11120         {
11121           countreg = copy_to_mode_reg (SImode,
11122                                        GEN_INT ((INTVAL (operands[1]) >> 2)
11123                                                 & 0x3fffffff));
11124           emit_insn (gen_rep_stossi (destreg, countreg, zeroreg,
11125                                      destreg, countreg));
11126         }
11127       if (INTVAL (operands[1]) & 0x02)
11128         emit_insn (gen_strsethi (destreg,
11129                                  gen_rtx_SUBREG (HImode, zeroreg, 0)));
11130       if (INTVAL (operands[1]) & 0x01)
11131         emit_insn (gen_strsetqi (destreg,
11132                                  gen_rtx_SUBREG (QImode, zeroreg, 0)));
11133     }
11134   else
11135     {
11136       rtx countreg2;
11137       rtx label = NULL;
11139       /* In case we don't know anything about the alignment, default to
11140          library version, since it is usually equally fast and result in
11141          shorter code.  */
11142       if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
11143         {
11144           end_sequence ();
11145           FAIL;
11146         }
11148       if (TARGET_SINGLE_STRINGOP)
11149         emit_insn (gen_cld ());
11151       countreg2 = gen_reg_rtx (SImode);
11152       countreg = copy_to_mode_reg (SImode, operands[1]);
11153       zeroreg = copy_to_mode_reg (SImode, const0_rtx);
11155       if (count < 0
11156           && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
11157         {
11158           label = gen_label_rtx ();
11159           emit_cmp_and_jump_insns (countreg, GEN_INT (3),
11160                                    LEU, 0, SImode, 1, 0, label);
11161         }
11162       if (align <= 1)
11163         {
11164           rtx label = gen_label_rtx ();
11165           rtx tmpcount = gen_reg_rtx (SImode);
11166           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
11167           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11168                                    SImode, 1, 0, label);
11169           emit_insn (gen_strsetqi (destreg,
11170                                    gen_rtx_SUBREG (QImode, zeroreg, 0)));
11171           emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
11172           emit_label (label);
11173           LABEL_NUSES (label) = 1;
11174         }
11175       if (align <= 2)
11176         {
11177           rtx label = gen_label_rtx ();
11178           rtx tmpcount = gen_reg_rtx (SImode);
11179           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
11180           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11181                                    SImode, 1, 0, label);
11182           emit_insn (gen_strsethi (destreg,
11183                                    gen_rtx_SUBREG (HImode, zeroreg, 0)));
11184           emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
11185           emit_label (label);
11186           LABEL_NUSES (label) = 1;
11187         }
11188       if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
11189         {
11190           rtx label = gen_label_rtx ();
11191           rtx tmpcount = gen_reg_rtx (SImode);
11192           emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
11193           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11194                                    SImode, 1, 0, label);
11195           emit_insn (gen_strsetsi (destreg, zeroreg));
11196           emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
11197           emit_label (label);
11198           LABEL_NUSES (label) = 1;
11199         }
11201       if (!TARGET_SINGLE_STRINGOP)
11202         emit_insn (gen_cld());
11203       emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
11204       emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg,
11205                                  destreg, countreg2));
11207       if (label)
11208         {
11209           emit_label (label);
11210           LABEL_NUSES (label) = 1;
11211         }
11212       if (align > 2 && count > 0 && (count & 2))
11213         emit_insn (gen_strsethi (destreg,
11214                                  gen_rtx_SUBREG (HImode, zeroreg, 0)));
11215       if (align <= 2 || count < 0)
11216         {
11217           rtx label = gen_label_rtx ();
11218           rtx tmpcount = gen_reg_rtx (SImode);
11219           emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
11220           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11221                                    SImode, 1, 0, label);
11222           emit_insn (gen_strsethi (destreg,
11223                                    gen_rtx_SUBREG (HImode, zeroreg, 0)));
11224           emit_label (label);
11225           LABEL_NUSES (label) = 1;
11226         }
11227       if (align > 1 && count > 0 && (count & 1))
11228         emit_insn (gen_strsetqi (destreg,
11229                                  gen_rtx_SUBREG (QImode, zeroreg, 0)));
11230       if (align <= 1 || count < 0)
11231         {
11232           rtx label = gen_label_rtx ();
11233           rtx tmpcount = gen_reg_rtx (SImode);
11234           emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
11235           emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11236                                    SImode, 1, 0, label);
11237           emit_insn (gen_strsetqi (destreg,
11238                                    gen_rtx_SUBREG (QImode, zeroreg, 0)));
11239           emit_label (label);
11240           LABEL_NUSES (label) = 1;
11241         }
11242     }
11244   insns = get_insns ();
11245   end_sequence ();
11247   ix86_set_move_mem_attrs (insns, operands[0], operands[0], destreg, destreg);
11248   emit_insns (insns);
11250   DONE;
11253 ;; Most CPUs don't like single string operations
11254 ;; Handle this case here to simplify previous expander.
11256 (define_expand "strsetsi"
11257   [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
11258         (match_operand:SI 1 "register_operand" ""))
11259    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
11260               (clobber (reg:CC 17))])]
11261   ""
11262   "
11264   if (TARGET_SINGLE_STRINGOP || optimize_size)
11265     {
11266       emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
11267       DONE;
11268     }
11271 (define_expand "strsethi"
11272   [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
11273         (match_operand:HI 1 "register_operand" ""))
11274    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
11275               (clobber (reg:CC 17))])]
11276   ""
11277   "
11279   if (TARGET_SINGLE_STRINGOP || optimize_size)
11280     {
11281       emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
11282       DONE;
11283     }
11286 (define_expand "strsetqi"
11287   [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
11288         (match_operand:QI 1 "register_operand" ""))
11289    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11290               (clobber (reg:CC 17))])]
11291   ""
11292   "
11294   if (TARGET_SINGLE_STRINGOP || optimize_size)
11295     {
11296       emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
11297       DONE;
11298     }
11301 (define_insn "strsetsi_1"
11302   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
11303         (match_operand:SI 2 "register_operand" "a"))
11304    (set (match_operand:SI 0 "register_operand" "=D")
11305         (plus:SI (match_dup 1)
11306                  (const_int 4)))
11307    (use (reg:SI 19))]
11308   "TARGET_SINGLE_STRINGOP || optimize_size"
11309   "stosl"
11310   [(set_attr "type" "str")
11311    (set_attr "memory" "store")
11312    (set_attr "mode" "SI")])
11314 (define_insn "strsethi_1"
11315   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
11316         (match_operand:HI 2 "register_operand" "a"))
11317    (set (match_operand:SI 0 "register_operand" "=D")
11318         (plus:SI (match_dup 1)
11319                  (const_int 2)))
11320    (use (reg:SI 19))]
11321   "TARGET_SINGLE_STRINGOP || optimize_size"
11322   "stosw"
11323   [(set_attr "type" "str")
11324    (set_attr "memory" "store")
11325    (set_attr "mode" "HI")])
11327 (define_insn "strsetqi_1"
11328   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
11329         (match_operand:QI 2 "register_operand" "a"))
11330    (set (match_operand:SI 0 "register_operand" "=D")
11331         (plus:SI (match_dup 1)
11332                  (const_int 1)))
11333    (use (reg:SI 19))]
11334   "TARGET_SINGLE_STRINGOP || optimize_size"
11335   "stosb"
11336   [(set_attr "type" "str")
11337    (set_attr "memory" "store")
11338    (set_attr "mode" "QI")])
11340 (define_insn "rep_stossi"
11341   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
11342    (set (match_operand:SI 0 "register_operand" "=D") 
11343         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
11344                             (const_int 2))
11345                  (match_operand:SI 3 "register_operand" "0")))
11346    (set (mem:BLK (match_dup 3))
11347         (const_int 0))
11348    (use (match_operand:SI 2 "register_operand" "a"))
11349    (use (match_dup 4))
11350    (use (reg:SI 19))]
11351   ""
11352   "rep\;stosl|rep stosd"
11353   [(set_attr "type" "str")
11354    (set_attr "prefix_rep" "1")
11355    (set_attr "memory" "store")
11356    (set_attr "mode" "SI")])
11358 (define_insn "rep_stosqi"
11359   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
11360    (set (match_operand:SI 0 "register_operand" "=D") 
11361         (plus:SI (match_operand:SI 3 "register_operand" "0")
11362                  (match_operand:SI 4 "register_operand" "1")))
11363    (set (mem:BLK (match_dup 3))
11364         (const_int 0))
11365    (use (match_operand:QI 2 "register_operand" "a"))
11366    (use (match_dup 4))
11367    (use (reg:SI 19))]
11368   ""
11369   "rep\;stosb|rep stosb"
11370   [(set_attr "type" "str")
11371    (set_attr "prefix_rep" "1")
11372    (set_attr "memory" "store")
11373    (set_attr "mode" "QI")])
11375 (define_expand "cmpstrsi"
11376   [(set (match_operand:SI 0 "register_operand" "")
11377         (compare:SI (match_operand:BLK 1 "general_operand" "")
11378                     (match_operand:BLK 2 "general_operand" "")))
11379    (use (match_operand:SI 3 "general_operand" ""))
11380    (use (match_operand:SI 4 "immediate_operand" ""))]
11381   ""
11382   "
11384   rtx addr1, addr2, out, outlow, count, countreg, align;
11386   out = operands[0];
11387   if (GET_CODE (out) != REG)
11388     out = gen_reg_rtx (SImode);
11390   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
11391   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
11392   
11393   count = operands[3];
11394   countreg = copy_to_mode_reg (SImode, count);
11396   /* %%% Iff we are testing strict equality, we can use known alignment
11397      to good advantage.  This may be possible with combine, particularly
11398      once cc0 is dead.  */
11399   align = operands[4];
11401   emit_insn (gen_cld ());
11402   if (GET_CODE (count) == CONST_INT)
11403     {
11404       if (INTVAL (count) == 0)
11405         {
11406           emit_move_insn (operands[0], const0_rtx);
11407           DONE;
11408         }
11409       emit_insn (gen_cmpstrsi_nz_1 (addr1, addr2, countreg, align,
11410                                     addr1, addr2, countreg));
11411     }
11412   else
11413     {
11414       emit_insn (gen_cmpsi_1 (countreg, countreg));
11415       emit_insn (gen_cmpstrsi_1 (addr1, addr2, countreg, align,
11416                                  addr1, addr2, countreg));
11417     }
11419   outlow = gen_lowpart (QImode, out);
11420   emit_insn (gen_cmpintqi (outlow));
11421   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
11423   if (operands[0] != out)
11424     emit_move_insn (operands[0], out);
11426   DONE;
11429 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
11431 (define_expand "cmpintqi"
11432   [(set (match_dup 1)
11433         (gtu:QI (reg:CC 17) (const_int 0)))
11434    (set (match_dup 2)
11435         (ltu:QI (reg:CC 17) (const_int 0)))
11436    (parallel [(set (match_operand:QI 0 "register_operand" "")
11437                    (minus:QI (match_dup 1)
11438                              (match_dup 2)))
11439               (clobber (reg:CC 17))])]
11440   ""
11441   "operands[1] = gen_reg_rtx (QImode);
11442    operands[2] = gen_reg_rtx (QImode);")
11444 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
11445 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
11447 (define_insn "cmpstrsi_nz_1"
11448   [(set (reg:CC 17)
11449         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
11450                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
11451    (use (match_operand:SI 6 "register_operand" "2"))
11452    (use (match_operand:SI 3 "immediate_operand" "i"))
11453    (use (reg:SI 19))
11454    (clobber (match_operand:SI 0 "register_operand" "=S"))
11455    (clobber (match_operand:SI 1 "register_operand" "=D"))
11456    (clobber (match_operand:SI 2 "register_operand" "=c"))]
11457   ""
11458   "repz{\;| }cmpsb"
11459   [(set_attr "type" "str")
11460    (set_attr "mode" "QI")
11461    (set_attr "prefix_rep" "1")])
11463 ;; The same, but the count is not known to not be zero.
11465 (define_insn "cmpstrsi_1"
11466   [(set (reg:CC 17)
11467         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
11468                              (const_int 0))
11469           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
11470                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
11471           (const_int 0)))
11472    (use (match_operand:SI 3 "immediate_operand" "i"))
11473    (use (reg:CC 17))
11474    (use (reg:SI 19))
11475    (clobber (match_operand:SI 0 "register_operand" "=S"))
11476    (clobber (match_operand:SI 1 "register_operand" "=D"))
11477    (clobber (match_operand:SI 2 "register_operand" "=c"))]
11478   ""
11479   "repz{\;| }cmpsb"
11480   [(set_attr "type" "str")
11481    (set_attr "mode" "QI")
11482    (set_attr "prefix_rep" "1")])
11484 (define_expand "strlensi"
11485   [(set (match_operand:SI 0 "register_operand" "")
11486         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
11487                     (match_operand:QI 2 "immediate_operand" "")
11488                     (match_operand:SI 3 "immediate_operand" "")] 0))]
11489   ""
11490   "
11492   rtx out, addr, scratch1, scratch2, scratch3;
11493   rtx eoschar = operands[2];
11494   rtx align = operands[3];
11496   /* The generic case of strlen expander is long.  Avoid it's
11497      expanding unless TARGET_INLINE_ALL_STRINGOPS.  */
11499   if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
11500       && !TARGET_INLINE_ALL_STRINGOPS
11501       && !optimize_size
11502       && (GET_CODE (align) != CONST_INT || INTVAL (align) < 4))
11503     FAIL;
11505   out = operands[0];
11506   addr = force_reg (Pmode, XEXP (operands[1], 0));
11507   scratch1 = gen_reg_rtx (SImode);
11509   if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
11510       && !optimize_size)
11511     {
11512       /* Well it seems that some optimizer does not combine a call like
11513              foo(strlen(bar), strlen(bar));
11514          when the move and the subtraction is done here.  It does calculate
11515          the length just once when these instructions are done inside of
11516          output_strlen_unroll().  But I think since &bar[strlen(bar)] is
11517          often used and I use one fewer register for the lifetime of
11518          output_strlen_unroll() this is better.  */
11520       if (GET_CODE (align) != CONST_INT || INTVAL (align) < 4)
11521         emit_move_insn (scratch1, addr);
11523       emit_move_insn (out, addr);
11525       ix86_expand_strlensi_unroll_1 (out, align, scratch1);
11527       /* strlensi_unroll_1 returns the address of the zero at the end of
11528          the string, like memchr(), so compute the length by subtracting
11529          the start address.  */
11530       emit_insn (gen_subsi3 (out, out, addr));
11531     }
11532   else
11533     {
11534       scratch2 = gen_reg_rtx (SImode);
11535       scratch3 = gen_reg_rtx (SImode);
11537       emit_move_insn (scratch3, addr);
11539       emit_insn (gen_cld ());
11540       emit_insn (gen_strlensi_1 (scratch1, scratch3, eoschar,
11541                                  align, constm1_rtx, scratch3));
11542       emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
11543       emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
11544     }
11545   DONE;
11548 (define_insn "strlensi_1"
11549   [(set (match_operand:SI 0 "register_operand" "=&c")
11550         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
11551                     (match_operand:QI 2 "general_operand" "a")
11552                     (match_operand:SI 3 "immediate_operand" "i")
11553                     (match_operand:SI 4 "immediate_operand" "0")] 0))
11554    (use (reg:SI 19))
11555    (clobber (match_operand:SI 1 "register_operand" "=D"))
11556    (clobber (reg:CC 17))]
11557   ""
11558   "repnz{\;| }scasb"
11559   [(set_attr "type" "str")
11560    (set_attr "mode" "QI")
11561    (set_attr "prefix_rep" "1")])
11563 ;; Peephole optimizations to clean up after cmpstr*.  This should be
11564 ;; handled in combine, but it is not currently up to the task.
11565 ;; When used for their truth value, the cmpstr* expanders generate
11566 ;; code like this:
11568 ;;   repz cmpsb
11569 ;;   seta       %al
11570 ;;   setb       %dl
11571 ;;   cmpb       %al, %dl
11572 ;;   jcc        label
11574 ;; The intermediate three instructions are unnecessary.
11576 ;; This one handles cmpstr*_nz_1...
11577 (define_peephole2
11578   [(parallel[
11579      (set (reg:CC 17)
11580           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
11581                       (mem:BLK (match_operand 5 "register_operand" ""))))
11582      (use (match_operand 6 "register_operand" ""))
11583      (use (match_operand:SI 3 "immediate_operand" ""))
11584      (use (reg:SI 19))
11585      (clobber (match_operand 0 "register_operand" ""))
11586      (clobber (match_operand 1 "register_operand" ""))
11587      (clobber (match_operand 2 "register_operand" ""))])
11588    (set (match_operand:QI 7 "register_operand" "")
11589         (gtu:QI (reg:CC 17) (const_int 0)))
11590    (set (match_operand:QI 8 "register_operand" "")
11591         (ltu:QI (reg:CC 17) (const_int 0)))
11592    (set (reg 17)
11593         (compare (match_dup 7) (match_dup 8)))
11594   ]
11595   ""
11596   [(parallel[
11597      (set (reg:CC 17)
11598           (compare:CC (mem:BLK (match_dup 4))
11599                       (mem:BLK (match_dup 5))))
11600      (use (match_dup 6))
11601      (use (match_dup 3))
11602      (use (reg:SI 19))
11603      (clobber (match_dup 0))
11604      (clobber (match_dup 1))
11605      (clobber (match_dup 2))])
11606    (clobber (match_dup 7))
11607    (clobber (match_dup 8))]
11608   "")
11610 ;; ...and this one handles cmpstr*_1.
11611 (define_peephole2
11612   [(parallel[
11613      (set (reg:CC 17)
11614           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
11615                                (const_int 0))
11616             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
11617                         (mem:BLK (match_operand 5 "register_operand" "")))
11618             (const_int 0)))
11619      (use (match_operand:SI 3 "immediate_operand" ""))
11620      (use (reg:CC 17))
11621      (use (reg:SI 19))
11622      (clobber (match_operand 0 "register_operand" ""))
11623      (clobber (match_operand 1 "register_operand" ""))
11624      (clobber (match_operand 2 "register_operand" ""))])
11625    (set (match_operand:QI 7 "register_operand" "")
11626         (gtu:QI (reg:CC 17) (const_int 0)))
11627    (set (match_operand:QI 8 "register_operand" "")
11628         (ltu:QI (reg:CC 17) (const_int 0)))
11629    (set (reg 17)
11630         (compare (match_dup 7) (match_dup 8)))
11631   ]
11632   ""
11633   [(parallel[
11634      (set (reg:CC 17)
11635           (if_then_else:CC (ne (match_dup 6)
11636                                (const_int 0))
11637             (compare:CC (mem:BLK (match_dup 4))
11638                         (mem:BLK (match_dup 5)))
11639             (const_int 0)))
11640      (use (match_dup 3))
11641      (use (reg:CC 17))
11642      (use (reg:SI 19))
11643      (clobber (match_dup 0))
11644      (clobber (match_dup 1))
11645      (clobber (match_dup 2))])
11646    (clobber (match_dup 7))
11647    (clobber (match_dup 8))]
11648   "")
11652 ;; Conditional move instructions.
11654 (define_expand "movsicc"
11655   [(set (match_operand:SI 0 "register_operand" "")
11656         (if_then_else:SI (match_operand 1 "comparison_operator" "")
11657                          (match_operand:SI 2 "general_operand" "")
11658                          (match_operand:SI 3 "general_operand" "")))]
11659   ""
11660   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
11662 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
11663 ;; the register first winds up with `sbbl $0,reg', which is also weird.
11664 ;; So just document what we're doing explicitly.
11666 (define_insn "x86_movsicc_0_m1"
11667   [(set (match_operand:SI 0 "register_operand" "=r")
11668         (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
11669           (const_int -1)
11670           (const_int 0)))
11671    (clobber (reg:CC 17))]
11672   ""
11673   "sbb{l}\\t%0, %0"
11674   ; Since we don't have the proper number of operands for an alu insn,
11675   ; fill in all the blanks.
11676   [(set_attr "type" "alu")
11677    (set_attr "memory" "none")
11678    (set_attr "imm_disp" "false")
11679    (set_attr "mode" "SI")
11680    (set_attr "length_immediate" "0")])
11682 (define_insn "*movsicc_noc"
11683   [(set (match_operand:SI 0 "register_operand" "=r,r")
11684         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
11685                                 [(reg 17) (const_int 0)])
11686                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
11687                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
11688   "TARGET_CMOVE
11689    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
11690   "@
11691    cmov%C1\\t{%2, %0|%0, %2}
11692    cmov%c1\\t{%3, %0|%0, %3}"
11693   [(set_attr "type" "icmov")
11694    (set_attr "mode" "SI")])
11696 (define_expand "movhicc"
11697   [(set (match_operand:HI 0 "register_operand" "")
11698         (if_then_else:HI (match_operand 1 "comparison_operator" "")
11699                          (match_operand:HI 2 "nonimmediate_operand" "")
11700                          (match_operand:HI 3 "nonimmediate_operand" "")))]
11701   "TARGET_CMOVE && TARGET_HIMODE_MATH"
11702   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
11704 (define_insn "*movhicc_noc"
11705   [(set (match_operand:HI 0 "register_operand" "=r,r")
11706         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
11707                                 [(reg 17) (const_int 0)])
11708                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
11709                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
11710   "TARGET_CMOVE
11711    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
11712   "@
11713    cmov%C1\\t{%2, %0|%0, %2}
11714    cmov%c1\\t{%3, %0|%0, %3}"
11715   [(set_attr "type" "icmov")
11716    (set_attr "mode" "HI")])
11718 (define_expand "movsfcc"
11719   [(set (match_operand:SF 0 "register_operand" "")
11720         (if_then_else:SF (match_operand 1 "comparison_operator" "")
11721                          (match_operand:SF 2 "register_operand" "")
11722                          (match_operand:SF 3 "register_operand" "")))]
11723   "TARGET_CMOVE"
11724   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
11726 (define_insn "*movsfcc_1"
11727   [(set (match_operand:SF 0 "register_operand" "=f,f")
11728         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
11729                                 [(reg 17) (const_int 0)])
11730                       (match_operand:SF 2 "register_operand" "f,0")
11731                       (match_operand:SF 3 "register_operand" "0,f")))]
11732   "TARGET_CMOVE"
11733   "@
11734    fcmov%F1\\t{%2, %0|%0, %2}
11735    fcmov%f1\\t{%3, %0|%0, %3}"
11736   [(set_attr "type" "fcmov")
11737    (set_attr "mode" "SF")])
11739 (define_expand "movdfcc"
11740   [(set (match_operand:DF 0 "register_operand" "")
11741         (if_then_else:DF (match_operand 1 "comparison_operator" "")
11742                          (match_operand:DF 2 "register_operand" "")
11743                          (match_operand:DF 3 "register_operand" "")))]
11744   "TARGET_CMOVE"
11745   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
11747 (define_insn "*movdfcc_1"
11748   [(set (match_operand:DF 0 "register_operand" "=f,f")
11749         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
11750                                 [(reg 17) (const_int 0)])
11751                       (match_operand:DF 2 "register_operand" "f,0")
11752                       (match_operand:DF 3 "register_operand" "0,f")))]
11753   "TARGET_CMOVE"
11754   "@
11755    fcmov%F1\\t{%2, %0|%0, %2}
11756    fcmov%f1\\t{%3, %0|%0, %3}"
11757   [(set_attr "type" "fcmov")
11758    (set_attr "mode" "DF")])
11760 (define_expand "movxfcc"
11761   [(set (match_operand:XF 0 "register_operand" "")
11762         (if_then_else:XF (match_operand 1 "comparison_operator" "")
11763                          (match_operand:XF 2 "register_operand" "")
11764                          (match_operand:XF 3 "register_operand" "")))]
11765   "TARGET_CMOVE"
11766   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
11768 (define_expand "movtfcc"
11769   [(set (match_operand:TF 0 "register_operand" "")
11770         (if_then_else:TF (match_operand 1 "comparison_operator" "")
11771                          (match_operand:TF 2 "register_operand" "")
11772                          (match_operand:TF 3 "register_operand" "")))]
11773   "TARGET_CMOVE"
11774   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
11776 (define_insn "*movxfcc_1"
11777   [(set (match_operand:XF 0 "register_operand" "=f,f")
11778         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
11779                                 [(reg 17) (const_int 0)])
11780                       (match_operand:XF 2 "register_operand" "f,0")
11781                       (match_operand:XF 3 "register_operand" "0,f")))]
11782   "TARGET_CMOVE"
11783   "@
11784    fcmov%F1\\t{%2, %0|%0, %2}
11785    fcmov%f1\\t{%3, %0|%0, %3}"
11786   [(set_attr "type" "fcmov")
11787    (set_attr "mode" "XF")])
11789 (define_insn "*movtfcc_1"
11790   [(set (match_operand:TF 0 "register_operand" "=f,f")
11791         (if_then_else:TF (match_operator 1 "fcmov_comparison_operator" 
11792                                 [(reg 17) (const_int 0)])
11793                       (match_operand:TF 2 "register_operand" "f,0")
11794                       (match_operand:TF 3 "register_operand" "0,f")))]
11795   "TARGET_CMOVE"
11796   "@
11797    fcmov%F1\\t{%2, %0|%0, %2}
11798    fcmov%f1\\t{%3, %0|%0, %3}"
11799   [(set_attr "type" "fcmov")
11800    (set_attr "mode" "XF")])
11802 ;; Misc patterns (?)
11804 ;; This pattern exists to put a dependancy on all ebp-based memory accesses.
11805 ;; Otherwise there will be nothing to keep
11806 ;; 
11807 ;; [(set (reg ebp) (reg esp))]
11808 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
11809 ;;  (clobber (eflags)]
11810 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
11812 ;; in proper program order.
11814 (define_insn "pro_epilogue_adjust_stack"
11815   [(set (match_operand:SI 0 "register_operand" "=r,r")
11816         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
11817                  (match_operand:SI 2 "immediate_operand" "i,i")))
11818    (set (match_operand:SI 3 "register_operand" "+r,r")
11819         (match_dup 3))
11820    (clobber (reg:CC 17))]
11821   ""
11822   "*
11824   switch (get_attr_type (insn))
11825     {
11826     case TYPE_IMOV:
11827       return \"mov{l}\\t{%1, %0|%0, %1}\";
11829     case TYPE_ALU:
11830       if (GET_CODE (operands[2]) == CONST_INT
11831           && (INTVAL (operands[2]) == 128
11832               || (INTVAL (operands[2]) < 0
11833                   && INTVAL (operands[2]) != -128)))
11834         {
11835           operands[2] = GEN_INT (-INTVAL (operands[2]));
11836           return \"sub{l}\\t{%2, %0|%0, %2}\";
11837         }
11838       return \"add{l}\\t{%2, %0|%0, %2}\";
11840     case TYPE_LEA:
11841       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
11842       return \"lea{l}\\t{%a2, %0|%0, %a2}\";
11844     default:
11845       abort ();
11846     }
11848   [(set (attr "type")
11849         (cond [(eq_attr "alternative" "0")
11850                  (const_string "alu")
11851                (match_operand:SI 2 "const0_operand" "")
11852                  (const_string "imov")
11853               ]
11854               (const_string "lea")))
11855    (set_attr "mode" "SI")])
11857 (define_insn "allocate_stack_worker"
11858   [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
11859    (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
11860    (clobber (match_dup 0))
11861    (clobber (reg:CC 17))]
11862   "TARGET_STACK_PROBE"
11863   "call\\t__alloca"
11864   [(set_attr "type" "multi")
11865    (set_attr "length" "5")])
11867 (define_expand "allocate_stack"
11868   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
11869                    (minus:SI (reg:SI 7)
11870                              (match_operand:SI 1 "general_operand" "")))
11871               (clobber (reg:CC 17))])
11872    (parallel [(set (reg:SI 7)
11873                    (minus:SI (reg:SI 7) (match_dup 1)))
11874               (clobber (reg:CC 17))])]
11875   "TARGET_STACK_PROBE"
11876   "
11878 #ifdef CHECK_STACK_LIMIT
11879   if (GET_CODE (operands[1]) == CONST_INT
11880       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
11881     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
11882                            operands[1]));
11883   else 
11884 #endif
11885     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
11886                                                             operands[1])));
11888   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
11889   DONE;
11892 (define_expand "builtin_setjmp_receiver"
11893   [(label_ref (match_operand 0 "" ""))]
11894   "flag_pic"
11895   "
11897   load_pic_register ();
11898   DONE;
11901 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
11903 (define_split
11904   [(set (match_operand 0 "register_operand" "")
11905         (match_operator 3 "promotable_binary_operator"
11906            [(match_operand 1 "register_operand" "")
11907             (match_operand 2 "aligned_operand" "")]))
11908    (clobber (reg:CC 17))]
11909   "! TARGET_PARTIAL_REG_STALL && reload_completed
11910    && ((GET_MODE (operands[0]) == HImode 
11911         && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
11912             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
11913        || (GET_MODE (operands[0]) == QImode 
11914            && (TARGET_PROMOTE_QImode || optimize_size)))"
11915   [(parallel [(set (match_dup 0)
11916                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
11917               (clobber (reg:CC 17))])]
11918   "operands[0] = gen_lowpart (SImode, operands[0]);
11919    operands[1] = gen_lowpart (SImode, operands[1]);
11920    if (GET_CODE (operands[3]) != ASHIFT)
11921      operands[2] = gen_lowpart (SImode, operands[2]);
11922    PUT_MODE (operands[3], SImode);")
11924 (define_split
11925   [(set (reg 17)
11926         (compare (and (match_operand 1 "aligned_operand" "")
11927                       (match_operand 2 "const_int_operand" ""))
11928                  (const_int 0)))
11929    (set (match_operand 0 "register_operand" "")
11930         (and (match_dup 1) (match_dup 2)))]
11931   "! TARGET_PARTIAL_REG_STALL && reload_completed
11932    && ix86_match_ccmode (insn, CCNOmode)
11933    && (GET_MODE (operands[0]) == HImode
11934        || (GET_MODE (operands[0]) == QImode 
11935            && (TARGET_PROMOTE_QImode || optimize_size)))"
11936   [(parallel [(set (reg:CCNO 17)
11937                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
11938                                  (const_int 0)))
11939               (set (match_dup 0)
11940                    (and:SI (match_dup 1) (match_dup 2)))])]
11941   "operands[2]
11942      = GEN_INT (INTVAL (operands[2]) & GET_MODE_MASK (GET_MODE (operands[0])));
11943    operands[0] = gen_lowpart (SImode, operands[0]);
11944    operands[1] = gen_lowpart (SImode, operands[1]);")
11946 (define_split
11947   [(set (reg 17)
11948         (compare (and (match_operand 0 "aligned_operand" "")
11949                       (match_operand 1 "const_int_operand" ""))
11950                  (const_int 0)))]
11951   "! TARGET_PARTIAL_REG_STALL && reload_completed
11952    && ix86_match_ccmode (insn, CCNOmode)
11953    && (GET_MODE (operands[0]) == HImode
11954        || (GET_MODE (operands[0]) == QImode 
11955            && (TARGET_PROMOTE_QImode || optimize_size)))"
11956   [(set (reg:CCNO 17)
11957         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
11958                       (const_int 0)))]
11959   "operands[1]
11960      = GEN_INT (INTVAL (operands[1]) & GET_MODE_MASK (GET_MODE (operands[0])));
11961    operands[0] = gen_lowpart (SImode, operands[0]);")
11963 (define_split
11964   [(set (match_operand 0 "register_operand" "")
11965         (neg (match_operand 1 "register_operand" "")))
11966    (clobber (reg:CC 17))]
11967   "! TARGET_PARTIAL_REG_STALL && reload_completed
11968    && (GET_MODE (operands[0]) == HImode
11969        || (GET_MODE (operands[0]) == QImode 
11970            && (TARGET_PROMOTE_QImode || optimize_size)))"
11971   [(parallel [(set (match_dup 0)
11972                    (neg:SI (match_dup 1)))
11973               (clobber (reg:CC 17))])]
11974   "operands[0] = gen_lowpart (SImode, operands[0]);
11975    operands[1] = gen_lowpart (SImode, operands[1]);")
11977 (define_split
11978   [(set (match_operand 0 "register_operand" "")
11979         (not (match_operand 1 "register_operand" "")))]
11980   "! TARGET_PARTIAL_REG_STALL && reload_completed
11981    && (GET_MODE (operands[0]) == HImode
11982        || (GET_MODE (operands[0]) == QImode 
11983            && (TARGET_PROMOTE_QImode || optimize_size)))"
11984   [(set (match_dup 0)
11985         (not:SI (match_dup 1)))]
11986   "operands[0] = gen_lowpart (SImode, operands[0]);
11987    operands[1] = gen_lowpart (SImode, operands[1]);")
11989 (define_split 
11990   [(set (match_operand 0 "register_operand" "")
11991         (if_then_else (match_operator 1 "comparison_operator" 
11992                                 [(reg 17) (const_int 0)])
11993                       (match_operand 2 "register_operand" "")
11994                       (match_operand 3 "register_operand" "")))]
11995   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
11996    && (GET_MODE (operands[0]) == HImode
11997        || (GET_MODE (operands[0]) == QImode 
11998            && (TARGET_PROMOTE_QImode || optimize_size)))"
11999   [(set (match_dup 0)
12000         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
12001   "operands[0] = gen_lowpart (SImode, operands[0]);
12002    operands[2] = gen_lowpart (SImode, operands[2]);
12003    operands[3] = gen_lowpart (SImode, operands[3]);")
12004                         
12006 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
12007 ;; transform a complex memory operation into two memory to register operations.
12009 ;; Don't push memory operands
12010 (define_peephole2
12011   [(set (match_operand:SI 0 "push_operand" "")
12012         (match_operand:SI 1 "memory_operand" ""))
12013    (match_scratch:SI 2 "r")]
12014   "! optimize_size && ! TARGET_PUSH_MEMORY"
12015   [(set (match_dup 2) (match_dup 1))
12016    (set (match_dup 0) (match_dup 2))]
12017   "")
12019 ;; We need to handle SFmode only, because DFmode and XFmode is split to
12020 ;; SImode pushes.
12021 (define_peephole2
12022   [(set (match_operand:SF 0 "push_operand" "")
12023         (match_operand:SF 1 "memory_operand" ""))
12024    (match_scratch:SF 2 "r")]
12025   "! optimize_size && ! TARGET_PUSH_MEMORY"
12026   [(set (match_dup 2) (match_dup 1))
12027    (set (match_dup 0) (match_dup 2))]
12028   "")
12030 (define_peephole2
12031   [(set (match_operand:HI 0 "push_operand" "")
12032         (match_operand:HI 1 "memory_operand" ""))
12033    (match_scratch:HI 2 "r")]
12034   "! optimize_size && ! TARGET_PUSH_MEMORY"
12035   [(set (match_dup 2) (match_dup 1))
12036    (set (match_dup 0) (match_dup 2))]
12037   "")
12039 (define_peephole2
12040   [(set (match_operand:QI 0 "push_operand" "")
12041         (match_operand:QI 1 "memory_operand" ""))
12042    (match_scratch:QI 2 "q")]
12043   "! optimize_size && ! TARGET_PUSH_MEMORY"
12044   [(set (match_dup 2) (match_dup 1))
12045    (set (match_dup 0) (match_dup 2))]
12046   "")
12048 ;; Don't move an immediate directly to memory when the instruction
12049 ;; gets too big.
12050 (define_peephole2
12051   [(match_scratch:SI 1 "r")
12052    (set (match_operand:SI 0 "memory_operand" "")
12053         (const_int 0))]
12054   "! optimize_size
12055    && ! TARGET_USE_MOV0
12056    && TARGET_SPLIT_LONG_MOVES
12057    && get_attr_length (insn) >= ix86_cost->large_insn
12058    && peep2_regno_dead_p (0, FLAGS_REG)"
12059   [(parallel [(set (match_dup 1) (const_int 0))
12060               (clobber (reg:CC 17))])
12061    (set (match_dup 0) (match_dup 1))]
12062   "")
12064 (define_peephole2
12065   [(match_scratch:HI 1 "r")
12066    (set (match_operand:HI 0 "memory_operand" "")
12067         (const_int 0))]
12068   "! optimize_size
12069    && ! TARGET_USE_MOV0
12070    && TARGET_SPLIT_LONG_MOVES
12071    && get_attr_length (insn) >= ix86_cost->large_insn
12072    && peep2_regno_dead_p (0, FLAGS_REG)"
12073   [(parallel [(set (match_dup 2) (const_int 0))
12074               (clobber (reg:CC 17))])
12075    (set (match_dup 0) (match_dup 1))]
12076   "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
12078 (define_peephole2
12079   [(match_scratch:QI 1 "q")
12080    (set (match_operand:QI 0 "memory_operand" "")
12081         (const_int 0))]
12082   "! optimize_size
12083    && ! TARGET_USE_MOV0
12084    && TARGET_SPLIT_LONG_MOVES
12085    && get_attr_length (insn) >= ix86_cost->large_insn
12086    && peep2_regno_dead_p (0, FLAGS_REG)"
12087   [(parallel [(set (match_dup 2) (const_int 0))
12088               (clobber (reg:CC 17))])
12089    (set (match_dup 0) (match_dup 1))]
12090   "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
12092 (define_peephole2
12093   [(match_scratch:SI 2 "r")
12094    (set (match_operand:SI 0 "memory_operand" "")
12095         (match_operand:SI 1 "immediate_operand" ""))]
12096   "! optimize_size
12097    && get_attr_length (insn) >= ix86_cost->large_insn
12098    && TARGET_SPLIT_LONG_MOVES"
12099   [(set (match_dup 2) (match_dup 1))
12100    (set (match_dup 0) (match_dup 2))]
12101   "")
12103 (define_peephole2
12104   [(match_scratch:HI 2 "r")
12105    (set (match_operand:HI 0 "memory_operand" "")
12106         (match_operand:HI 1 "immediate_operand" ""))]
12107   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
12108   && TARGET_SPLIT_LONG_MOVES"
12109   [(set (match_dup 2) (match_dup 1))
12110    (set (match_dup 0) (match_dup 2))]
12111   "")
12113 (define_peephole2
12114   [(match_scratch:QI 2 "q")
12115    (set (match_operand:QI 0 "memory_operand" "")
12116         (match_operand:QI 1 "immediate_operand" ""))]
12117   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
12118   && TARGET_SPLIT_LONG_MOVES"
12119   [(set (match_dup 2) (match_dup 1))
12120    (set (match_dup 0) (match_dup 2))]
12121   "")
12123 ;; Don't compare memory with zero, load and use a test instead.
12124 (define_peephole2
12125   [(set (reg 17)
12126         (compare (match_operand:SI 0 "memory_operand" "")
12127                  (const_int 0)))
12128    (match_scratch:SI 3 "r")]
12129   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
12130   [(set (match_dup 3) (match_dup 0))
12131    (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
12132   "")
12134 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
12135 ;; Don't split NOTs with a displacement operand, because resulting XOR
12136 ;; will not be pariable anyway.
12138 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
12139 ;; represented using a modRM byte.  The XOR replacement is long decoded,
12140 ;; so this split helps here as well.
12142 ;; Note: Can't do this as a regular split because we can't get proper
12143 ;; lifetime information then.
12145 (define_peephole2
12146   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12147         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
12148   "!optimize_size
12149    && peep2_regno_dead_p (0, FLAGS_REG)
12150    && ((TARGET_PENTIUM 
12151         && (GET_CODE (operands[0]) != MEM
12152             || !memory_displacement_operand (operands[0], SImode)))
12153        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
12154   [(parallel [(set (match_dup 0)
12155                    (xor:SI (match_dup 1) (const_int -1)))
12156               (clobber (reg:CC 17))])]
12157   "")
12159 (define_peephole2
12160   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12161         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
12162   "!optimize_size
12163    && peep2_regno_dead_p (0, FLAGS_REG)
12164    && ((TARGET_PENTIUM 
12165         && (GET_CODE (operands[0]) != MEM
12166             || !memory_displacement_operand (operands[0], HImode)))
12167        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
12168   [(parallel [(set (match_dup 0)
12169                    (xor:HI (match_dup 1) (const_int -1)))
12170               (clobber (reg:CC 17))])]
12171   "")
12173 (define_peephole2
12174   [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
12175         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
12176   "!optimize_size
12177    && peep2_regno_dead_p (0, FLAGS_REG)
12178    && ((TARGET_PENTIUM 
12179         && (GET_CODE (operands[0]) != MEM
12180             || !memory_displacement_operand (operands[0], QImode)))
12181        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
12182   [(parallel [(set (match_dup 0)
12183                    (xor:QI (match_dup 1) (const_int -1)))
12184               (clobber (reg:CC 17))])]
12185   "")
12187 ;; Non pairable "test imm, reg" instructions can be translated to
12188 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
12189 ;; byte opcode instead of two, have a short form for byte operands),
12190 ;; so do it for other CPUs as well.  Given that the value was dead,
12191 ;; this should not create any new dependancies.  Pass on the sub-word
12192 ;; versions if we're concerned about partial register stalls.
12194 (define_peephole2
12195   [(set (reg 17)
12196         (compare (and:SI (match_operand:SI 0 "register_operand" "")
12197                          (match_operand:SI 1 "immediate_operand" ""))
12198                  (const_int 0)))]
12199   "ix86_match_ccmode (insn, CCNOmode)
12200    && (true_regnum (operands[0]) != 0
12201        || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
12202    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12203   [(parallel
12204      [(set (reg:CCNO 17)
12205            (compare:CCNO (and:SI (match_dup 0)
12206                                  (match_dup 1))
12207                          (const_int 0)))
12208       (set (match_dup 0)
12209            (and:SI (match_dup 0) (match_dup 1)))])]
12210   "")
12212 ;; We don't need to handle HImode case, because it will be promoted to SImode
12213 ;; on ! TARGET_PARTIAL_REG_STALL
12215 (define_peephole2
12216   [(set (reg 17)
12217         (compare (and:QI (match_operand:QI 0 "register_operand" "")
12218                          (match_operand:QI 1 "immediate_operand" ""))
12219                  (const_int 0)))]
12220   "! TARGET_PARTIAL_REG_STALL
12221    && ix86_match_ccmode (insn, CCNOmode)
12222    && true_regnum (operands[0]) != 0
12223    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12224   [(parallel
12225      [(set (reg:CCNO 17)
12226            (compare:CCNO (and:QI (match_dup 0)
12227                                  (match_dup 1))
12228                          (const_int 0)))
12229       (set (match_dup 0)
12230            (and:QI (match_dup 0) (match_dup 1)))])]
12231   "")
12233 (define_peephole2
12234   [(set (reg 17)
12235         (compare
12236           (and:SI
12237             (zero_extract:SI
12238               (match_operand 0 "ext_register_operand" "q")
12239               (const_int 8)
12240               (const_int 8))
12241             (match_operand 1 "const_int_operand" "n"))
12242           (const_int 0)))]
12243   "! TARGET_PARTIAL_REG_STALL
12244    && ix86_match_ccmode (insn, CCNOmode)
12245    && true_regnum (operands[0]) != 0
12246    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12247   [(parallel [(set (reg:CCNO 17)
12248                    (compare:CCNO
12249                        (and:SI
12250                          (zero_extract:SI
12251                          (match_dup 0)
12252                          (const_int 8)
12253                          (const_int 8))
12254                         (match_dup 1))
12255                    (const_int 0)))
12256               (set (zero_extract:SI (match_dup 0)
12257                                     (const_int 8)
12258                                     (const_int 8))
12259                    (and:SI 
12260                      (zero_extract:SI
12261                        (match_dup 0)
12262                        (const_int 8)
12263                        (const_int 8))
12264                      (match_dup 1)))])]
12265   "")
12267 ;; Don't do logical operations with memory inputs.
12268 (define_peephole2
12269   [(match_scratch:SI 2 "r")
12270    (parallel [(set (match_operand:SI 0 "register_operand" "")
12271                    (match_operator:SI 3 "arith_or_logical_operator"
12272                      [(match_dup 0)
12273                       (match_operand:SI 1 "memory_operand" "")]))
12274               (clobber (reg:CC 17))])]
12275   "! optimize_size && ! TARGET_READ_MODIFY"
12276   [(set (match_dup 2) (match_dup 1))
12277    (parallel [(set (match_dup 0)
12278                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
12279               (clobber (reg:CC 17))])]
12280   "")
12282 (define_peephole2
12283   [(match_scratch:SI 2 "r")
12284    (parallel [(set (match_operand:SI 0 "register_operand" "")
12285                    (match_operator:SI 3 "arith_or_logical_operator"
12286                      [(match_operand:SI 1 "memory_operand" "")
12287                       (match_dup 0)]))
12288               (clobber (reg:CC 17))])]
12289   "! optimize_size && ! TARGET_READ_MODIFY"
12290   [(set (match_dup 2) (match_dup 1))
12291    (parallel [(set (match_dup 0)
12292                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
12293               (clobber (reg:CC 17))])]
12294   "")
12296 ; Don't do logical operations with memory outputs
12298 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
12299 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
12300 ; the same decoder scheduling characteristics as the original.
12302 (define_peephole2
12303   [(match_scratch:SI 2 "r")
12304    (parallel [(set (match_operand:SI 0 "memory_operand" "")
12305                    (match_operator:SI 3 "arith_or_logical_operator"
12306                      [(match_dup 0)
12307                       (match_operand:SI 1 "nonmemory_operand" "")]))
12308               (clobber (reg:CC 17))])]
12309   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
12310   [(set (match_dup 2) (match_dup 0))
12311    (parallel [(set (match_dup 2)
12312                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
12313               (clobber (reg:CC 17))])
12314    (set (match_dup 0) (match_dup 2))]
12315   "")
12317 (define_peephole2
12318   [(match_scratch:SI 2 "r")
12319    (parallel [(set (match_operand:SI 0 "memory_operand" "")
12320                    (match_operator:SI 3 "arith_or_logical_operator"
12321                      [(match_operand:SI 1 "nonmemory_operand" "")
12322                       (match_dup 0)]))
12323               (clobber (reg:CC 17))])]
12324   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
12325   [(set (match_dup 2) (match_dup 0))
12326    (parallel [(set (match_dup 2)
12327                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
12328               (clobber (reg:CC 17))])
12329    (set (match_dup 0) (match_dup 2))]
12330   "")
12332 ;; Attempt to always use XOR for zeroing registers.
12333 (define_peephole2
12334   [(set (match_operand 0 "register_operand" "")
12335         (const_int 0))]
12336   "(GET_MODE (operands[0]) == QImode
12337     || GET_MODE (operands[0]) == HImode
12338     || GET_MODE (operands[0]) == SImode)
12339    && (! TARGET_USE_MOV0 || optimize_size)
12340    && peep2_regno_dead_p (0, FLAGS_REG)"
12341   [(parallel [(set (match_dup 0) (const_int 0))
12342               (clobber (reg:CC 17))])]
12343   "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
12345 (define_peephole2
12346   [(set (strict_low_part (match_operand 0 "register_operand" ""))
12347         (const_int 0))]
12348   "(GET_MODE (operands[0]) == QImode
12349     || GET_MODE (operands[0]) == HImode)
12350    && (! TARGET_USE_MOV0 || optimize_size)
12351    && peep2_regno_dead_p (0, FLAGS_REG)"
12352   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
12353               (clobber (reg:CC 17))])])
12355 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
12356 (define_peephole2
12357   [(set (match_operand 0 "register_operand" "")
12358         (const_int -1))]
12359   "(GET_MODE (operands[0]) == HImode
12360     || GET_MODE (operands[0]) == SImode)
12361    && (optimize_size || TARGET_PENTIUM)
12362    && peep2_regno_dead_p (0, FLAGS_REG)"
12363   [(parallel [(set (match_dup 0) (const_int -1))
12364               (clobber (reg:CC 17))])]
12365   "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
12367 ;; Attempt to convert simple leas to adds. These can be created by
12368 ;; move expanders.
12369 (define_peephole2
12370   [(set (match_operand:SI 0 "register_operand" "")
12371         (plus:SI (match_dup 0)
12372                  (match_operand:SI 1 "nonmemory_operand" "")))]
12373   "peep2_regno_dead_p (0, FLAGS_REG)"
12374   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
12375               (clobber (reg:CC 17))])]
12376   "")
12378 (define_peephole2
12379   [(set (match_operand:SI 0 "register_operand" "")
12380         (mult:SI (match_dup 0)
12381                  (match_operand:SI 1 "immediate_operand" "")))]
12382   "exact_log2 (INTVAL (operands[1])) >= 0
12383    && peep2_regno_dead_p (0, FLAGS_REG)"
12384   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
12385               (clobber (reg:CC 17))])]
12386   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
12388 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
12389 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
12390 ;; many CPUs it is also faster, since special hardware to avoid esp
12391 ;; dependancies is present.
12393 ;; While some of these converisons may be done using splitters, we use peepholes
12394 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
12396 ;; Convert prologue esp substractions to push.
12397 ;; We need register to push.  In order to keep verify_flow_info happy we have
12398 ;; two choices
12399 ;; - use scratch and clobber it in order to avoid dependencies
12400 ;; - use already live register
12401 ;; We can't use the second way right now, since there is no reliable way how to
12402 ;; verify that given register is live.  First choice will also most likely in
12403 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
12404 ;; call clobbered registers are dead.  We may want to use base pointer as an
12405 ;; alternative when no register is available later.
12407 (define_peephole2
12408   [(match_scratch:SI 0 "r")
12409    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
12410               (set (reg:SI 6) (reg:SI 6))
12411               (clobber (reg:CC 17))])]
12412   "optimize_size || !TARGET_SUB_ESP_4"
12413   [(clobber (match_dup 0))
12414    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
12415               (set (reg:SI 6) (reg:SI 6))])])
12417 (define_peephole2
12418   [(match_scratch:SI 0 "r")
12419    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
12420               (set (reg:SI 6) (reg:SI 6))
12421               (clobber (reg:CC 17))])]
12422   "optimize_size || !TARGET_SUB_ESP_8"
12423   [(clobber (match_dup 0))
12424    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
12425    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
12426               (set (reg:SI 6) (reg:SI 6))])])
12428 ;; Convert esp substractions to push.
12429 (define_peephole2
12430   [(match_scratch:SI 0 "r")
12431    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
12432               (clobber (reg:CC 17))])]
12433   "optimize_size || !TARGET_SUB_ESP_4"
12434   [(clobber (match_dup 0))
12435    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
12437 (define_peephole2
12438   [(match_scratch:SI 0 "r")
12439    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
12440               (clobber (reg:CC 17))])]
12441   "optimize_size || !TARGET_SUB_ESP_8"
12442   [(clobber (match_dup 0))
12443    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
12444    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
12446 ;; Convert epilogue deallocator to pop.
12447 (define_peephole2
12448   [(match_scratch:SI 0 "r")
12449    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12450               (set (reg:SI 6) (reg:SI 6))
12451               (clobber (reg:CC 17))])]
12452   "optimize_size || !TARGET_ADD_ESP_4"
12453   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12454               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12455               (set (reg:SI 6) (reg:SI 6))])]
12456   "")
12458 ;; Two pops case is tricky, since pop causes dependency on destination register.
12459 ;; We use two registers if available.
12460 (define_peephole2
12461   [(match_scratch:SI 0 "r")
12462    (match_scratch:SI 1 "r")
12463    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
12464               (set (reg:SI 6) (reg:SI 6))
12465               (clobber (reg:CC 17))])]
12466   "optimize_size || !TARGET_ADD_ESP_8"
12467   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12468               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12469               (set (reg:SI 6) (reg:SI 6))])
12470    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
12471               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12472   "")
12474 (define_peephole2
12475   [(match_scratch:SI 0 "r")
12476    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
12477               (set (reg:SI 6) (reg:SI 6))
12478               (clobber (reg:CC 17))])]
12479   "optimize_size"
12480   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12481               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12482               (set (reg:SI 6) (reg:SI 6))])
12483    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12484               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12485   "")
12487 ;; Convert esp additions to pop.
12488 (define_peephole2
12489   [(match_scratch:SI 0 "r")
12490    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12491               (clobber (reg:CC 17))])]
12492   ""
12493   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12494               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12495   "")
12497 ;; Two pops case is tricky, since pop causes dependency on destination register.
12498 ;; We use two registers if available.
12499 (define_peephole2
12500   [(match_scratch:SI 0 "r")
12501    (match_scratch:SI 1 "r")
12502    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
12503               (clobber (reg:CC 17))])]
12504   ""
12505   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12506               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
12507    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
12508               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12509   "")
12511 (define_peephole2
12512   [(match_scratch:SI 0 "r")
12513    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
12514               (clobber (reg:CC 17))])]
12515   "optimize_size"
12516   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12517               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
12518    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12519               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12520   "")
12522 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
12523 ;; required and register dies.
12524 (define_peephole2
12525   [(set (reg 17)
12526         (compare (match_operand:SI 0 "register_operand" "")
12527                  (match_operand:SI 1 "incdec_operand" "")))]
12528   "ix86_match_ccmode (insn, CCGCmode)
12529    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12530   [(parallel [(set (reg:CCGC 17)
12531                    (compare:CCGC (match_dup 0)
12532                                  (match_dup 1)))
12533               (clobber (match_dup 0))])]
12534   "")
12536 (define_peephole2
12537   [(set (reg 17)
12538         (compare (match_operand:HI 0 "register_operand" "")
12539                  (match_operand:HI 1 "incdec_operand" "")))]
12540   "ix86_match_ccmode (insn, CCGCmode)
12541    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12542   [(parallel [(set (reg:CCGC 17)
12543                    (compare:CCGC (match_dup 0)
12544                                  (match_dup 1)))
12545               (clobber (match_dup 0))])]
12546   "")
12548 (define_peephole2
12549   [(set (reg 17)
12550         (compare (match_operand:QI 0 "register_operand" "")
12551                  (match_operand:QI 1 "incdec_operand" "")))]
12552   "ix86_match_ccmode (insn, CCGCmode)
12553    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12554   [(parallel [(set (reg:CCGC 17)
12555                    (compare:CCGC (match_dup 0)
12556                                  (match_dup 1)))
12557               (clobber (match_dup 0))])]
12558   "")
12560 ;; Convert compares with 128 to shorter add -128
12561 (define_peephole2
12562   [(set (reg 17)
12563         (compare (match_operand:SI 0 "register_operand" "")
12564                  (const_int 128)))]
12565   "ix86_match_ccmode (insn, CCGCmode)
12566    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12567   [(parallel [(set (reg:CCGC 17)
12568                    (compare:CCGC (match_dup 0)
12569                                  (const_int 128)))
12570               (clobber (match_dup 0))])]
12571   "")
12573 (define_peephole2
12574   [(set (reg 17)
12575         (compare (match_operand:HI 0 "register_operand" "")
12576                  (const_int 128)))]
12577   "ix86_match_ccmode (insn, CCGCmode)
12578    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12579   [(parallel [(set (reg:CCGC 17)
12580                    (compare:CCGC (match_dup 0)
12581                                  (const_int 128)))
12582               (clobber (match_dup 0))])]
12583   "")
12585 ;; Call-value patterns last so that the wildcard operand does not
12586 ;; disrupt insn-recog's switch tables.
12588 (define_insn "*call_value_pop_0"
12589   [(set (match_operand 0 "" "")
12590         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
12591               (match_operand:SI 2 "" "")))
12592    (set (reg:SI 7) (plus:SI (reg:SI 7)
12593                             (match_operand:SI 3 "immediate_operand" "")))]
12594   ""
12595   "*
12597   if (SIBLING_CALL_P (insn))
12598     return \"jmp\\t%P1\";
12599   else
12600     return \"call\\t%P1\";
12602   [(set_attr "type" "callv")])
12604 (define_insn "*call_value_pop_1"
12605   [(set (match_operand 0 "" "")
12606         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
12607               (match_operand:SI 2 "" "")))
12608    (set (reg:SI 7) (plus:SI (reg:SI 7)
12609                             (match_operand:SI 3 "immediate_operand" "i")))]
12610   ""
12611   "*
12613   if (constant_call_address_operand (operands[1], QImode))
12614     {
12615       if (SIBLING_CALL_P (insn))
12616         return \"jmp\\t%P1\";
12617       else
12618         return \"call\\t%P1\";
12619     }
12620   if (SIBLING_CALL_P (insn))
12621     return \"jmp\\t%A1\";
12622   else
12623     return \"call\\t%A1\";
12625   [(set_attr "type" "callv")])
12627 (define_insn "*call_value_0"
12628   [(set (match_operand 0 "" "")
12629         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
12630               (match_operand:SI 2 "" "")))]
12631   ""
12632   "*
12634   if (SIBLING_CALL_P (insn))
12635     return \"jmp\\t%P1\";
12636   else
12637     return \"call\\t%P1\";
12639   [(set_attr "type" "callv")])
12641 (define_insn "*call_value_1"
12642   [(set (match_operand 0 "" "")
12643         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
12644               (match_operand:SI 2 "" "")))]
12645   ""
12646   "*
12648   if (constant_call_address_operand (operands[1], QImode))
12649     {
12650       if (SIBLING_CALL_P (insn))
12651         return \"jmp\\t%P1\";
12652       else
12653         return \"call\\t%P1\";
12654     }
12655   if (SIBLING_CALL_P (insn))
12656     return \"jmp\\t%A1\";
12657   else
12658     return \"call\\t%A1\";
12660   [(set_attr "type" "callv")])
12662 (define_insn "trap"
12663   [(trap_if (const_int 1) (const_int 5))]
12664   ""
12665   "int\\t$5")
12667 ;;; ix86 doesn't have conditional trap instructions, but we fake them
12668 ;;; for the sake of bounds checking.  By emitting bounds checks as
12669 ;;; conditional traps rather than as conditional jumps around
12670 ;;; unconditional traps we avoid introducing spurious basic-block
12671 ;;; boundaries and facilitate elimination of redundant checks.  In
12672 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
12673 ;;; interrupt 5.
12674 ;;; 
12675 ;;; FIXME: Static branch prediction rules for ix86 are such that
12676 ;;; forward conditional branches predict as untaken.  As implemented
12677 ;;; below, pseudo conditional traps violate that rule.  We should use
12678 ;;; .pushsection/.popsection to place all of the `int 5's in a special
12679 ;;; section loaded at the end of the text segment and branch forward
12680 ;;; there on bounds-failure, and then jump back immediately (in case
12681 ;;; the system chooses to ignore bounds violations, or to report
12682 ;;; violations and continue execution).
12684 (define_expand "conditional_trap"
12685   [(trap_if (match_operator 0 "comparison_operator"
12686              [(match_dup 2) (const_int 0)])
12687             (match_operand 1 "const_int_operand" ""))]
12688   ""
12689   "
12691   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
12692                               ix86_expand_compare (GET_CODE (operands[0]),
12693                                                    NULL_RTX, NULL_RTX),
12694                               operands[1]));
12695   DONE;
12698 (define_insn ""
12699   [(trap_if (match_operator 0 "comparison_operator"
12700              [(reg 17) (const_int 0)])
12701             (match_operand 1 "const_int_operand" ""))]
12702   ""
12703   "*
12705   operands[2] = gen_label_rtx ();
12706   output_asm_insn (\"j%c0\\t%l2\; int\\t%1\", operands);
12707   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
12708                              CODE_LABEL_NUMBER (operands[2]));
12709   RET;
12712         ;; Pentium III SIMD instructions.
12714 ;; Moves for SSE/MMX regs.
12716 (define_insn "movv4sf_internal"
12717   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
12718         (match_operand:V4SF 1 "general_operand" "xm,x"))]
12719   "TARGET_SSE"
12720   ;; @@@ let's try to use movaps here.
12721   "movaps\\t{%1, %0|%0, %1}"
12722   [(set_attr "type" "sse")])
12724 (define_insn "movv4si_internal"
12725   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
12726         (match_operand:V4SI 1 "general_operand" "xm,x"))]
12727   "TARGET_SSE"
12728   ;; @@@ let's try to use movaps here.
12729   "movaps\\t{%1, %0|%0, %1}"
12730   [(set_attr "type" "sse")])
12732 (define_insn "movv8qi_internal"
12733   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
12734         (match_operand:V8QI 1 "general_operand" "ym,y"))]
12735   "TARGET_MMX"
12736   "movq\\t{%1, %0|%0, %1}"
12737   [(set_attr "type" "mmx")])
12739 (define_insn "movv4hi_internal"
12740   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
12741         (match_operand:V4HI 1 "general_operand" "ym,y"))]
12742   "TARGET_MMX"
12743   "movq\\t{%1, %0|%0, %1}"
12744   [(set_attr "type" "mmx")])
12746 (define_insn "movv2si_internal"
12747   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
12748         (match_operand:V2SI 1 "general_operand" "ym,y"))]
12749   "TARGET_MMX"
12750   "movq\\t{%1, %0|%0, %1}"
12751   [(set_attr "type" "mmx")])
12753 (define_expand "movti"
12754   [(set (match_operand:TI 0 "general_operand" "")
12755         (match_operand:TI 1 "general_operand" ""))]
12756   "TARGET_SSE"
12757   "
12759   /* For constants other than zero into memory.  We do not know how the
12760      instructions used to build constants modify the upper 64 bits
12761      of the register, once we have that information we may be able
12762      to handle some of them more efficiently.  */
12763   if ((reload_in_progress | reload_completed) == 0
12764       && register_operand (operands[0], TImode)
12765       && CONSTANT_P (operands[1]))
12766     {
12767       rtx addr = gen_reg_rtx (Pmode);
12769       emit_move_insn (addr, XEXP (force_const_mem (TImode, operands[1]), 0));
12770       operands[1] = gen_rtx_MEM (TImode, addr);
12771     }
12773   /* Make operand1 a register if it isn't already.  */
12774   if ((reload_in_progress | reload_completed) == 0
12775       && !register_operand (operands[0], TImode)
12776       && !register_operand (operands[1], TImode)
12777       && operands[1] != CONST0_RTX (TImode))
12778     {
12779       rtx temp = force_reg (TImode, operands[1]);
12780       emit_move_insn (operands[0], temp);
12781       DONE;
12782     }
12785 (define_expand "movv4sf"
12786   [(set (match_operand:V4SF 0 "general_operand" "")
12787         (match_operand:V4SF 1 "general_operand" ""))]
12788   "TARGET_SSE"
12789   "
12791   /* For constants other than zero into memory.  We do not know how the
12792      instructions used to build constants modify the upper 64 bits
12793      of the register, once we have that information we may be able
12794      to handle some of them more efficiently.  */
12795   if ((reload_in_progress | reload_completed) == 0
12796       && register_operand (operands[0], V4SFmode)
12797       && CONSTANT_P (operands[1]))
12798     {
12799       rtx addr = gen_reg_rtx (Pmode);
12801       emit_move_insn (addr, XEXP (force_const_mem (V4SFmode, operands[1]), 0));
12802       operands[1] = gen_rtx_MEM (V4SFmode, addr);
12803     }
12805   /* Make operand1 a register if it isn't already.  */
12806   if ((reload_in_progress | reload_completed) == 0
12807       && !register_operand (operands[0], V4SFmode)
12808       && !register_operand (operands[1], V4SFmode)
12809       && operands[1] != CONST0_RTX (V4SFmode))
12810     {
12811       rtx temp = force_reg (V4SFmode, operands[1]);
12812       emit_move_insn (operands[0], temp);
12813       DONE;
12814     }
12817 (define_expand "movv4si"
12818   [(set (match_operand:V4SI 0 "general_operand" "")
12819         (match_operand:V4SI 1 "general_operand" ""))]
12820   "TARGET_MMX"
12821   "
12823   /* For constants other than zero into memory.  We do not know how the
12824      instructions used to build constants modify the upper 64 bits
12825      of the register, once we have that information we may be able
12826      to handle some of them more efficiently.  */
12827   if ((reload_in_progress | reload_completed) == 0
12828       && register_operand (operands[0], V4SImode)
12829       && CONSTANT_P (operands[1]))
12830     {
12831       rtx addr = gen_reg_rtx (Pmode);
12833       emit_move_insn (addr, XEXP (force_const_mem (V4SImode, operands[1]), 0));
12834       operands[1] = gen_rtx_MEM (V4SImode, addr);
12835     }
12837   /* Make operand1 a register if it isn't already.  */
12838   if ((reload_in_progress | reload_completed) == 0
12839       && !register_operand (operands[0], V4SImode)
12840       && !register_operand (operands[1], V4SImode)
12841       && operands[1] != CONST0_RTX (V4SImode))
12842     {
12843       rtx temp = force_reg (V4SImode, operands[1]);
12844       emit_move_insn (operands[0], temp);
12845       DONE;
12846     }
12849 (define_expand "movv2si"
12850   [(set (match_operand:V2SI 0 "general_operand" "")
12851         (match_operand:V2SI 1 "general_operand" ""))]
12852   "TARGET_MMX"
12853   "
12855   /* For constants other than zero into memory.  We do not know how the
12856      instructions used to build constants modify the upper 64 bits
12857      of the register, once we have that information we may be able
12858      to handle some of them more efficiently.  */
12859   if ((reload_in_progress | reload_completed) == 0
12860       && register_operand (operands[0], V2SImode)
12861       && CONSTANT_P (operands[1]))
12862     {
12863       rtx addr = gen_reg_rtx (Pmode);
12865       emit_move_insn (addr, XEXP (force_const_mem (V2SImode, operands[1]), 0));
12866       operands[1] = gen_rtx_MEM (V2SImode, addr);
12867     }
12869   /* Make operand1 a register if it isn't already.  */
12870   if ((reload_in_progress | reload_completed) == 0
12871       && !register_operand (operands[0], V2SImode)
12872       && !register_operand (operands[1], V2SImode)
12873       && operands[1] != CONST0_RTX (V2SImode))
12874     {
12875       rtx temp = force_reg (V2SImode, operands[1]);
12876       emit_move_insn (operands[0], temp);
12877       DONE;
12878     }
12881 (define_expand "movv4hi"
12882   [(set (match_operand:V4HI 0 "general_operand" "")
12883         (match_operand:V4HI 1 "general_operand" ""))]
12884   "TARGET_MMX"
12885   "
12887   /* For constants other than zero into memory.  We do not know how the
12888      instructions used to build constants modify the upper 64 bits
12889      of the register, once we have that information we may be able
12890      to handle some of them more efficiently.  */
12891   if ((reload_in_progress | reload_completed) == 0
12892       && register_operand (operands[0], V4HImode)
12893       && CONSTANT_P (operands[1]))
12894     {
12895       rtx addr = gen_reg_rtx (Pmode);
12897       emit_move_insn (addr, XEXP (force_const_mem (V4HImode, operands[1]), 0));
12898       operands[1] = gen_rtx_MEM (V4HImode, addr);
12899     }
12901   /* Make operand1 a register if it isn't already.  */
12902   if ((reload_in_progress | reload_completed) == 0
12903       && !register_operand (operands[0], V4HImode)
12904       && !register_operand (operands[1], V4HImode)
12905       && operands[1] != CONST0_RTX (V4HImode))
12906     {
12907       rtx temp = force_reg (V4HImode, operands[1]);
12908       emit_move_insn (operands[0], temp);
12909       DONE;
12910     }
12913 (define_expand "movv8qi"
12914   [(set (match_operand:V8QI 0 "general_operand" "")
12915         (match_operand:V8QI 1 "general_operand" ""))]
12916   "TARGET_MMX"
12917   "
12919   /* For constants other than zero into memory.  We do not know how the
12920      instructions used to build constants modify the upper 64 bits
12921      of the register, once we have that information we may be able
12922      to handle some of them more efficiently.  */
12923   if ((reload_in_progress | reload_completed) == 0
12924       && register_operand (operands[0], V8QImode)
12925       && CONSTANT_P (operands[1]))
12926     {
12927       rtx addr = gen_reg_rtx (Pmode);
12929       emit_move_insn (addr, XEXP (force_const_mem (V8QImode, operands[1]), 0));
12930       operands[1] = gen_rtx_MEM (V8QImode, addr);
12931     }
12933   /* Make operand1 a register if it isn't already.  */
12934   if ((reload_in_progress | reload_completed) == 0
12935       && !register_operand (operands[0], V8QImode)
12936       && !register_operand (operands[1], V8QImode)
12937       && operands[1] != CONST0_RTX (V8QImode))
12938     {
12939       rtx temp = force_reg (V8QImode, operands[1]);
12940       emit_move_insn (operands[0], temp);
12941       DONE;
12942     }
12945 (define_insn_and_split "*pushti"
12946   [(set (match_operand:TI 0 "push_operand" "=<")
12947         (match_operand:TI 1 "nonmemory_operand" "x"))]
12948   "TARGET_SSE"
12949   "#"
12950   ""
12951   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
12952    (set (mem:TI (reg:SI 7)) (match_dup 1))]
12953   ""
12954   [(set_attr "type" "sse")])
12956 (define_insn_and_split "*pushv4sf"
12957   [(set (match_operand:V4SF 0 "push_operand" "=<")
12958         (match_operand:V4SF 1 "nonmemory_operand" "x"))]
12959   "TARGET_SSE"
12960   "#"
12961   ""
12962   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
12963    (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
12964   ""
12965   [(set_attr "type" "sse")])
12967 (define_insn_and_split "*pushv4si"
12968   [(set (match_operand:V4SI 0 "push_operand" "=<")
12969         (match_operand:V4SI 1 "nonmemory_operand" "x"))]
12970   "TARGET_SSE"
12971   "#"
12972   ""
12973   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
12974    (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
12975   ""
12976   [(set_attr "type" "sse")])
12978 (define_insn_and_split "*pushv2si"
12979   [(set (match_operand:V2SI 0 "push_operand" "=<")
12980         (match_operand:V2SI 1 "nonmemory_operand" "y"))]
12981   "TARGET_MMX"
12982   "#"
12983   ""
12984   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
12985    (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
12986   ""
12987   [(set_attr "type" "mmx")])
12989 (define_insn_and_split "*pushv4hi"
12990   [(set (match_operand:V4HI 0 "push_operand" "=<")
12991         (match_operand:V4HI 1 "nonmemory_operand" "y"))]
12992   "TARGET_MMX"
12993   "#"
12994   ""
12995   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
12996    (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
12997   ""
12998   [(set_attr "type" "mmx")])
13000 (define_insn_and_split "*pushv8qi"
13001   [(set (match_operand:V8QI 0 "push_operand" "=<")
13002         (match_operand:V8QI 1 "nonmemory_operand" "y"))]
13003   "TARGET_MMX"
13004   "#"
13005   ""
13006   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
13007    (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
13008   ""
13009   [(set_attr "type" "mmx")])
13011 (define_insn "movti_internal"
13012   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
13013         (match_operand:TI 1 "general_operand" "xm,x"))]
13014   "TARGET_SSE"
13015   "@
13016    movaps\\t{%1, %0|%0, %1}
13017    movaps\\t{%1, %0|%0, %1}"
13018   [(set_attr "type" "sse")])
13020 ;; These two patterns are useful for specifying exactly whether to use
13021 ;; movaps or movups
13022 (define_insn "sse_movaps"
13023   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13024         (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 38))]
13025   "TARGET_SSE"
13026   "@
13027    movaps\\t{%1, %0|%0, %1}
13028    movaps\\t{%1, %0|%0, %1}"
13029   [(set_attr "type" "sse")])
13031 (define_insn "sse_movups"
13032   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13033         (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 39))]
13034   "TARGET_SSE"
13035   "@
13036    movups\\t{%1, %0|%0, %1}
13037    movups\\t{%1, %0|%0, %1}"
13038   [(set_attr "type" "sse")])
13041 ;; SSE Strange Moves.
13043 (define_insn "sse_movmskps"
13044   [(set (match_operand:SI 0 "register_operand" "=r")
13045         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
13046   "TARGET_SSE"
13047   "movmskps\\t{%1, %0|%0, %1}"
13048   [(set_attr "type" "sse")])
13050 (define_insn "mmx_pmovmskb"
13051   [(set (match_operand:SI 0 "register_operand" "=r")
13052         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
13053   "TARGET_SSE"
13054   "pmovmskb\\t{%1, %0|%0, %1}"
13055   [(set_attr "type" "sse")])
13057 (define_insn "mmx_maskmovq"
13058   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
13059         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
13060                       (match_operand:V8QI 2 "register_operand" "y")] 32))]
13061   "TARGET_SSE"
13062   ;; @@@ check ordering of operands in intel/nonintel syntax
13063   "maskmovq\\t{%2, %1|%1, %2}"
13064   [(set_attr "type" "sse")])
13066 (define_insn "sse_movntv4sf"
13067   [(set (match_operand:V4SF 0 "memory_operand" "=m")
13068         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
13069   "TARGET_SSE"
13070   "movntps\\t{%1, %0|%0, %1}"
13071   [(set_attr "type" "sse")])
13073 (define_insn "sse_movntdi"
13074   [(set (match_operand:DI 0 "memory_operand" "=m")
13075         (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
13076   "TARGET_SSE"
13077   "movntq\\t{%1, %0|%0, %1}"
13078   [(set_attr "type" "sse")])
13080 (define_insn "sse_movhlps"
13081   [(set (match_operand:V4SF 0 "register_operand" "=x")
13082         (vec_merge:V4SF
13083          (match_operand:V4SF 1 "register_operand" "0")
13084          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
13085                           (parallel [(const_int 2)
13086                                      (const_int 3)
13087                                      (const_int 0)
13088                                      (const_int 1)]))
13089          (const_int 3)))]
13090   "TARGET_SSE"
13091   "movhlps\\t{%2, %0|%0, %2}"
13092   [(set_attr "type" "sse")])
13094 (define_insn "sse_movlhps"
13095   [(set (match_operand:V4SF 0 "register_operand" "=x")
13096         (vec_merge:V4SF
13097          (match_operand:V4SF 1 "register_operand" "0")
13098          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
13099                           (parallel [(const_int 2)
13100                                      (const_int 3)
13101                                      (const_int 0)
13102                                      (const_int 1)]))
13103          (const_int 12)))]
13104   "TARGET_SSE"
13105   "movlhps\\t{%2, %0|%0, %2}"
13106   [(set_attr "type" "sse")])
13108 (define_insn "sse_movhps"
13109   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13110         (vec_merge:V4SF
13111          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
13112          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
13113          (const_int 12)))]
13114   "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
13115   "movhps\\t{%2, %0|%0, %2}"
13116   [(set_attr "type" "sse")])
13118 (define_insn "sse_movlps"
13119   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13120         (vec_merge:V4SF
13121          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
13122          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
13123          (const_int 3)))]
13124   "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
13125   "movlps\\t{%2, %0|%0, %2}"
13126   [(set_attr "type" "sse")])
13128 (define_insn "sse_loadss"
13129   [(set (match_operand:V4SF 0 "register_operand" "=x")
13130         (vec_merge:V4SF
13131          (match_operand:V4SF 1 "memory_operand" "m")
13132          (vec_duplicate:V4SF (float:SF (const_int 0)))
13133          (const_int 1)))]
13134   "TARGET_SSE"
13135   "movss\\t{%1, %0|%0, %1}"
13136   [(set_attr "type" "sse")])
13138 (define_insn "sse_movss"
13139   [(set (match_operand:V4SF 0 "register_operand" "=x")
13140         (vec_merge:V4SF
13141          (match_operand:V4SF 1 "register_operand" "0")
13142          (match_operand:V4SF 2 "register_operand" "x")
13143          (const_int 1)))]
13144   "TARGET_SSE"
13145   "movss\\t{%2, %0|%0, %2}"
13146   [(set_attr "type" "sse")])
13148 (define_insn "sse_storess"
13149   [(set (match_operand:SF 0 "memory_operand" "=m")
13150         (vec_select:SF
13151          (match_operand:V4SF 1 "register_operand" "x")
13152          (parallel [(const_int 0)])))]
13153   "TARGET_SSE"
13154   "movss\\t{%1, %0|%0, %1}"
13155   [(set_attr "type" "sse")])
13157 (define_insn "sse_shufps"
13158   [(set (match_operand:V4SF 0 "register_operand" "=x")
13159         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
13160                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
13161                       (match_operand:SI 3 "immediate_operand" "i")] 41))]
13162   "TARGET_SSE"
13163   ;; @@@ check operand order for intel/nonintel syntax
13164   "shufps\\t{%3, %2, %0|%0, %2, %3}"
13165   [(set_attr "type" "sse")])
13168 ;; SSE arithmetic
13170 (define_insn "addv4sf3"
13171   [(set (match_operand:V4SF 0 "register_operand" "=x")
13172         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
13173                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13174   "TARGET_SSE"
13175   "addps\\t{%2, %0|%0, %2}"
13176   [(set_attr "type" "sse")])
13178 (define_insn "vmaddv4sf3"
13179   [(set (match_operand:V4SF 0 "register_operand" "=x")
13180         (vec_merge:V4SF (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
13181                                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13182                         (match_dup 1)
13183                         (const_int 1)))]
13184   "TARGET_SSE"
13185   "addss\\t{%2, %0|%0, %2}"
13186   [(set_attr "type" "sse")])
13188 (define_insn "subv4sf3"
13189   [(set (match_operand:V4SF 0 "register_operand" "=x")
13190         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
13191                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13192   "TARGET_SSE"
13193   "subps\\t{%2, %0|%0, %2}"
13194   [(set_attr "type" "sse")])
13196 (define_insn "vmsubv4sf3"
13197   [(set (match_operand:V4SF 0 "register_operand" "=x")
13198         (vec_merge:V4SF (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
13199                                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13200                         (match_dup 1)
13201                         (const_int 1)))]
13202   "TARGET_SSE"
13203   "subss\\t{%2, %0|%0, %2}"
13204   [(set_attr "type" "sse")])
13206 (define_insn "mulv4sf3"
13207   [(set (match_operand:V4SF 0 "register_operand" "=x")
13208         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
13209                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13210   "TARGET_SSE"
13211   "mulps\\t{%2, %0|%0, %2}"
13212   [(set_attr "type" "sse")])
13214 (define_insn "vmmulv4sf3"
13215   [(set (match_operand:V4SF 0 "register_operand" "=x")
13216         (vec_merge:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
13217                                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13218                         (match_dup 1)
13219                         (const_int 1)))]
13220   "TARGET_SSE"
13221   "mulss\\t{%2, %0|%0, %2}"
13222   [(set_attr "type" "sse")])
13224 (define_insn "divv4sf3"
13225   [(set (match_operand:V4SF 0 "register_operand" "=x")
13226         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
13227                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13228   "TARGET_SSE"
13229   "divps\\t{%2, %0|%0, %2}"
13230   [(set_attr "type" "sse")])
13232 (define_insn "vmdivv4sf3"
13233   [(set (match_operand:V4SF 0 "register_operand" "=x")
13234         (vec_merge:V4SF (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
13235                                   (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13236                         (match_dup 1)
13237                         (const_int 1)))]
13238   "TARGET_SSE"
13239   "divss\\t{%2, %0|%0, %2}"
13240   [(set_attr "type" "sse")])
13243 ;; SSE square root/reciprocal
13245 (define_insn "rcpv4sf2"
13246   [(set (match_operand:V4SF 0 "register_operand" "=x")
13247         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42))]
13248   "TARGET_SSE"
13249   "rcpps\\t{%1, %0|%0, %1}"
13250   [(set_attr "type" "sse")])
13252 (define_insn "vmrcpv4sf2"
13253   [(set (match_operand:V4SF 0 "register_operand" "=x")
13254         (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42)
13255                         (match_operand:V4SF 2 "register_operand" "0")
13256                         (const_int 1)))]
13257   "TARGET_SSE"
13258   "rcpss\\t{%1, %0|%0, %1}"
13259   [(set_attr "type" "sse")])
13261 (define_insn "rsqrtv4sf2"
13262   [(set (match_operand:V4SF 0 "register_operand" "=x")
13263         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43))]
13264   "TARGET_SSE"
13265   "rsqrtps\\t{%1, %0|%0, %1}"
13266   [(set_attr "type" "sse")])
13268 (define_insn "vmrsqrtv4sf2"
13269   [(set (match_operand:V4SF 0 "register_operand" "=x")
13270         (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43)
13271                         (match_operand:V4SF 2 "register_operand" "0")
13272                         (const_int 1)))]
13273   "TARGET_SSE"
13274   "rsqrtss\\t{%1, %0|%0, %1}"
13275   [(set_attr "type" "sse")])
13277 (define_insn "sqrtv4sf2"
13278   [(set (match_operand:V4SF 0 "register_operand" "=x")
13279         (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm")))]
13280   "TARGET_SSE"
13281   "sqrtps\\t{%1, %0|%0, %1}"
13282   [(set_attr "type" "sse")])
13284 (define_insn "vmsqrtv4sf2"
13285   [(set (match_operand:V4SF 0 "register_operand" "=x")
13286         (vec_merge:V4SF (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm"))
13287                         (match_operand:V4SF 2 "register_operand" "0")
13288                         (const_int 1)))]
13289   "TARGET_SSE"
13290   "sqrtss\\t{%1, %0|%0, %1}"
13291   [(set_attr "type" "sse")])
13294 ;; SSE logical operations.
13296 ;; These are not called andti3 etc. because we really really don't want
13297 ;; the compiler to widen DImode ands to TImode ands and then try to move
13298 ;; into DImode subregs of SSE registers, and them together, and move out
13299 ;; of DImode subregs again!
13301 (define_insn "sse_andti3"
13302   [(set (match_operand:TI 0 "register_operand" "=x")
13303         (and:TI (match_operand:TI 1 "register_operand" "0")
13304                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
13305   "TARGET_SSE"
13306   "andps\\t{%2, %0|%0, %2}"
13307   [(set_attr "type" "sse")])
13309 (define_insn "sse_nandti3"
13310   [(set (match_operand:TI 0 "register_operand" "=x")
13311         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
13312                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
13313   "TARGET_SSE"
13314   "andnps\\t{%2, %0|%0, %2}"
13315   [(set_attr "type" "sse")])
13317 (define_insn "sse_iorti3"
13318   [(set (match_operand:TI 0 "register_operand" "=x")
13319         (ior:TI (match_operand:TI 1 "register_operand" "0")
13320                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
13321   "TARGET_SSE"
13322   "iorps\\t{%2, %0|%0, %2}"
13323   [(set_attr "type" "sse")])
13325 (define_insn "sse_xorti3"
13326   [(set (match_operand:TI 0 "register_operand" "=x")
13327         (xor:TI (match_operand:TI 1 "register_operand" "0")
13328                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
13329   "TARGET_SSE"
13330   "xorps\\t{%2, %0|%0, %2}"
13331   [(set_attr "type" "sse")])
13333 ;; Use xor, but don't show input operands so they aren't live before
13334 ;; this insn.
13335 (define_insn "sse_clrti"
13336   [(set (match_operand:TI 0 "register_operand" "=x")
13337         (unspec:TI [(const_int 0)] 45))]
13338   "TARGET_SSE"
13339   "xorps\\t{%0, %0|%0, %0}"
13340   [(set_attr "type" "sse")])
13343 ;; SSE mask-generating compares
13345 (define_insn "maskcmpv4sf3"
13346   [(set (match_operand:V4SI 0 "register_operand" "=x")
13347         (match_operator:V4SI 3 "sse_comparison_operator"
13348                              [(match_operand:V4SF 1 "register_operand" "0")
13349                               (match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
13350   "TARGET_SSE"
13351   "*
13353   switch (GET_CODE (operands[3]))
13354     {
13355     case EQ:
13356       return \"cmpeqps\\t{%2, %0|%0, %2}\";
13357     case LT:
13358       return \"cmpltps\\t{%2, %0|%0, %2}\";
13359     case LE:
13360       return \"cmpleps\\t{%2, %0|%0, %2}\";
13361     case UNORDERED:
13362       return \"cmpunordps\\t{%2, %0|%0, %2}\";
13363     default:
13364       abort ();
13365     }
13367   [(set_attr "type" "sse")])
13369 (define_insn "maskncmpv4sf3"
13370   [(set (match_operand:V4SI 0 "register_operand" "=x")
13371         (not:V4SI
13372          (match_operator:V4SI 3 "sse_comparison_operator"
13373                               [(match_operand:V4SF 1 "register_operand" "0")
13374                                (match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
13375   "TARGET_SSE"
13376   "*
13378   switch (GET_CODE (operands[3]))
13379     {
13380     case EQ:
13381       return \"cmpneqps\\t{%2, %0|%0, %2}\";
13382     case LT:
13383       return \"cmpnltps\\t{%2, %0|%0, %2}\";
13384     case LE:
13385       return \"cmpnleps\\t{%2, %0|%0, %2}\";
13386     case UNORDERED:
13387       return \"cmpordps\\t{%2, %0|%0, %2}\";
13388     default:
13389       abort ();
13390     }
13392   [(set_attr "type" "sse")])
13394 (define_insn "vmmaskcmpv4sf3"
13395   [(set (match_operand:V4SI 0 "register_operand" "=x")
13396         (vec_merge:V4SI
13397          (match_operator:V4SI 3 "sse_comparison_operator"
13398                               [(match_operand:V4SF 1 "register_operand" "0")
13399                                (match_operand:V4SF 2 "nonimmediate_operand" "x")])
13400          (match_dup 1)
13401          (const_int 1)))]
13402   "TARGET_SSE"
13403   "*
13405   switch (GET_CODE (operands[3]))
13406     {
13407     case EQ:
13408       return \"cmpeqss\\t{%2, %0|%0, %2}\";
13409     case LT:
13410       return \"cmpltss\\t{%2, %0|%0, %2}\";
13411     case LE:
13412       return \"cmpless\\t{%2, %0|%0, %2}\";
13413     case UNORDERED:
13414       return \"cmpunordss\\t{%2, %0|%0, %2}\";
13415     default:
13416       abort ();
13417     }
13419   [(set_attr "type" "sse")])
13421 (define_insn "vmmaskncmpv4sf3"
13422   [(set (match_operand:V4SI 0 "register_operand" "=x")
13423         (vec_merge:V4SI
13424          (not:V4SI
13425           (match_operator:V4SI 3 "sse_comparison_operator"
13426                                [(match_operand:V4SF 1 "register_operand" "0")
13427                                 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))
13428          (subreg:V4SI (match_dup 1) 0)
13429          (const_int 1)))]
13430   "TARGET_SSE"
13431   "*
13433   switch (GET_CODE (operands[3]))
13434     {
13435     case EQ:
13436       return \"cmpneqss\\t{%2, %0|%0, %2}\";
13437     case LT:
13438       return \"cmpnltss\\t{%2, %0|%0, %2}\";
13439     case LE:
13440       return \"cmpnless\\t{%2, %0|%0, %2}\";
13441     case UNORDERED:
13442       return \"cmpordss\\t{%2, %0|%0, %2}\";
13443     default:
13444       abort ();
13445     }
13447   [(set_attr "type" "sse")])
13449 (define_insn "sse_comi"
13450   [(set (reg:CCFP 17)
13451         (match_operator:CCFP 2 "sse_comparison_operator"
13452                         [(vec_select:SF
13453                           (match_operand:V4SF 0 "register_operand" "x")
13454                           (parallel [(const_int 0)]))
13455                          (vec_select:SF
13456                           (match_operand:V4SF 1 "register_operand" "x")
13457                           (parallel [(const_int 0)]))]))]
13458   "TARGET_SSE"
13459   "comiss\\t{%2, %0|%0, %2}"
13460   [(set_attr "type" "sse")])
13462 (define_insn "sse_ucomi"
13463   [(set (reg:CCFPU 17)
13464         (match_operator:CCFPU 2 "sse_comparison_operator"
13465                         [(vec_select:SF
13466                           (match_operand:V4SF 0 "register_operand" "x")
13467                           (parallel [(const_int 0)]))
13468                          (vec_select:SF
13469                           (match_operand:V4SF 1 "register_operand" "x")
13470                           (parallel [(const_int 0)]))]))]
13471   "TARGET_SSE"
13472   "ucomiss\\t{%2, %0|%0, %2}"
13473   [(set_attr "type" "sse")])
13476 ;; SSE unpack
13478 (define_insn "sse_unpckhps"
13479   [(set (match_operand:V4SF 0 "register_operand" "=x")
13480         (vec_merge:V4SF
13481          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
13482                           (parallel [(const_int 2)
13483                                      (const_int 0)
13484                                      (const_int 3)
13485                                      (const_int 1)]))
13486          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x")
13487                           (parallel [(const_int 0)
13488                                      (const_int 2)
13489                                      (const_int 1)
13490                                      (const_int 3)]))
13491          (const_int 5)))]
13492   "TARGET_SSE"
13493   "unpckhps\\t{%2, %0|%0, %2}"
13494   [(set_attr "type" "sse")])
13496 (define_insn "sse_unpcklps"
13497   [(set (match_operand:V4SF 0 "register_operand" "=x")
13498         (vec_merge:V4SF
13499          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
13500                           (parallel [(const_int 0)
13501                                      (const_int 2)
13502                                      (const_int 1)
13503                                      (const_int 3)]))
13504          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x")
13505                           (parallel [(const_int 2)
13506                                      (const_int 0)
13507                                      (const_int 3)
13508                                      (const_int 1)]))
13509          (const_int 5)))]
13510   "TARGET_SSE"
13511   "unpcklps\\t{%2, %0|%0, %2}"
13512   [(set_attr "type" "sse")])
13515 ;; SSE min/max
13517 (define_insn "smaxv4sf3"
13518   [(set (match_operand:V4SF 0 "register_operand" "=x")
13519         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
13520                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13521   "TARGET_SSE"
13522   "maxps\\t{%2, %0|%0, %2}"
13523   [(set_attr "type" "sse")])
13525 (define_insn "vmsmaxv4sf3"
13526   [(set (match_operand:V4SF 0 "register_operand" "=x")
13527         (vec_merge:V4SF (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
13528                                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13529                         (match_dup 1)
13530                         (const_int 1)))]
13531   "TARGET_SSE"
13532   "maxss\\t{%2, %0|%0, %2}"
13533   [(set_attr "type" "sse")])
13535 (define_insn "sminv4sf3"
13536   [(set (match_operand:V4SF 0 "register_operand" "=x")
13537         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
13538                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13539   "TARGET_SSE"
13540   "minps\\t{%2, %0|%0, %2}"
13541   [(set_attr "type" "sse")])
13543 (define_insn "vmsminv4sf3"
13544   [(set (match_operand:V4SF 0 "register_operand" "=x")
13545         (vec_merge:V4SF (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
13546                                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13547                         (match_dup 1)
13548                         (const_int 1)))]
13549   "TARGET_SSE"
13550   "minss\\t{%2, %0|%0, %2}"
13551   [(set_attr "type" "sse")])
13554 ;; SSE <-> integer/MMX conversions
13556 (define_insn "cvtpi2ps"
13557   [(set (match_operand:V4SF 0 "register_operand" "=x")
13558         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
13559                         (vec_duplicate:V4SF
13560                          (float:V2SF (match_operand:V2SI 2 "register_operand" "ym")))
13561                         (const_int 12)))]
13562   "TARGET_SSE"
13563   "cvtpi2ps\\t{%2, %0|%0, %2}"
13564   [(set_attr "type" "sse")])
13566 (define_insn "cvtps2pi"
13567   [(set (match_operand:V2SI 0 "register_operand" "=y")
13568         (vec_select:V2SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
13569                          (parallel
13570                           [(const_int 0)
13571                            (const_int 1)])))]
13572   "TARGET_SSE"
13573   "cvtps2pi\\t{%1, %0|%0, %1}"
13574   [(set_attr "type" "sse")])
13576 (define_insn "cvttps2pi"
13577   [(set (match_operand:V2SI 0 "register_operand" "=y")
13578         (vec_select:V2SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
13579                          (parallel
13580                           [(const_int 0)
13581                            (const_int 1)])))]
13582   "TARGET_SSE"
13583   "cvttps2pi\\t{%1, %0|%0, %1}"
13584   [(set_attr "type" "sse")])
13586 (define_insn "cvtsi2ss"
13587   [(set (match_operand:V4SF 0 "register_operand" "=x")
13588         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
13589                         (vec_duplicate:V4SF
13590                          (float:SF (match_operand:SI 2 "register_operand" "rm")))
13591                         (const_int 15)))]
13592   "TARGET_SSE"
13593   "cvtsi2ss\\t{%2, %0|%0, %2}"
13594   [(set_attr "type" "sse")])
13596 (define_insn "cvtss2si"
13597   [(set (match_operand:SI 0 "register_operand" "=y")
13598         (vec_select:SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
13599                        (parallel [(const_int 0)])))]
13600   "TARGET_SSE"
13601   "cvtss2si\\t{%1, %0|%0, %1}"
13602   [(set_attr "type" "sse")])
13604 (define_insn "cvttss2si"
13605   [(set (match_operand:SI 0 "register_operand" "=y")
13606         (vec_select:SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
13607                        (parallel [(const_int 0)])))]
13608   "TARGET_SSE"
13609   "cvttss2si\\t{%1, %0|%0, %1}"
13610   [(set_attr "type" "sse")])
13613 ;; MMX insns
13615 ;; MMX arithmetic
13617 (define_insn "addv8qi3"
13618   [(set (match_operand:V8QI 0 "register_operand" "=y")
13619         (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13620                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13621   "TARGET_MMX"
13622   "paddb\\t{%2, %0|%0, %2}"
13623   [(set_attr "type" "mmx")])
13625 (define_insn "addv4hi3"
13626   [(set (match_operand:V4HI 0 "register_operand" "=y")
13627         (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13628                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13629   "TARGET_MMX"
13630   "paddw\\t{%2, %0|%0, %2}"
13631   [(set_attr "type" "mmx")])
13633 (define_insn "addv2si3"
13634   [(set (match_operand:V2SI 0 "register_operand" "=y")
13635         (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
13636                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
13637   "TARGET_MMX"
13638   "paddd\\t{%2, %0|%0, %2}"
13639   [(set_attr "type" "mmx")])
13641 (define_insn "ssaddv8qi3"
13642   [(set (match_operand:V8QI 0 "register_operand" "=y")
13643         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13644                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13645   "TARGET_MMX"
13646   "paddsb\\t{%2, %0|%0, %2}"
13647   [(set_attr "type" "mmx")])
13649 (define_insn "ssaddv4hi3"
13650   [(set (match_operand:V4HI 0 "register_operand" "=y")
13651         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13652                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13653   "TARGET_MMX"
13654   "paddsw\\t{%2, %0|%0, %2}"
13655   [(set_attr "type" "mmx")])
13657 (define_insn "usaddv8qi3"
13658   [(set (match_operand:V8QI 0 "register_operand" "=y")
13659         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13660                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13661   "TARGET_MMX"
13662   "paddusb\\t{%2, %0|%0, %2}"
13663   [(set_attr "type" "mmx")])
13665 (define_insn "usaddv4hi3"
13666   [(set (match_operand:V4HI 0 "register_operand" "=y")
13667         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13668                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13669   "TARGET_MMX"
13670   "paddusw\\t{%2, %0|%0, %2}"
13671   [(set_attr "type" "mmx")])
13673 (define_insn "subv8qi3"
13674   [(set (match_operand:V8QI 0 "register_operand" "=y")
13675         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13676                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13677   "TARGET_MMX"
13678   "psubb\\t{%2, %0|%0, %2}"
13679   [(set_attr "type" "mmx")])
13681 (define_insn "subv4hi3"
13682   [(set (match_operand:V4HI 0 "register_operand" "=y")
13683         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13684                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13685   "TARGET_MMX"
13686   "psubw\\t{%2, %0|%0, %2}"
13687   [(set_attr "type" "mmx")])
13689 (define_insn "subv2si3"
13690   [(set (match_operand:V2SI 0 "register_operand" "=y")
13691         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
13692                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
13693   "TARGET_MMX"
13694   "psubd\\t{%2, %0|%0, %2}"
13695   [(set_attr "type" "mmx")])
13697 (define_insn "sssubv8qi3"
13698   [(set (match_operand:V8QI 0 "register_operand" "=y")
13699         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13700                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13701   "TARGET_MMX"
13702   "psubsb\\t{%2, %0|%0, %2}"
13703   [(set_attr "type" "mmx")])
13705 (define_insn "sssubv4hi3"
13706   [(set (match_operand:V4HI 0 "register_operand" "=y")
13707         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13708                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13709   "TARGET_MMX"
13710   "psubsw\\t{%2, %0|%0, %2}"
13711   [(set_attr "type" "mmx")])
13713 (define_insn "ussubv8qi3"
13714   [(set (match_operand:V8QI 0 "register_operand" "=y")
13715         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13716                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13717   "TARGET_MMX"
13718   "psubusb\\t{%2, %0|%0, %2}"
13719   [(set_attr "type" "mmx")])
13721 (define_insn "ussubv4hi3"
13722   [(set (match_operand:V4HI 0 "register_operand" "=y")
13723         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13724                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13725   "TARGET_MMX"
13726   "psubusw\\t{%2, %0|%0, %2}"
13727   [(set_attr "type" "mmx")])
13729 (define_insn "mulv4hi3"
13730   [(set (match_operand:V4HI 0 "register_operand" "=y")
13731         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
13732                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13733   "TARGET_MMX"
13734   "pmullw\\t{%2, %0|%0, %2}"
13735   [(set_attr "type" "mmx")])
13737 (define_insn "smulv4hi3_highpart"
13738   [(set (match_operand:V4HI 0 "register_operand" "=y")
13739         (truncate:V4HI
13740          (lshiftrt:V4SI
13741           (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
13742                      (sign_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
13743           (const_int 16))))]
13744   "TARGET_MMX"
13745   "pmulhw\\t{%2, %0|%0, %2}"
13746   [(set_attr "type" "mmx")])
13748 (define_insn "umulv4hi3_highpart"
13749   [(set (match_operand:V4HI 0 "register_operand" "=y")
13750         (truncate:V4HI
13751          (lshiftrt:V4SI
13752           (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
13753                      (zero_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
13754           (const_int 16))))]
13755   "TARGET_MMX"
13756   "pmulhuw\\t{%2, %0|%0, %2}"
13757   [(set_attr "type" "mmx")])
13759 (define_insn "mmx_pmaddwd"
13760   [(set (match_operand:V2SI 0 "register_operand" "=y")
13761         (plus:V2SI
13762          (mult:V2SI
13763           (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
13764                                              (parallel [(const_int 0)
13765                                                         (const_int 2)])))
13766           (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
13767                                              (parallel [(const_int 0)
13768                                                         (const_int 2)]))))
13769          (mult:V2SI
13770           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
13771                                              (parallel [(const_int 1)
13772                                                         (const_int 3)])))
13773           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
13774                                              (parallel [(const_int 1)
13775                                                         (const_int 3)]))))))]
13776   "TARGET_MMX"
13777   "pmaddwd\\t{%2, %0|%0, %2}"
13778   [(set_attr "type" "mmx")])
13781 ;; MMX logical operations
13782 ;; Note we don't want to declare these as regular iordi3 insns to prevent
13783 ;; normal code that also wants to use the FPU from getting broken.
13784 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
13785 (define_insn "mmx_iordi3"
13786   [(set (match_operand:DI 0 "register_operand" "=y")
13787         (unspec:DI
13788          [(ior:DI (match_operand:DI 1 "register_operand" "0")
13789                   (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
13790   "TARGET_MMX"
13791   "por\\t{%2, %0|%0, %2}"
13792   [(set_attr "type" "mmx")])
13794 (define_insn "mmx_xordi3"
13795   [(set (match_operand:DI 0 "register_operand" "=y")
13796         (unspec:DI
13797          [(xor:DI (match_operand:DI 1 "register_operand" "0")
13798                   (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
13799   "TARGET_MMX"
13800   "pxor\\t{%2, %0|%0, %2}"
13801   [(set_attr "type" "mmx")])
13803 ;; Same as pxor, but don't show input operands so that we don't think
13804 ;; they are live.
13805 (define_insn "mmx_clrdi"
13806   [(set (match_operand:DI 0 "register_operand" "=y")
13807         (unspec:DI [(const_int 0)] 45))]
13808   "TARGET_MMX"
13809   "pxor\\t{%0, %0|%0, %0}"
13810   [(set_attr "type" "mmx")])
13812 (define_insn "mmx_anddi3"
13813   [(set (match_operand:DI 0 "register_operand" "=y")
13814         (unspec:DI
13815          [(and:DI (match_operand:DI 1 "register_operand" "0")
13816                   (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
13817   "TARGET_MMX"
13818   "pand\\t{%2, %0|%0, %2}"
13819   [(set_attr "type" "mmx")])
13821 (define_insn "mmx_nanddi3"
13822   [(set (match_operand:DI 0 "register_operand" "=y")
13823         (unspec:DI
13824          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
13825                           (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
13826   "TARGET_MMX"
13827   "pandn\\t{%2, %0|%0, %2}"
13828   [(set_attr "type" "mmx")])
13831 ;; MMX unsigned averages/sum of absolute differences
13833 (define_insn "mmx_uavgv8qi3"
13834   [(set (match_operand:V8QI 0 "register_operand" "=y")
13835         (ashiftrt:V8QI
13836          (plus:V8QI (plus:V8QI
13837                      (match_operand:V8QI 1 "register_operand" "0")
13838                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
13839                     (vec_const:V8QI (parallel [(const_int 1)
13840                                                (const_int 1)
13841                                                (const_int 1)
13842                                                (const_int 1)
13843                                                (const_int 1)
13844                                                (const_int 1)
13845                                                (const_int 1)
13846                                                (const_int 1)])))
13847          (const_int 1)))]
13848   "TARGET_SSE"
13849   "pavgb\\t{%2, %0|%0, %2}"
13850   [(set_attr "type" "sse")])
13852 (define_insn "mmx_uavgv4hi3"
13853   [(set (match_operand:V4HI 0 "register_operand" "=y")
13854         (ashiftrt:V4HI
13855          (plus:V4HI (plus:V4HI
13856                      (match_operand:V4HI 1 "register_operand" "0")
13857                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
13858                     (vec_const:V4HI (parallel [(const_int 1)
13859                                                (const_int 1)
13860                                                (const_int 1)
13861                                                (const_int 1)])))
13862          (const_int 1)))]
13863   "TARGET_SSE"
13864   "pavgw\\t{%2, %0|%0, %2}"
13865   [(set_attr "type" "sse")])
13867 (define_insn "mmx_psadbw"
13868   [(set (match_operand:V8QI 0 "register_operand" "=y")
13869         (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13870                               (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
13871   "TARGET_SSE"
13872   "psadbw\\t{%2, %0|%0, %2}"
13873   [(set_attr "type" "sse")])
13876 ;; MMX insert/extract/shuffle
13878 (define_insn "mmx_pinsrw"
13879   [(set (match_operand:V4HI 0 "register_operand" "=y")
13880         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
13881                         (vec_duplicate:V4HI
13882                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
13883                         (match_operand:SI 3 "immediate_operand" "i")))]
13884   "TARGET_SSE"
13885   "pinsrw\\t{%3, %2, %0|%0, %2, %3}"
13886   [(set_attr "type" "sse")])
13888 (define_insn "mmx_pextrw"
13889   [(set (match_operand:SI 0 "register_operand" "=r")
13890         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
13891                                        (parallel
13892                                         [(match_operand:SI 2 "immediate_operand" "i")]))))]
13893   "TARGET_SSE"
13894   "pextrw\\t{%2, %1, %0|%0, %1, %2}"
13895   [(set_attr "type" "sse")])
13897 (define_insn "mmx_pshufw"
13898   [(set (match_operand:V4HI 0 "register_operand" "=y")
13899         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
13900                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")
13901                       (match_operand:SI 3 "immediate_operand" "i")] 41))]
13902   "TARGET_SSE"
13903   "pshufw\\t{%3, %2, %0|%0, %2, %3}"
13904   [(set_attr "type" "sse")])
13907 ;; MMX mask-generating comparisons
13909 (define_insn "eqv8qi3"
13910   [(set (match_operand:V8QI 0 "register_operand" "=y")
13911         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
13912                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13913   "TARGET_MMX"
13914   "pcmpeqb\\t{%2, %0|%0, %2}"
13915   [(set_attr "type" "mmx")])
13917 (define_insn "eqv4hi3"
13918   [(set (match_operand:V4HI 0 "register_operand" "=y")
13919         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
13920                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13921   "TARGET_MMX"
13922   "pcmpeqw\\t{%2, %0|%0, %2}"
13923   [(set_attr "type" "mmx")])
13925 (define_insn "eqv2si3"
13926   [(set (match_operand:V2SI 0 "register_operand" "=y")
13927         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
13928                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
13929   "TARGET_MMX"
13930   "pcmpeqd\\t{%2, %0|%0, %2}"
13931   [(set_attr "type" "mmx")])
13933 (define_insn "gtv8qi3"
13934   [(set (match_operand:V8QI 0 "register_operand" "=y")
13935         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
13936                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13937   "TARGET_MMX"
13938   "pcmpgtb\\t{%2, %0|%0, %2}"
13939   [(set_attr "type" "mmx")])
13941 (define_insn "gtv4hi3"
13942   [(set (match_operand:V4HI 0 "register_operand" "=y")
13943         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
13944                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13945   "TARGET_MMX"
13946   "pcmpgtw\\t{%2, %0|%0, %2}"
13947   [(set_attr "type" "mmx")])
13949 (define_insn "gtv2si3"
13950   [(set (match_operand:V2SI 0 "register_operand" "=y")
13951         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
13952                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
13953   "TARGET_MMX"
13954   "pcmpgtd\\t{%2, %0|%0, %2}"
13955   [(set_attr "type" "mmx")])
13958 ;; MMX max/min insns
13960 (define_insn "umaxv8qi3"
13961   [(set (match_operand:V8QI 0 "register_operand" "=y")
13962         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
13963                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13964   "TARGET_SSE"
13965   "pmaxub\\t{%2, %0|%0, %2}"
13966   [(set_attr "type" "sse")])
13968 (define_insn "smaxv4hi3"
13969   [(set (match_operand:V4HI 0 "register_operand" "=y")
13970         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
13971                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13972   "TARGET_SSE"
13973   "pmaxsw\\t{%2, %0|%0, %2}"
13974   [(set_attr "type" "sse")])
13976 (define_insn "uminv8qi3"
13977   [(set (match_operand:V8QI 0 "register_operand" "=y")
13978         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
13979                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13980   "TARGET_SSE"
13981   "pminub\\t{%2, %0|%0, %2}"
13982   [(set_attr "type" "sse")])
13984 (define_insn "sminv4hi3"
13985   [(set (match_operand:V4HI 0 "register_operand" "=y")
13986         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
13987                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13988   "TARGET_SSE"
13989   "pminsw\\t{%2, %0|%0, %2}"
13990   [(set_attr "type" "sse")])
13993 ;; MMX shifts
13995 (define_insn "ashrv4hi3"
13996   [(set (match_operand:V4HI 0 "register_operand" "=y")
13997         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
13998                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
13999   "TARGET_MMX"
14000   "psraw\\t{%2, %0|%0, %2}"
14001   [(set_attr "type" "mmx")])
14003 (define_insn "ashrv2si3"
14004   [(set (match_operand:V2SI 0 "register_operand" "=y")
14005         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
14006                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
14007   "TARGET_MMX"
14008   "psrad\\t{%2, %0|%0, %2}"
14009   [(set_attr "type" "mmx")])
14011 (define_insn "lshrv4hi3"
14012   [(set (match_operand:V4HI 0 "register_operand" "=y")
14013         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
14014                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
14015   "TARGET_MMX"
14016   "psrlw\\t{%2, %0|%0, %2}"
14017   [(set_attr "type" "mmx")])
14019 (define_insn "lshrv2si3"
14020   [(set (match_operand:V2SI 0 "register_operand" "=y")
14021         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
14022                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
14023   "TARGET_MMX"
14024   "psrld\\t{%2, %0|%0, %2}"
14025   [(set_attr "type" "mmx")])
14027 ;; See logical MMX insns.
14028 (define_insn "mmx_lshrdi3"
14029   [(set (match_operand:DI 0 "register_operand" "=y")
14030         (unspec:DI
14031           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
14032                        (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
14033   "TARGET_MMX"
14034   "psrlq\\t{%2, %0|%0, %2}"
14035   [(set_attr "type" "mmx")])
14037 (define_insn "ashlv4hi3"
14038   [(set (match_operand:V4HI 0 "register_operand" "=y")
14039         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
14040                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
14041   "TARGET_MMX"
14042   "psllw\\t{%2, %0|%0, %2}"
14043   [(set_attr "type" "mmx")])
14045 (define_insn "ashlv2si3"
14046   [(set (match_operand:V2SI 0 "register_operand" "=y")
14047         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
14048                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
14049   "TARGET_MMX"
14050   "pslld\\t{%2, %0|%0, %2}"
14051   [(set_attr "type" "mmx")])
14053 ;; See logical MMX insns.
14054 (define_insn "mmx_ashldi3"
14055   [(set (match_operand:DI 0 "register_operand" "=y")
14056         (unspec:DI
14057          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
14058                      (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
14059   "TARGET_MMX"
14060   "psllq\\t{%2, %0|%0, %2}"
14061   [(set_attr "type" "mmx")])
14064 ;; MMX pack/unpack insns.
14066 (define_insn "mmx_packsswb"
14067   [(set (match_operand:V8QI 0 "register_operand" "=y")
14068         (vec_concat:V8QI
14069          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
14070          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
14071   "TARGET_MMX"
14072   "packsswb\\t{%2, %0|%0, %2}"
14073   [(set_attr "type" "mmx")])
14075 (define_insn "mmx_packssdw"
14076   [(set (match_operand:V4HI 0 "register_operand" "=y")
14077         (vec_concat:V4HI
14078          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
14079          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
14080   "TARGET_MMX"
14081   "packssdw\\t{%2, %0|%0, %2}"
14082   [(set_attr "type" "mmx")])
14084 (define_insn "mmx_packuswb"
14085   [(set (match_operand:V8QI 0 "register_operand" "=y")
14086         (vec_concat:V8QI
14087          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
14088          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
14089   "TARGET_MMX"
14090   "packuswb\\t{%2, %0|%0, %2}"
14091   [(set_attr "type" "mmx")])
14093 (define_insn "mmx_punpckhbw"
14094   [(set (match_operand:V8QI 0 "register_operand" "=y")
14095         (vec_merge:V8QI
14096          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
14097                           (parallel [(const_int 4)
14098                                      (const_int 0)
14099                                      (const_int 5)
14100                                      (const_int 1)
14101                                      (const_int 6)
14102                                      (const_int 2)
14103                                      (const_int 7)
14104                                      (const_int 3)]))
14105          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
14106                           (parallel [(const_int 0)
14107                                      (const_int 4)
14108                                      (const_int 1)
14109                                      (const_int 5)
14110                                      (const_int 2)
14111                                      (const_int 6)
14112                                      (const_int 3)
14113                                      (const_int 7)]))
14114          (const_int 85)))]
14115   "TARGET_MMX"
14116   "punpckhbw\\t{%2, %0|%0, %2}"
14117   [(set_attr "type" "mmx")])
14119 (define_insn "mmx_punpckhwd"
14120   [(set (match_operand:V4HI 0 "register_operand" "=y")
14121         (vec_merge:V4HI
14122          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
14123                           (parallel [(const_int 0)
14124                                      (const_int 2)
14125                                      (const_int 1)
14126                                      (const_int 3)]))
14127          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
14128                           (parallel [(const_int 2)
14129                                      (const_int 0)
14130                                      (const_int 3)
14131                                      (const_int 1)]))
14132          (const_int 5)))]
14133   "TARGET_MMX"
14134   "punpckhwd\\t{%2, %0|%0, %2}"
14135   [(set_attr "type" "mmx")])
14137 (define_insn "mmx_punpckhdq"
14138   [(set (match_operand:V2SI 0 "register_operand" "=y")
14139         (vec_merge:V2SI
14140          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
14141                           (parallel [(const_int 0)
14142                                      (const_int 1)]))
14143          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
14144                           (parallel [(const_int 1)
14145                                      (const_int 0)]))
14146          (const_int 1)))]
14147   "TARGET_MMX"
14148   "punpckhdq\\t{%2, %0|%0, %2}"
14149   [(set_attr "type" "mmx")])
14151 (define_insn "mmx_punpcklbw"
14152   [(set (match_operand:V8QI 0 "register_operand" "=y")
14153         (vec_merge:V8QI
14154          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
14155                           (parallel [(const_int 0)
14156                                      (const_int 4)
14157                                      (const_int 1)
14158                                      (const_int 5)
14159                                      (const_int 2)
14160                                      (const_int 6)
14161                                      (const_int 3)
14162                                      (const_int 7)]))
14163          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
14164                           (parallel [(const_int 4)
14165                                      (const_int 0)
14166                                      (const_int 5)
14167                                      (const_int 1)
14168                                      (const_int 6)
14169                                      (const_int 2)
14170                                      (const_int 7)
14171                                      (const_int 3)]))
14172          (const_int 85)))]
14173   "TARGET_MMX"
14174   "punpcklbw\\t{%2, %0|%0, %2}"
14175   [(set_attr "type" "mmx")])
14177 (define_insn "mmx_punpcklwd"
14178   [(set (match_operand:V4HI 0 "register_operand" "=y")
14179         (vec_merge:V4HI
14180          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
14181                           (parallel [(const_int 2)
14182                                      (const_int 0)
14183                                      (const_int 3)
14184                                      (const_int 1)]))
14185          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
14186                           (parallel [(const_int 0)
14187                                      (const_int 2)
14188                                      (const_int 1)
14189                                      (const_int 3)]))
14190          (const_int 5)))]
14191   "TARGET_MMX"
14192   "punpcklwd\\t{%2, %0|%0, %2}"
14193   [(set_attr "type" "mmx")])
14195 (define_insn "mmx_punpckldq"
14196   [(set (match_operand:V2SI 0 "register_operand" "=y")
14197         (vec_merge:V2SI
14198          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
14199                            (parallel [(const_int 1)
14200                                       (const_int 0)]))
14201          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
14202                           (parallel [(const_int 0)
14203                                      (const_int 1)]))
14204          (const_int 1)))]
14205   "TARGET_MMX"
14206   "punpckldq\\t{%2, %0|%0, %2}"
14207   [(set_attr "type" "mmx")])
14210 ;; Miscellaneous stuff
14212 (define_insn "emms"
14213   [(unspec_volatile [(const_int 0)] 31)
14214    (clobber (reg:XF 8))
14215    (clobber (reg:XF 9))
14216    (clobber (reg:XF 10))
14217    (clobber (reg:XF 11))
14218    (clobber (reg:XF 12))
14219    (clobber (reg:XF 13))
14220    (clobber (reg:XF 14))
14221    (clobber (reg:XF 15))
14222    (clobber (reg:DI 29))
14223    (clobber (reg:DI 30))
14224    (clobber (reg:DI 31))
14225    (clobber (reg:DI 32))
14226    (clobber (reg:DI 33))
14227    (clobber (reg:DI 34))
14228    (clobber (reg:DI 35))
14229    (clobber (reg:DI 36))]
14230   "TARGET_MMX"
14231   "emms"
14232   [(set_attr "type" "mmx")
14233    (set_attr "memory" "unknown")])
14235 (define_insn "ldmxcsr"
14236   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
14237   "TARGET_MMX"
14238   "ldmxcsr\\t%0"
14239   [(set_attr "type" "mmx")])
14241 (define_insn "stmxcsr"
14242   [(set (match_operand:SI 0 "memory_operand" "=m")
14243         (unspec_volatile:SI [(const_int 0)] 40))]
14244   "TARGET_MMX"
14245   "stmxcsr\\t%0"
14246   [(set_attr "type" "mmx")])
14248 (define_expand "sfence"
14249   [(set (match_dup 0)
14250         (unspec:BLK [(match_dup 0)] 44))]
14251   "TARGET_SSE"
14252   "
14254   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
14255   MEM_VOLATILE_P (operands[0]) = 1;
14258 (define_insn "*sfence_insn"
14259   [(set (match_operand:BLK 0 "" "")
14260         (unspec:BLK [(match_dup 0)] 44))]
14261   "TARGET_SSE"
14262   "sfence"
14263   [(set_attr "type" "sse")
14264    (set_attr "memory" "unknown")])
14266 (define_insn "prefetch"
14267   [(unspec [(match_operand:SI 0 "address_operand" "p")
14268             (match_operand:SI 1 "immediate_operand" "n")] 35)]
14269   "TARGET_SSE"
14270   "*
14272   switch (INTVAL (operands[1]))
14273     {
14274     case 0:
14275       return \"prefetchnta\\t%a0\";
14276     case 1:
14277       return \"prefetcht0\\t%a0\";
14278     case 2:
14279       return \"prefetcht1\\t%a0\";
14280     case 3:
14281       return \"prefetcht2\\t%a0\";
14282     default:
14283       abort ();
14284     }
14286   [(set_attr "type" "sse")])