1 ;; GCC machine description for IA-32.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000
3 ;; Free Software Foundation, Inc.
4 ;; Mostly by William Schelter.
6 ;; This file is part of GNU CC.
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)
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
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.
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
75 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
79 ;; Processor type. This attribute must exactly match the processor_type
80 ;; enumeration in i386.h.
81 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon"
82 (const (symbol_ref "ix86_cpu")))
84 ;; A basic instruction type. Refinements due to arguments to be
85 ;; provided in other attributes.
87 "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"
88 (const_string "other"))
90 ;; Main data type used by the insn
91 (define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF"
92 (const_string "unknown"))
94 ;; Set for i387 operations.
95 (define_attr "i387" ""
96 (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch")
100 ;; The (bounding maximum) length of an instruction immediate.
101 (define_attr "length_immediate" ""
102 (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv")
106 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
107 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
108 (eq_attr "type" "imov,test")
109 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
110 (eq_attr "type" "call")
111 (if_then_else (match_operand 0 "constant_call_address_operand" "")
114 (eq_attr "type" "callv")
115 (if_then_else (match_operand 1 "constant_call_address_operand" "")
118 (eq_attr "type" "ibr")
119 (if_then_else (and (ge (minus (match_dup 0) (pc))
121 (lt (minus (match_dup 0) (pc))
126 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
128 ;; The (bounding maximum) length of an instruction address.
129 (define_attr "length_address" ""
130 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
132 (and (eq_attr "type" "call")
133 (match_operand 1 "constant_call_address_operand" ""))
135 (and (eq_attr "type" "callv")
136 (match_operand 1 "constant_call_address_operand" ""))
139 (symbol_ref "ix86_attr_length_address_default (insn)")))
141 ;; Set when length prefix is used.
142 (define_attr "prefix_data16" ""
143 (if_then_else (eq_attr "mode" "HI")
147 ;; Set when string REP prefix is used.
148 (define_attr "prefix_rep" "" (const_int 0))
150 ;; Set when 0f opcode prefix is used.
151 (define_attr "prefix_0f" ""
152 (if_then_else (eq_attr "type" "imovx,setcc,icmov")
156 ;; Set when modrm byte is used.
157 (define_attr "modrm" ""
158 (cond [(eq_attr "type" "str,cld")
162 (and (eq_attr "type" "incdec")
163 (ior (match_operand:SI 1 "register_operand" "")
164 (match_operand:HI 1 "register_operand" "")))
166 (and (eq_attr "type" "push")
167 (not (match_operand 1 "memory_operand" "")))
169 (and (eq_attr "type" "pop")
170 (not (match_operand 0 "memory_operand" "")))
172 (and (eq_attr "type" "imov")
173 (and (match_operand 0 "register_operand" "")
174 (match_operand 1 "immediate_operand" "")))
179 ;; The (bounding maximum) length of an instruction in bytes.
180 (define_attr "length" ""
181 (cond [(eq_attr "type" "other,multi")
184 (plus (plus (attr "modrm")
185 (plus (attr "prefix_0f")
188 (plus (attr "prefix_rep")
189 (plus (attr "prefix_data16")
190 (plus (attr "length_immediate")
191 (attr "length_address")))))))
193 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
194 ;; `store' if there is a simple memory reference therein, or `unknown'
195 ;; if the instruction is complex.
197 (define_attr "memory" "none,load,store,both,unknown"
198 (cond [(eq_attr "type" "other,multi,str")
199 (const_string "unknown")
200 (eq_attr "type" "lea,fcmov,fpspc,cld")
201 (const_string "none")
202 (eq_attr "type" "push")
203 (if_then_else (match_operand 1 "memory_operand" "")
204 (const_string "both")
205 (const_string "store"))
206 (eq_attr "type" "pop,setcc")
207 (if_then_else (match_operand 0 "memory_operand" "")
208 (const_string "both")
209 (const_string "load"))
210 (eq_attr "type" "icmp,test")
211 (if_then_else (ior (match_operand 0 "memory_operand" "")
212 (match_operand 1 "memory_operand" ""))
213 (const_string "load")
214 (const_string "none"))
215 (eq_attr "type" "ibr")
216 (if_then_else (match_operand 0 "memory_operand" "")
217 (const_string "load")
218 (const_string "none"))
219 (eq_attr "type" "call")
220 (if_then_else (match_operand 0 "constant_call_address_operand" "")
221 (const_string "none")
222 (const_string "load"))
223 (eq_attr "type" "callv")
224 (if_then_else (match_operand 1 "constant_call_address_operand" "")
225 (const_string "none")
226 (const_string "load"))
227 (and (eq_attr "type" "alu1,negnot")
228 (match_operand 1 "memory_operand" ""))
229 (const_string "both")
230 (and (match_operand 0 "memory_operand" "")
231 (match_operand 1 "memory_operand" ""))
232 (const_string "both")
233 (match_operand 0 "memory_operand" "")
234 (const_string "store")
235 (match_operand 1 "memory_operand" "")
236 (const_string "load")
237 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp")
238 (match_operand 2 "memory_operand" ""))
239 (const_string "load")
240 (and (eq_attr "type" "icmov")
241 (match_operand 3 "memory_operand" ""))
242 (const_string "load")
244 (const_string "none")))
246 ;; Indicates if an instruction has both an immediate and a displacement.
248 (define_attr "imm_disp" "false,true,unknown"
249 (cond [(eq_attr "type" "other,multi")
250 (const_string "unknown")
251 (and (eq_attr "type" "icmp,test,imov")
252 (and (match_operand 0 "memory_displacement_operand" "")
253 (match_operand 1 "immediate_operand" "")))
254 (const_string "true")
255 (and (eq_attr "type" "alu,ishift,imul,idiv")
256 (and (match_operand 0 "memory_displacement_operand" "")
257 (match_operand 2 "immediate_operand" "")))
258 (const_string "true")
260 (const_string "false")))
262 ;; Indicates if an FP operation has an integer source.
264 (define_attr "fp_int_src" "false,true"
265 (const_string "false"))
267 ;; Describe a user's asm statement.
268 (define_asm_attributes
269 [(set_attr "length" "128")
270 (set_attr "type" "multi")])
272 ;; Pentium Scheduling
274 ;; The Pentium is an in-order core with two integer pipelines.
276 ;; True for insns that behave like prefixed insns on the Pentium.
277 (define_attr "pent_prefix" "false,true"
278 (if_then_else (ior (eq_attr "prefix_0f" "1")
279 (ior (eq_attr "prefix_data16" "1")
280 (eq_attr "prefix_rep" "1")))
281 (const_string "true")
282 (const_string "false")))
284 ;; Categorize how an instruction slots.
286 ;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
287 ;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium
288 ;; rules, because it results in noticeably better code on non-MMX Pentium
289 ;; and doesn't hurt much on MMX. (Prefixed instructions are not very
290 ;; common, so the scheduler usualy has a non-prefixed insn to pair).
292 (define_attr "pent_pair" "uv,pu,pv,np"
293 (cond [(eq_attr "imm_disp" "true")
295 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
296 (and (eq_attr "type" "pop,push")
297 (eq_attr "memory" "!both")))
298 (if_then_else (eq_attr "pent_prefix" "true")
301 (eq_attr "type" "ibr")
303 (and (eq_attr "type" "ishift")
304 (match_operand 2 "const_int_operand" ""))
306 (and (eq_attr "type" "call")
307 (match_operand 0 "constant_call_address_operand" ""))
309 (and (eq_attr "type" "callv")
310 (match_operand 1 "constant_call_address_operand" ""))
313 (const_string "np")))
315 ;; Rough readiness numbers. Fine tuning happens in i386.c.
317 ;; u describes pipe U
318 ;; v describes pipe V
319 ;; uv describes either pipe U or V for those that can issue to either
320 ;; np describes not paring
322 ;; fpm describes fp insns of different types are not pipelined.
324 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
326 (define_function_unit "pent_np" 1 0
327 (and (eq_attr "cpu" "pentium")
328 (eq_attr "type" "imul"))
331 (define_function_unit "pent_mul" 1 1
332 (and (eq_attr "cpu" "pentium")
333 (eq_attr "type" "imul"))
336 ;; Rep movs takes minimally 12 cycles.
337 (define_function_unit "pent_np" 1 0
338 (and (eq_attr "cpu" "pentium")
339 (eq_attr "type" "str"))
342 ; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
343 (define_function_unit "pent_np" 1 0
344 (and (eq_attr "cpu" "pentium")
345 (eq_attr "type" "idiv"))
348 ; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
349 ; 3 cycles for XFmode. Stores takes 2 cycles for SF/DF and 3 for XF.
350 ; fldz and fld1 takes 2 cycles. Only reg-reg moves are pairable.
351 ; The integer <-> fp conversion is not modeled correctly. Fild behaves
352 ; like normal fp operation and fist takes 6 cycles.
354 (define_function_unit "fpu" 1 0
355 (and (eq_attr "cpu" "pentium")
356 (and (eq_attr "type" "fmov")
357 (ior (and (eq_attr "memory" "store")
358 (match_operand:XF 0 "memory_operand" ""))
359 (and (eq_attr "memory" "load")
360 (match_operand:XF 1 "memory_operand" "")))))
363 (define_function_unit "pent_np" 1 0
364 (and (eq_attr "cpu" "pentium")
365 (and (eq_attr "type" "fmov")
366 (ior (and (eq_attr "memory" "store")
367 (match_operand:XF 0 "memory_operand" ""))
368 (and (eq_attr "memory" "load")
369 (match_operand:XF 1 "memory_operand" "")))))
372 (define_function_unit "fpu" 1 0
373 (and (eq_attr "cpu" "pentium")
374 (and (eq_attr "type" "fmov")
375 (ior (match_operand 1 "immediate_operand" "")
376 (eq_attr "memory" "store"))))
379 (define_function_unit "pent_np" 1 0
380 (and (eq_attr "cpu" "pentium")
381 (and (eq_attr "type" "fmov")
382 (ior (match_operand 1 "immediate_operand" "")
383 (eq_attr "memory" "store"))))
386 (define_function_unit "pent_np" 1 0
387 (and (eq_attr "cpu" "pentium")
388 (eq_attr "type" "cld"))
391 (define_function_unit "fpu" 1 0
392 (and (eq_attr "cpu" "pentium")
393 (and (eq_attr "type" "fmov")
394 (eq_attr "memory" "none,load")))
397 ; Read/Modify/Write instructions usually take 3 cycles.
398 (define_function_unit "pent_u" 1 0
399 (and (eq_attr "cpu" "pentium")
400 (and (eq_attr "type" "alu,alu1,ishift")
401 (and (eq_attr "pent_pair" "pu")
402 (eq_attr "memory" "both"))))
405 (define_function_unit "pent_uv" 2 0
406 (and (eq_attr "cpu" "pentium")
407 (and (eq_attr "type" "alu,alu1,ishift")
408 (and (eq_attr "pent_pair" "!np")
409 (eq_attr "memory" "both"))))
412 (define_function_unit "pent_np" 1 0
413 (and (eq_attr "cpu" "pentium")
414 (and (eq_attr "type" "alu,alu1,negnot,ishift")
415 (and (eq_attr "pent_pair" "np")
416 (eq_attr "memory" "both"))))
419 ; Read/Modify or Modify/Write instructions usually take 2 cycles.
420 (define_function_unit "pent_u" 1 0
421 (and (eq_attr "cpu" "pentium")
422 (and (eq_attr "type" "alu,ishift")
423 (and (eq_attr "pent_pair" "pu")
424 (eq_attr "memory" "load,store"))))
427 (define_function_unit "pent_uv" 2 0
428 (and (eq_attr "cpu" "pentium")
429 (and (eq_attr "type" "alu,ishift")
430 (and (eq_attr "pent_pair" "!np")
431 (eq_attr "memory" "load,store"))))
434 (define_function_unit "pent_np" 1 0
435 (and (eq_attr "cpu" "pentium")
436 (and (eq_attr "type" "alu,ishift")
437 (and (eq_attr "pent_pair" "np")
438 (eq_attr "memory" "load,store"))))
441 ; Insns w/o memory operands and move instructions usually take one cycle.
442 (define_function_unit "pent_u" 1 0
443 (and (eq_attr "cpu" "pentium")
444 (eq_attr "pent_pair" "pu"))
447 (define_function_unit "pent_v" 1 0
448 (and (eq_attr "cpu" "pentium")
449 (eq_attr "pent_pair" "pv"))
452 (define_function_unit "pent_uv" 2 0
453 (and (eq_attr "cpu" "pentium")
454 (eq_attr "pent_pair" "!np"))
457 (define_function_unit "pent_np" 1 0
458 (and (eq_attr "cpu" "pentium")
459 (eq_attr "pent_pair" "np"))
462 ; Pairable insns only conflict with other non-pairable insns.
463 (define_function_unit "pent_np" 1 0
464 (and (eq_attr "cpu" "pentium")
465 (and (eq_attr "type" "alu,alu1,ishift")
466 (and (eq_attr "pent_pair" "!np")
467 (eq_attr "memory" "both"))))
469 [(eq_attr "pent_pair" "np")])
471 (define_function_unit "pent_np" 1 0
472 (and (eq_attr "cpu" "pentium")
473 (and (eq_attr "type" "alu,alu1,ishift")
474 (and (eq_attr "pent_pair" "!np")
475 (eq_attr "memory" "load,store"))))
477 [(eq_attr "pent_pair" "np")])
479 (define_function_unit "pent_np" 1 0
480 (and (eq_attr "cpu" "pentium")
481 (eq_attr "pent_pair" "!np"))
483 [(eq_attr "pent_pair" "np")])
485 ; Floating point instructions usually blocks cycle longer when combined with
486 ; integer instructions, because of the inpaired fxch instruction.
487 (define_function_unit "pent_np" 1 0
488 (and (eq_attr "cpu" "pentium")
489 (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp"))
491 [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp")])
493 (define_function_unit "fpu" 1 0
494 (and (eq_attr "cpu" "pentium")
495 (eq_attr "type" "fcmp,fxch,fsgn"))
498 ; Addition takes 3 cycles; assume other random cruft does as well.
499 ; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
500 (define_function_unit "fpu" 1 0
501 (and (eq_attr "cpu" "pentium")
502 (eq_attr "type" "fop,fop1"))
505 ; Multiplication takes 3 cycles and is only half pipelined.
506 (define_function_unit "fpu" 1 0
507 (and (eq_attr "cpu" "pentium")
508 (eq_attr "type" "fmul"))
511 (define_function_unit "pent_mul" 1 1
512 (and (eq_attr "cpu" "pentium")
513 (eq_attr "type" "fmul"))
516 ; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles.
517 ; They can overlap with integer insns. Only the last two cycles can overlap
518 ; with other fp insns. Only fsin/fcos can overlap with multiplies.
519 ; Only last two cycles of fsin/fcos can overlap with other instructions.
520 (define_function_unit "fpu" 1 0
521 (and (eq_attr "cpu" "pentium")
522 (eq_attr "type" "fdiv"))
525 (define_function_unit "pent_mul" 1 1
526 (and (eq_attr "cpu" "pentium")
527 (eq_attr "type" "fdiv"))
530 (define_function_unit "fpu" 1 0
531 (and (eq_attr "cpu" "pentium")
532 (eq_attr "type" "fpspc"))
535 (define_function_unit "pent_mul" 1 1
536 (and (eq_attr "cpu" "pentium")
537 (eq_attr "type" "fpspc"))
540 ;; Pentium Pro/PII Scheduling
542 ;; The PPro has an out-of-order core, but the instruction decoders are
543 ;; naturally in-order and asymmetric. We get best performance by scheduling
544 ;; for the decoders, for in doing so we give the oo execution unit the
547 ;; Categorize how many uops an ia32 instruction evaluates to:
548 ;; one -- an instruction with 1 uop can be decoded by any of the
550 ;; few -- an instruction with 1 to 4 uops can be decoded only by
552 ;; many -- a complex instruction may take an unspecified number of
553 ;; cycles to decode in decoder 0.
555 (define_attr "ppro_uops" "one,few,many"
556 (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
557 (const_string "many")
558 (eq_attr "type" "icmov,fcmov,str,cld")
560 (eq_attr "type" "imov")
561 (if_then_else (eq_attr "memory" "store,both")
563 (const_string "one"))
564 (eq_attr "memory" "!none")
567 (const_string "one")))
569 ;; Rough readiness numbers. Fine tuning happens in i386.c.
571 ;; p0 describes port 0.
572 ;; p01 describes ports 0 and 1 as a pair; alu insns can issue to either.
573 ;; p2 describes port 2 for loads.
574 ;; p34 describes ports 3 and 4 for stores.
575 ;; fpu describes the fpu accessed via port 0.
576 ;; ??? It is less than clear if there are separate fadd and fmul units
577 ;; that could operate in parallel.
579 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
581 (define_function_unit "ppro_p0" 1 0
582 (and (eq_attr "cpu" "pentiumpro")
583 (eq_attr "type" "ishift,lea,ibr,cld"))
586 (define_function_unit "ppro_p0" 1 0
587 (and (eq_attr "cpu" "pentiumpro")
588 (eq_attr "type" "imul"))
591 ;; ??? Does the divider lock out the pipe while it works,
592 ;; or is there a disconnected unit?
593 (define_function_unit "ppro_p0" 1 0
594 (and (eq_attr "cpu" "pentiumpro")
595 (eq_attr "type" "idiv"))
598 (define_function_unit "ppro_p0" 1 0
599 (and (eq_attr "cpu" "pentiumpro")
600 (eq_attr "type" "fop,fop1,fsgn"))
603 (define_function_unit "ppro_p0" 1 0
604 (and (eq_attr "cpu" "pentiumpro")
605 (eq_attr "type" "fcmov"))
608 (define_function_unit "ppro_p0" 1 0
609 (and (eq_attr "cpu" "pentiumpro")
610 (eq_attr "type" "fcmp"))
613 (define_function_unit "ppro_p0" 1 0
614 (and (eq_attr "cpu" "pentiumpro")
615 (eq_attr "type" "fmov"))
618 (define_function_unit "ppro_p0" 1 0
619 (and (eq_attr "cpu" "pentiumpro")
620 (eq_attr "type" "fmul"))
623 (define_function_unit "ppro_p0" 1 0
624 (and (eq_attr "cpu" "pentiumpro")
625 (eq_attr "type" "fdiv,fpspc"))
628 (define_function_unit "ppro_p01" 2 0
629 (and (eq_attr "cpu" "pentiumpro")
630 (eq_attr "type" "!imov,fmov"))
633 (define_function_unit "ppro_p01" 2 0
634 (and (and (eq_attr "cpu" "pentiumpro")
635 (eq_attr "type" "imov,fmov"))
636 (eq_attr "memory" "none"))
639 (define_function_unit "ppro_p2" 1 0
640 (and (eq_attr "cpu" "pentiumpro")
641 (ior (eq_attr "type" "pop")
642 (eq_attr "memory" "load,both")))
645 (define_function_unit "ppro_p34" 1 0
646 (and (eq_attr "cpu" "pentiumpro")
647 (ior (eq_attr "type" "push")
648 (eq_attr "memory" "store,both")))
651 (define_function_unit "fpu" 1 0
652 (and (eq_attr "cpu" "pentiumpro")
653 (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov"))
656 (define_function_unit "fpu" 1 0
657 (and (eq_attr "cpu" "pentiumpro")
658 (eq_attr "type" "fmul"))
661 (define_function_unit "fpu" 1 0
662 (and (eq_attr "cpu" "pentiumpro")
663 (eq_attr "type" "fdiv,fpspc"))
666 ;; imul uses the fpu. ??? does it have the same throughput as fmul?
667 (define_function_unit "fpu" 1 0
668 (and (eq_attr "cpu" "pentiumpro")
669 (eq_attr "type" "imul"))
672 ;; AMD K6/K6-2 Scheduling
674 ;; The K6 has similar architecture to PPro. Important difference is, that
675 ;; there are only two decoders and they seems to be much slower than execution
676 ;; units. So we have to pay much more attention to proper decoding for
677 ;; schedulers. We share most of scheduler code for PPro in i386.c
679 ;; The fp unit is not pipelined and do one operation per two cycles including
682 ;; alu describes both ALU units (ALU-X and ALU-Y).
683 ;; alux describes X alu unit
684 ;; fpu describes FPU unit
685 ;; load describes load unit.
686 ;; branch describes branch unit.
687 ;; store decsribes store unit. This unit is not modelled completely and only
688 ;; used to model lea operation. Otherwise it lie outside of the critical
691 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
693 ;; The decoder specification is in the PPro section above!
695 ;; Shift instructions and certain arithmetic are issued only to X pipe.
696 (define_function_unit "k6_alux" 1 0
697 (and (eq_attr "cpu" "k6")
698 (eq_attr "type" "ishift,alu1,negnot,cld"))
701 ;; The QI mode arithmetic is issued to X pipe only.
702 (define_function_unit "k6_alux" 1 0
703 (and (eq_attr "cpu" "k6")
704 (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
705 (match_operand:QI 0 "general_operand" "")))
708 (define_function_unit "k6_alu" 2 0
709 (and (eq_attr "cpu" "k6")
710 (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
713 (define_function_unit "k6_alu" 2 0
714 (and (eq_attr "cpu" "k6")
715 (and (eq_attr "type" "imov")
716 (eq_attr "memory" "none")))
719 (define_function_unit "k6_branch" 1 0
720 (and (eq_attr "cpu" "k6")
721 (eq_attr "type" "call,callv,ibr"))
724 ;; Load unit have two cycle latency, but we take care for it in adjust_cost
725 (define_function_unit "k6_load" 1 0
726 (and (eq_attr "cpu" "k6")
727 (ior (eq_attr "type" "pop")
728 (eq_attr "memory" "load,both")))
731 (define_function_unit "k6_load" 1 0
732 (and (eq_attr "cpu" "k6")
733 (and (eq_attr "type" "str")
734 (eq_attr "memory" "load,both")))
737 ;; Lea have two instructions, so latency is probably 2
738 (define_function_unit "k6_store" 1 0
739 (and (eq_attr "cpu" "k6")
740 (eq_attr "type" "lea"))
743 (define_function_unit "k6_store" 1 0
744 (and (eq_attr "cpu" "k6")
745 (eq_attr "type" "str"))
748 (define_function_unit "k6_store" 1 0
749 (and (eq_attr "cpu" "k6")
750 (ior (eq_attr "type" "push")
751 (eq_attr "memory" "store,both")))
754 (define_function_unit "k6_fpu" 1 1
755 (and (eq_attr "cpu" "k6")
756 (eq_attr "type" "fop,fop1,fmov,fcmp"))
759 (define_function_unit "k6_fpu" 1 1
760 (and (eq_attr "cpu" "k6")
761 (eq_attr "type" "fmul"))
765 (define_function_unit "k6_fpu" 1 1
766 (and (eq_attr "cpu" "k6")
767 (eq_attr "type" "fdiv,fpspc"))
770 (define_function_unit "k6_alu" 2 0
771 (and (eq_attr "cpu" "k6")
772 (eq_attr "type" "imul"))
775 (define_function_unit "k6_alux" 1 0
776 (and (eq_attr "cpu" "k6")
777 (eq_attr "type" "imul"))
781 (define_function_unit "k6_alu" 2 0
782 (and (eq_attr "cpu" "k6")
783 (eq_attr "type" "idiv"))
786 (define_function_unit "k6_alux" 1 0
787 (and (eq_attr "cpu" "k6")
788 (eq_attr "type" "idiv"))
791 ;; AMD Athlon Scheduling
793 ;; The Athlon does contain three pipelined FP units, three integer units and
794 ;; three address generation units.
796 ;; The predecode logic is determining boundaries of instructions in the 64
797 ;; byte cache line. So the cache line straddling problem of K6 might be issue
798 ;; here as well, but it is not noted in the documentation.
800 ;; Three DirectPath instructions decoders and only one VectorPath decoder
801 ;; is available. They can decode three DirectPath instructions or one VectorPath
802 ;; instruction per cycle.
803 ;; Decoded macro instructions are then passed to 72 entry instruction control
805 ;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
807 ;; The load/store queue unit is not attached to the schedulers but
808 ;; communicates with all the execution units seperately instead.
810 (define_attr "athlon_decode" "direct,vector"
811 (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
812 (const_string "vector")
813 (and (eq_attr "type" "push")
814 (match_operand 1 "memory_operand" ""))
815 (const_string "vector")
816 (and (eq_attr "type" "fmov")
817 (ior (match_operand:XF 0 "memory_operand" "")
818 (match_operand:XF 1 "memory_operand" "")))
819 (const_string "vector")]
820 (const_string "direct")))
822 (define_function_unit "athlon_vectordec" 1 0
823 (and (eq_attr "cpu" "athlon")
824 (eq_attr "athlon_decode" "vector"))
827 (define_function_unit "athlon_directdec" 3 0
828 (and (eq_attr "cpu" "athlon")
829 (eq_attr "athlon_decode" "direct"))
832 (define_function_unit "athlon_vectordec" 1 0
833 (and (eq_attr "cpu" "athlon")
834 (eq_attr "athlon_decode" "direct"))
835 1 1 [(eq_attr "athlon_decode" "vector")])
837 (define_function_unit "athlon_ieu" 3 0
838 (and (eq_attr "cpu" "athlon")
839 (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
842 (define_function_unit "athlon_ieu" 3 0
843 (and (eq_attr "cpu" "athlon")
844 (eq_attr "type" "str"))
847 (define_function_unit "athlon_ieu" 3 0
848 (and (eq_attr "cpu" "athlon")
849 (eq_attr "type" "imul"))
852 (define_function_unit "athlon_ieu" 3 0
853 (and (eq_attr "cpu" "athlon")
854 (eq_attr "type" "idiv"))
857 (define_function_unit "athlon_muldiv" 1 0
858 (and (eq_attr "cpu" "athlon")
859 (eq_attr "type" "imul"))
862 (define_function_unit "athlon_muldiv" 1 0
863 (and (eq_attr "cpu" "athlon")
864 (eq_attr "type" "idiv"))
867 (define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
868 (cond [(eq_attr "type" "fop,fop1,fcmp")
870 (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
872 (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
873 (const_string "store")
874 (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
876 (and (eq_attr "type" "fmov")
877 (ior (match_operand:SI 1 "register_operand" "")
878 (match_operand 1 "immediate_operand" "")))
879 (const_string "store")
880 (eq_attr "type" "fmov")
881 (const_string "muladd")]
882 (const_string "none")))
884 ;; We use latencies 1 for definitions. This is OK to model colisions
885 ;; in execution units. The real latencies are modeled in the "fp" pipeline.
887 ;; fsin, fcos: 96-192
889 ;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
890 (define_function_unit "athlon_fp" 3 0
891 (and (eq_attr "cpu" "athlon")
892 (eq_attr "type" "fpspc"))
895 ;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
896 (define_function_unit "athlon_fp" 3 0
897 (and (eq_attr "cpu" "athlon")
898 (eq_attr "type" "fdiv"))
901 (define_function_unit "athlon_fp" 3 0
902 (and (eq_attr "cpu" "athlon")
903 (eq_attr "type" "fop,fop1,fmul"))
906 ;; XFmode loads are slow.
907 ;; XFmode store is slow too (8 cycles), but we don't need to model it, because
908 ;; there are no dependent instructions.
910 (define_function_unit "athlon_fp" 3 0
911 (and (eq_attr "cpu" "athlon")
912 (and (eq_attr "type" "fmov")
913 (match_operand:XF 1 "memory_operand" "")))
916 (define_function_unit "athlon_fp" 3 0
917 (and (eq_attr "cpu" "athlon")
918 (eq_attr "type" "fmov,fsgn"))
921 ;; fcmp and ftst instructions
922 (define_function_unit "athlon_fp" 3 0
923 (and (eq_attr "cpu" "athlon")
924 (and (eq_attr "type" "fcmp")
925 (eq_attr "athlon_decode" "direct")))
928 ;; fcmpi instructions.
929 (define_function_unit "athlon_fp" 3 0
930 (and (eq_attr "cpu" "athlon")
931 (and (eq_attr "type" "fcmp")
932 (eq_attr "athlon_decode" "vector")))
935 (define_function_unit "athlon_fp" 3 0
936 (and (eq_attr "cpu" "athlon")
937 (eq_attr "type" "fcmov"))
940 (define_function_unit "athlon_fp_mul" 1 0
941 (and (eq_attr "cpu" "athlon")
942 (eq_attr "athlon_fpunits" "mul"))
945 (define_function_unit "athlon_fp_add" 1 0
946 (and (eq_attr "cpu" "athlon")
947 (eq_attr "athlon_fpunits" "add"))
950 (define_function_unit "athlon_fp_muladd" 2 0
951 (and (eq_attr "cpu" "athlon")
952 (eq_attr "athlon_fpunits" "muladd,mul,add"))
955 (define_function_unit "athlon_fp_store" 1 0
956 (and (eq_attr "cpu" "athlon")
957 (eq_attr "athlon_fpunits" "store"))
960 ;; We don't need to model the Adress Generation Unit, since we don't model
961 ;; the re-order buffer yet and thus we never schedule more than three operations
962 ;; at time. Later we may want to experiment with MD_SCHED macros modeling the
963 ;; decoders independently on the functional units.
965 ;(define_function_unit "athlon_agu" 3 0
966 ; (and (eq_attr "cpu" "athlon")
967 ; (and (eq_attr "memory" "!none")
968 ; (eq_attr "athlon_fpunits" "none")))
971 ;; Model load unit to avoid too long sequences of loads. We don't need to
972 ;; model store queue, since it is hardly going to be bottleneck.
974 (define_function_unit "athlon_load" 2 0
975 (and (eq_attr "cpu" "athlon")
976 (eq_attr "memory" "load,both"))
980 ;; Compare instructions.
982 ;; All compare insns have expanders that save the operands away without
983 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
984 ;; after the cmp) will actually emit the cmpM.
986 (define_expand "cmpdi"
988 (compare:CC (match_operand:DI 0 "general_operand" "")
989 (match_operand:DI 1 "general_operand" "")))]
993 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
994 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
995 operands[0] = force_reg (DImode, operands[0]);
996 ix86_compare_op0 = operands[0];
997 ix86_compare_op1 = operands[1];
1001 (define_expand "cmpsi"
1003 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
1004 (match_operand:SI 1 "general_operand" "")))]
1008 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1009 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1010 operands[0] = force_reg (SImode, operands[0]);
1011 ix86_compare_op0 = operands[0];
1012 ix86_compare_op1 = operands[1];
1016 (define_expand "cmphi"
1018 (compare:CC (match_operand:HI 0 "general_operand" "")
1019 (match_operand:HI 1 "general_operand" "")))]
1023 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1024 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1025 operands[0] = force_reg (HImode, operands[0]);
1026 ix86_compare_op0 = operands[0];
1027 ix86_compare_op1 = operands[1];
1031 (define_expand "cmpqi"
1033 (compare:CC (match_operand:QI 0 "general_operand" "")
1034 (match_operand:QI 1 "general_operand" "")))]
1035 "TARGET_QIMODE_MATH"
1038 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1039 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1040 operands[0] = force_reg (QImode, operands[0]);
1041 ix86_compare_op0 = operands[0];
1042 ix86_compare_op1 = operands[1];
1046 (define_insn "cmpsi_ccz_1"
1048 (compare:CCZ (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1049 (match_operand:SI 1 "const0_operand" "n,n")))]
1052 test{l}\\t{%0, %0|%0, %0}
1053 cmp{l}\\t{%1, %0|%0, %1}"
1054 [(set_attr "type" "test,icmp")
1055 (set_attr "length_immediate" "0,1")
1056 (set_attr "mode" "SI")])
1058 (define_insn "cmpsi_ccno_1"
1060 (compare:CCNO (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1061 (match_operand:SI 1 "const0_operand" "n,n")))]
1064 test{l}\\t{%0, %0|%0, %0}
1065 cmp{l}\\t{%1, %0|%0, %1}"
1066 [(set_attr "type" "test,icmp")
1067 (set_attr "length_immediate" "0,1")
1068 (set_attr "mode" "SI")])
1070 (define_insn "cmpsi_1"
1072 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1073 (match_operand:SI 1 "general_operand" "ri,mr")))]
1074 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1075 "cmp{l}\\t{%1, %0|%0, %1}"
1076 [(set_attr "type" "icmp")
1077 (set_attr "mode" "SI")])
1079 (define_insn "*cmphi_0"
1081 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1082 (match_operand:HI 1 "const0_operand" "n,n")))]
1083 "ix86_match_ccmode (insn, CCNOmode)"
1085 test{w}\\t{%0, %0|%0, %0}
1086 cmp{w}\\t{%1, %0|%0, %1}"
1087 [(set_attr "type" "test,icmp")
1088 (set_attr "length_immediate" "0,1")
1089 (set_attr "mode" "HI")])
1091 (define_insn "*cmphi_1"
1093 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1094 (match_operand:HI 1 "general_operand" "ri,mr")))]
1095 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1096 "cmp{w}\\t{%1, %0|%0, %1}"
1097 [(set_attr "type" "icmp")
1098 (set_attr "mode" "HI")])
1100 (define_insn "cmpqi_ccz_1"
1102 (compare:CCZ (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1103 (match_operand:QI 1 "const0_operand" "n,n")))]
1106 test{b}\\t{%0, %0|%0, %0}
1107 cmp{b}\\t{$0, %0|%0, 0}"
1108 [(set_attr "type" "test,icmp")
1109 (set_attr "length_immediate" "0,1")
1110 (set_attr "mode" "QI")])
1112 (define_insn "*cmpqi_ccno_1"
1114 (compare:CCNO (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1115 (match_operand:QI 1 "const0_operand" "n,n")))]
1118 test{b}\\t{%0, %0|%0, %0}
1119 cmp{b}\\t{$0, %0|%0, 0}"
1120 [(set_attr "type" "test,icmp")
1121 (set_attr "length_immediate" "0,1")
1122 (set_attr "mode" "QI")])
1124 (define_insn "*cmpqi_1"
1126 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1127 (match_operand:QI 1 "general_operand" "qi,mq")))]
1128 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1129 "cmp{b}\\t{%1, %0|%0, %1}"
1130 [(set_attr "type" "icmp")
1131 (set_attr "mode" "QI")])
1133 (define_insn "*cmpqi_ext_1"
1136 (match_operand:QI 0 "general_operand" "qm")
1139 (match_operand 1 "ext_register_operand" "q")
1141 (const_int 8)) 0)))]
1143 "cmp{b}\\t{%h1, %0|%0, %h1}"
1144 [(set_attr "type" "icmp")
1145 (set_attr "mode" "QI")])
1147 (define_insn "*cmpqi_ext_2"
1152 (match_operand 0 "ext_register_operand" "q")
1155 (match_operand:QI 1 "const0_operand" "n")))]
1156 "ix86_match_ccmode (insn, CCNOmode)"
1157 "test{b}\\t%h0, %h0"
1158 [(set_attr "type" "test")
1159 (set_attr "length_immediate" "0")
1160 (set_attr "mode" "QI")])
1162 (define_insn "cmpqi_ext_3"
1167 (match_operand 0 "ext_register_operand" "q")
1170 (match_operand:QI 1 "general_operand" "qmn")))]
1172 "cmp{b}\\t{%1, %h0|%h0, %1}"
1173 [(set_attr "type" "icmp")
1174 (set_attr "mode" "QI")])
1176 (define_insn "*cmpqi_ext_4"
1181 (match_operand 0 "ext_register_operand" "q")
1186 (match_operand 1 "ext_register_operand" "q")
1188 (const_int 8)) 0)))]
1190 "cmp{b}\\t{%h1, %h0|%h0, %h1}"
1191 [(set_attr "type" "icmp")
1192 (set_attr "mode" "QI")])
1194 ;; These implement float point compares.
1195 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1196 ;; which would allow mix and match FP modes on the compares. Which is what
1197 ;; the old patterns did, but with many more of them.
1199 (define_expand "cmpxf"
1201 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1202 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1206 ix86_compare_op0 = operands[0];
1207 ix86_compare_op1 = operands[1];
1211 (define_expand "cmpdf"
1213 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1214 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
1218 ix86_compare_op0 = operands[0];
1219 ix86_compare_op1 = operands[1];
1223 (define_expand "cmpsf"
1225 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1226 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
1230 ix86_compare_op0 = operands[0];
1231 ix86_compare_op1 = operands[1];
1235 ;; FP compares, step 1:
1236 ;; Set the FP condition codes.
1238 ;; CCFPmode compare with exceptions
1239 ;; CCFPUmode compare with no exceptions
1241 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1242 ;; and that fp moves clobber the condition codes, and that there is
1243 ;; currently no way to describe this fact to reg-stack. So there are
1244 ;; no splitters yet for this.
1246 ;; %%% YIKES! This scheme does not retain a strong connection between
1247 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1248 ;; work! Only allow tos/mem with tos in op 0.
1250 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
1251 ;; things aren't as bad as they sound...
1253 (define_insn "*cmpfp_0"
1254 [(set (match_operand:HI 0 "register_operand" "=a")
1256 [(compare:CCFP (match_operand 1 "register_operand" "f")
1257 (match_operand 2 "const0_operand" "X"))] 9))]
1259 && FLOAT_MODE_P (GET_MODE (operands[1]))
1260 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1263 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1264 return \"ftst\;fnstsw\\t%0\;fstp\\t%y0\";
1266 return \"ftst\;fnstsw\\t%0\";
1268 [(set_attr "type" "multi")
1269 (set_attr "mode" "unknownfp")])
1271 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1272 ;; used to manage the reg stack popping would not be preserved.
1274 (define_insn "*cmpfp_2_sf"
1277 (match_operand:SF 0 "register_operand" "f")
1278 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1280 "* return output_fp_compare (insn, operands, 0, 0);"
1281 [(set_attr "type" "fcmp")
1282 (set_attr "mode" "SF")])
1284 (define_insn "*cmpfp_2_sf_1"
1285 [(set (match_operand:HI 0 "register_operand" "=a")
1288 (match_operand:SF 1 "register_operand" "f")
1289 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
1291 "* return output_fp_compare (insn, operands, 2, 0);"
1292 [(set_attr "type" "fcmp")
1293 (set_attr "mode" "SF")])
1295 (define_insn "*cmpfp_2_df"
1298 (match_operand:DF 0 "register_operand" "f")
1299 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1301 "* return output_fp_compare (insn, operands, 0, 0);"
1302 [(set_attr "type" "fcmp")
1303 (set_attr "mode" "DF")])
1305 (define_insn "*cmpfp_2_df_1"
1306 [(set (match_operand:HI 0 "register_operand" "=a")
1309 (match_operand:DF 1 "register_operand" "f")
1310 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
1312 "* return output_fp_compare (insn, operands, 2, 0);"
1313 [(set_attr "type" "multi")
1314 (set_attr "mode" "DF")])
1316 (define_insn "*cmpfp_2_xf"
1319 (match_operand:XF 0 "register_operand" "f")
1320 (match_operand:XF 1 "register_operand" "f")))]
1322 "* return output_fp_compare (insn, operands, 0, 0);"
1323 [(set_attr "type" "fcmp")
1324 (set_attr "mode" "XF")])
1326 (define_insn "*cmpfp_2_xf_1"
1327 [(set (match_operand:HI 0 "register_operand" "=a")
1330 (match_operand:XF 1 "register_operand" "f")
1331 (match_operand:XF 2 "register_operand" "f"))] 9))]
1333 "* return output_fp_compare (insn, operands, 2, 0);"
1334 [(set_attr "type" "multi")
1335 (set_attr "mode" "XF")])
1337 (define_insn "*cmpfp_2u"
1338 [(set (reg:CCFPU 18)
1340 (match_operand 0 "register_operand" "f")
1341 (match_operand 1 "register_operand" "f")))]
1343 && FLOAT_MODE_P (GET_MODE (operands[0]))
1344 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1345 "* return output_fp_compare (insn, operands, 0, 1);"
1346 [(set_attr "type" "fcmp")
1347 (set_attr "mode" "unknownfp")])
1349 (define_insn "*cmpfp_2u_1"
1350 [(set (match_operand:HI 0 "register_operand" "=a")
1353 (match_operand 1 "register_operand" "f")
1354 (match_operand 2 "register_operand" "f"))] 9))]
1356 && FLOAT_MODE_P (GET_MODE (operands[1]))
1357 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1358 "* return output_fp_compare (insn, operands, 2, 1);"
1359 [(set_attr "type" "multi")
1360 (set_attr "mode" "unknownfp")])
1362 ;; Patterns to match the SImode-in-memory ficom instructions.
1364 ;; %%% Play games with accepting gp registers, as otherwise we have to
1365 ;; force them to memory during rtl generation, which is no good. We
1366 ;; can get rid of this once we teach reload to do memory input reloads
1369 (define_insn "*ficom_1"
1372 (match_operand 0 "register_operand" "f,f")
1373 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1374 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1375 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1378 ;; Split the not-really-implemented gp register case into a
1379 ;; push-op-pop sequence.
1381 ;; %%% This is most efficient, but am I gonna get in trouble
1382 ;; for separating cc0_setter and cc0_user?
1387 (match_operand:SF 0 "register_operand" "")
1388 (float (match_operand:SI 1 "register_operand" ""))))]
1389 "0 && TARGET_80387 && reload_completed"
1390 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1391 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1392 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1393 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1394 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1395 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1397 ;; FP compares, step 2
1398 ;; Move the fpsw to ax.
1400 (define_insn "x86_fnstsw_1"
1401 [(set (match_operand:HI 0 "register_operand" "=a")
1402 (unspec:HI [(reg 18)] 9))]
1405 [(set_attr "length" "2")
1406 (set_attr "mode" "SI")
1407 (set_attr "i387" "1")
1408 (set_attr "ppro_uops" "few")])
1410 ;; FP compares, step 3
1411 ;; Get ax into flags, general case.
1413 (define_insn "x86_sahf_1"
1415 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1418 [(set_attr "length" "1")
1419 (set_attr "athlon_decode" "vector")
1420 (set_attr "mode" "SI")
1421 (set_attr "ppro_uops" "one")])
1423 ;; Pentium Pro can do steps 1 through 3 in one go.
1425 (define_insn "*cmpfp_i"
1427 (compare:CCFP (match_operand 0 "register_operand" "f")
1428 (match_operand 1 "register_operand" "f")))]
1429 "TARGET_80387 && TARGET_CMOVE
1430 && FLOAT_MODE_P (GET_MODE (operands[0]))
1431 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1432 "* return output_fp_compare (insn, operands, 1, 0);"
1433 [(set_attr "type" "fcmp")
1434 (set_attr "mode" "unknownfp")
1435 (set_attr "athlon_decode" "vector")])
1437 (define_insn "*cmpfp_iu"
1438 [(set (reg:CCFPU 17)
1439 (compare:CCFPU (match_operand 0 "register_operand" "f")
1440 (match_operand 1 "register_operand" "f")))]
1441 "TARGET_80387 && TARGET_CMOVE
1442 && FLOAT_MODE_P (GET_MODE (operands[0]))
1443 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1444 "* return output_fp_compare (insn, operands, 1, 1);"
1445 [(set_attr "type" "fcmp")
1446 (set_attr "mode" "unknownfp")
1447 (set_attr "athlon_decode" "vector")])
1449 ;; Move instructions.
1451 ;; General case of fullword move.
1453 (define_expand "movsi"
1454 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1455 (match_operand:SI 1 "general_operand" ""))]
1457 "ix86_expand_move (SImode, operands); DONE;")
1459 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1462 ;; %%% We don't use a post-inc memory reference because x86 is not a
1463 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1464 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1465 ;; targets without our curiosities, and it is just as easy to represent
1466 ;; this differently.
1468 (define_insn "pushsi2"
1469 [(set (match_operand:SI 0 "push_operand" "=<")
1470 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1473 [(set_attr "type" "push")
1474 (set_attr "mode" "SI")])
1476 (define_insn "*pushsi2_prologue"
1477 [(set (match_operand:SI 0 "push_operand" "=<")
1478 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1479 (set (reg:SI 6) (reg:SI 6))]
1482 [(set_attr "type" "push")
1483 (set_attr "mode" "SI")])
1485 (define_insn "*popsi1_epilogue"
1486 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1487 (mem:SI (reg:SI 7)))
1489 (plus:SI (reg:SI 7) (const_int 4)))
1490 (set (reg:SI 6) (reg:SI 6))]
1493 [(set_attr "type" "pop")
1494 (set_attr "mode" "SI")])
1496 (define_insn "popsi1"
1497 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1498 (mem:SI (reg:SI 7)))
1500 (plus:SI (reg:SI 7) (const_int 4)))]
1503 [(set_attr "type" "pop")
1504 (set_attr "mode" "SI")])
1506 (define_insn "*movsi_xor"
1507 [(set (match_operand:SI 0 "register_operand" "=r")
1508 (match_operand:SI 1 "const0_operand" "i"))
1509 (clobber (reg:CC 17))]
1510 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1511 "xor{l}\\t{%0, %0|%0, %0}"
1512 [(set_attr "type" "alu1")
1513 (set_attr "mode" "SI")
1514 (set_attr "length_immediate" "0")])
1516 (define_insn "*movsi_or"
1517 [(set (match_operand:SI 0 "register_operand" "=r")
1518 (match_operand:SI 1 "immediate_operand" "i"))
1519 (clobber (reg:CC 17))]
1520 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1521 && INTVAL (operands[1]) == -1
1522 && (TARGET_PENTIUM || optimize_size)"
1525 operands[1] = constm1_rtx;
1526 return \"or{l}\\t{%1, %0|%1, %0}\";
1528 [(set_attr "type" "alu1")
1529 (set_attr "mode" "SI")
1530 (set_attr "length_immediate" "1")])
1532 (define_insn "*movsi_1"
1533 [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m")
1534 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin"))]
1535 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1538 switch (get_attr_type (insn))
1541 return \"lea{l}\\t{%1, %0|%0, %1}\";
1543 if (flag_pic && SYMBOLIC_CONST (operands[1]))
1545 return \"mov{l}\\t{%1, %0|%0, %1}\";
1549 (cond [(and (ne (symbol_ref "flag_pic") (const_int 0))
1550 (match_operand:SI 1 "symbolic_operand" ""))
1551 (const_string "lea")
1553 (const_string "imov")))
1554 (set_attr "modrm" "0,*,0,*")
1555 (set_attr "mode" "SI")])
1557 (define_insn "*swapsi"
1558 [(set (match_operand:SI 0 "register_operand" "+r")
1559 (match_operand:SI 1 "register_operand" "+r"))
1564 [(set_attr "type" "imov")
1565 (set_attr "pent_pair" "np")
1566 (set_attr "athlon_decode" "vector")
1567 (set_attr "mode" "SI")
1568 (set_attr "modrm" "0")
1569 (set_attr "ppro_uops" "few")])
1571 (define_expand "movhi"
1572 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1573 (match_operand:HI 1 "general_operand" ""))]
1575 "ix86_expand_move (HImode, operands); DONE;")
1577 (define_insn "pushhi2"
1578 [(set (match_operand:HI 0 "push_operand" "=<,<")
1579 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1582 push{w}\\t{|WORD PTR }%1
1584 [(set_attr "type" "push")
1585 (set_attr "mode" "HI")])
1587 (define_insn "pophi1"
1588 [(set (match_operand:HI 0 "nonimmediate_operand" "=r*m")
1589 (mem:HI (reg:SI 7)))
1591 (plus:SI (reg:SI 7) (const_int 2)))]
1594 [(set_attr "type" "pop")
1595 (set_attr "mode" "HI")])
1597 (define_insn "*movhi_1"
1598 [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
1599 (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1600 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1603 switch (get_attr_type (insn))
1606 /* movzwl is faster than movw on p2 due to partial word stalls,
1607 though not as fast as an aligned movl. */
1608 return \"movz{wl|x}\\t{%1, %k0|%k0, %1}\";
1610 if (get_attr_mode (insn) == MODE_SI)
1611 return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1613 return \"mov{w}\\t{%1, %0|%0, %1}\";
1617 (cond [(and (eq_attr "alternative" "0,1")
1618 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1620 (eq (symbol_ref "TARGET_HIMODE_MATH")
1622 (const_string "imov")
1623 (and (eq_attr "alternative" "2,3,4")
1624 (match_operand:HI 1 "aligned_operand" ""))
1625 (const_string "imov")
1626 (and (ne (symbol_ref "TARGET_MOVX")
1628 (eq_attr "alternative" "0,1,3,4"))
1629 (const_string "imovx")
1631 (const_string "imov")))
1633 (cond [(eq_attr "type" "imovx")
1635 (and (eq_attr "alternative" "2,3,4")
1636 (match_operand:HI 1 "aligned_operand" ""))
1638 (and (eq_attr "alternative" "0,1")
1639 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1641 (eq (symbol_ref "TARGET_HIMODE_MATH")
1645 (const_string "HI")))
1646 (set_attr "modrm" "0,*,*,0,*,*")])
1648 (define_insn "*swaphi_1"
1649 [(set (match_operand:HI 0 "register_operand" "+r")
1650 (match_operand:HI 1 "register_operand" "+r"))
1653 "TARGET_PARTIAL_REG_STALL"
1655 [(set_attr "type" "imov")
1656 (set_attr "pent_pair" "np")
1657 (set_attr "mode" "HI")
1658 (set_attr "modrm" "0")
1659 (set_attr "ppro_uops" "few")])
1661 (define_insn "*swaphi_2"
1662 [(set (match_operand:HI 0 "register_operand" "+r")
1663 (match_operand:HI 1 "register_operand" "+r"))
1666 "! TARGET_PARTIAL_REG_STALL"
1667 "xchg{l}\\t%k1, %k0"
1668 [(set_attr "type" "imov")
1669 (set_attr "pent_pair" "np")
1670 (set_attr "mode" "SI")
1671 (set_attr "modrm" "0")
1672 (set_attr "ppro_uops" "few")])
1674 (define_expand "movstricthi"
1675 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1676 (match_operand:HI 1 "general_operand" ""))]
1677 "! TARGET_PARTIAL_REG_STALL"
1680 /* Don't generate memory->memory moves, go through a register */
1681 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1682 operands[1] = force_reg (HImode, operands[1]);
1685 (define_insn "*movstricthi_1"
1686 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1687 (match_operand:HI 1 "general_operand" "rn,m"))]
1688 "! TARGET_PARTIAL_REG_STALL
1689 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1690 "mov{w}\\t{%1, %0|%0, %1}"
1691 [(set_attr "type" "imov")
1692 (set_attr "mode" "HI")])
1694 (define_insn "*movstricthi_xor"
1695 [(set (strict_low_part (match_operand:HI 0 "register_operand" "=r"))
1696 (match_operand:HI 1 "const0_operand" "i"))
1697 (clobber (reg:CC 17))]
1698 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1699 "xor{w}\\t{%0, %0|%0, %0}"
1700 [(set_attr "type" "alu1")
1701 (set_attr "mode" "HI")
1702 (set_attr "length_immediate" "0")])
1704 (define_expand "movqi"
1705 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1706 (match_operand:QI 1 "general_operand" ""))]
1708 "ix86_expand_move (QImode, operands); DONE;")
1710 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1711 ;; "push a byte". But actually we use pushw, which has the effect
1712 ;; of rounding the amount pushed up to a halfword.
1714 (define_insn "pushqi2"
1715 [(set (match_operand:QI 0 "push_operand" "=<,<")
1716 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1719 push{w}\\t{|word ptr }%1
1721 [(set_attr "type" "push")
1722 (set_attr "mode" "HI")])
1724 (define_insn "popqi1"
1725 [(set (match_operand:QI 0 "nonimmediate_operand" "=r*m")
1726 (mem:QI (reg:SI 7)))
1728 (plus:SI (reg:SI 7) (const_int 2)))]
1731 [(set_attr "type" "pop")
1732 (set_attr "mode" "HI")])
1734 ;; Situation is quite tricky about when to choose full sized (SImode) move
1735 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1736 ;; partial register dependency machines (such as AMD Athlon), where QImode
1737 ;; moves issue extra dependency and for partial register stalls machines
1738 ;; that don't use QImode patterns (and QImode move cause stall on the next
1741 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1742 ;; register stall machines with, where we use QImode instructions, since
1743 ;; partial register stall can be caused there. Then we use movzx.
1744 (define_insn "*movqi_1"
1745 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1746 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1747 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1750 switch (get_attr_type (insn))
1753 if (!QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1755 return \"movz{bl|x}\\t{%1, %k0|%k0, %1}\";
1757 if (get_attr_mode (insn) == MODE_SI)
1758 return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1760 return \"mov{b}\\t{%1, %0|%0, %1}\";
1764 (cond [(and (eq_attr "alternative" "3")
1765 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1767 (eq (symbol_ref "TARGET_QIMODE_MATH")
1769 (const_string "imov")
1770 (eq_attr "alternative" "3,5")
1771 (const_string "imovx")
1772 (and (ne (symbol_ref "TARGET_MOVX")
1774 (eq_attr "alternative" "2"))
1775 (const_string "imovx")
1777 (const_string "imov")))
1779 (cond [(eq_attr "alternative" "3,4,5")
1781 (eq_attr "alternative" "6")
1783 (eq_attr "type" "imovx")
1785 (and (eq_attr "type" "imov")
1786 (and (eq_attr "alternative" "0,1,2")
1787 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1790 ;; Avoid partial register stalls when not using QImode arithmetic
1791 (and (eq_attr "type" "imov")
1792 (and (eq_attr "alternative" "0,1,2")
1793 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1795 (eq (symbol_ref "TARGET_QIMODE_MATH")
1799 (const_string "QI")))])
1801 (define_expand "reload_outqi"
1802 [(parallel [(match_operand:QI 0 "" "=m")
1803 (match_operand:QI 1 "register_operand" "r")
1804 (match_operand:QI 2 "register_operand" "=&q")])]
1809 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1811 if (reg_overlap_mentioned_p (op2, op0))
1813 if (! q_regs_operand (op1, QImode))
1815 emit_insn (gen_movqi (op2, op1));
1818 emit_insn (gen_movqi (op0, op1));
1822 (define_insn "*swapqi"
1823 [(set (match_operand:QI 0 "register_operand" "+r")
1824 (match_operand:QI 1 "register_operand" "+r"))
1829 [(set_attr "type" "imov")
1830 (set_attr "pent_pair" "np")
1831 (set_attr "mode" "QI")
1832 (set_attr "modrm" "0")
1833 (set_attr "ppro_uops" "few")])
1835 (define_expand "movstrictqi"
1836 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1837 (match_operand:QI 1 "general_operand" ""))]
1838 "! TARGET_PARTIAL_REG_STALL"
1841 /* Don't generate memory->memory moves, go through a register */
1842 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1843 operands[1] = force_reg (QImode, operands[1]);
1846 (define_insn "*movstrictqi_1"
1847 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1848 (match_operand:QI 1 "general_operand" "*qn,m"))]
1849 "! TARGET_PARTIAL_REG_STALL
1850 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1851 "mov{b}\\t{%1, %0|%0, %1}"
1852 [(set_attr "type" "imov")
1853 (set_attr "mode" "QI")])
1855 (define_insn "*movstrictqi_xor"
1856 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1857 (match_operand:QI 1 "const0_operand" "i"))
1858 (clobber (reg:CC 17))]
1859 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1860 "xor{b}\\t{%0, %0|%0, %0}"
1861 [(set_attr "type" "alu1")
1862 (set_attr "mode" "QI")
1863 (set_attr "length_immediate" "0")])
1865 (define_insn "*movsi_extv_1"
1866 [(set (match_operand:SI 0 "register_operand" "=r")
1867 (sign_extract:SI (match_operand:SI 1 "register_operand" "q")
1871 "movs{bl|x}\\t{%h1, %0|%0, %h1}"
1872 [(set_attr "type" "imovx")
1873 (set_attr "mode" "SI")])
1875 (define_insn "*movhi_extv_1"
1876 [(set (match_operand:HI 0 "register_operand" "=r")
1877 (sign_extract:HI (match_operand:SI 1 "register_operand" "q")
1881 "movs{bl|x}\\t{%h1, %k0|%k0, %h1}"
1882 [(set_attr "type" "imovx")
1883 (set_attr "mode" "SI")])
1885 (define_insn "*movqi_extv_1"
1886 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
1887 (sign_extract:QI (match_operand:SI 1 "register_operand" "q,q")
1893 switch (get_attr_type (insn))
1896 return \"movs{bl|x}\\t{%h1, %k0|%k0, %h1}\";
1898 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
1902 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1903 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1904 (ne (symbol_ref "TARGET_MOVX")
1906 (const_string "imovx")
1907 (const_string "imov")))
1909 (if_then_else (eq_attr "type" "imovx")
1911 (const_string "QI")))])
1913 (define_insn "*movsi_extzv_1"
1914 [(set (match_operand:SI 0 "register_operand" "=r")
1915 (zero_extract:SI (match_operand 1 "ext_register_operand" "q")
1919 "movz{bl|x}\\t{%h1, %0|%0, %h1}"
1920 [(set_attr "type" "imovx")
1921 (set_attr "mode" "SI")])
1923 (define_insn "*movqi_extzv_1"
1924 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
1925 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "q,q")
1931 switch (get_attr_type (insn))
1934 return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\";
1936 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
1940 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1941 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1942 (ne (symbol_ref "TARGET_MOVX")
1944 (const_string "imovx")
1945 (const_string "imov")))
1947 (if_then_else (eq_attr "type" "imovx")
1949 (const_string "QI")))])
1951 (define_insn "*movsi_insv_1"
1952 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
1955 (match_operand:SI 1 "nonimmediate_operand" "qm"))]
1957 "mov{b}\\t{%b1, %h0|%h0, %b1}"
1958 [(set_attr "type" "imov")
1959 (set_attr "mode" "QI")])
1961 (define_insn "*movqi_insv_2"
1962 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
1965 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "q")
1969 "mov{b}\\t{%h1, %h0|%h0, %h1}"
1970 [(set_attr "type" "imov")
1971 (set_attr "mode" "QI")])
1973 (define_expand "movdi"
1974 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1975 (match_operand:DI 1 "general_operand" ""))]
1977 "ix86_expand_move (DImode, operands); DONE;")
1979 (define_insn "*pushdi"
1980 [(set (match_operand:DI 0 "push_operand" "=<")
1981 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1985 (define_insn "*movdi_2"
1986 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
1987 (match_operand:DI 1 "general_operand" "riFo,riF"))]
1988 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1992 [(set (match_operand:DI 0 "push_operand" "")
1993 (match_operand:DI 1 "general_operand" ""))]
1996 "if (!ix86_split_long_move (operands)) abort (); DONE;")
1998 ;; %%% This multiword shite has got to go.
2000 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2001 (match_operand:DI 1 "general_operand" ""))]
2003 [(set (match_dup 2) (match_dup 5))
2004 (set (match_dup 3) (match_dup 6))]
2005 "if (ix86_split_long_move (operands)) DONE;")
2007 (define_expand "movsf"
2008 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2009 (match_operand:SF 1 "general_operand" ""))]
2011 "ix86_expand_move (SFmode, operands); DONE;")
2013 (define_insn "*pushsf"
2014 [(set (match_operand:SF 0 "push_operand" "=<,<")
2015 (match_operand:SF 1 "general_no_elim_operand" "f#r,rFm#f"))]
2019 switch (which_alternative)
2022 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2023 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2024 operands[2] = stack_pointer_rtx;
2025 operands[3] = GEN_INT (4);
2026 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2027 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2029 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2032 return \"push{l}\\t%1\";
2038 [(set_attr "type" "multi,push")
2039 (set_attr "mode" "SF,SI")])
2042 [(set (match_operand:SF 0 "push_operand" "")
2043 (match_operand:SF 1 "memory_operand" ""))]
2045 && GET_CODE (operands[1]) == MEM
2046 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2047 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2050 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2053 ;; %%% Kill this when call knows how to work this out.
2055 [(set (match_operand:SF 0 "push_operand" "")
2056 (match_operand:SF 1 "register_operand" ""))]
2057 "FP_REGNO_P (REGNO (operands[1]))"
2058 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2059 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2061 (define_insn "*movsf_1"
2062 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,m")
2063 (match_operand:SF 1 "general_operand" "fm#r,f#r,G,rmF#f,Fr#f"))]
2064 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2065 && (reload_in_progress || reload_completed
2066 || GET_CODE (operands[1]) != CONST_DOUBLE
2067 || memory_operand (operands[0], SFmode))"
2070 switch (which_alternative)
2073 if (REG_P (operands[1])
2074 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2075 return \"fstp\\t%y0\";
2076 else if (STACK_TOP_P (operands[0]))
2077 return \"fld%z1\\t%y1\";
2079 return \"fst\\t%y0\";
2082 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2083 return \"fstp%z0\\t%y0\";
2085 return \"fst%z0\\t%y0\";
2088 switch (standard_80387_constant_p (operands[1]))
2099 return \"mov{l}\\t{%1, %0|%0, %1}\";
2105 [(set_attr "type" "fmov,fmov,fmov,imov,imov")
2106 (set_attr "mode" "SF,SF,SF,SI,SI")])
2109 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2110 (match_operand:SF 1 "memory_operand" ""))]
2112 && GET_CODE (operands[1]) == MEM
2113 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2114 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2115 && (!(FP_REG_P (operands[0]) ||
2116 (GET_CODE (operands[0]) == SUBREG
2117 && FP_REG_P (SUBREG_REG (operands[0]))))
2118 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
2121 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2123 (define_insn "swapsf"
2124 [(set (match_operand:SF 0 "register_operand" "+f")
2125 (match_operand:SF 1 "register_operand" "+f"))
2131 if (STACK_TOP_P (operands[0]))
2132 return \"fxch\\t%1\";
2134 return \"fxch\\t%0\";
2136 [(set_attr "type" "fxch")
2137 (set_attr "mode" "SF")])
2139 (define_expand "movdf"
2140 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2141 (match_operand:DF 1 "general_operand" ""))]
2143 "ix86_expand_move (DFmode, operands); DONE;")
2145 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2146 ;; Size of pushdf using integer insturctions is 2+2*memory operand size
2147 ;; On the average, pushdf using integers can be still shorter. Allow this
2148 ;; pattern for optimize_size too.
2150 (define_insn "*pushdf_nointeger"
2151 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2152 (match_operand:DF 1 "general_no_elim_operand" "f,Fo#f,*r#f"))]
2153 "!TARGET_INTEGER_DFMODE_MOVES"
2156 switch (which_alternative)
2159 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2160 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2161 operands[2] = stack_pointer_rtx;
2162 operands[3] = GEN_INT (8);
2163 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2164 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2166 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2176 [(set_attr "type" "multi")
2177 (set_attr "mode" "DF,SI,SI")])
2179 (define_insn "*pushdf_integer"
2180 [(set (match_operand:DF 0 "push_operand" "=<,<")
2181 (match_operand:DF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2182 "TARGET_INTEGER_DFMODE_MOVES"
2185 switch (which_alternative)
2188 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2189 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2190 operands[2] = stack_pointer_rtx;
2191 operands[3] = GEN_INT (8);
2192 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2193 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2195 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2204 [(set_attr "type" "multi")
2205 (set_attr "mode" "DF,SI")])
2207 ;; %%% Kill this when call knows how to work this out.
2209 [(set (match_operand:DF 0 "push_operand" "")
2210 (match_operand:DF 1 "register_operand" ""))]
2211 "reload_completed && FP_REGNO_P (REGNO (operands[1]))"
2212 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2213 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2217 [(set (match_operand:DF 0 "push_operand" "")
2218 (match_operand:DF 1 "general_operand" ""))]
2221 "if (!ix86_split_long_move (operands)) abort (); DONE;")
2223 ;; Moving is usually shorter when only FP registers are used. This separate
2224 ;; movdf pattern avoids the use of integer registers for FP operations
2225 ;; when optimizing for size.
2227 (define_insn "*movdf_nointeger"
2228 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2229 (match_operand:DF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2230 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2231 && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2232 && (reload_in_progress || reload_completed
2233 || GET_CODE (operands[1]) != CONST_DOUBLE
2234 || memory_operand (operands[0], DFmode))"
2237 switch (which_alternative)
2240 if (REG_P (operands[1])
2241 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2242 return \"fstp\\t%y0\";
2243 else if (STACK_TOP_P (operands[0]))
2244 return \"fld%z1\\t%y1\";
2246 return \"fst\\t%y0\";
2249 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2250 return \"fstp%z0\\t%y0\";
2252 return \"fst%z0\\t%y0\";
2255 switch (standard_80387_constant_p (operands[1]))
2272 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2273 (set_attr "mode" "DF,DF,DF,SI,SI")])
2275 (define_insn "*movdf_integer"
2276 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2277 (match_operand:DF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2278 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2279 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2280 && (reload_in_progress || reload_completed
2281 || GET_CODE (operands[1]) != CONST_DOUBLE
2282 || memory_operand (operands[0], DFmode))"
2285 switch (which_alternative)
2288 if (REG_P (operands[1])
2289 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2290 return \"fstp\\t%y0\";
2291 else if (STACK_TOP_P (operands[0]))
2292 return \"fld%z1\\t%y1\";
2294 return \"fst\\t%y0\";
2297 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298 return \"fstp%z0\\t%y0\";
2300 return \"fst%z0\\t%y0\";
2303 switch (standard_80387_constant_p (operands[1]))
2320 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2321 (set_attr "mode" "DF,DF,DF,SI,SI")])
2324 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2325 (match_operand:DF 1 "general_operand" ""))]
2327 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2328 && ! (FP_REG_P (operands[0]) ||
2329 (GET_CODE (operands[0]) == SUBREG
2330 && FP_REG_P (SUBREG_REG (operands[0]))))
2331 && ! (FP_REG_P (operands[1]) ||
2332 (GET_CODE (operands[1]) == SUBREG
2333 && FP_REG_P (SUBREG_REG (operands[1]))))"
2334 [(set (match_dup 2) (match_dup 5))
2335 (set (match_dup 3) (match_dup 6))]
2336 "if (ix86_split_long_move (operands)) DONE;")
2339 [(set (match_operand:DF 0 "register_operand" "")
2340 (match_operand:DF 1 "memory_operand" ""))]
2342 && GET_CODE (operands[1]) == MEM
2343 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2344 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2345 && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
2348 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2350 (define_insn "swapdf"
2351 [(set (match_operand:DF 0 "register_operand" "+f")
2352 (match_operand:DF 1 "register_operand" "+f"))
2358 if (STACK_TOP_P (operands[0]))
2359 return \"fxch\\t%1\";
2361 return \"fxch\\t%0\";
2363 [(set_attr "type" "fxch")
2364 (set_attr "mode" "DF")])
2366 (define_expand "movxf"
2367 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2368 (match_operand:XF 1 "general_operand" ""))]
2370 "ix86_expand_move (XFmode, operands); DONE;")
2372 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2373 ;; Size of pushdf using integer insturctions is 3+3*memory operand size
2374 ;; Pushing using integer instructions is longer except for constants
2375 ;; and direct memory references.
2376 ;; (assuming that any given constant is pushed only once, but this ought to be
2377 ;; handled elsewhere).
2379 (define_insn "*pushxf_nointeger"
2380 [(set (match_operand:XF 0 "push_operand" "=<,<,<")
2381 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2385 switch (which_alternative)
2388 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2389 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2390 operands[2] = stack_pointer_rtx;
2391 operands[3] = GEN_INT (12);
2392 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2393 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2395 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2405 [(set_attr "type" "multi")
2406 (set_attr "mode" "XF,SI,SI")])
2408 (define_insn "*pushxf_integer"
2409 [(set (match_operand:XF 0 "push_operand" "=<,<")
2410 (match_operand:XF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2414 switch (which_alternative)
2417 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2418 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2419 operands[2] = stack_pointer_rtx;
2420 operands[3] = GEN_INT (12);
2421 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2422 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2424 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2433 [(set_attr "type" "multi")
2434 (set_attr "mode" "XF,SI")])
2437 [(set (match_operand:XF 0 "push_operand" "")
2438 (match_operand:XF 1 "general_operand" ""))]
2440 && (!REG_P (operands[1]) || !FP_REGNO_P (REGNO (operands[1])))"
2442 "if (!ix86_split_long_move (operands)) abort (); DONE;")
2445 [(set (match_operand:XF 0 "push_operand" "")
2446 (match_operand:XF 1 "register_operand" ""))]
2447 "FP_REGNO_P (REGNO (operands[1]))"
2448 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2449 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2451 ;; Do not use integer registers when optimizing for size
2452 (define_insn "*movxf_nointeger"
2453 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2454 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2455 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2457 && (reload_in_progress || reload_completed
2458 || GET_CODE (operands[1]) != CONST_DOUBLE
2459 || memory_operand (operands[0], XFmode))"
2462 switch (which_alternative)
2465 if (REG_P (operands[1])
2466 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2467 return \"fstp\\t%y0\";
2468 else if (STACK_TOP_P (operands[0]))
2469 return \"fld%z1\\t%y1\";
2471 return \"fst\\t%y0\";
2474 /* There is no non-popping store to memory for XFmode. So if
2475 we need one, follow the store with a load. */
2476 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2477 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2479 return \"fstp%z0\\t%y0\";
2482 switch (standard_80387_constant_p (operands[1]))
2496 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2497 (set_attr "mode" "XF,XF,XF,SI,SI")])
2499 (define_insn "*movxf_integer"
2500 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2501 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2502 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2504 && (reload_in_progress || reload_completed
2505 || GET_CODE (operands[1]) != CONST_DOUBLE
2506 || memory_operand (operands[0], XFmode))"
2509 switch (which_alternative)
2512 if (REG_P (operands[1])
2513 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2514 return \"fstp\\t%y0\";
2515 else if (STACK_TOP_P (operands[0]))
2516 return \"fld%z1\\t%y1\";
2518 return \"fst\\t%y0\";
2521 /* There is no non-popping store to memory for XFmode. So if
2522 we need one, follow the store with a load. */
2523 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2524 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2526 return \"fstp%z0\\t%y0\";
2529 switch (standard_80387_constant_p (operands[1]))
2543 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2544 (set_attr "mode" "XF,XF,XF,SI,SI")])
2547 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2548 (match_operand:XF 1 "general_operand" ""))]
2550 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2551 && ! (FP_REG_P (operands[0]) ||
2552 (GET_CODE (operands[0]) == SUBREG
2553 && FP_REG_P (SUBREG_REG (operands[0]))))
2554 && ! (FP_REG_P (operands[1]) ||
2555 (GET_CODE (operands[1]) == SUBREG
2556 && FP_REG_P (SUBREG_REG (operands[1]))))"
2557 [(set (match_dup 2) (match_dup 5))
2558 (set (match_dup 3) (match_dup 6))
2559 (set (match_dup 4) (match_dup 7))]
2560 "if (ix86_split_long_move (operands)) DONE;")
2563 [(set (match_operand:XF 0 "register_operand" "")
2564 (match_operand:XF 1 "memory_operand" ""))]
2566 && GET_CODE (operands[1]) == MEM
2567 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2568 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2569 && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
2572 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2574 (define_insn "swapxf"
2575 [(set (match_operand:XF 0 "register_operand" "+f")
2576 (match_operand:XF 1 "register_operand" "+f"))
2582 if (STACK_TOP_P (operands[0]))
2583 return \"fxch\\t%1\";
2585 return \"fxch\\t%0\";
2587 [(set_attr "type" "fxch")
2588 (set_attr "mode" "XF")])
2590 ;; Zero extension instructions
2592 (define_expand "zero_extendhisi2"
2593 [(set (match_operand:SI 0 "register_operand" "")
2594 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2598 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2600 operands[1] = force_reg (HImode, operands[1]);
2601 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2606 (define_insn "zero_extendhisi2_and"
2607 [(set (match_operand:SI 0 "register_operand" "=r")
2608 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2609 (clobber (reg:CC 17))]
2610 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2612 [(set_attr "type" "alu1")
2613 (set_attr "mode" "SI")])
2616 [(set (match_operand:SI 0 "register_operand" "")
2617 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2618 (clobber (reg:CC 17))]
2619 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2620 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2621 (clobber (reg:CC 17))])]
2624 (define_insn "*zero_extendhisi2_movzwl"
2625 [(set (match_operand:SI 0 "register_operand" "=r")
2626 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2627 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2628 "movz{wl|x}\\t{%1, %0|%0, %1}"
2629 [(set_attr "type" "imovx")
2630 (set_attr "mode" "SI")])
2632 (define_expand "zero_extendqihi2"
2634 [(set (match_operand:HI 0 "register_operand" "")
2635 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2636 (clobber (reg:CC 17))])]
2640 (define_insn "*zero_extendqihi2_and"
2641 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2642 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2643 (clobber (reg:CC 17))]
2644 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2646 [(set_attr "type" "alu1")
2647 (set_attr "mode" "HI")])
2649 (define_insn "*zero_extendqihi2_movzbw_and"
2650 [(set (match_operand:HI 0 "register_operand" "=r,r")
2651 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2652 (clobber (reg:CC 17))]
2653 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2655 [(set_attr "type" "imovx,alu1")
2656 (set_attr "mode" "HI")])
2658 (define_insn "*zero_extendqihi2_movzbw"
2659 [(set (match_operand:HI 0 "register_operand" "=r")
2660 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2661 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2662 "movz{bw|x}\\t{%1, %0|%0, %1}"
2663 [(set_attr "type" "imovx")
2664 (set_attr "mode" "HI")])
2666 ;; For the movzbw case strip only the clobber
2668 [(set (match_operand:HI 0 "register_operand" "")
2669 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2670 (clobber (reg:CC 17))]
2672 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2673 && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
2674 [(set (match_operand:HI 0 "register_operand" "")
2675 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2677 ;; When source and destination does not overlap, clear destination
2678 ;; first and then do the movb
2680 [(set (match_operand:HI 0 "register_operand" "")
2681 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2682 (clobber (reg:CC 17))]
2684 && QI_REG_P (operands[0])
2685 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2686 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2687 [(set (match_dup 0) (const_int 0))
2688 (set (strict_low_part (match_dup 2)) (match_dup 1))]
2689 "operands[2] = gen_lowpart (QImode, operands[0]);")
2691 ;; Rest is handled by single and.
2693 [(set (match_operand:HI 0 "register_operand" "")
2694 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2695 (clobber (reg:CC 17))]
2697 && true_regnum (operands[0]) == true_regnum (operands[1])"
2698 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2699 (clobber (reg:CC 17))])]
2702 (define_expand "zero_extendqisi2"
2704 [(set (match_operand:SI 0 "register_operand" "")
2705 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2706 (clobber (reg:CC 17))])]
2710 (define_insn "*zero_extendqisi2_and"
2711 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2712 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2713 (clobber (reg:CC 17))]
2714 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2716 [(set_attr "type" "alu1")
2717 (set_attr "mode" "SI")])
2719 (define_insn "*zero_extendqisi2_movzbw_and"
2720 [(set (match_operand:SI 0 "register_operand" "=r,r")
2721 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2722 (clobber (reg:CC 17))]
2723 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2725 [(set_attr "type" "imovx,alu1")
2726 (set_attr "mode" "SI")])
2728 (define_insn "*zero_extendqisi2_movzbw"
2729 [(set (match_operand:SI 0 "register_operand" "=r")
2730 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2731 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2732 "movz{bl|x}\\t{%1, %0|%0, %1}"
2733 [(set_attr "type" "imovx")
2734 (set_attr "mode" "SI")])
2736 ;; For the movzbl case strip only the clobber
2738 [(set (match_operand:SI 0 "register_operand" "")
2739 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2740 (clobber (reg:CC 17))]
2742 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2743 && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
2745 (zero_extend:SI (match_dup 1)))])
2747 ;; When source and destination does not overlap, clear destination
2748 ;; first and then do the movb
2750 [(set (match_operand:SI 0 "register_operand" "")
2751 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2752 (clobber (reg:CC 17))]
2754 && QI_REG_P (operands[0])
2755 && (QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
2756 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2757 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2758 [(set (match_dup 0) (const_int 0))
2759 (set (strict_low_part (match_dup 2)) (match_dup 1))]
2760 "operands[2] = gen_lowpart (QImode, operands[0]);")
2762 ;; Rest is handled by single and.
2764 [(set (match_operand:SI 0 "register_operand" "")
2765 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
2766 (clobber (reg:CC 17))]
2768 && true_regnum (operands[0]) == true_regnum (operands[1])"
2769 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
2770 (clobber (reg:CC 17))])]
2773 ;; %%% Kill me once multi-word ops are sane.
2774 (define_insn "zero_extendsidi2"
2775 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
2776 (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))
2777 (clobber (reg:CC 17))]
2780 [(set_attr "mode" "SI")])
2783 [(set (match_operand:DI 0 "register_operand" "")
2784 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
2785 (clobber (reg:CC 17))]
2786 "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
2787 [(set (match_dup 4) (const_int 0))]
2788 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2791 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2792 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
2793 (clobber (reg:CC 17))]
2795 [(set (match_dup 3) (match_dup 1))
2796 (set (match_dup 4) (const_int 0))]
2797 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2799 ;; Sign extension instructions
2801 (define_insn "extendsidi2"
2802 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
2803 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
2804 (clobber (reg:CC 17))
2805 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
2809 ;; Extend to memory case when source register does die.
2811 [(set (match_operand:DI 0 "memory_operand" "")
2812 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2813 (clobber (reg:CC 17))
2814 (clobber (match_operand:SI 2 "register_operand" ""))]
2816 && dead_or_set_p (insn, operands[1])
2817 && !reg_mentioned_p (operands[1], operands[0]))"
2818 [(set (match_dup 3) (match_dup 1))
2819 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
2820 (clobber (reg:CC 17))])
2821 (set (match_dup 4) (match_dup 1))]
2822 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2824 ;; Extend to memory case when source register does not die.
2826 [(set (match_operand:DI 0 "memory_operand" "")
2827 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2828 (clobber (reg:CC 17))
2829 (clobber (match_operand:SI 2 "register_operand" ""))]
2834 split_di (&operands[0], 1, &operands[3], &operands[4]);
2836 emit_move_insn (operands[3], operands[1]);
2838 /* Generate a cltd if possible and doing so it profitable. */
2839 if (true_regnum (operands[1]) == 0
2840 && true_regnum (operands[2]) == 1
2841 && (optimize_size || TARGET_USE_CLTD))
2843 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
2847 emit_move_insn (operands[2], operands[1]);
2848 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
2850 emit_move_insn (operands[4], operands[2]);
2854 ;; Extend to register case. Optimize case where source and destination
2855 ;; registers match and cases where we can use cltd.
2857 [(set (match_operand:DI 0 "register_operand" "")
2858 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2859 (clobber (reg:CC 17))
2860 (clobber (match_scratch:SI 2 ""))]
2865 split_di (&operands[0], 1, &operands[3], &operands[4]);
2867 if (true_regnum (operands[3]) != true_regnum (operands[1]))
2868 emit_move_insn (operands[3], operands[1]);
2870 /* Generate a cltd if possible and doing so it profitable. */
2871 if (true_regnum (operands[3]) == 0
2872 && (optimize_size || TARGET_USE_CLTD))
2874 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
2878 if (true_regnum (operands[4]) != true_regnum (operands[1]))
2879 emit_move_insn (operands[4], operands[1]);
2881 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
2885 (define_insn "extendhisi2"
2886 [(set (match_operand:SI 0 "register_operand" "=*a,r")
2887 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
2891 switch (get_attr_prefix_0f (insn))
2894 return \"{cwtl|cwde}\";
2896 return \"movs{wl|x}\\t{%1,%0|%0, %1}\";
2899 [(set_attr "type" "imovx")
2900 (set_attr "mode" "SI")
2901 (set (attr "prefix_0f")
2902 ;; movsx is short decodable while cwtl is vector decoded.
2903 (if_then_else (and (eq_attr "cpu" "!k6")
2904 (eq_attr "alternative" "0"))
2906 (const_string "1")))
2908 (if_then_else (eq_attr "prefix_0f" "0")
2910 (const_string "1")))])
2912 (define_insn "extendqihi2"
2913 [(set (match_operand:HI 0 "register_operand" "=*a,r")
2914 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
2918 switch (get_attr_prefix_0f (insn))
2921 return \"{cbtw|cbw}\";
2923 return \"movs{bw|x}\\t{%1,%0|%0, %1}\";
2926 [(set_attr "type" "imovx")
2927 (set_attr "mode" "HI")
2928 (set (attr "prefix_0f")
2929 ;; movsx is short decodable while cwtl is vector decoded.
2930 (if_then_else (and (eq_attr "cpu" "!k6")
2931 (eq_attr "alternative" "0"))
2933 (const_string "1")))
2935 (if_then_else (eq_attr "prefix_0f" "0")
2937 (const_string "1")))])
2939 (define_insn "extendqisi2"
2940 [(set (match_operand:SI 0 "register_operand" "=r")
2941 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2943 "movs{bl|x}\\t{%1,%0|%0, %1}"
2944 [(set_attr "type" "imovx")
2945 (set_attr "mode" "SI")])
2947 ;; Conversions between float and double.
2949 ;; These are all no-ops in the model used for the 80387. So just
2952 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
2953 (define_insn "*dummy_extendsfdf2"
2954 [(set (match_operand:DF 0 "push_operand" "=<")
2955 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f")))]
2960 [(set (match_operand:DF 0 "push_operand" "")
2961 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
2962 "FP_REGNO_P (REGNO (operands[1]))"
2963 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2964 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
2966 (define_insn "*dummy_extendsfxf2"
2967 [(set (match_operand:XF 0 "push_operand" "=<")
2968 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
2973 [(set (match_operand:XF 0 "push_operand" "")
2974 (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
2975 "FP_REGNO_P (REGNO (operands[1]))"
2976 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2977 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
2979 (define_insn "*dummy_extenddfxf2"
2980 [(set (match_operand:XF 0 "push_operand" "=<")
2981 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
2986 [(set (match_operand:XF 0 "push_operand" "")
2987 (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
2988 "FP_REGNO_P (REGNO (operands[1]))"
2989 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2990 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
2992 (define_expand "extendsfdf2"
2993 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2994 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
2998 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2999 operands[1] = force_reg (SFmode, operands[1]);
3002 (define_insn "*extendsfdf2_1"
3003 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3004 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3006 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3009 switch (which_alternative)
3012 if (REG_P (operands[1])
3013 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3014 return \"fstp\\t%y0\";
3015 else if (STACK_TOP_P (operands[0]))
3016 return \"fld%z1\\t%y1\";
3018 return \"fst\\t%y0\";
3021 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3022 return \"fstp%z0\\t%y0\";
3025 return \"fst%z0\\t%y0\";
3031 [(set_attr "type" "fmov")
3032 (set_attr "mode" "SF,XF")])
3034 (define_expand "extendsfxf2"
3035 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3036 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
3040 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3041 operands[1] = force_reg (SFmode, operands[1]);
3044 (define_insn "*extendsfxf2_1"
3045 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3046 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3048 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3051 switch (which_alternative)
3054 if (REG_P (operands[1])
3055 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3056 return \"fstp\\t%y0\";
3057 else if (STACK_TOP_P (operands[0]))
3058 return \"fld%z1\\t%y1\";
3060 return \"fst\\t%y0\";
3063 /* There is no non-popping store to memory for XFmode. So if
3064 we need one, follow the store with a load. */
3065 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3066 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3068 return \"fstp%z0\\t%y0\";
3074 [(set_attr "type" "fmov")
3075 (set_attr "mode" "SF,XF")])
3077 (define_expand "extenddfxf2"
3078 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3079 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
3083 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3084 operands[1] = force_reg (DFmode, operands[1]);
3087 (define_insn "*extenddfxf2_1"
3088 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3089 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3091 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3094 switch (which_alternative)
3097 if (REG_P (operands[1])
3098 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3099 return \"fstp\\t%y0\";
3100 else if (STACK_TOP_P (operands[0]))
3101 return \"fld%z1\\t%y1\";
3103 return \"fst\\t%y0\";
3106 /* There is no non-popping store to memory for XFmode. So if
3107 we need one, follow the store with a load. */
3108 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3109 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3111 return \"fstp%z0\\t%y0\";
3117 [(set_attr "type" "fmov")
3118 (set_attr "mode" "DF,XF")])
3120 ;; %%% This seems bad bad news.
3121 ;; This cannot output into an f-reg because there is no way to be sure
3122 ;; of truncating in that case. Otherwise this is just like a simple move
3123 ;; insn. So we pretend we can output to a reg in order to get better
3124 ;; register preferencing, but we really use a stack slot.
3126 (define_expand "truncdfsf2"
3127 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3129 (match_operand:DF 1 "register_operand" "")))
3130 (clobber (match_dup 2))])]
3132 "operands[2] = assign_386_stack_local (SFmode, 0);")
3134 (define_insn "*truncdfsf2_1"
3135 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3137 (match_operand:DF 1 "register_operand" "f,0")))
3138 (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3142 switch (which_alternative)
3145 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3146 return \"fstp%z0\\t%y0\";
3148 return \"fst%z0\\t%y0\";
3150 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3154 [(set_attr "type" "fmov,multi")
3155 (set_attr "mode" "SF")])
3157 (define_insn "*truncdfsf2_2"
3158 [(set (match_operand:SF 0 "memory_operand" "=m")
3160 (match_operand:DF 1 "register_operand" "f")))]
3164 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3165 return \"fstp%z0\\t%y0\";
3167 return \"fst%z0\\t%y0\";
3169 [(set_attr "type" "fmov")
3170 (set_attr "mode" "SF")])
3173 [(set (match_operand:SF 0 "memory_operand" "")
3175 (match_operand:DF 1 "register_operand" "")))
3176 (clobber (match_operand:SF 2 "memory_operand" ""))]
3178 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3182 [(set (match_operand:SF 0 "register_operand" "")
3184 (match_operand:DF 1 "register_operand" "")))
3185 (clobber (match_operand:SF 2 "memory_operand" ""))]
3186 "TARGET_80387 && reload_completed"
3187 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3188 (set (match_dup 0) (match_dup 2))]
3191 (define_expand "truncxfsf2"
3192 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3194 (match_operand:XF 1 "register_operand" "")))
3195 (clobber (match_dup 2))])]
3197 "operands[2] = assign_386_stack_local (SFmode, 0);")
3199 (define_insn "*truncxfsf2_1"
3200 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3202 (match_operand:XF 1 "register_operand" "f,0")))
3203 (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3207 switch (which_alternative)
3210 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3211 return \"fstp%z0\\t%y0\";
3213 return \"fst%z0\\t%y0\";
3215 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3219 [(set_attr "type" "fmov,multi")
3220 (set_attr "mode" "SF")])
3222 (define_insn "*truncxfsf2_2"
3223 [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
3225 (match_operand:XF 1 "register_operand" "f")))]
3229 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3230 return \"fstp%z0\\t%y0\";
3232 return \"fst%z0\\t%y0\";
3234 [(set_attr "type" "fmov")
3235 (set_attr "mode" "SF")])
3238 [(set (match_operand:SF 0 "memory_operand" "")
3240 (match_operand:XF 1 "register_operand" "")))
3241 (clobber (match_operand:SF 2 "memory_operand" ""))]
3243 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3247 [(set (match_operand:SF 0 "register_operand" "")
3249 (match_operand:XF 1 "register_operand" "")))
3250 (clobber (match_operand:SF 2 "memory_operand" ""))]
3251 "TARGET_80387 && reload_completed"
3252 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3253 (set (match_dup 0) (match_dup 2))]
3256 (define_expand "truncxfdf2"
3257 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3259 (match_operand:XF 1 "register_operand" "")))
3260 (clobber (match_dup 2))])]
3262 "operands[2] = assign_386_stack_local (DFmode, 0);")
3264 (define_insn "*truncxfdf2_1"
3265 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
3267 (match_operand:XF 1 "register_operand" "f,0")))
3268 (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
3272 switch (which_alternative)
3275 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3276 return \"fstp%z0\\t%y0\";
3278 return \"fst%z0\\t%y0\";
3280 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3284 [(set_attr "type" "fmov,multi")
3285 (set_attr "mode" "DF")])
3287 (define_insn "*truncxfdf2_2"
3288 [(set (match_operand:DF 0 "memory_operand" "=m")
3290 (match_operand:XF 1 "register_operand" "f")))]
3294 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3295 return \"fstp%z0\\t%y0\";
3297 return \"fst%z0\\t%y0\";
3299 [(set_attr "type" "fmov")
3300 (set_attr "mode" "DF")])
3303 [(set (match_operand:DF 0 "memory_operand" "")
3305 (match_operand:XF 1 "register_operand" "")))
3306 (clobber (match_operand:DF 2 "memory_operand" ""))]
3308 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3312 [(set (match_operand:DF 0 "register_operand" "")
3314 (match_operand:XF 1 "register_operand" "")))
3315 (clobber (match_operand:DF 2 "memory_operand" ""))]
3316 "TARGET_80387 && reload_completed"
3317 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3318 (set (match_dup 0) (match_dup 2))]
3322 ;; %%% Break up all these bad boys.
3324 ;; Signed conversion to DImode.
3326 (define_expand "fix_truncxfdi2"
3327 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3328 (fix:DI (match_operand:XF 1 "register_operand" "")))
3329 (clobber (match_dup 2))
3330 (clobber (match_dup 3))
3331 (clobber (match_scratch:SI 4 ""))
3332 (clobber (match_scratch:XF 5 ""))])]
3334 "operands[2] = assign_386_stack_local (SImode, 0);
3335 operands[3] = assign_386_stack_local (DImode, 1);")
3337 (define_expand "fix_truncdfdi2"
3338 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3339 (fix:DI (match_operand:DF 1 "register_operand" "")))
3340 (clobber (match_dup 2))
3341 (clobber (match_dup 3))
3342 (clobber (match_scratch:SI 4 ""))
3343 (clobber (match_scratch:DF 5 ""))])]
3345 "operands[2] = assign_386_stack_local (SImode, 0);
3346 operands[3] = assign_386_stack_local (DImode, 1);")
3348 (define_expand "fix_truncsfdi2"
3349 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3350 (fix:DI (match_operand:SF 1 "register_operand" "")))
3351 (clobber (match_dup 2))
3352 (clobber (match_dup 3))
3353 (clobber (match_scratch:SI 4 ""))
3354 (clobber (match_scratch:SF 5 ""))])]
3356 "operands[2] = assign_386_stack_local (SImode, 0);
3357 operands[3] = assign_386_stack_local (DImode, 1);")
3359 (define_insn "*fix_truncdi_1"
3360 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
3361 (fix:DI (match_operand 1 "register_operand" "f,f")))
3362 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3363 (clobber (match_operand:DI 3 "memory_operand" "=m,m"))
3364 (clobber (match_scratch:SI 4 "=&r,&r"))
3365 (clobber (match_scratch 5 "=&f,&f"))]
3366 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3367 "* return output_fix_trunc (insn, operands);"
3368 [(set_attr "type" "multi")])
3371 [(set (match_operand:DI 0 "register_operand" "")
3372 (fix:DI (match_operand 1 "register_operand" "")))
3373 (clobber (match_operand:SI 2 "memory_operand" ""))
3374 (clobber (match_operand:DI 3 "memory_operand" ""))
3375 (clobber (match_scratch:SI 4 ""))
3376 (clobber (match_scratch 5 ""))]
3377 "reload_completed && !reg_overlap_mentioned_p (operands[4], operands[3])"
3378 [(parallel [(set (match_dup 3) (fix:DI (match_dup 1)))
3379 (clobber (match_dup 2))
3380 (clobber (match_dup 3))
3381 (clobber (match_dup 4))
3382 (clobber (match_dup 5))])
3383 (set (match_dup 0) (match_dup 3))]
3386 ;; Signed conversion to SImode.
3388 (define_expand "fix_truncxfsi2"
3389 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3390 (fix:SI (match_operand:XF 1 "register_operand" "")))
3391 (clobber (match_dup 2))
3392 (clobber (match_dup 3))
3393 (clobber (match_scratch:SI 4 ""))])]
3395 "operands[2] = assign_386_stack_local (SImode, 0);
3396 operands[3] = assign_386_stack_local (SImode, 1);")
3398 (define_expand "fix_truncdfsi2"
3399 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3400 (fix:SI (match_operand:DF 1 "register_operand" "")))
3401 (clobber (match_dup 2))
3402 (clobber (match_dup 3))
3403 (clobber (match_scratch:SI 4 ""))])]
3405 "operands[2] = assign_386_stack_local (SImode, 0);
3406 operands[3] = assign_386_stack_local (SImode, 1);")
3408 (define_expand "fix_truncsfsi2"
3409 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3410 (fix:SI (match_operand:SF 1 "register_operand" "")))
3411 (clobber (match_dup 2))
3412 (clobber (match_dup 3))
3413 (clobber (match_scratch:SI 4 ""))])]
3415 "operands[2] = assign_386_stack_local (SImode, 0);
3416 operands[3] = assign_386_stack_local (SImode, 1);")
3418 (define_insn "*fix_truncsi_1"
3419 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
3420 (fix:SI (match_operand 1 "register_operand" "f,f")))
3421 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3422 (clobber (match_operand:SI 3 "memory_operand" "=m,m"))
3423 (clobber (match_scratch:SI 4 "=&r,r"))]
3424 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3425 "* return output_fix_trunc (insn, operands);"
3426 [(set_attr "type" "multi")])
3429 [(set (match_operand:SI 0 "register_operand" "")
3430 (fix:SI (match_operand 1 "register_operand" "")))
3431 (clobber (match_operand:SI 2 "memory_operand" ""))
3432 (clobber (match_operand:SI 3 "memory_operand" ""))
3433 (clobber (match_scratch:SI 4 ""))]
3435 [(parallel [(set (match_dup 3) (fix:SI (match_dup 1)))
3436 (clobber (match_dup 2))
3437 (clobber (match_dup 3))
3438 (clobber (match_dup 4))])
3439 (set (match_dup 0) (match_dup 3))]
3442 ;; Signed conversion to HImode.
3444 (define_expand "fix_truncxfhi2"
3445 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3446 (fix:HI (match_operand:XF 1 "register_operand" "")))
3447 (clobber (match_dup 2))
3448 (clobber (match_dup 3))
3449 (clobber (match_scratch:SI 4 ""))])]
3451 "operands[2] = assign_386_stack_local (SImode, 0);
3452 operands[3] = assign_386_stack_local (HImode, 1);")
3454 (define_expand "fix_truncdfhi2"
3455 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3456 (fix:HI (match_operand:DF 1 "register_operand" "")))
3457 (clobber (match_dup 2))
3458 (clobber (match_dup 3))
3459 (clobber (match_scratch:SI 4 ""))])]
3461 "operands[2] = assign_386_stack_local (SImode, 0);
3462 operands[3] = assign_386_stack_local (HImode, 1);")
3464 (define_expand "fix_truncsfhi2"
3465 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3466 (fix:HI (match_operand:SF 1 "register_operand" "")))
3467 (clobber (match_dup 2))
3468 (clobber (match_dup 3))
3469 (clobber (match_scratch:SI 4 ""))])]
3471 "operands[2] = assign_386_stack_local (SImode, 0);
3472 operands[3] = assign_386_stack_local (HImode, 1);")
3474 (define_insn "*fix_trunchi_1"
3475 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
3476 (fix:HI (match_operand 1 "register_operand" "f,f")))
3477 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3478 (clobber (match_operand:HI 3 "memory_operand" "=m,m"))
3479 (clobber (match_scratch:SI 4 "=&r,r"))]
3480 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3481 "* return output_fix_trunc (insn, operands);"
3482 [(set_attr "type" "multi")])
3485 [(set (match_operand:HI 0 "register_operand" "")
3486 (fix:HI (match_operand 1 "register_operand" "")))
3487 (clobber (match_operand:SI 2 "memory_operand" ""))
3488 (clobber (match_operand:HI 3 "memory_operand" ""))
3489 (clobber (match_scratch:SI 4 ""))]
3491 [(parallel [(set (match_dup 3) (fix:HI (match_dup 1)))
3492 (clobber (match_dup 2))
3493 (clobber (match_dup 3))
3494 (clobber (match_dup 4))])
3495 (set (match_dup 0) (match_dup 3))]
3499 (define_insn "x86_fnstcw_1"
3500 [(set (match_operand:HI 0 "memory_operand" "=m")
3501 (unspec:HI [(reg:HI 18)] 11))]
3504 [(set_attr "length" "2")
3505 (set_attr "mode" "HI")
3506 (set_attr "i387" "1")
3507 (set_attr "ppro_uops" "few")])
3509 (define_insn "x86_fldcw_1"
3511 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
3514 [(set_attr "length" "2")
3515 (set_attr "mode" "HI")
3516 (set_attr "i387" "1")
3517 (set_attr "athlon_decode" "vector")
3518 (set_attr "ppro_uops" "few")])
3520 ;; Conversion between fixed point and floating point.
3522 ;; Even though we only accept memory inputs, the backend _really_
3523 ;; wants to be able to do this between registers.
3525 (define_insn "floathisf2"
3526 [(set (match_operand:SF 0 "register_operand" "=f,f")
3527 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
3532 [(set_attr "type" "fmov,multi")
3533 (set_attr "mode" "SF")
3534 (set_attr "fp_int_src" "true")])
3536 (define_insn "floatsisf2"
3537 [(set (match_operand:SF 0 "register_operand" "=f,f")
3538 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
3543 [(set_attr "type" "fmov,multi")
3544 (set_attr "mode" "SF")
3545 (set_attr "fp_int_src" "true")])
3547 (define_insn "floatdisf2"
3548 [(set (match_operand:SF 0 "register_operand" "=f,f")
3549 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
3554 [(set_attr "type" "fmov,multi")
3555 (set_attr "mode" "SF")
3556 (set_attr "fp_int_src" "true")])
3558 (define_insn "floathidf2"
3559 [(set (match_operand:DF 0 "register_operand" "=f,f")
3560 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
3565 [(set_attr "type" "fmov,multi")
3566 (set_attr "mode" "DF")
3567 (set_attr "fp_int_src" "true")])
3569 (define_insn "floatsidf2"
3570 [(set (match_operand:DF 0 "register_operand" "=f,f")
3571 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
3576 [(set_attr "type" "fmov,multi")
3577 (set_attr "mode" "DF")
3578 (set_attr "fp_int_src" "true")])
3580 (define_insn "floatdidf2"
3581 [(set (match_operand:DF 0 "register_operand" "=f,f")
3582 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
3587 [(set_attr "type" "fmov,multi")
3588 (set_attr "mode" "DF")
3589 (set_attr "fp_int_src" "true")])
3591 (define_insn "floathixf2"
3592 [(set (match_operand:XF 0 "register_operand" "=f,f")
3593 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
3598 [(set_attr "type" "fmov,multi")
3599 (set_attr "mode" "XF")
3600 (set_attr "fp_int_src" "true")])
3602 (define_insn "floatsixf2"
3603 [(set (match_operand:XF 0 "register_operand" "=f,f")
3604 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
3609 [(set_attr "type" "fmov,multi")
3610 (set_attr "mode" "XF")
3611 (set_attr "fp_int_src" "true")])
3613 (define_insn "floatdixf2"
3614 [(set (match_operand:XF 0 "register_operand" "=f,f")
3615 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
3620 [(set_attr "type" "fmov,multi")
3621 (set_attr "mode" "XF")
3622 (set_attr "fp_int_src" "true")])
3624 ;; %%% Kill these when reload knows how to do it.
3626 [(set (match_operand 0 "register_operand" "")
3627 (float (match_operand:HI 1 "register_operand" "")))]
3628 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
3629 [(set (mem:HI (pre_dec:SI (reg:SI 7))) (match_dup 1))
3630 (set (match_dup 0) (match_dup 2))
3631 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 2)))]
3632 "operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]),
3633 gen_rtx_MEM (HImode, stack_pointer_rtx));")
3636 [(set (match_operand 0 "register_operand" "")
3637 (float (match_operand:SI 1 "register_operand" "")))]
3638 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
3639 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
3640 (set (match_dup 0) (match_dup 2))
3641 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
3642 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
3643 "operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]),
3644 gen_rtx_MEM (SImode, stack_pointer_rtx));")
3647 [(set (match_operand 0 "register_operand" "")
3648 (float (match_operand:DI 1 "nonmemory_operand" "")))]
3649 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
3650 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 2))
3651 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
3652 (set (match_dup 0) (match_dup 3))
3653 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
3654 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
3655 (parallel [(set (match_dup 2) (mem:SI (reg:SI 7)))
3656 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
3657 "split_di (operands+1, 1, operands+1, operands+2);
3658 operands[3] = gen_rtx_FLOAT (GET_MODE (operands[0]),
3659 gen_rtx_MEM (DImode, stack_pointer_rtx));")
3663 ;; %%% define_expand from the very first?
3664 ;; %%% splits for addsidi3
3665 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
3666 ; (plus:DI (match_operand:DI 1 "general_operand" "")
3667 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
3669 (define_insn "adddi3"
3670 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3671 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
3672 (match_operand:DI 2 "general_operand" "roiF,riF")))
3673 (clobber (reg:CC 17))]
3678 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3679 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
3680 (match_operand:DI 2 "general_operand" "")))
3681 (clobber (reg:CC 17))]
3683 [(parallel [(set (reg:CC 17) (plus:CC (match_dup 1) (match_dup 2)))
3684 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
3685 (parallel [(set (match_dup 3)
3686 (plus:SI (match_dup 4)
3687 (plus:SI (match_dup 5)
3688 (ltu:SI (reg:CC 17) (const_int 0)))))
3689 (clobber (reg:CC 17))])]
3690 "split_di (operands+0, 1, operands+0, operands+3);
3691 split_di (operands+1, 1, operands+1, operands+4);
3692 split_di (operands+2, 1, operands+2, operands+5);")
3694 (define_insn "*addsi3_cc"
3695 [(set (reg:CC 17) (plus:CC (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3696 (match_operand:SI 2 "general_operand" "ri,rm")))
3697 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3698 (plus:SI (match_dup 1) (match_dup 2)))]
3699 "ix86_binary_operator_ok (PLUS, SImode, operands)"
3700 "add{l}\\t{%2, %0|%0, %2}"
3701 [(set_attr "type" "alu")
3702 (set_attr "mode" "SI")])
3704 (define_insn "addqi3_cc"
3705 [(set (reg:CC 17) (plus:CC (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3706 (match_operand:QI 2 "general_operand" "qi,qm")))
3707 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3708 (plus:QI (match_dup 1) (match_dup 2)))]
3709 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3710 "add{b}\\t{%2, %0|%0, %2}"
3711 [(set_attr "type" "alu")
3712 (set_attr "mode" "QI")])
3714 (define_insn "*addsi3_carry"
3715 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3716 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3717 (plus:SI (match_operand:SI 2 "general_operand" "ri,rm")
3718 (ltu:SI (reg:CC 17) (const_int 0)))))
3719 (clobber (reg:CC 17))]
3720 "ix86_binary_operator_ok (PLUS, SImode, operands)"
3721 "adc{l}\\t{%2, %0|%0, %2}"
3722 [(set_attr "type" "alu")
3723 (set_attr "pent_pair" "pu")
3724 (set_attr "mode" "SI")
3725 (set_attr "ppro_uops" "few")])
3727 (define_expand "addsi3"
3728 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3729 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3730 (match_operand:SI 2 "general_operand" "")))
3731 (clobber (reg:CC 17))])]
3733 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
3735 (define_insn "*lea_0"
3736 [(set (match_operand:SI 0 "register_operand" "=r")
3737 (match_operand:SI 1 "address_operand" "p"))]
3739 "lea{l}\\t{%a1, %0|%0, %a1}"
3740 [(set_attr "type" "lea")
3741 (set_attr "mode" "SI")])
3743 (define_insn "*addsi_1"
3744 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
3745 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
3746 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
3747 (clobber (reg:CC 17))]
3748 "ix86_binary_operator_ok (PLUS, SImode, operands)"
3751 switch (get_attr_type (insn))
3754 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
3755 return \"lea{l}\\t{%a2, %0|%0, %a2}\";
3758 if (! rtx_equal_p (operands[0], operands[1]))
3760 if (operands[2] == const1_rtx)
3761 return \"inc{l}\\t%0\";
3762 else if (operands[2] == constm1_rtx)
3763 return \"dec{l}\\t%0\";
3768 if (! rtx_equal_p (operands[0], operands[1]))
3771 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3772 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
3773 if (GET_CODE (operands[2]) == CONST_INT
3774 && (INTVAL (operands[2]) == 128
3775 || (INTVAL (operands[2]) < 0
3776 && INTVAL (operands[2]) != -128)))
3778 operands[2] = GEN_INT (-INTVAL (operands[2]));
3779 return \"sub{l}\\t{%2, %0|%0, %2}\";
3781 return \"add{l}\\t{%2, %0|%0, %2}\";
3785 (cond [(eq_attr "alternative" "2")
3786 (const_string "lea")
3787 ; Current assemblers are broken and do not allow @GOTOFF in
3788 ; ought but a memory context.
3789 (match_operand:SI 2 "pic_symbolic_operand" "")
3790 (const_string "lea")
3791 (match_operand:SI 2 "incdec_operand" "")
3792 (const_string "incdec")
3794 (const_string "alu")))
3795 (set_attr "mode" "SI")])
3797 ;; Convert lea to the lea pattern to avoid flags dependency.
3799 [(set (match_operand:SI 0 "register_operand" "")
3800 (plus:SI (match_operand:SI 1 "register_operand" "")
3801 (match_operand:SI 2 "nonmemory_operand" "")))
3802 (clobber (reg:CC 17))]
3804 && true_regnum (operands[0]) != true_regnum (operands[1])"
3806 (plus:SI (match_dup 1)
3810 (define_insn "*addsi_2"
3813 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3814 (match_operand:SI 2 "general_operand" "rmni,rni"))
3816 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
3817 (plus:SI (match_dup 1) (match_dup 2)))]
3818 "ix86_match_ccmode (insn, CCNOmode)
3819 && ix86_binary_operator_ok (PLUS, SImode, operands)
3820 /* Current assemblers are broken and do not allow @GOTOFF in
3821 ought but a memory context. */
3822 && ! pic_symbolic_operand (operands[2], VOIDmode)"
3825 switch (get_attr_type (insn))
3828 if (! rtx_equal_p (operands[0], operands[1]))
3830 if (operands[2] == const1_rtx)
3831 return \"inc{l}\\t%0\";
3832 else if (operands[2] == constm1_rtx)
3833 return \"dec{l}\\t%0\";
3838 if (! rtx_equal_p (operands[0], operands[1]))
3840 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3841 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
3842 if (GET_CODE (operands[2]) == CONST_INT
3843 && (INTVAL (operands[2]) == 128
3844 || (INTVAL (operands[2]) < 0
3845 && INTVAL (operands[2]) != -128)))
3847 operands[2] = GEN_INT (-INTVAL (operands[2]));
3848 return \"sub{l}\\t{%2, %0|%0, %2}\";
3850 return \"add{l}\\t{%2, %0|%0, %2}\";
3854 (if_then_else (match_operand:SI 2 "incdec_operand" "")
3855 (const_string "incdec")
3856 (const_string "alu")))
3857 (set_attr "mode" "SI")])
3859 (define_insn "*addsi_3"
3861 (compare:CC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3862 (match_operand:SI 2 "general_operand" "rmni,rni"))
3864 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
3865 (plus:SI (match_dup 1) (match_dup 2)))]
3866 "ix86_binary_operator_ok (PLUS, SImode, operands)
3867 /* Current assemblers are broken and do not allow @GOTOFF in
3868 ought but a memory context. */
3869 && ! pic_symbolic_operand (operands[2], VOIDmode)"
3870 "add{l}\\t{%2, %0|%0, %2}"
3871 [(set_attr "type" "alu")
3872 (set_attr "mode" "SI")])
3874 (define_expand "addhi3"
3875 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3876 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3877 (match_operand:HI 2 "general_operand" "")))
3878 (clobber (reg:CC 17))])]
3879 "TARGET_HIMODE_MATH"
3880 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
3882 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
3883 ;; type optimizations enabled by define-splits. This is not important
3884 ;; for PII, and in fact harmful because of partial register stalls.
3886 (define_insn "*addhi_1"
3887 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3888 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3889 (match_operand:HI 2 "general_operand" "ri,rm")))
3890 (clobber (reg:CC 17))]
3891 "ix86_binary_operator_ok (PLUS, HImode, operands)"
3894 switch (get_attr_type (insn))
3897 if (operands[2] == const1_rtx)
3898 return \"inc{w}\\t%0\";
3899 else if (operands[2] == constm1_rtx
3900 || (GET_CODE (operands[2]) == CONST_INT
3901 && INTVAL (operands[2]) == 65535))
3902 return \"dec{w}\\t%0\";
3906 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3907 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
3908 if (GET_CODE (operands[2]) == CONST_INT
3909 && (INTVAL (operands[2]) == 128
3910 || (INTVAL (operands[2]) < 0
3911 && INTVAL (operands[2]) != -128)))
3913 operands[2] = GEN_INT (-INTVAL (operands[2]));
3914 return \"sub{w}\\t{%2, %0|%0, %2}\";
3916 return \"add{w}\\t{%2, %0|%0, %2}\";
3920 (if_then_else (match_operand:HI 2 "incdec_operand" "")
3921 (const_string "incdec")
3922 (const_string "alu")))
3923 (set_attr "mode" "HI")])
3925 (define_insn "*addhi_2"
3928 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3929 (match_operand:HI 2 "general_operand" "rmni,rni"))
3931 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
3932 (plus:HI (match_dup 1) (match_dup 2)))]
3933 "ix86_match_ccmode (insn, CCNOmode)
3934 && ix86_binary_operator_ok (PLUS, HImode, operands)"
3937 switch (get_attr_type (insn))
3940 if (operands[2] == const1_rtx)
3941 return \"inc{w}\\t%0\";
3942 else if (operands[2] == constm1_rtx
3943 || (GET_CODE (operands[2]) == CONST_INT
3944 && INTVAL (operands[2]) == 65535))
3945 return \"dec{w}\\t%0\";
3949 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3950 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
3951 if (GET_CODE (operands[2]) == CONST_INT
3952 && (INTVAL (operands[2]) == 128
3953 || (INTVAL (operands[2]) < 0
3954 && INTVAL (operands[2]) != -128)))
3956 operands[2] = GEN_INT (-INTVAL (operands[2]));
3957 return \"sub{w}\\t{%2, %0|%0, %2}\";
3959 return \"add{w}\\t{%2, %0|%0, %2}\";
3963 (if_then_else (match_operand:HI 2 "incdec_operand" "")
3964 (const_string "incdec")
3965 (const_string "alu")))
3966 (set_attr "mode" "HI")])
3968 (define_insn "*addhi_3"
3970 (compare:CC (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3971 (match_operand:HI 2 "general_operand" "rmni,rni"))
3973 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
3974 (plus:HI (match_dup 1) (match_dup 2)))]
3975 "ix86_binary_operator_ok (PLUS, HImode, operands)"
3976 "add{w}\\t{%2, %0|%0, %2}"
3977 [(set_attr "type" "alu")
3978 (set_attr "mode" "HI")])
3980 (define_expand "addqi3"
3981 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
3982 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
3983 (match_operand:QI 2 "general_operand" "")))
3984 (clobber (reg:CC 17))])]
3985 "TARGET_QIMODE_MATH"
3986 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
3988 ;; %%% Potential partial reg stall on alternative 2. What to do?
3989 (define_insn "*addqi_1"
3990 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
3991 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
3992 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
3993 (clobber (reg:CC 17))]
3994 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3997 int widen = (which_alternative == 2);
3998 switch (get_attr_type (insn))
4001 if (operands[2] == const1_rtx)
4002 return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
4003 else if (operands[2] == constm1_rtx
4004 || (GET_CODE (operands[2]) == CONST_INT
4005 && INTVAL (operands[2]) == 255))
4006 return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
4010 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4011 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4012 if (GET_CODE (operands[2]) == CONST_INT
4013 && (INTVAL (operands[2]) == 128
4014 || (INTVAL (operands[2]) < 0
4015 && INTVAL (operands[2]) != -128)))
4017 operands[2] = GEN_INT (-INTVAL (operands[2]));
4019 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
4021 return \"sub{b}\\t{%2, %0|%0, %2}\";
4024 return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
4026 return \"add{b}\\t{%2, %0|%0, %2}\";
4030 (if_then_else (match_operand:QI 2 "incdec_operand" "")
4031 (const_string "incdec")
4032 (const_string "alu")))
4033 (set_attr "mode" "QI,QI,SI")])
4035 (define_insn "*addqi_2"
4038 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4039 (match_operand:QI 2 "general_operand" "qmni,qni"))
4041 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
4042 (plus:QI (match_dup 1) (match_dup 2)))]
4043 "ix86_match_ccmode (insn, CCNOmode)
4044 && ix86_binary_operator_ok (PLUS, QImode, operands)"
4047 switch (get_attr_type (insn))
4050 if (operands[2] == const1_rtx)
4051 return \"inc{b}\\t%0\";
4052 else if (operands[2] == constm1_rtx
4053 || (GET_CODE (operands[2]) == CONST_INT
4054 && INTVAL (operands[2]) == 255))
4055 return \"dec{b}\\t%0\";
4059 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
4060 if (GET_CODE (operands[2]) == CONST_INT
4061 && INTVAL (operands[2]) < 0)
4063 operands[2] = GEN_INT (-INTVAL (operands[2]));
4064 return \"sub{b}\\t{%2, %0|%0, %2}\";
4066 return \"add{b}\\t{%2, %0|%0, %2}\";
4070 (if_then_else (match_operand:QI 2 "incdec_operand" "")
4071 (const_string "incdec")
4072 (const_string "alu")))
4073 (set_attr "mode" "QI")])
4075 (define_insn "*addqi_3"
4077 (compare:CC (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4078 (match_operand:QI 2 "general_operand" "qmni,qni"))
4080 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
4081 (plus:QI (match_dup 1) (match_dup 2)))]
4082 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4083 "add{b}\\t{%2, %0|%0, %2}"
4084 [(set_attr "type" "alu")
4085 (set_attr "mode" "QI")])
4088 (define_insn "addqi_ext_1"
4089 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4094 (match_operand 1 "ext_register_operand" "0")
4097 (match_operand:QI 2 "general_operand" "qmn")))
4098 (clobber (reg:CC 17))]
4102 switch (get_attr_type (insn))
4105 if (operands[2] == const1_rtx)
4106 return \"inc{b}\\t%h0\";
4107 else if (operands[2] == constm1_rtx
4108 || (GET_CODE (operands[2]) == CONST_INT
4109 && INTVAL (operands[2]) == 255))
4110 return \"dec{b}\\t%h0\";
4114 return \"add{b}\\t{%2, %h0|%h0, %2}\";
4118 (if_then_else (match_operand:QI 2 "incdec_operand" "")
4119 (const_string "incdec")
4120 (const_string "alu")))
4121 (set_attr "mode" "QI")])
4123 (define_insn "*addqi_ext_2"
4124 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4129 (match_operand 1 "ext_register_operand" "%0")
4133 (match_operand 2 "ext_register_operand" "q")
4136 (clobber (reg:CC 17))]
4138 "add{b}\\t{%h2, %h0|%h0, %h2}"
4139 [(set_attr "type" "alu")
4140 (set_attr "mode" "QI")])
4142 ;; The patterns that match these are at the end of this file.
4144 (define_expand "addxf3"
4145 [(set (match_operand:XF 0 "register_operand" "")
4146 (plus:XF (match_operand:XF 1 "register_operand" "")
4147 (match_operand:XF 2 "register_operand" "")))]
4151 (define_expand "adddf3"
4152 [(set (match_operand:DF 0 "register_operand" "")
4153 (plus:DF (match_operand:DF 1 "register_operand" "")
4154 (match_operand:DF 2 "nonimmediate_operand" "")))]
4158 (define_expand "addsf3"
4159 [(set (match_operand:SF 0 "register_operand" "")
4160 (plus:SF (match_operand:SF 1 "register_operand" "")
4161 (match_operand:SF 2 "nonimmediate_operand" "")))]
4165 ;; Subtract instructions
4167 ;; %%% define_expand from the very first?
4168 ;; %%% splits for subsidi3
4170 (define_insn "subdi3"
4171 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4172 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
4173 (match_operand:DI 2 "general_operand" "roiF,riF")))
4174 (clobber (reg:CC 17))]
4179 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4180 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4181 (match_operand:DI 2 "general_operand" "")))
4182 (clobber (reg:CC 17))]
4184 [(parallel [(set (reg:CC 17) (minus:CC (match_dup 1) (match_dup 2)))
4185 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
4186 (parallel [(set (match_dup 3)
4187 (minus:SI (match_dup 4)
4188 (plus:SI (match_dup 5)
4189 (ltu:SI (reg:CC 17) (const_int 0)))))
4190 (clobber (reg:CC 17))])]
4191 "split_di (operands+0, 1, operands+0, operands+3);
4192 split_di (operands+1, 1, operands+1, operands+4);
4193 split_di (operands+2, 1, operands+2, operands+5);")
4195 (define_insn "*subsi3_cc"
4196 [(set (reg:CC 17) (minus:CC (match_operand:SI 1 "nonimmediate_operand" "0,0")
4197 (match_operand:SI 2 "general_operand" "ri,rm")))
4198 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4199 (minus:SI (match_dup 1) (match_dup 2)))]
4200 "ix86_binary_operator_ok (MINUS, SImode, operands)"
4201 "sub{l}\\t{%2, %0|%0, %2}"
4202 [(set_attr "type" "alu")
4203 (set_attr "mode" "SI")])
4205 (define_insn "subsi3_carry"
4206 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4207 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
4208 (plus:SI (match_operand:SI 2 "general_operand" "ri,rm")
4209 (ltu:SI (reg:CC 17) (const_int 0)))))
4210 (clobber (reg:CC 17))]
4211 "ix86_binary_operator_ok (MINUS, SImode, operands)"
4212 "sbb{l}\\t{%2, %0|%0, %2}"
4213 [(set_attr "type" "alu")
4214 (set_attr "pent_pair" "pu")
4215 (set_attr "ppro_uops" "few")
4216 (set_attr "mode" "SI")])
4218 (define_expand "subsi3"
4219 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4220 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4221 (match_operand:SI 2 "general_operand" "")))
4222 (clobber (reg:CC 17))])]
4224 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
4226 (define_insn "*subsi_1"
4227 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4228 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
4229 (match_operand:SI 2 "general_operand" "ri,rm")))
4230 (clobber (reg:CC 17))]
4231 "ix86_binary_operator_ok (MINUS, SImode, operands)"
4232 "sub{l}\\t{%2, %0|%0, %2}"
4233 [(set_attr "type" "alu")
4234 (set_attr "mode" "SI")])
4236 (define_insn "*subsi_2"
4239 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
4240 (match_operand:SI 2 "general_operand" "ri,rm"))
4242 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4243 (minus:SI (match_dup 1) (match_dup 2)))]
4244 "ix86_match_ccmode (insn, CCmode)
4245 && ix86_binary_operator_ok (MINUS, SImode, operands)"
4246 "sub{l}\\t{%2, %0|%0, %2}"
4247 [(set_attr "type" "alu")
4248 (set_attr "mode" "SI")])
4250 (define_expand "subhi3"
4251 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4252 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
4253 (match_operand:HI 2 "general_operand" "")))
4254 (clobber (reg:CC 17))])]
4255 "TARGET_HIMODE_MATH"
4256 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
4258 (define_insn "*subhi_1"
4259 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4260 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
4261 (match_operand:HI 2 "general_operand" "ri,rm")))
4262 (clobber (reg:CC 17))]
4263 "ix86_binary_operator_ok (MINUS, HImode, operands)"
4264 "sub{w}\\t{%2, %0|%0, %2}"
4265 [(set_attr "type" "alu")
4266 (set_attr "mode" "HI")])
4268 (define_insn "*subhi_2"
4271 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
4272 (match_operand:HI 2 "general_operand" "ri,rm"))
4274 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4275 (minus:HI (match_dup 1) (match_dup 2)))]
4276 "ix86_match_ccmode (insn, CCmode)
4277 && ix86_binary_operator_ok (MINUS, HImode, operands)"
4278 "sub{w}\\t{%2, %0|%0, %2}"
4279 [(set_attr "type" "alu")
4280 (set_attr "mode" "HI")])
4282 (define_expand "subqi3"
4283 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
4284 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
4285 (match_operand:QI 2 "general_operand" "")))
4286 (clobber (reg:CC 17))])]
4287 "TARGET_QIMODE_MATH"
4288 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
4290 (define_insn "*subqi_1"
4291 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4292 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
4293 (match_operand:QI 2 "general_operand" "qn,qmn")))
4294 (clobber (reg:CC 17))]
4295 "ix86_binary_operator_ok (MINUS, QImode, operands)"
4296 "sub{b}\\t{%2, %0|%0, %2}"
4297 [(set_attr "type" "alu")
4298 (set_attr "mode" "QI")])
4300 (define_insn "*subqi_2"
4303 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
4304 (match_operand:QI 2 "general_operand" "qi,qm"))
4306 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
4307 (minus:HI (match_dup 1) (match_dup 2)))]
4308 "ix86_match_ccmode (insn, CCmode)
4309 && ix86_binary_operator_ok (MINUS, QImode, operands)"
4310 "sub{b}\\t{%2, %0|%0, %2}"
4311 [(set_attr "type" "alu")
4312 (set_attr "mode" "QI")])
4314 ;; The patterns that match these are at the end of this file.
4316 (define_expand "subxf3"
4317 [(set (match_operand:XF 0 "register_operand" "")
4318 (minus:XF (match_operand:XF 1 "register_operand" "")
4319 (match_operand:XF 2 "register_operand" "")))]
4323 (define_expand "subdf3"
4324 [(set (match_operand:DF 0 "register_operand" "")
4325 (minus:DF (match_operand:DF 1 "register_operand" "")
4326 (match_operand:DF 2 "nonimmediate_operand" "")))]
4330 (define_expand "subsf3"
4331 [(set (match_operand:SF 0 "register_operand" "")
4332 (minus:SF (match_operand:SF 1 "register_operand" "")
4333 (match_operand:SF 2 "nonimmediate_operand" "")))]
4337 ;; Multiply instructions
4339 (define_expand "mulsi3"
4340 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4341 (mult:SI (match_operand:SI 1 "register_operand" "")
4342 (match_operand:SI 2 "general_operand" "")))
4343 (clobber (reg:CC 17))])]
4347 (define_insn "*mulsi3_1"
4348 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4349 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
4350 (match_operand:SI 2 "general_operand" "K,i,mr")))
4351 (clobber (reg:CC 17))]
4352 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
4353 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
4354 ; there are two ways of writing the exact same machine instruction
4355 ; in assembly language. One, for example, is:
4359 ; while the other is:
4361 ; imul $12, %eax, %eax
4363 ; The first is simply short-hand for the latter. But, some assemblers,
4364 ; like the SCO OSR5 COFF assembler, don't handle the first form.
4366 imul{l}\\t{%2, %1, %0|%0, %1, %2}
4367 imul{l}\\t{%2, %1, %0|%0, %1, %2}
4368 imul{l}\\t{%2, %0|%0, %2}"
4369 [(set_attr "type" "imul")
4370 (set_attr "prefix_0f" "0,0,1")
4371 (set_attr "mode" "SI")])
4373 (define_expand "mulhi3"
4374 [(parallel [(set (match_operand:HI 0 "register_operand" "")
4375 (mult:HI (match_operand:HI 1 "register_operand" "")
4376 (match_operand:HI 2 "general_operand" "")))
4377 (clobber (reg:CC 17))])]
4378 "TARGET_HIMODE_MATH"
4381 (define_insn "*mulhi3_1"
4382 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
4383 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
4384 (match_operand:HI 2 "general_operand" "K,i,mr")))
4385 (clobber (reg:CC 17))]
4386 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
4387 ; %%% There was a note about "Assembler has weird restrictions",
4388 ; concerning alternative 1 when op1 == op0. True?
4390 imul{w}\\t{%2, %1, %0|%0, %1, %2}
4391 imul{w}\\t{%2, %1, %0|%0, %1, %2}
4392 imul{w}\\t{%2, %0|%0, %2}"
4393 [(set_attr "type" "imul")
4394 (set_attr "prefix_0f" "0,0,1")
4395 (set_attr "mode" "HI")])
4397 (define_insn "mulqi3"
4398 [(set (match_operand:QI 0 "register_operand" "=a")
4399 (mult:QI (match_operand:QI 1 "register_operand" "%0")
4400 (match_operand:QI 2 "nonimmediate_operand" "qm")))
4401 (clobber (reg:CC 17))]
4402 "TARGET_QIMODE_MATH"
4404 [(set_attr "type" "imul")
4405 (set_attr "length_immediate" "0")
4406 (set_attr "mode" "QI")])
4408 (define_insn "umulqihi3"
4409 [(set (match_operand:HI 0 "register_operand" "=a")
4410 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
4411 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
4412 (clobber (reg:CC 17))]
4413 "TARGET_QIMODE_MATH"
4415 [(set_attr "type" "imul")
4416 (set_attr "length_immediate" "0")
4417 (set_attr "mode" "QI")])
4419 (define_insn "mulqihi3"
4420 [(set (match_operand:HI 0 "register_operand" "=a")
4421 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
4422 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
4423 (clobber (reg:CC 17))]
4424 "TARGET_QIMODE_MATH"
4426 [(set_attr "type" "imul")
4427 (set_attr "length_immediate" "0")
4428 (set_attr "mode" "QI")])
4430 (define_insn "umulsidi3"
4431 [(set (match_operand:DI 0 "register_operand" "=A")
4432 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
4433 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
4434 (clobber (reg:CC 17))]
4437 [(set_attr "type" "imul")
4438 (set_attr "ppro_uops" "few")
4439 (set_attr "length_immediate" "0")
4440 (set_attr "mode" "SI")])
4442 (define_insn "mulsidi3"
4443 [(set (match_operand:DI 0 "register_operand" "=A")
4444 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
4445 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
4446 (clobber (reg:CC 17))]
4449 [(set_attr "type" "imul")
4450 (set_attr "length_immediate" "0")
4451 (set_attr "mode" "SI")])
4453 (define_insn "umulsi3_highpart"
4454 [(set (match_operand:SI 0 "register_operand" "=d")
4457 (mult:DI (zero_extend:DI
4458 (match_operand:SI 1 "register_operand" "%a"))
4460 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4462 (clobber (match_scratch:SI 3 "=a"))
4463 (clobber (reg:CC 17))]
4466 [(set_attr "type" "imul")
4467 (set_attr "ppro_uops" "few")
4468 (set_attr "length_immediate" "0")
4469 (set_attr "mode" "SI")])
4471 (define_insn "smulsi3_highpart"
4472 [(set (match_operand:SI 0 "register_operand" "=d")
4475 (mult:DI (sign_extend:DI
4476 (match_operand:SI 1 "register_operand" "%a"))
4478 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4480 (clobber (match_scratch:SI 3 "=a"))
4481 (clobber (reg:CC 17))]
4484 [(set_attr "type" "imul")
4485 (set_attr "ppro_uops" "few")
4486 (set_attr "mode" "SI")])
4488 ;; The patterns that match these are at the end of this file.
4490 (define_expand "mulxf3"
4491 [(set (match_operand:XF 0 "register_operand" "")
4492 (mult:XF (match_operand:XF 1 "register_operand" "")
4493 (match_operand:XF 2 "register_operand" "")))]
4497 (define_expand "muldf3"
4498 [(set (match_operand:DF 0 "register_operand" "")
4499 (mult:DF (match_operand:DF 1 "register_operand" "")
4500 (match_operand:DF 2 "nonimmediate_operand" "")))]
4504 (define_expand "mulsf3"
4505 [(set (match_operand:SF 0 "register_operand" "")
4506 (mult:SF (match_operand:SF 1 "register_operand" "")
4507 (match_operand:SF 2 "nonimmediate_operand" "")))]
4511 ;; Divide instructions
4513 (define_insn "divqi3"
4514 [(set (match_operand:QI 0 "register_operand" "=a")
4515 (div:QI (match_operand:HI 1 "register_operand" "0")
4516 (match_operand:QI 2 "nonimmediate_operand" "qm")))
4517 (clobber (reg:CC 17))]
4518 "TARGET_QIMODE_MATH"
4520 [(set_attr "type" "idiv")
4521 (set_attr "mode" "QI")
4522 (set_attr "ppro_uops" "few")])
4524 (define_insn "udivqi3"
4525 [(set (match_operand:QI 0 "register_operand" "=a")
4526 (udiv:QI (match_operand:HI 1 "register_operand" "0")
4527 (match_operand:QI 2 "nonimmediate_operand" "qm")))
4528 (clobber (reg:CC 17))]
4529 "TARGET_QIMODE_MATH"
4531 [(set_attr "type" "idiv")
4532 (set_attr "mode" "QI")
4533 (set_attr "ppro_uops" "few")])
4535 ;; The patterns that match these are at the end of this file.
4537 (define_expand "divxf3"
4538 [(set (match_operand:XF 0 "register_operand" "")
4539 (div:XF (match_operand:XF 1 "register_operand" "")
4540 (match_operand:XF 2 "register_operand" "")))]
4544 (define_expand "divdf3"
4545 [(set (match_operand:DF 0 "register_operand" "")
4546 (div:DF (match_operand:DF 1 "register_operand" "")
4547 (match_operand:DF 2 "nonimmediate_operand" "")))]
4551 (define_expand "divsf3"
4552 [(set (match_operand:SF 0 "register_operand" "")
4553 (div:SF (match_operand:SF 1 "register_operand" "")
4554 (match_operand:SF 2 "nonimmediate_operand" "")))]
4558 ;; Remainder instructions.
4559 (define_expand "divmodsi4"
4560 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4561 (div:SI (match_operand:SI 1 "register_operand" "")
4562 (match_operand:SI 2 "nonimmediate_operand" "")))
4563 (set (match_operand:SI 3 "register_operand" "")
4564 (mod:SI (match_dup 1) (match_dup 2)))
4565 (clobber (reg:CC 17))])]
4569 ;; Allow to come the parameter in eax or edx to avoid extra moves.
4570 ;; Penalize eax case sligthly because it results in worse scheduling
4572 (define_insn "*divmodsi4_nocltd"
4573 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
4574 (div:SI (match_operand:SI 2 "register_operand" "1,0")
4575 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
4576 (set (match_operand:SI 1 "register_operand" "=&d,&d")
4577 (mod:SI (match_dup 2) (match_dup 3)))
4578 (clobber (reg:CC 17))]
4579 "!optimize_size && !TARGET_USE_CLTD"
4581 [(set_attr "type" "multi")])
4583 (define_insn "*divmodsi4_cltd"
4584 [(set (match_operand:SI 0 "register_operand" "=a")
4585 (div:SI (match_operand:SI 2 "register_operand" "a")
4586 (match_operand:SI 3 "nonimmediate_operand" "rm")))
4587 (set (match_operand:SI 1 "register_operand" "=&d")
4588 (mod:SI (match_dup 2) (match_dup 3)))
4589 (clobber (reg:CC 17))]
4590 "optimize_size || TARGET_USE_CLTD"
4592 [(set_attr "type" "multi")])
4594 (define_insn "*divmodsi_noext"
4595 [(set (match_operand:SI 0 "register_operand" "=a")
4596 (div:SI (match_operand:SI 1 "register_operand" "0")
4597 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4598 (set (match_operand:SI 3 "register_operand" "=d")
4599 (mod:SI (match_dup 1) (match_dup 2)))
4600 (use (match_operand:SI 4 "register_operand" "3"))
4601 (clobber (reg:CC 17))]
4604 [(set_attr "type" "idiv")
4605 (set_attr "mode" "SI")
4606 (set_attr "ppro_uops" "few")])
4609 [(set (match_operand:SI 0 "register_operand" "")
4610 (div:SI (match_operand:SI 1 "register_operand" "")
4611 (match_operand:SI 2 "nonimmediate_operand" "")))
4612 (set (match_operand:SI 3 "register_operand" "")
4613 (mod:SI (match_dup 1) (match_dup 2)))
4614 (clobber (reg:CC 17))]
4616 [(parallel [(set (match_dup 3)
4617 (ashiftrt:SI (match_dup 4) (const_int 31)))
4618 (clobber (reg:CC 17))])
4619 (parallel [(set (match_dup 0)
4620 (div:SI (reg:SI 0) (match_dup 2)))
4622 (mod:SI (reg:SI 0) (match_dup 2)))
4624 (clobber (reg:CC 17))])]
4627 /* Avoid use of cltd in favour of a mov+shift. */
4628 if (!TARGET_USE_CLTD && !optimize_size)
4630 if (true_regnum (operands[1]))
4631 emit_move_insn (operands[0], operands[1]);
4633 emit_move_insn (operands[3], operands[1]);
4634 operands[4] = operands[3];
4638 if (true_regnum (operands[1]))
4640 operands[4] = operands[1];
4644 (define_insn "divmodhi4"
4645 [(set (match_operand:HI 0 "register_operand" "=a")
4646 (div:HI (match_operand:HI 1 "register_operand" "0")
4647 (match_operand:HI 2 "nonimmediate_operand" "rm")))
4648 (set (match_operand:HI 3 "register_operand" "=&d")
4649 (mod:HI (match_dup 1) (match_dup 2)))
4650 (clobber (reg:CC 17))]
4651 "TARGET_HIMODE_MATH"
4652 "cwtd\;idiv{w}\\t%2"
4653 [(set_attr "type" "multi")
4654 (set_attr "length_immediate" "0")
4655 (set_attr "mode" "SI")])
4657 (define_insn "udivmodsi4"
4658 [(set (match_operand:SI 0 "register_operand" "=a")
4659 (udiv:SI (match_operand:SI 1 "register_operand" "0")
4660 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4661 (set (match_operand:SI 3 "register_operand" "=&d")
4662 (umod:SI (match_dup 1) (match_dup 2)))
4663 (clobber (reg:CC 17))]
4665 "xor{l}\\t%3, %3\;div{l}\\t%2"
4666 [(set_attr "type" "multi")
4667 (set_attr "length_immediate" "0")
4668 (set_attr "mode" "SI")])
4670 (define_insn "*udivmodsi4_noext"
4671 [(set (match_operand:SI 0 "register_operand" "=a")
4672 (udiv:SI (match_operand:SI 1 "register_operand" "0")
4673 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4674 (set (match_operand:SI 3 "register_operand" "=d")
4675 (umod:SI (match_dup 1) (match_dup 2)))
4677 (clobber (reg:CC 17))]
4680 [(set_attr "type" "idiv")
4681 (set_attr "ppro_uops" "few")
4682 (set_attr "mode" "SI")])
4685 [(set (match_operand:SI 0 "register_operand" "")
4686 (udiv:SI (match_operand:SI 1 "register_operand" "")
4687 (match_operand:SI 2 "nonimmediate_operand" "")))
4688 (set (match_operand:SI 3 "register_operand" "")
4689 (umod:SI (match_dup 1) (match_dup 2)))
4690 (clobber (reg:CC 17))]
4692 [(set (match_dup 3) (const_int 0))
4693 (parallel [(set (match_dup 0)
4694 (udiv:SI (match_dup 1) (match_dup 2)))
4696 (umod:SI (match_dup 1) (match_dup 2)))
4698 (clobber (reg:CC 17))])]
4701 (define_expand "udivmodhi4"
4702 [(set (match_dup 4) (const_int 0))
4703 (parallel [(set (match_operand:HI 0 "register_operand" "")
4704 (udiv:HI (match_operand:HI 1 "register_operand" "")
4705 (match_operand:HI 2 "nonimmediate_operand" "")))
4706 (set (match_operand:HI 3 "register_operand" "")
4707 (umod:HI (match_dup 1) (match_dup 2)))
4709 (clobber (reg:CC 17))])]
4710 "TARGET_HIMODE_MATH"
4711 "operands[4] = gen_reg_rtx (HImode);")
4713 (define_insn "*udivmodhi_noext"
4714 [(set (match_operand:HI 0 "register_operand" "=a")
4715 (udiv:HI (match_operand:HI 1 "register_operand" "0")
4716 (match_operand:HI 2 "nonimmediate_operand" "rm")))
4717 (set (match_operand:HI 3 "register_operand" "=d")
4718 (umod:HI (match_dup 1) (match_dup 2)))
4719 (use (match_operand:HI 4 "register_operand" "3"))
4720 (clobber (reg:CC 17))]
4723 [(set_attr "type" "idiv")
4724 (set_attr "mode" "HI")
4725 (set_attr "ppro_uops" "few")])
4727 ;; We can not use div/idiv for double division, because it causes
4728 ;; "division by zero" on the overflow and that's not what we expect
4729 ;; from truncate. Because true (non truncating) double division is
4730 ;; never generated, we can't create this insn anyway.
4733 ; [(set (match_operand:SI 0 "register_operand" "=a")
4735 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
4737 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
4738 ; (set (match_operand:SI 3 "register_operand" "=d")
4740 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
4741 ; (clobber (reg:CC 17))]
4743 ; "div{l}\\t{%2, %0|%0, %2}"
4744 ; [(set_attr "type" "idiv")
4745 ; (set_attr "ppro_uops" "few")])
4747 ;;- Logical AND instructions
4749 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
4750 ;; Note that this excludes ah.
4752 (define_insn "*testsi_ccz_1"
4755 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
4756 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
4759 "test{l}\\t{%1, %0|%0, %1}"
4760 [(set_attr "type" "test")
4761 (set_attr "modrm" "0,1,1")
4762 (set_attr "mode" "SI")
4763 (set_attr "pent_pair" "uv,np,uv")])
4765 (define_insn "testsi_ccno_1"
4768 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
4769 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
4772 "test{l}\\t{%1, %0|%0, %1}"
4773 [(set_attr "type" "test")
4774 (set_attr "modrm" "0,1,1")
4775 (set_attr "mode" "SI")
4776 (set_attr "pent_pair" "uv,np,uv")])
4778 (define_insn "*testhi_1"
4780 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
4781 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
4783 "ix86_match_ccmode (insn, CCNOmode)"
4784 "test{w}\\t{%1, %0|%0, %1}"
4785 [(set_attr "type" "test")
4786 (set_attr "modrm" "0,1,1")
4787 (set_attr "mode" "HI")
4788 (set_attr "pent_pair" "uv,np,uv")])
4790 (define_insn "testqi_ccz_1"
4793 (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm")
4794 (match_operand:QI 1 "nonmemory_operand" "n,n,qn"))
4797 "test{b}\\t{%1, %0|%0, %1}"
4798 [(set_attr "type" "test")
4799 (set_attr "modrm" "0,1,1")
4800 (set_attr "mode" "QI")
4801 (set_attr "pent_pair" "uv,np,uv")])
4803 (define_insn "testqi_ccno_1"
4805 (compare:CCNO (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
4806 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
4810 test{b}\\t{%1, %0|%0, %1}
4811 test{b}\\t{%1, %0|%0, %1}
4812 test{b}\\t{%1, %0|%0, %1}
4813 test{l}\\t{%1, %0|%0, %1}"
4814 [(set_attr "type" "test")
4815 (set_attr "modrm" "0,1,1,1")
4816 (set_attr "mode" "QI,QI,QI,SI")
4817 (set_attr "pent_pair" "uv,np,uv,np")])
4819 (define_insn "*testqi_ext_ccz_0"
4824 (match_operand 0 "ext_register_operand" "q")
4827 (match_operand 1 "const_int_operand" "n"))
4829 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff"
4830 "test{b}\\t{%1, %h0|%h0, %1}"
4831 [(set_attr "type" "test")
4832 (set_attr "mode" "QI")
4833 (set_attr "length_immediate" "1")
4834 (set_attr "pent_pair" "np")])
4836 (define_insn "testqi_ext_ccno_0"
4841 (match_operand 0 "ext_register_operand" "q")
4844 (match_operand 1 "const_int_operand" "n"))
4846 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff"
4847 "test{b}\\t{%1, %h0|%h0, %1}"
4848 [(set_attr "type" "test")
4849 (set_attr "mode" "QI")
4850 (set_attr "length_immediate" "1")
4851 (set_attr "pent_pair" "np")])
4853 (define_insn "*testqi_ext_1"
4858 (match_operand 0 "ext_register_operand" "q")
4862 (match_operand:QI 1 "nonimmediate_operand" "qm")))
4864 "ix86_match_ccmode (insn, CCNOmode)"
4865 "test{b}\\t{%1, %h0|%h0, %1}"
4866 [(set_attr "type" "test")
4867 (set_attr "mode" "QI")])
4869 (define_insn "*testqi_ext_2"
4874 (match_operand 0 "ext_register_operand" "q")
4878 (match_operand 1 "ext_register_operand" "q")
4882 "ix86_match_ccmode (insn, CCNOmode)"
4883 "test{b}\\t{%h1, %h0|%h0, %h1}"
4884 [(set_attr "type" "test")
4885 (set_attr "mode" "QI")])
4887 ;; Combine likes to form bit extractions for some tests. Humor it.
4888 (define_insn "*testqi_ext_3"
4890 (compare (zero_extract:SI
4891 (match_operand 0 "nonimmediate_operand" "rm")
4892 (match_operand:SI 1 "const_int_operand" "")
4893 (match_operand:SI 2 "const_int_operand" ""))
4895 "ix86_match_ccmode (insn, CCNOmode)
4896 && (GET_MODE (operands[0]) == SImode
4897 || GET_MODE (operands[0]) == HImode
4898 || GET_MODE (operands[0]) == QImode)"
4903 (compare (zero_extract:SI
4904 (match_operand 0 "nonimmediate_operand" "rm")
4905 (match_operand:SI 1 "const_int_operand" "")
4906 (match_operand:SI 2 "const_int_operand" ""))
4908 "ix86_match_ccmode (insn, CCNOmode)"
4909 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
4912 HOST_WIDE_INT len = INTVAL (operands[1]);
4913 HOST_WIDE_INT pos = INTVAL (operands[2]);
4915 enum machine_mode mode;
4917 mode = GET_MODE (operands[0]);
4918 if (GET_CODE (operands[0]) == MEM)
4920 /* ??? Combine likes to put non-volatile mem extractions in QImode
4921 no matter the size of the test. So find a mode that works. */
4922 if (! MEM_VOLATILE_P (operands[0]))
4924 mode = smallest_mode_for_size (pos + len, MODE_INT);
4925 operands[0] = change_address (operands[0], mode, NULL_RTX);
4928 else if (mode == HImode && pos + len <= 8)
4930 /* Small HImode tests can be converted to QImode. */
4932 operands[0] = gen_lowpart (QImode, operands[0]);
4935 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
4936 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
4938 operands[3] = gen_rtx_AND (mode, operands[0], GEN_INT (mask));
4941 ;; %%% This used to optimize known byte-wide and operations to memory,
4942 ;; and sometimes to QImode registers. If this is considered useful,
4943 ;; it should be done with splitters.
4945 (define_expand "andsi3"
4946 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4947 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
4948 (match_operand:SI 2 "general_operand" "")))
4949 (clobber (reg:CC 17))]
4951 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
4953 (define_insn "*andsi_1"
4954 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
4955 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
4956 (match_operand:SI 2 "general_operand" "ri,rm,L")))
4957 (clobber (reg:CC 17))]
4958 "ix86_binary_operator_ok (AND, SImode, operands)"
4961 switch (get_attr_type (insn))
4965 enum machine_mode mode;
4967 if (GET_CODE (operands[2]) != CONST_INT)
4969 if (INTVAL (operands[2]) == 0xff)
4971 else if (INTVAL (operands[2]) == 0xffff)
4976 operands[1] = gen_lowpart (mode, operands[1]);
4978 return \"movz{bl|x}\\t{%1,%0|%0, %1}\";
4980 return \"movz{wl|x}\\t{%1,%0|%0, %1}\";
4984 if (! rtx_equal_p (operands[0], operands[1]))
4986 return \"and{l}\\t{%2, %0|%0, %2}\";
4989 [(set_attr "type" "alu,alu,imovx")
4990 (set_attr "length_immediate" "*,*,0")
4991 (set_attr "mode" "SI")])
4994 [(set (match_operand:SI 0 "register_operand" "")
4995 (and:SI (match_dup 0)
4996 (const_int -65536)))
4997 (clobber (reg:CC 17))]
4999 [(set (strict_low_part (match_dup 1)) (const_int 0))]
5000 "operands[1] = gen_lowpart (HImode, operands[0]);")
5003 [(set (match_operand:SI 0 "q_regs_operand" "")
5004 (and:SI (match_dup 0)
5006 (clobber (reg:CC 17))]
5007 "(optimize_size || !TARGET_PARTIAL_REG_STALL)
5008 && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)"
5009 [(set (strict_low_part (match_dup 1)) (const_int 0))]
5010 "operands[1] = gen_lowpart (QImode, operands[0]);")
5013 [(set (match_operand 0 "register_operand" "")
5015 (const_int -65281)))
5016 (clobber (reg:CC 17))]
5017 "(optimize_size || !TARGET_PARTIAL_REG_STALL)
5018 && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)"
5019 [(parallel [(set (zero_extract:SI (match_dup 0)
5023 (zero_extract:SI (match_dup 0)
5026 (zero_extract:SI (match_dup 0)
5029 (clobber (reg:CC 17))])]
5030 "operands[0] = gen_lowpart (SImode, operands[0]);")
5032 (define_insn "*andsi_2"
5034 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5035 (match_operand:SI 2 "general_operand" "rim,ri"))
5037 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5038 (and:SI (match_dup 1) (match_dup 2)))]
5039 "ix86_match_ccmode (insn, CCNOmode)
5040 && ix86_binary_operator_ok (AND, SImode, operands)"
5041 "and{l}\\t{%2, %0|%0, %2}"
5042 [(set_attr "type" "alu")
5043 (set_attr "mode" "SI")])
5045 (define_expand "andhi3"
5046 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5047 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
5048 (match_operand:HI 2 "general_operand" "")))
5049 (clobber (reg:CC 17))]
5050 "TARGET_HIMODE_MATH"
5051 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
5053 (define_insn "*andhi_1"
5054 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5055 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
5056 (match_operand:HI 2 "general_operand" "ri,rm,L")))
5057 (clobber (reg:CC 17))]
5058 "ix86_binary_operator_ok (AND, HImode, operands)"
5061 switch (get_attr_type (insn))
5064 if (GET_CODE (operands[2]) != CONST_INT)
5066 if (INTVAL (operands[2]) == 0xff)
5067 return \"movz{bl|x}\\t{%b1, %k0|%k0, %b1}\";
5071 if (! rtx_equal_p (operands[0], operands[1]))
5074 return \"and{w}\\t{%2, %0|%0, %2}\";
5077 [(set_attr "type" "alu,alu,imovx")
5078 (set_attr "length_immediate" "*,*,0")
5079 (set_attr "mode" "HI,HI,SI")])
5081 (define_insn "*andhi_2"
5083 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5084 (match_operand:HI 2 "general_operand" "rim,ri"))
5086 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5087 (and:HI (match_dup 1) (match_dup 2)))]
5088 "ix86_match_ccmode (insn, CCNOmode)
5089 && ix86_binary_operator_ok (AND, HImode, operands)"
5090 "and{w}\\t{%2, %0|%0, %2}"
5091 [(set_attr "type" "alu")
5092 (set_attr "mode" "HI")])
5094 (define_expand "andqi3"
5095 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5096 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
5097 (match_operand:QI 2 "general_operand" "")))
5098 (clobber (reg:CC 17))]
5099 "TARGET_QIMODE_MATH"
5100 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
5102 ;; %%% Potential partial reg stall on alternative 2. What to do?
5103 (define_insn "*andqi_1"
5104 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5105 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5106 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
5107 (clobber (reg:CC 17))]
5108 "ix86_binary_operator_ok (AND, QImode, operands)"
5110 and{b}\\t{%2, %0|%0, %2}
5111 and{b}\\t{%2, %0|%0, %2}
5112 and{l}\\t{%k2, %k0|%k0, %k2}"
5113 [(set_attr "type" "alu")
5114 (set_attr "mode" "QI,QI,SI")])
5116 (define_insn "*andqi_2"
5119 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5120 (match_operand:QI 2 "general_operand" "qim,qi,i"))
5122 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
5123 (and:QI (match_dup 1) (match_dup 2)))]
5124 "ix86_match_ccmode (insn, CCNOmode)
5125 && ix86_binary_operator_ok (AND, QImode, operands)"
5127 and{b}\\t{%2, %0|%0, %2}
5128 and{b}\\t{%2, %0|%0, %2}
5129 and{l}\\t{%2, %k0|%k0, %2}"
5130 [(set_attr "type" "alu")
5131 (set_attr "mode" "QI,QI,SI")])
5133 ;; ??? A bug in recog prevents it from recognizing a const_int as an
5134 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
5135 ;; for a QImode operand, which of course failed.
5137 (define_insn "andqi_ext_0"
5138 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5143 (match_operand 1 "ext_register_operand" "0")
5146 (match_operand 2 "const_int_operand" "n")))
5147 (clobber (reg:CC 17))]
5148 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
5149 "and{b}\\t{%2, %h0|%h0, %2}"
5150 [(set_attr "type" "alu")
5151 (set_attr "length_immediate" "1")
5152 (set_attr "mode" "QI")])
5154 ;; Generated by peephole translating test to and. This shows up
5155 ;; often in fp comparisons.
5157 (define_insn "*andqi_ext_0_cc"
5162 (match_operand 1 "ext_register_operand" "q")
5165 (match_operand 2 "const_int_operand" "n"))
5167 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5176 "ix86_match_ccmode (insn, CCNOmode)
5177 && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
5178 "and{b}\\t{%2, %h0|%h0, %2}"
5179 [(set_attr "type" "alu")
5180 (set_attr "length_immediate" "1")
5181 (set_attr "mode" "QI")])
5183 (define_insn "*andqi_ext_1"
5184 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5189 (match_operand 1 "ext_register_operand" "0")
5193 (match_operand:QI 2 "general_operand" "qm"))))
5194 (clobber (reg:CC 17))]
5196 "and{b}\\t{%2, %h0|%h0, %2}"
5197 [(set_attr "type" "alu")
5198 (set_attr "length_immediate" "0")
5199 (set_attr "mode" "QI")])
5201 (define_insn "*andqi_ext_2"
5202 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5207 (match_operand 1 "ext_register_operand" "%0")
5211 (match_operand 2 "ext_register_operand" "q")
5214 (clobber (reg:CC 17))]
5216 "and{b}\\t{%h2, %h0|%h0, %h2}"
5217 [(set_attr "type" "alu")
5218 (set_attr "length_immediate" "0")
5219 (set_attr "mode" "QI")])
5221 ;; Logical inclusive OR instructions
5223 ;; %%% This used to optimize known byte-wide and operations to memory.
5224 ;; If this is considered useful, it should be done with splitters.
5226 (define_expand "iorsi3"
5227 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5228 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
5229 (match_operand:SI 2 "general_operand" "")))
5230 (clobber (reg:CC 17))]
5232 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
5234 (define_insn "*iorsi_1"
5235 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5236 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5237 (match_operand:SI 2 "general_operand" "ri,rmi")))
5238 (clobber (reg:CC 17))]
5239 "ix86_binary_operator_ok (IOR, SImode, operands)"
5240 "or{l}\\t{%2, %0|%0, %2}"
5241 [(set_attr "type" "alu")
5242 (set_attr "mode" "SI")])
5244 (define_insn "*iorsi_2"
5246 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5247 (match_operand:SI 2 "general_operand" "rim,ri"))
5249 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5250 (ior:SI (match_dup 1) (match_dup 2)))]
5251 "ix86_match_ccmode (insn, CCNOmode)
5252 && ix86_binary_operator_ok (IOR, SImode, operands)"
5253 "or{l}\\t{%2, %0|%0, %2}"
5254 [(set_attr "type" "alu")
5255 (set_attr "mode" "SI")])
5257 (define_expand "iorhi3"
5258 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5259 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
5260 (match_operand:HI 2 "general_operand" "")))
5261 (clobber (reg:CC 17))]
5262 "TARGET_HIMODE_MATH"
5263 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
5265 (define_insn "*iorhi_1"
5266 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
5267 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5268 (match_operand:HI 2 "general_operand" "rmi,ri")))
5269 (clobber (reg:CC 17))]
5270 "ix86_binary_operator_ok (IOR, HImode, operands)"
5271 "or{w}\\t{%2, %0|%0, %2}"
5272 [(set_attr "type" "alu")
5273 (set_attr "mode" "HI")])
5275 (define_insn "*iorhi_2"
5277 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5278 (match_operand:HI 2 "general_operand" "rim,ri"))
5280 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5281 (ior:HI (match_dup 1) (match_dup 2)))]
5282 "ix86_match_ccmode (insn, CCNOmode)
5283 && ix86_binary_operator_ok (IOR, HImode, operands)"
5284 "or{w}\\t{%2, %0|%0, %2}"
5285 [(set_attr "type" "alu")
5286 (set_attr "mode" "HI")])
5288 (define_expand "iorqi3"
5289 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5290 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
5291 (match_operand:QI 2 "general_operand" "")))
5292 (clobber (reg:CC 17))]
5293 "TARGET_QIMODE_MATH"
5294 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
5296 ;; %%% Potential partial reg stall on alternative 2. What to do?
5297 (define_insn "*iorqi_1"
5298 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
5299 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5300 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
5301 (clobber (reg:CC 17))]
5302 "ix86_binary_operator_ok (IOR, QImode, operands)"
5304 or{b}\\t{%2, %0|%0, %2}
5305 or{b}\\t{%2, %0|%0, %2}
5306 or{l}\\t{%k2, %k0|%k0, %k2}"
5307 [(set_attr "type" "alu")
5308 (set_attr "mode" "QI")])
5310 (define_insn "*iorqi_2"
5312 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
5313 (match_operand:QI 2 "general_operand" "qim,qi"))
5315 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
5316 (ior:QI (match_dup 1) (match_dup 2)))]
5317 "ix86_match_ccmode (insn, CCNOmode)
5318 && ix86_binary_operator_ok (IOR, QImode, operands)"
5319 "or{b}\\t{%2, %0|%0, %2}"
5320 [(set_attr "type" "alu")
5321 (set_attr "mode" "QI")])
5323 ;; Logical XOR instructions
5325 ;; %%% This used to optimize known byte-wide and operations to memory.
5326 ;; If this is considered useful, it should be done with splitters.
5328 (define_expand "xorsi3"
5329 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5330 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
5331 (match_operand:SI 2 "general_operand" "")))
5332 (clobber (reg:CC 17))]
5334 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
5336 (define_insn "*xorsi_1"
5337 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5338 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5339 (match_operand:SI 2 "general_operand" "ri,rm")))
5340 (clobber (reg:CC 17))]
5341 "ix86_binary_operator_ok (XOR, SImode, operands)"
5342 "xor{l}\\t{%2, %0|%0, %2}"
5343 [(set_attr "type" "alu")
5344 (set_attr "mode" "SI")])
5346 (define_insn "*xorsi_2"
5348 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5349 (match_operand:SI 2 "general_operand" "rim,ri"))
5351 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5352 (xor:SI (match_dup 1) (match_dup 2)))]
5353 "ix86_match_ccmode (insn, CCNOmode)
5354 && ix86_binary_operator_ok (XOR, SImode, operands)"
5355 "xor{l}\\t{%2, %0|%0, %2}"
5356 [(set_attr "type" "alu")
5357 (set_attr "mode" "SI")])
5359 (define_expand "xorhi3"
5360 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5361 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
5362 (match_operand:HI 2 "general_operand" "")))
5363 (clobber (reg:CC 17))]
5364 "TARGET_HIMODE_MATH"
5365 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
5367 (define_insn "*xorhi_1"
5368 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
5369 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5370 (match_operand:HI 2 "general_operand" "rmi,ri")))
5371 (clobber (reg:CC 17))]
5372 "ix86_binary_operator_ok (XOR, HImode, operands)"
5373 "xor{w}\\t{%2, %0|%0, %2}"
5374 [(set_attr "type" "alu")
5375 (set_attr "mode" "HI")])
5377 (define_insn "*xorhi_2"
5379 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5380 (match_operand:HI 2 "general_operand" "rim,ri"))
5382 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5383 (xor:HI (match_dup 1) (match_dup 2)))]
5384 "ix86_match_ccmode (insn, CCNOmode)
5385 && ix86_binary_operator_ok (XOR, HImode, operands)"
5386 "xor{w}\\t{%2, %0|%0, %2}"
5387 [(set_attr "type" "alu")
5388 (set_attr "mode" "HI")])
5390 (define_expand "xorqi3"
5391 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5392 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
5393 (match_operand:QI 2 "general_operand" "")))
5394 (clobber (reg:CC 17))]
5395 "TARGET_QIMODE_MATH"
5396 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
5398 ;; %%% Potential partial reg stall on alternative 2. What to do?
5399 (define_insn "*xorqi_1"
5400 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
5401 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5402 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
5403 (clobber (reg:CC 17))]
5404 "ix86_binary_operator_ok (XOR, QImode, operands)"
5406 xor{b}\\t{%2, %0|%0, %2}
5407 xor{b}\\t{%2, %0|%0, %2}
5408 xor{l}\\t{%k2, %k0|%k0, %k2}"
5409 [(set_attr "type" "alu")
5410 (set_attr "mode" "QI,QI,SI")])
5412 (define_insn "xorqi_ext_1"
5413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5417 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
5420 (zero_extract:SI (match_operand 2 "ext_register_operand" "q")
5423 (clobber (reg:CC 17))]
5425 "xor{b}\\t{%h2, %h0|%h0, %h2}"
5426 [(set_attr "type" "alu")
5427 (set_attr "length_immediate" "0")
5428 (set_attr "mode" "QI")])
5430 (define_insn "*xorqi_cc_1"
5433 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
5434 (match_operand:QI 2 "general_operand" "qim,qi"))
5436 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
5437 (xor:QI (match_dup 1) (match_dup 2)))]
5438 "ix86_match_ccmode (insn, CCNOmode)
5439 && ix86_binary_operator_ok (XOR, QImode, operands)"
5440 "xor{b}\\t{%2, %0|%0, %2}"
5441 [(set_attr "type" "alu")
5442 (set_attr "mode" "QI")])
5444 (define_insn "xorqi_cc_ext_1"
5449 (match_operand 1 "ext_register_operand" "0")
5452 (match_operand:QI 2 "general_operand" "qmn"))
5454 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5458 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
5461 "xor{b}\\t{%2, %h0|%h0, %2}"
5462 [(set_attr "type" "alu")
5463 (set_attr "mode" "QI")])
5465 ;; Negation instructions
5467 ;; %%% define_expand from the very first?
5469 (define_expand "negdi2"
5470 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
5471 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
5472 (clobber (reg:CC 17))])]
5474 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
5476 (define_insn "*negdi2_1"
5477 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
5478 (neg:DI (match_operand:DI 1 "general_operand" "0")))
5479 (clobber (reg:CC 17))]
5480 "ix86_unary_operator_ok (NEG, DImode, operands)"
5484 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5485 (neg:DI (match_operand:DI 1 "general_operand" "")))
5486 (clobber (reg:CC 17))]
5490 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
5491 (set (match_dup 0) (neg:SI (match_dup 2)))])
5494 (plus:SI (match_dup 3)
5495 (plus:SI (const_int 0)
5496 (ltu:SI (reg:CC 17) (const_int 0)))))
5497 (clobber (reg:CC 17))])
5500 (neg:SI (match_dup 1)))
5501 (clobber (reg:CC 17))])]
5502 "split_di (operands+1, 1, operands+2, operands+3);
5503 split_di (operands+0, 1, operands+0, operands+1);")
5505 (define_expand "negsi2"
5506 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5507 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
5508 (clobber (reg:CC 17))])]
5510 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
5512 (define_insn "*negsi2_1"
5513 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5514 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
5515 (clobber (reg:CC 17))]
5516 "ix86_unary_operator_ok (NEG, SImode, operands)"
5518 [(set_attr "type" "negnot")
5519 (set_attr "mode" "SI")])
5521 ;; The problem with neg is that it does not perform (compare x 0),
5522 ;; it really performs (compare 0 x), which leaves us with the zero
5523 ;; flag being the only useful item.
5525 (define_insn "*negsi2_cmpz"
5527 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
5529 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5530 (neg:SI (match_dup 1)))]
5531 "ix86_unary_operator_ok (NEG, SImode, operands)"
5533 [(set_attr "type" "negnot")
5534 (set_attr "mode" "SI")])
5536 (define_expand "neghi2"
5537 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5538 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
5539 (clobber (reg:CC 17))])]
5540 "TARGET_HIMODE_MATH"
5541 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
5543 (define_insn "*neghi2_1"
5544 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5545 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
5546 (clobber (reg:CC 17))]
5547 "ix86_unary_operator_ok (NEG, HImode, operands)"
5549 [(set_attr "type" "negnot")
5550 (set_attr "mode" "HI")])
5552 (define_insn "*neghi2_cmpz"
5554 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
5556 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5557 (neg:HI (match_dup 1)))]
5558 "ix86_unary_operator_ok (NEG, HImode, operands)"
5560 [(set_attr "type" "negnot")
5561 (set_attr "mode" "HI")])
5563 (define_expand "negqi2"
5564 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5565 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
5566 (clobber (reg:CC 17))])]
5567 "TARGET_QIMODE_MATH"
5568 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
5570 (define_insn "*negqi2_1"
5571 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5572 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
5573 (clobber (reg:CC 17))]
5574 "ix86_unary_operator_ok (NEG, QImode, operands)"
5576 [(set_attr "type" "negnot")
5577 (set_attr "mode" "QI")])
5579 (define_insn "*negqi2_cmpz"
5581 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
5583 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5584 (neg:QI (match_dup 1)))]
5585 "ix86_unary_operator_ok (NEG, QImode, operands)"
5587 [(set_attr "type" "negnot")
5588 (set_attr "mode" "QI")])
5590 ;; Changing of sign for FP values is doable using integer unit too.
5592 (define_expand "negsf2"
5593 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
5594 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
5595 (clobber (reg:CC 17))])]
5597 "ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
5599 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5600 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5602 (define_insn "*negsf2_if"
5603 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
5604 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
5605 (clobber (reg:CC 17))]
5606 "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
5610 [(set (match_operand:SF 0 "register_operand" "")
5611 (neg:SF (match_operand:SF 1 "register_operand" "")))
5612 (clobber (reg:CC 17))]
5613 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5615 (neg:SF (match_dup 1)))]
5619 [(set (match_operand:SF 0 "register_operand" "")
5620 (neg:SF (match_operand:SF 1 "register_operand" "")))
5621 (clobber (reg:CC 17))]
5622 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5623 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
5624 (clobber (reg:CC 17))])]
5625 "operands[1] = GEN_INT (0x80000000);
5626 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
5629 [(set (match_operand 0 "memory_operand" "")
5630 (neg (match_operand 1 "memory_operand" "")))
5631 (clobber (reg:CC 17))]
5632 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5633 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5634 (clobber (reg:CC 17))])]
5637 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
5639 /* XFmode's size is 12, but only 10 bytes are used. */
5642 operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
5643 operands[0] = adj_offsettable_operand (operands[0], size - 1);
5644 operands[1] = GEN_INT (0x80);
5647 (define_expand "negdf2"
5648 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
5649 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
5650 (clobber (reg:CC 17))])]
5652 "ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
5654 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5655 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5657 (define_insn "*negdf2_if"
5658 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
5659 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
5660 (clobber (reg:CC 17))]
5661 "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
5665 [(set (match_operand:DF 0 "register_operand" "")
5666 (neg:DF (match_operand:DF 1 "register_operand" "")))
5667 (clobber (reg:CC 17))]
5668 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5670 (neg:DF (match_dup 1)))]
5674 [(set (match_operand:DF 0 "register_operand" "")
5675 (neg:DF (match_operand:DF 1 "register_operand" "")))
5676 (clobber (reg:CC 17))]
5677 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5678 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
5679 (clobber (reg:CC 17))])]
5680 "operands[4] = GEN_INT (0x80000000);
5681 split_di (operands+0, 1, operands+2, operands+3);")
5683 (define_expand "negxf2"
5684 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
5685 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
5686 (clobber (reg:CC 17))])]
5688 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
5690 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5691 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5693 (define_insn "*negxf2_if"
5694 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
5695 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
5696 (clobber (reg:CC 17))]
5697 "TARGET_80387 && ix86_unary_operator_ok (NEG, XFmode, operands)"
5701 [(set (match_operand:XF 0 "register_operand" "")
5702 (neg:XF (match_operand:XF 1 "register_operand" "")))
5703 (clobber (reg:CC 17))]
5704 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5706 (neg:XF (match_dup 1)))]
5710 [(set (match_operand:XF 0 "register_operand" "")
5711 (neg:XF (match_operand:XF 1 "register_operand" "")))
5712 (clobber (reg:CC 17))]
5713 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5714 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
5715 (clobber (reg:CC 17))])]
5716 "operands[1] = GEN_INT (0x8000);
5717 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
5719 ;; Conditionize these after reload. If they matches before reload, we
5720 ;; lose the clobber and ability to use integer instructions.
5722 (define_insn "*negsf2_1"
5723 [(set (match_operand:SF 0 "register_operand" "=f")
5724 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
5725 "TARGET_80387 && reload_completed"
5727 [(set_attr "type" "fsgn")
5728 (set_attr "mode" "SF")
5729 (set_attr "ppro_uops" "few")])
5731 (define_insn "*negdf2_1"
5732 [(set (match_operand:DF 0 "register_operand" "=f")
5733 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
5734 "TARGET_80387 && reload_completed"
5736 [(set_attr "type" "fsgn")
5737 (set_attr "mode" "DF")
5738 (set_attr "ppro_uops" "few")])
5740 (define_insn "*negextendsfdf2"
5741 [(set (match_operand:DF 0 "register_operand" "=f")
5742 (neg:DF (float_extend:DF
5743 (match_operand:SF 1 "register_operand" "0"))))]
5746 [(set_attr "type" "fsgn")
5747 (set_attr "mode" "DF")
5748 (set_attr "ppro_uops" "few")])
5750 (define_insn "*negxf2_1"
5751 [(set (match_operand:XF 0 "register_operand" "=f")
5752 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
5753 "TARGET_80387 && reload_completed"
5755 [(set_attr "type" "fsgn")
5756 (set_attr "mode" "XF")
5757 (set_attr "ppro_uops" "few")])
5759 (define_insn "*negextenddfxf2"
5760 [(set (match_operand:XF 0 "register_operand" "=f")
5761 (neg:XF (float_extend:XF
5762 (match_operand:DF 1 "register_operand" "0"))))]
5765 [(set_attr "type" "fsgn")
5766 (set_attr "mode" "XF")
5767 (set_attr "ppro_uops" "few")])
5769 (define_insn "*negextendsfxf2"
5770 [(set (match_operand:XF 0 "register_operand" "=f")
5771 (neg:XF (float_extend:XF
5772 (match_operand:SF 1 "register_operand" "0"))))]
5775 [(set_attr "type" "fsgn")
5776 (set_attr "mode" "XF")
5777 (set_attr "ppro_uops" "few")])
5779 ;; Absolute value instructions
5781 (define_expand "abssf2"
5782 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
5783 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
5784 (clobber (reg:CC 17))])]
5786 "ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
5788 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5789 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5791 (define_insn "*abssf2_if"
5792 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
5793 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
5794 (clobber (reg:CC 17))]
5795 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
5799 [(set (match_operand:SF 0 "register_operand" "")
5800 (abs:SF (match_operand:SF 1 "register_operand" "")))
5801 (clobber (reg:CC 17))]
5802 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
5804 (abs:SF (match_dup 1)))]
5808 [(set (match_operand:SF 0 "register_operand" "")
5809 (abs:SF (match_operand:SF 1 "register_operand" "")))
5810 (clobber (reg:CC 17))]
5811 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5812 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
5813 (clobber (reg:CC 17))])]
5814 "operands[1] = GEN_INT (~0x80000000);
5815 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
5818 [(set (match_operand 0 "memory_operand" "")
5819 (abs (match_operand 1 "memory_operand" "")))
5820 (clobber (reg:CC 17))]
5821 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5822 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5823 (clobber (reg:CC 17))])]
5826 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
5828 /* XFmode's size is 12, but only 10 bytes are used. */
5831 operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
5832 operands[0] = adj_offsettable_operand (operands[0], size - 1);
5833 operands[1] = GEN_INT (~0x80);
5836 (define_expand "absdf2"
5837 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
5838 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
5839 (clobber (reg:CC 17))])]
5841 "ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
5843 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5844 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5846 (define_insn "*absdf2_if"
5847 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
5848 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
5849 (clobber (reg:CC 17))]
5850 "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
5854 [(set (match_operand:DF 0 "register_operand" "")
5855 (abs:DF (match_operand:DF 1 "register_operand" "")))
5856 (clobber (reg:CC 17))]
5857 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5859 (abs:DF (match_dup 1)))]
5863 [(set (match_operand:DF 0 "register_operand" "")
5864 (abs:DF (match_operand:DF 1 "register_operand" "")))
5865 (clobber (reg:CC 17))]
5866 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5867 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
5868 (clobber (reg:CC 17))])]
5869 "operands[4] = GEN_INT (~0x80000000);
5870 split_di (operands+0, 1, operands+2, operands+3);")
5872 (define_expand "absxf2"
5873 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
5874 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
5875 (clobber (reg:CC 17))])]
5877 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
5879 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5880 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5882 (define_insn "*absxf2_if"
5883 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
5884 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
5885 (clobber (reg:CC 17))]
5886 "TARGET_80387 && ix86_unary_operator_ok (ABS, XFmode, operands)"
5890 [(set (match_operand:XF 0 "register_operand" "")
5891 (abs:XF (match_operand:XF 1 "register_operand" "")))
5892 (clobber (reg:CC 17))]
5893 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5895 (abs:XF (match_dup 1)))]
5899 [(set (match_operand:XF 0 "register_operand" "")
5900 (abs:XF (match_operand:XF 1 "register_operand" "")))
5901 (clobber (reg:CC 17))]
5902 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5903 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
5904 (clobber (reg:CC 17))])]
5905 "operands[1] = GEN_INT (~0x8000);
5906 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
5908 (define_insn "*abssf2_1"
5909 [(set (match_operand:SF 0 "register_operand" "=f")
5910 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
5911 "TARGET_80387 && reload_completed"
5913 [(set_attr "type" "fsgn")
5914 (set_attr "mode" "SF")])
5916 (define_insn "*absdf2_1"
5917 [(set (match_operand:DF 0 "register_operand" "=f")
5918 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
5919 "TARGET_80387 && reload_completed"
5921 [(set_attr "type" "fsgn")
5922 (set_attr "mode" "DF")])
5924 (define_insn "*absextendsfdf2"
5925 [(set (match_operand:DF 0 "register_operand" "=f")
5926 (abs:DF (float_extend:DF
5927 (match_operand:SF 1 "register_operand" "0"))))]
5930 [(set_attr "type" "fsgn")
5931 (set_attr "mode" "DF")])
5933 (define_insn "*absxf2_1"
5934 [(set (match_operand:XF 0 "register_operand" "=f")
5935 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
5936 "TARGET_80387 && reload_completed"
5938 [(set_attr "type" "fsgn")
5939 (set_attr "mode" "DF")])
5941 (define_insn "*absextenddfxf2"
5942 [(set (match_operand:XF 0 "register_operand" "=f")
5943 (abs:XF (float_extend:XF
5944 (match_operand:DF 1 "register_operand" "0"))))]
5947 [(set_attr "type" "fsgn")
5948 (set_attr "mode" "XF")])
5950 (define_insn "*absextendsfxf2"
5951 [(set (match_operand:XF 0 "register_operand" "=f")
5952 (abs:XF (float_extend:XF
5953 (match_operand:SF 1 "register_operand" "0"))))]
5956 [(set_attr "type" "fsgn")
5957 (set_attr "mode" "XF")])
5959 ;; One complement instructions
5961 (define_expand "one_cmplsi2"
5962 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5963 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
5965 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
5967 (define_insn "*one_cmplsi2_1"
5968 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5969 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
5970 "ix86_unary_operator_ok (NOT, SImode, operands)"
5972 [(set_attr "type" "negnot")
5973 (set_attr "mode" "SI")])
5975 (define_insn "*one_cmplsi2_2"
5977 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
5979 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5980 (not:SI (match_dup 1)))]
5981 "ix86_match_ccmode (insn, CCNOmode)
5982 && ix86_unary_operator_ok (NOT, SImode, operands)"
5984 [(set_attr "type" "alu1")
5985 (set_attr "mode" "SI")])
5989 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
5991 (set (match_operand:SI 0 "nonimmediate_operand" "")
5992 (not:SI (match_dup 1)))]
5993 "ix86_match_ccmode (insn, CCNOmode)"
5994 [(parallel [(set (reg:CCNO 17)
5995 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
5998 (xor:SI (match_dup 1) (const_int -1)))])]
6001 (define_expand "one_cmplhi2"
6002 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6003 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
6004 "TARGET_HIMODE_MATH"
6005 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
6007 (define_insn "*one_cmplhi2_1"
6008 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6009 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
6010 "ix86_unary_operator_ok (NOT, HImode, operands)"
6012 [(set_attr "type" "negnot")
6013 (set_attr "mode" "HI")])
6015 (define_insn "*one_cmplhi2_2"
6017 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
6019 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6020 (not:HI (match_dup 1)))]
6021 "ix86_match_ccmode (insn, CCNOmode)
6022 && ix86_unary_operator_ok (NEG, HImode, operands)"
6024 [(set_attr "type" "alu1")
6025 (set_attr "mode" "HI")])
6029 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
6031 (set (match_operand:HI 0 "nonimmediate_operand" "")
6032 (not:HI (match_dup 1)))]
6033 "ix86_match_ccmode (insn, CCNOmode)"
6034 [(parallel [(set (reg:CCNO 17)
6035 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
6038 (xor:HI (match_dup 1) (const_int -1)))])]
6041 ;; %%% Potential partial reg stall on alternative 1. What to do?
6042 (define_expand "one_cmplqi2"
6043 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6044 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
6045 "TARGET_QIMODE_MATH"
6046 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
6048 (define_insn "*one_cmplqi2_1"
6049 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
6050 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
6051 "ix86_unary_operator_ok (NOT, QImode, operands)"
6055 [(set_attr "type" "negnot")
6056 (set_attr "mode" "QI,SI")])
6058 (define_insn "*one_cmplqi2_2"
6060 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
6062 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6063 (not:QI (match_dup 1)))]
6064 "ix86_match_ccmode (insn, CCNOmode)
6065 && ix86_unary_operator_ok (NOT, QImode, operands)"
6067 [(set_attr "type" "alu1")
6068 (set_attr "mode" "QI")])
6072 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
6074 (set (match_operand:QI 0 "nonimmediate_operand" "")
6075 (not:QI (match_dup 1)))]
6076 "ix86_match_ccmode (insn, CCNOmode)"
6077 [(parallel [(set (reg:CCNO 17)
6078 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
6081 (xor:QI (match_dup 1) (const_int -1)))])]
6084 ;; Arithmetic shift instructions
6086 ;; DImode shifts are implemented using the i386 "shift double" opcode,
6087 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
6088 ;; is variable, then the count is in %cl and the "imm" operand is dropped
6089 ;; from the assembler input.
6091 ;; This instruction shifts the target reg/mem as usual, but instead of
6092 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
6093 ;; is a left shift double, bits are taken from the high order bits of
6094 ;; reg, else if the insn is a shift right double, bits are taken from the
6095 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
6096 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
6098 ;; Since sh[lr]d does not change the `reg' operand, that is done
6099 ;; separately, making all shifts emit pairs of shift double and normal
6100 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
6101 ;; support a 63 bit shift, each shift where the count is in a reg expands
6102 ;; to a pair of shifts, a branch, a shift by 32 and a label.
6104 ;; If the shift count is a constant, we need never emit more than one
6105 ;; shift pair, instead using moves and sign extension for counts greater
6108 (define_expand "ashldi3"
6109 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
6110 (ashift:DI (match_operand:DI 1 "register_operand" "0")
6111 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6112 (clobber (reg:CC 17))])]
6116 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
6118 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
6123 (define_insn "ashldi3_1"
6124 [(set (match_operand:DI 0 "register_operand" "=r")
6125 (ashift:DI (match_operand:DI 1 "register_operand" "0")
6126 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6127 (clobber (match_scratch:SI 3 "=&r"))
6128 (clobber (reg:CC 17))]
6131 [(set_attr "type" "multi")])
6133 (define_insn "*ashldi3_2"
6134 [(set (match_operand:DI 0 "register_operand" "=r")
6135 (ashift:DI (match_operand:DI 1 "register_operand" "0")
6136 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6137 (clobber (reg:CC 17))]
6140 [(set_attr "type" "multi")])
6143 [(set (match_operand:DI 0 "register_operand" "")
6144 (ashift:DI (match_operand:DI 1 "register_operand" "")
6145 (match_operand:QI 2 "nonmemory_operand" "")))
6146 (clobber (match_scratch:SI 3 ""))
6147 (clobber (reg:CC 17))]
6148 "TARGET_CMOVE && reload_completed"
6150 "ix86_split_ashldi (operands, operands[3]); DONE;")
6153 [(set (match_operand:DI 0 "register_operand" "")
6154 (ashift:DI (match_operand:DI 1 "register_operand" "")
6155 (match_operand:QI 2 "nonmemory_operand" "")))
6156 (clobber (reg:CC 17))]
6159 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
6161 (define_insn "x86_shld_1"
6162 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
6163 (ior:SI (ashift:SI (match_dup 0)
6164 (match_operand:QI 2 "nonmemory_operand" "I,c"))
6165 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
6166 (minus:QI (const_int 32) (match_dup 2)))))
6167 (clobber (reg:CC 17))]
6170 shld{l}\\t{%2, %1, %0|%0, %1, %2}
6171 shld{l}\\t{%s2%1, %0|%0, %1, %2}"
6172 [(set_attr "type" "ishift")
6173 (set_attr "prefix_0f" "1")
6174 (set_attr "mode" "SI")
6175 (set_attr "pent_pair" "np")
6176 (set_attr "athlon_decode" "vector")
6177 (set_attr "ppro_uops" "few")])
6179 (define_expand "x86_shift_adj_1"
6181 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
6184 (set (match_operand:SI 0 "register_operand" "")
6185 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
6186 (match_operand:SI 1 "register_operand" "")
6189 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
6190 (match_operand:SI 3 "register_operand" "r")
6195 (define_expand "x86_shift_adj_2"
6196 [(use (match_operand:SI 0 "register_operand" ""))
6197 (use (match_operand:SI 1 "register_operand" ""))
6198 (use (match_operand:QI 2 "register_operand" ""))]
6202 rtx label = gen_label_rtx ();
6205 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
6207 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
6208 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
6209 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
6210 gen_rtx_LABEL_REF (VOIDmode, label),
6212 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
6213 JUMP_LABEL (tmp) = label;
6215 emit_move_insn (operands[0], operands[1]);
6216 emit_move_insn (operands[1], const0_rtx);
6219 LABEL_NUSES (label) = 1;
6224 (define_expand "ashlsi3"
6225 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6226 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
6227 (match_operand:QI 2 "nonmemory_operand" "")))
6228 (clobber (reg:CC 17))]
6230 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
6232 (define_insn "*ashlsi3_1"
6233 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6234 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
6235 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
6236 (clobber (reg:CC 17))]
6237 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
6240 switch (get_attr_type (insn))
6243 if (operands[2] != const1_rtx)
6245 if (!rtx_equal_p (operands[0], operands[1]))
6247 return \"add{l}\\t{%0, %0|%0, %0}\";
6250 if (GET_CODE (operands[2]) != CONST_INT
6251 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
6253 operands[1] = gen_rtx_MULT (SImode, operands[1],
6254 GEN_INT (1 << INTVAL (operands[2])));
6255 return \"lea{l}\\t{%a1, %0|%0, %a1}\";
6258 if (REG_P (operands[2]))
6259 return \"sal{l}\\t{%b2, %0|%0, %b2}\";
6260 else if (GET_CODE (operands[2]) == CONST_INT
6261 && INTVAL (operands[2]) == 1
6262 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
6263 return \"sal{l}\\t%0\";
6265 return \"sal{l}\\t{%2, %0|%0, %2}\";
6269 (cond [(eq_attr "alternative" "1")
6270 (const_string "lea")
6271 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6273 (match_operand 0 "register_operand" ""))
6274 (match_operand 2 "const1_operand" ""))
6275 (const_string "alu")
6277 (const_string "ishift")))
6278 (set_attr "mode" "SI")])
6280 ;; Convert lea to the lea pattern to avoid flags dependency.
6282 [(set (match_operand:SI 0 "register_operand" "")
6283 (ashift:SI (match_operand:SI 1 "register_operand" "")
6284 (match_operand:QI 2 "immediate_operand" "")))
6285 (clobber (reg:CC 17))]
6287 && true_regnum (operands[0]) != true_regnum (operands[1])"
6289 (mult:SI (match_dup 1)
6291 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));")
6293 ;; This pattern can't accept a variable shift count, since shifts by
6294 ;; zero don't affect the flags. We assume that shifts by constant
6295 ;; zero are optimized away.
6296 (define_insn "*ashlsi3_cmpno"
6299 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6300 (match_operand:QI 2 "immediate_operand" "I"))
6302 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6303 (ashift:SI (match_dup 1) (match_dup 2)))]
6304 "ix86_match_ccmode (insn, CCNOmode)
6305 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
6308 switch (get_attr_type (insn))
6311 if (operands[2] != const1_rtx)
6313 return \"add{l}\\t{%0, %0|%0, %0}\";
6316 if (REG_P (operands[2]))
6317 return \"sal{l}\\t{%b2, %0|%0, %b2}\";
6318 else if (GET_CODE (operands[2]) == CONST_INT
6319 && INTVAL (operands[2]) == 1
6320 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
6321 return \"sal{l}\\t%0\";
6323 return \"sal{l}\\t{%2, %0|%0, %2}\";
6327 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6329 (match_operand 0 "register_operand" ""))
6330 (match_operand 2 "const1_operand" ""))
6331 (const_string "alu")
6333 (const_string "ishift")))
6334 (set_attr "mode" "SI")])
6336 (define_expand "ashlhi3"
6337 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6338 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
6339 (match_operand:QI 2 "nonmemory_operand" "")))
6340 (clobber (reg:CC 17))]
6341 "TARGET_HIMODE_MATH"
6342 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
6344 (define_insn "*ashlhi3_1"
6345 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6346 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6347 (match_operand:QI 2 "nonmemory_operand" "cI")))
6348 (clobber (reg:CC 17))]
6349 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
6352 switch (get_attr_type (insn))
6355 if (operands[2] != const1_rtx)
6357 return \"add{w}\\t{%0, %0|%0, %0}\";
6360 if (REG_P (operands[2]))
6361 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
6362 else if (GET_CODE (operands[2]) == CONST_INT
6363 && INTVAL (operands[2]) == 1
6364 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
6365 return \"sal{w}\\t%0\";
6367 return \"sal{w}\\t{%2, %0|%0, %2}\";
6371 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6373 (match_operand 0 "register_operand" ""))
6374 (match_operand 2 "const1_operand" ""))
6375 (const_string "alu")
6377 (const_string "ishift")))
6378 (set_attr "mode" "HI")])
6380 ;; This pattern can't accept a variable shift count, since shifts by
6381 ;; zero don't affect the flags. We assume that shifts by constant
6382 ;; zero are optimized away.
6383 (define_insn "*ashlhi3_cmpno"
6386 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6387 (match_operand:QI 2 "immediate_operand" "I"))
6389 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6390 (ashift:HI (match_dup 1) (match_dup 2)))]
6391 "ix86_match_ccmode (insn, CCNOmode)
6392 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
6395 switch (get_attr_type (insn))
6398 if (operands[2] != const1_rtx)
6400 return \"add{w}\\t{%0, %0|%0, %0}\";
6403 if (REG_P (operands[2]))
6404 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
6405 else if (GET_CODE (operands[2]) == CONST_INT
6406 && INTVAL (operands[2]) == 1
6407 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
6408 return \"sal{w}\\t%0\";
6410 return \"sal{w}\\t{%2, %0|%0, %2}\";
6414 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6416 (match_operand 0 "register_operand" ""))
6417 (match_operand 2 "const1_operand" ""))
6418 (const_string "alu")
6420 (const_string "ishift")))
6421 (set_attr "mode" "HI")])
6423 (define_expand "ashlqi3"
6424 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6425 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
6426 (match_operand:QI 2 "nonmemory_operand" "")))
6427 (clobber (reg:CC 17))]
6428 "TARGET_QIMODE_MATH"
6429 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
6431 ;; %%% Potential partial reg stall on alternative 2. What to do?
6432 (define_insn "*ashlqi3_1"
6433 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
6434 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6435 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
6436 (clobber (reg:CC 17))]
6437 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
6440 switch (get_attr_type (insn))
6443 if (operands[2] != const1_rtx)
6445 if (NON_QI_REG_P (operands[1]))
6446 return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
6448 return \"add{b}\\t{%0, %0|%0, %0}\";
6451 if (REG_P (operands[2]))
6453 if (NON_QI_REG_P (operands[1]))
6454 return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
6456 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
6458 else if (GET_CODE (operands[2]) == CONST_INT
6459 && INTVAL (operands[2]) == 1
6460 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
6462 if (NON_QI_REG_P (operands[1]))
6463 return \"sal{l}\\t%0\";
6465 return \"sal{b}\\t%0\";
6469 if (NON_QI_REG_P (operands[1]))
6470 return \"sal{l}\\t{%2, %k0|%k0, %2}\";
6472 return \"sal{b}\\t{%2, %0|%0, %2}\";
6477 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6479 (match_operand 0 "register_operand" ""))
6480 (match_operand 2 "const1_operand" ""))
6481 (const_string "alu")
6483 (const_string "ishift")))
6484 (set_attr "mode" "QI,SI")])
6486 ;; This pattern can't accept a variable shift count, since shifts by
6487 ;; zero don't affect the flags. We assume that shifts by constant
6488 ;; zero are optimized away.
6489 (define_insn "*ashlqi3_cmpno"
6492 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6493 (match_operand:QI 2 "immediate_operand" "I"))
6495 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6496 (ashift:QI (match_dup 1) (match_dup 2)))]
6497 "ix86_match_ccmode (insn, CCNOmode)
6498 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
6501 switch (get_attr_type (insn))
6504 if (operands[2] != const1_rtx)
6506 return \"add{b}\\t{%0, %0|%0, %0}\";
6509 if (REG_P (operands[2]))
6510 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
6511 else if (GET_CODE (operands[2]) == CONST_INT
6512 && INTVAL (operands[2]) == 1
6513 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
6514 return \"sal{b}\\t%0\";
6516 return \"sal{b}\\t{%2, %0|%0, %2}\";
6520 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
6522 (match_operand 0 "register_operand" ""))
6523 (match_operand 2 "const1_operand" ""))
6524 (const_string "alu")
6526 (const_string "ishift")))
6527 (set_attr "mode" "QI")])
6529 ;; See comment above `ashldi3' about how this works.
6531 (define_expand "ashrdi3"
6532 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
6533 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6534 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6535 (clobber (reg:CC 17))])]
6539 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
6541 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
6546 (define_insn "ashrdi3_1"
6547 [(set (match_operand:DI 0 "register_operand" "=r")
6548 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6549 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6550 (clobber (match_scratch:SI 3 "=&r"))
6551 (clobber (reg:CC 17))]
6554 [(set_attr "type" "multi")])
6556 (define_insn "*ashrdi3_2"
6557 [(set (match_operand:DI 0 "register_operand" "=r")
6558 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6559 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6560 (clobber (reg:CC 17))]
6563 [(set_attr "type" "multi")])
6566 [(set (match_operand:DI 0 "register_operand" "")
6567 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6568 (match_operand:QI 2 "nonmemory_operand" "")))
6569 (clobber (match_scratch:SI 3 ""))
6570 (clobber (reg:CC 17))]
6571 "TARGET_CMOVE && reload_completed"
6573 "ix86_split_ashrdi (operands, operands[3]); DONE;")
6576 [(set (match_operand:DI 0 "register_operand" "")
6577 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6578 (match_operand:QI 2 "nonmemory_operand" "")))
6579 (clobber (reg:CC 17))]
6582 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
6584 (define_insn "x86_shrd_1"
6585 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
6586 (ior:SI (ashiftrt:SI (match_dup 0)
6587 (match_operand:QI 2 "nonmemory_operand" "I,c"))
6588 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
6589 (minus:QI (const_int 32) (match_dup 2)))))
6590 (clobber (reg:CC 17))]
6593 shrd{l}\\t{%2, %1, %0|%0, %1, %2}
6594 shrd{l}\\t{%s2%1, %0|%0, %1, %2}"
6595 [(set_attr "type" "ishift")
6596 (set_attr "prefix_0f" "1")
6597 (set_attr "pent_pair" "np")
6598 (set_attr "ppro_uops" "few")
6599 (set_attr "mode" "SI")])
6601 (define_expand "x86_shift_adj_3"
6602 [(use (match_operand:SI 0 "register_operand" ""))
6603 (use (match_operand:SI 1 "register_operand" ""))
6604 (use (match_operand:QI 2 "register_operand" ""))]
6608 rtx label = gen_label_rtx ();
6611 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
6613 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
6614 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
6615 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
6616 gen_rtx_LABEL_REF (VOIDmode, label),
6618 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
6619 JUMP_LABEL (tmp) = label;
6621 emit_move_insn (operands[0], operands[1]);
6622 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
6625 LABEL_NUSES (label) = 1;
6630 (define_insn "ashrsi3_31"
6631 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
6632 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
6633 (match_operand:SI 2 "const_int_operand" "i,i")))
6634 (clobber (reg:CC 17))]
6635 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
6636 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6639 sar{l}\\t{%2, %0|%0, %2}"
6640 [(set_attr "type" "imovx,ishift")
6641 (set_attr "prefix_0f" "0,*")
6642 (set_attr "length_immediate" "0,*")
6643 (set_attr "modrm" "0,1")
6644 (set_attr "mode" "SI")])
6646 (define_expand "ashrsi3"
6647 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6648 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
6649 (match_operand:QI 2 "nonmemory_operand" "")))
6650 (clobber (reg:CC 17))]
6652 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
6654 (define_insn "*ashrsi3_1_one_bit"
6655 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6656 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6657 (match_operand:QI 2 "const_int_1_operand" "")))
6658 (clobber (reg:CC 17))]
6659 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
6660 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
6662 [(set_attr "type" "ishift")
6663 (set (attr "length")
6664 (if_then_else (match_operand:SI 0 "register_operand" "")
6666 (const_string "*")))])
6668 (define_insn "*ashrsi3_1"
6669 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6670 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6671 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6672 (clobber (reg:CC 17))]
6673 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6675 sar{l}\\t{%2, %0|%0, %2}
6676 sar{l}\\t{%b2, %0|%0, %b2}"
6677 [(set_attr "type" "ishift")
6678 (set_attr "mode" "SI")])
6680 ;; This pattern can't accept a variable shift count, since shifts by
6681 ;; zero don't affect the flags. We assume that shifts by constant
6682 ;; zero are optimized away.
6683 (define_insn "*ashrsi3_one_bit_cmpno"
6686 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6687 (match_operand:QI 2 "const_int_1_operand" ""))
6689 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6690 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
6691 "ix86_match_ccmode (insn, CCNOmode)
6692 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
6693 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6695 [(set_attr "type" "ishift")
6696 (set (attr "length")
6697 (if_then_else (match_operand:SI 0 "register_operand" "")
6699 (const_string "*")))])
6701 ;; This pattern can't accept a variable shift count, since shifts by
6702 ;; zero don't affect the flags. We assume that shifts by constant
6703 ;; zero are optimized away.
6704 (define_insn "*ashrsi3_cmpno"
6707 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6708 (match_operand:QI 2 "immediate_operand" "I"))
6710 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6711 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
6712 "ix86_match_ccmode (insn, CCNOmode)
6713 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6715 sar{l}\\t{%2, %0|%0, %2}"
6716 [(set_attr "type" "ishift")
6717 (set_attr "mode" "SI")])
6719 (define_expand "ashrhi3"
6720 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6721 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
6722 (match_operand:QI 2 "nonmemory_operand" "")))
6723 (clobber (reg:CC 17))]
6724 "TARGET_HIMODE_MATH"
6725 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
6727 (define_insn "*ashrhi3_1_one_bit"
6728 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6729 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6730 (match_operand:QI 2 "const_int_1_operand" "")))
6731 (clobber (reg:CC 17))]
6732 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
6733 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
6735 [(set_attr "type" "ishift")
6736 (set (attr "length")
6737 (if_then_else (match_operand:SI 0 "register_operand" "")
6739 (const_string "*")))])
6741 (define_insn "*ashrhi3_1"
6742 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
6743 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6744 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6745 (clobber (reg:CC 17))]
6746 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
6748 sar{w}\\t{%2, %0|%0, %2}
6749 sar{w}\\t{%b2, %0|%0, %b2}"
6750 [(set_attr "type" "ishift")
6751 (set_attr "mode" "HI")])
6753 ;; This pattern can't accept a variable shift count, since shifts by
6754 ;; zero don't affect the flags. We assume that shifts by constant
6755 ;; zero are optimized away.
6756 (define_insn "*ashrhi3_one_bit_cmpno"
6759 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6760 (match_operand:QI 2 "const_int_1_operand" ""))
6762 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6763 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
6764 "ix86_match_ccmode (insn, CCNOmode)
6765 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
6766 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
6768 [(set_attr "type" "ishift")
6769 (set (attr "length")
6770 (if_then_else (match_operand:SI 0 "register_operand" "")
6772 (const_string "*")))])
6774 ;; This pattern can't accept a variable shift count, since shifts by
6775 ;; zero don't affect the flags. We assume that shifts by constant
6776 ;; zero are optimized away.
6777 (define_insn "*ashrhi3_cmpno"
6780 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6781 (match_operand:QI 2 "immediate_operand" "I"))
6783 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6784 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
6785 "ix86_match_ccmode (insn, CCNOmode)
6786 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
6788 sar{w}\\t{%2, %0|%0, %2}"
6789 [(set_attr "type" "ishift")
6790 (set_attr "mode" "HI")])
6792 (define_expand "ashrqi3"
6793 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6794 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
6795 (match_operand:QI 2 "nonmemory_operand" "")))
6796 (clobber (reg:CC 17))]
6797 "TARGET_QIMODE_MATH"
6798 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
6800 (define_insn "*ashrqi3_1_one_bit"
6801 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6802 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6803 (match_operand:QI 2 "const_int_1_operand" "")))
6804 (clobber (reg:CC 17))]
6805 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
6806 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
6808 [(set_attr "type" "ishift")
6809 (set (attr "length")
6810 (if_then_else (match_operand:SI 0 "register_operand" "")
6812 (const_string "*")))])
6814 (define_insn "*ashrqi3_1"
6815 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
6816 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6817 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6818 (clobber (reg:CC 17))]
6819 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
6821 sar{b}\\t{%2, %0|%0, %2}
6822 sar{b}\\t{%b2, %0|%0, %b2}"
6823 [(set_attr "type" "ishift")
6824 (set_attr "mode" "QI")])
6826 ;; This pattern can't accept a variable shift count, since shifts by
6827 ;; zero don't affect the flags. We assume that shifts by constant
6828 ;; zero are optimized away.
6829 (define_insn "*ashrqi3_cmpno_one_bit"
6832 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6833 (match_operand:QI 2 "const_int_1_operand" "I"))
6835 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
6836 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
6837 "ix86_match_ccmode (insn, CCNOmode)
6838 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
6839 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
6841 [(set_attr "type" "ishift")
6842 (set (attr "length")
6843 (if_then_else (match_operand:SI 0 "register_operand" "")
6845 (const_string "*")))])
6847 ;; This pattern can't accept a variable shift count, since shifts by
6848 ;; zero don't affect the flags. We assume that shifts by constant
6849 ;; zero are optimized away.
6850 (define_insn "*ashrqi3_cmpno"
6853 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6854 (match_operand:QI 2 "immediate_operand" "I"))
6856 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
6857 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
6858 "ix86_match_ccmode (insn, CCNOmode)
6859 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
6861 sar{b}\\t{%2, %0|%0, %2}"
6862 [(set_attr "type" "ishift")
6863 (set_attr "mode" "QI")])
6865 ;; Logical shift instructions
6867 ;; See comment above `ashldi3' about how this works.
6869 (define_expand "lshrdi3"
6870 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
6871 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
6872 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6873 (clobber (reg:CC 17))])]
6877 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
6879 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
6884 (define_insn "lshrdi3_1"
6885 [(set (match_operand:DI 0 "register_operand" "=r")
6886 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
6887 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6888 (clobber (match_scratch:SI 3 "=&r"))
6889 (clobber (reg:CC 17))]
6892 [(set_attr "type" "multi")])
6894 (define_insn "*lshrdi3_2"
6895 [(set (match_operand:DI 0 "register_operand" "=r")
6896 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
6897 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6898 (clobber (reg:CC 17))]
6901 [(set_attr "type" "multi")])
6904 [(set (match_operand:DI 0 "register_operand" "")
6905 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6906 (match_operand:QI 2 "nonmemory_operand" "")))
6907 (clobber (match_scratch:SI 3 ""))
6908 (clobber (reg:CC 17))]
6909 "TARGET_CMOVE && reload_completed"
6911 "ix86_split_lshrdi (operands, operands[3]); DONE;")
6914 [(set (match_operand:DI 0 "register_operand" "")
6915 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6916 (match_operand:QI 2 "nonmemory_operand" "")))
6917 (clobber (reg:CC 17))]
6920 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
6922 (define_expand "lshrsi3"
6923 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6924 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
6925 (match_operand:QI 2 "nonmemory_operand" "")))
6926 (clobber (reg:CC 17))]
6928 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
6930 (define_insn "*lshrsi3_1_one_bit"
6931 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6932 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6933 (match_operand:QI 2 "const_int_1_operand" "")))
6934 (clobber (reg:CC 17))]
6935 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
6936 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
6938 [(set_attr "type" "ishift")
6939 (set (attr "length")
6940 (if_then_else (match_operand:SI 0 "register_operand" "")
6942 (const_string "*")))])
6944 (define_insn "*lshrsi3_1"
6945 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6946 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6947 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6948 (clobber (reg:CC 17))]
6949 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6951 shr{l}\\t{%2, %0|%0, %2}
6952 shr{l}\\t{%b2, %0|%0, %b2}"
6953 [(set_attr "type" "ishift")
6954 (set_attr "mode" "SI")])
6956 ;; This pattern can't accept a variable shift count, since shifts by
6957 ;; zero don't affect the flags. We assume that shifts by constant
6958 ;; zero are optimized away.
6959 (define_insn "*lshrsi3_cmpno_one_bit"
6962 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6963 (match_operand:QI 2 "const_int_1_operand" ""))
6965 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6966 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
6967 "ix86_match_ccmode (insn, CCNOmode)
6968 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
6969 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6971 [(set_attr "type" "ishift")
6972 (set (attr "length")
6973 (if_then_else (match_operand:SI 0 "register_operand" "")
6975 (const_string "*")))])
6977 ;; This pattern can't accept a variable shift count, since shifts by
6978 ;; zero don't affect the flags. We assume that shifts by constant
6979 ;; zero are optimized away.
6980 (define_insn "*lshrsi3_cmpno"
6983 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6984 (match_operand:QI 2 "immediate_operand" "I"))
6986 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6987 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
6988 "ix86_match_ccmode (insn, CCNOmode)
6989 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6991 shr{l}\\t{%2, %0|%0, %2}"
6992 [(set_attr "type" "ishift")
6993 (set_attr "mode" "SI")])
6995 (define_expand "lshrhi3"
6996 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6997 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
6998 (match_operand:QI 2 "nonmemory_operand" "")))
6999 (clobber (reg:CC 17))]
7000 "TARGET_HIMODE_MATH"
7001 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
7003 (define_insn "*lshrhi3_1_one_bit"
7004 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7005 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
7006 (match_operand:QI 2 "const_int_1_operand" "")))
7007 (clobber (reg:CC 17))]
7008 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
7009 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7011 [(set_attr "type" "ishift")
7012 (set (attr "length")
7013 (if_then_else (match_operand:SI 0 "register_operand" "")
7015 (const_string "*")))])
7017 (define_insn "*lshrhi3_1"
7018 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
7019 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7020 (match_operand:QI 2 "nonmemory_operand" "I,c")))
7021 (clobber (reg:CC 17))]
7022 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
7024 shr{w}\\t{%2, %0|%0, %2}
7025 shr{w}\\t{%b2, %0|%0, %b2}"
7026 [(set_attr "type" "ishift")
7027 (set_attr "mode" "HI")])
7029 ;; This pattern can't accept a variable shift count, since shifts by
7030 ;; zero don't affect the flags. We assume that shifts by constant
7031 ;; zero are optimized away.
7032 (define_insn "*lshrhi3_cmpno_one_bit"
7035 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
7036 (match_operand:QI 2 "const_int_1_operand" ""))
7038 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7039 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
7040 "ix86_match_ccmode (insn, CCNOmode)
7041 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
7042 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
7044 [(set_attr "type" "ishift")
7045 (set (attr "length")
7046 (if_then_else (match_operand:SI 0 "register_operand" "")
7048 (const_string "*")))])
7050 ;; This pattern can't accept a variable shift count, since shifts by
7051 ;; zero don't affect the flags. We assume that shifts by constant
7052 ;; zero are optimized away.
7053 (define_insn "*lshrhi3_cmpno"
7056 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
7057 (match_operand:QI 2 "immediate_operand" "I"))
7059 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7060 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
7061 "ix86_match_ccmode (insn, CCNOmode)
7062 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
7064 shr{w}\\t{%2, %0|%0, %2}"
7065 [(set_attr "type" "ishift")
7066 (set_attr "mode" "HI")])
7068 (define_expand "lshrqi3"
7069 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7070 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
7071 (match_operand:QI 2 "nonmemory_operand" "")))
7072 (clobber (reg:CC 17))]
7073 "TARGET_QIMODE_MATH"
7074 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
7076 (define_insn "*lshrqi3_1_one_bit"
7077 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7078 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
7079 (match_operand:QI 2 "const_int_1_operand" "")))
7080 (clobber (reg:CC 17))]
7081 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
7082 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7084 [(set_attr "type" "ishift")
7085 (set (attr "length")
7086 (if_then_else (match_operand:SI 0 "register_operand" "")
7088 (const_string "*")))])
7090 (define_insn "*lshrqi3_1"
7091 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
7092 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7093 (match_operand:QI 2 "nonmemory_operand" "I,c")))
7094 (clobber (reg:CC 17))]
7095 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
7097 shr{b}\\t{%2, %0|%0, %2}
7098 shr{b}\\t{%b2, %0|%0, %b2}"
7099 [(set_attr "type" "ishift")
7100 (set_attr "mode" "QI")])
7102 ;; This pattern can't accept a variable shift count, since shifts by
7103 ;; zero don't affect the flags. We assume that shifts by constant
7104 ;; zero are optimized away.
7105 (define_insn "*lshrqi2_cmpno_one_bit"
7108 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
7109 (match_operand:QI 2 "const_int_1_operand" ""))
7111 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7112 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
7113 "ix86_match_ccmode (insn, CCNOmode)
7114 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
7115 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
7117 [(set_attr "type" "ishift")
7118 (set (attr "length")
7119 (if_then_else (match_operand:SI 0 "register_operand" "")
7121 (const_string "*")))])
7123 ;; This pattern can't accept a variable shift count, since shifts by
7124 ;; zero don't affect the flags. We assume that shifts by constant
7125 ;; zero are optimized away.
7126 (define_insn "*lshrqi2_cmpno"
7129 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
7130 (match_operand:QI 2 "immediate_operand" "I"))
7132 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7133 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
7134 "ix86_match_ccmode (insn, CCNOmode)
7135 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
7136 "shr{b}\\t{%2, %0|%0, %2}"
7137 [(set_attr "type" "ishift")
7138 (set_attr "mode" "QI")])
7140 ;; Rotate instructions
7142 (define_expand "rotlsi3"
7143 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7144 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
7145 (match_operand:QI 2 "nonmemory_operand" "")))
7146 (clobber (reg:CC 17))]
7148 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
7150 (define_insn "*rotlsi3_1_one_bit"
7151 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7152 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
7153 (match_operand:QI 2 "const_int_1_operand" "")))
7154 (clobber (reg:CC 17))]
7155 "ix86_binary_operator_ok (ROTATE, SImode, operands)
7156 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7158 [(set_attr "type" "ishift")
7159 (set (attr "length")
7160 (if_then_else (match_operand:SI 0 "register_operand" "")
7162 (const_string "*")))])
7164 (define_insn "*rotlsi3_1"
7165 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7166 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7167 (match_operand:QI 2 "nonmemory_operand" "I,c")))
7168 (clobber (reg:CC 17))]
7169 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
7171 rol{l}\\t{%2, %0|%0, %2}
7172 rol{l}\\t{%b2, %0|%0, %b2}"
7173 [(set_attr "type" "ishift")
7174 (set_attr "mode" "SI")])
7176 (define_expand "rotlhi3"
7177 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7178 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
7179 (match_operand:QI 2 "nonmemory_operand" "")))
7180 (clobber (reg:CC 17))]
7181 "TARGET_HIMODE_MATH"
7182 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
7184 (define_insn "*rotlhi3_1_one_bit"
7185 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7186 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
7187 (match_operand:QI 2 "const_int_1_operand" "")))
7188 (clobber (reg:CC 17))]
7189 "ix86_binary_operator_ok (ROTATE, HImode, operands)
7190 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7192 [(set_attr "type" "ishift")
7193 (set (attr "length")
7194 (if_then_else (match_operand:SI 0 "register_operand" "")
7196 (const_string "*")))])
7198 (define_insn "*rotlhi3_1"
7199 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
7200 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7201 (match_operand:QI 2 "nonmemory_operand" "I,c")))
7202 (clobber (reg:CC 17))]
7203 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
7205 rol{w}\\t{%2, %0|%0, %2}
7206 rol{w}\\t{%b2, %0|%0, %b2}"
7207 [(set_attr "type" "ishift")
7208 (set_attr "mode" "HI")])
7210 (define_expand "rotlqi3"
7211 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7212 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
7213 (match_operand:QI 2 "nonmemory_operand" "")))
7214 (clobber (reg:CC 17))]
7215 "TARGET_QIMODE_MATH"
7216 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
7218 (define_insn "*rotlqi3_1_one_bit"
7219 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7220 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
7221 (match_operand:QI 2 "const_int_1_operand" "")))
7222 (clobber (reg:CC 17))]
7223 "ix86_binary_operator_ok (ROTATE, QImode, operands)
7224 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7226 [(set_attr "type" "ishift")
7227 (set (attr "length")
7228 (if_then_else (match_operand:SI 0 "register_operand" "")
7230 (const_string "*")))])
7232 (define_insn "*rotlqi3_1"
7233 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
7234 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7235 (match_operand:QI 2 "nonmemory_operand" "I,c")))
7236 (clobber (reg:CC 17))]
7237 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
7239 rol{b}\\t{%2, %0|%0, %2}
7240 rol{b}\\t{%b2, %0|%0, %b2}"
7241 [(set_attr "type" "ishift")
7242 (set_attr "mode" "QI")])
7244 (define_expand "rotrsi3"
7245 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7246 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
7247 (match_operand:QI 2 "nonmemory_operand" "")))
7248 (clobber (reg:CC 17))]
7250 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
7252 (define_insn "*rotrsi3_1_one_bit"
7253 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7254 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
7255 (match_operand:QI 2 "const_int_1_operand" "")))
7256 (clobber (reg:CC 17))]
7257 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
7258 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7260 [(set_attr "type" "ishift")
7261 (set (attr "length")
7262 (if_then_else (match_operand:SI 0 "register_operand" "")
7264 (const_string "*")))])
7266 (define_insn "*rotrsi3_1"
7267 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7268 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7269 (match_operand:QI 2 "nonmemory_operand" "I,c")))
7270 (clobber (reg:CC 17))]
7271 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
7273 ror{l}\\t{%2, %0|%0, %2}
7274 ror{l}\\t{%b2, %0|%0, %b2}"
7275 [(set_attr "type" "ishift")
7276 (set_attr "mode" "SI")])
7278 (define_expand "rotrhi3"
7279 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7280 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
7281 (match_operand:QI 2 "nonmemory_operand" "")))
7282 (clobber (reg:CC 17))]
7283 "TARGET_HIMODE_MATH"
7284 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
7286 (define_insn "*rotrhi3_one_bit"
7287 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7288 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
7289 (match_operand:QI 2 "const_int_1_operand" "")))
7290 (clobber (reg:CC 17))]
7291 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
7292 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7294 [(set_attr "type" "ishift")
7295 (set (attr "length")
7296 (if_then_else (match_operand:SI 0 "register_operand" "")
7298 (const_string "*")))])
7300 (define_insn "*rotrhi3"
7301 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
7302 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7303 (match_operand:QI 2 "nonmemory_operand" "I,c")))
7304 (clobber (reg:CC 17))]
7305 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
7307 ror{w}\\t{%2, %0|%0, %2}
7308 ror{w}\\t{%b2, %0|%0, %b2}"
7309 [(set_attr "type" "ishift")
7310 (set_attr "mode" "HI")])
7312 (define_expand "rotrqi3"
7313 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7314 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
7315 (match_operand:QI 2 "nonmemory_operand" "")))
7316 (clobber (reg:CC 17))]
7317 "TARGET_QIMODE_MATH"
7318 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
7320 (define_insn "*rotrqi3_1_one_bit"
7321 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7322 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
7323 (match_operand:QI 2 "const_int_1_operand" "")))
7324 (clobber (reg:CC 17))]
7325 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
7326 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
7328 [(set_attr "type" "ishift")
7329 (set (attr "length")
7330 (if_then_else (match_operand:SI 0 "register_operand" "")
7332 (const_string "*")))])
7334 (define_insn "*rotrqi3_1"
7335 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
7336 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7337 (match_operand:QI 2 "nonmemory_operand" "I,c")))
7338 (clobber (reg:CC 17))]
7339 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
7341 ror{b}\\t{%2, %0|%0, %2}
7342 ror{b}\\t{%b2, %0|%0, %b2}"
7343 [(set_attr "type" "ishift")
7344 (set_attr "mode" "QI")])
7346 ;; Bit set / bit test instructions
7348 (define_expand "extv"
7349 [(set (match_operand:SI 0 "register_operand" "")
7350 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
7351 (match_operand:SI 2 "immediate_operand" "")
7352 (match_operand:SI 3 "immediate_operand" "")))]
7356 /* Handle extractions from %ah et al. */
7357 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
7360 /* From mips.md: extract_bit_field doesn't verify that our source
7361 matches the predicate, so check it again here. */
7362 if (! register_operand (operands[1], VOIDmode))
7366 (define_expand "extzv"
7367 [(set (match_operand:SI 0 "register_operand" "")
7368 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
7369 (match_operand:SI 2 "immediate_operand" "")
7370 (match_operand:SI 3 "immediate_operand" "")))]
7374 /* Handle extractions from %ah et al. */
7375 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
7378 /* From mips.md: extract_bit_field doesn't verify that our source
7379 matches the predicate, so check it again here. */
7380 if (! register_operand (operands[1], VOIDmode))
7384 (define_expand "insv"
7385 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
7386 (match_operand:SI 1 "immediate_operand" "")
7387 (match_operand:SI 2 "immediate_operand" ""))
7388 (match_operand:SI 3 "register_operand" ""))]
7392 /* Handle extractions from %ah et al. */
7393 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
7396 /* From mips.md: insert_bit_field doesn't verify that our source
7397 matches the predicate, so check it again here. */
7398 if (! register_operand (operands[0], VOIDmode))
7402 ;; %%% bts, btr, btc, bt.
7404 ;; Store-flag instructions.
7406 ;; For all sCOND expanders, also expand the compare or test insn that
7407 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
7409 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
7410 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
7411 ;; way, which can later delete the movzx if only QImode is needed.
7413 (define_expand "seq"
7414 [(set (match_operand:SI 0 "register_operand" "")
7415 (eq:SI (reg:CC 17) (const_int 0)))]
7417 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
7419 (define_expand "sne"
7420 [(set (match_operand:SI 0 "register_operand" "")
7421 (ne:SI (reg:CC 17) (const_int 0)))]
7423 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
7425 (define_expand "sgt"
7426 [(set (match_operand:SI 0 "register_operand" "")
7427 (gt:SI (reg:CC 17) (const_int 0)))]
7429 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
7431 (define_expand "sgtu"
7432 [(set (match_operand:SI 0 "register_operand" "")
7433 (gtu:SI (reg:CC 17) (const_int 0)))]
7435 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
7437 (define_expand "slt"
7438 [(set (match_operand:SI 0 "register_operand" "")
7439 (lt:SI (reg:CC 17) (const_int 0)))]
7441 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
7443 (define_expand "sltu"
7444 [(set (match_operand:SI 0 "register_operand" "")
7445 (ltu:SI (reg:CC 17) (const_int 0)))]
7447 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
7449 (define_expand "sge"
7450 [(set (match_operand:SI 0 "register_operand" "")
7451 (ge:SI (reg:CC 17) (const_int 0)))]
7453 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
7455 (define_expand "sgeu"
7456 [(set (match_operand:SI 0 "register_operand" "")
7457 (geu:SI (reg:CC 17) (const_int 0)))]
7459 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
7461 (define_expand "sle"
7462 [(set (match_operand:SI 0 "register_operand" "")
7463 (le:SI (reg:CC 17) (const_int 0)))]
7465 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
7467 (define_expand "sleu"
7468 [(set (match_operand:SI 0 "register_operand" "")
7469 (leu:SI (reg:CC 17) (const_int 0)))]
7471 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
7473 (define_expand "sunordered"
7474 [(set (match_operand:SI 0 "register_operand" "")
7475 (unordered:SI (reg:CC 17) (const_int 0)))]
7477 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
7479 (define_expand "sordered"
7480 [(set (match_operand:SI 0 "register_operand" "")
7481 (ordered:SI (reg:CC 17) (const_int 0)))]
7483 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
7485 (define_expand "suneq"
7486 [(set (match_operand:SI 0 "register_operand" "")
7487 (uneq:SI (reg:CC 17) (const_int 0)))]
7489 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
7491 (define_expand "sunge"
7492 [(set (match_operand:SI 0 "register_operand" "")
7493 (unge:SI (reg:CC 17) (const_int 0)))]
7495 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
7497 (define_expand "sungt"
7498 [(set (match_operand:SI 0 "register_operand" "")
7499 (ungt:SI (reg:CC 17) (const_int 0)))]
7501 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
7503 (define_expand "sunle"
7504 [(set (match_operand:SI 0 "register_operand" "")
7505 (unle:SI (reg:CC 17) (const_int 0)))]
7507 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
7509 (define_expand "sunlt"
7510 [(set (match_operand:SI 0 "register_operand" "")
7511 (unlt:SI (reg:CC 17) (const_int 0)))]
7513 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
7515 (define_expand "sltgt"
7516 [(set (match_operand:SI 0 "register_operand" "")
7517 (ltgt:SI (reg:CC 17) (const_int 0)))]
7519 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
7521 (define_insn "*setcc_1"
7522 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7523 (match_operator:QI 1 "no_comparison_operator"
7524 [(reg 17) (const_int 0)]))]
7527 [(set_attr "type" "setcc")
7528 (set_attr "mode" "QI")])
7530 (define_insn "*setcc_2"
7531 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
7532 (match_operator:QI 1 "no_comparison_operator"
7533 [(reg 17) (const_int 0)]))]
7536 [(set_attr "type" "setcc")
7537 (set_attr "mode" "QI")])
7539 (define_insn "*setcc_3"
7540 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7541 (match_operator:QI 1 "uno_comparison_operator"
7542 [(reg:CC 17) (const_int 0)]))]
7545 [(set_attr "type" "setcc")
7546 (set_attr "mode" "QI")])
7548 (define_insn "*setcc_4"
7549 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
7550 (match_operator:QI 1 "uno_comparison_operator"
7551 [(reg:CC 17) (const_int 0)]))]
7554 [(set_attr "type" "setcc")
7555 (set_attr "mode" "QI")])
7557 ;; Basic conditional jump instructions.
7558 ;; We ignore the overflow flag for signed branch instructions.
7560 ;; For all bCOND expanders, also expand the compare or test insn that
7561 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
7563 (define_expand "beq"
7565 (if_then_else (match_dup 1)
7566 (label_ref (match_operand 0 "" ""))
7569 "ix86_expand_branch (EQ, operands[0]); DONE;")
7571 (define_expand "bne"
7573 (if_then_else (match_dup 1)
7574 (label_ref (match_operand 0 "" ""))
7577 "ix86_expand_branch (NE, operands[0]); DONE;")
7579 (define_expand "bgt"
7581 (if_then_else (match_dup 1)
7582 (label_ref (match_operand 0 "" ""))
7585 "ix86_expand_branch (GT, operands[0]); DONE;")
7587 (define_expand "bgtu"
7589 (if_then_else (match_dup 1)
7590 (label_ref (match_operand 0 "" ""))
7593 "ix86_expand_branch (GTU, operands[0]); DONE;")
7595 (define_expand "blt"
7597 (if_then_else (match_dup 1)
7598 (label_ref (match_operand 0 "" ""))
7601 "ix86_expand_branch (LT, operands[0]); DONE;")
7603 (define_expand "bltu"
7605 (if_then_else (match_dup 1)
7606 (label_ref (match_operand 0 "" ""))
7609 "ix86_expand_branch (LTU, operands[0]); DONE;")
7611 (define_expand "bge"
7613 (if_then_else (match_dup 1)
7614 (label_ref (match_operand 0 "" ""))
7617 "ix86_expand_branch (GE, operands[0]); DONE;")
7619 (define_expand "bgeu"
7621 (if_then_else (match_dup 1)
7622 (label_ref (match_operand 0 "" ""))
7625 "ix86_expand_branch (GEU, operands[0]); DONE;")
7627 (define_expand "ble"
7629 (if_then_else (match_dup 1)
7630 (label_ref (match_operand 0 "" ""))
7633 "ix86_expand_branch (LE, operands[0]); DONE;")
7635 (define_expand "bleu"
7637 (if_then_else (match_dup 1)
7638 (label_ref (match_operand 0 "" ""))
7641 "ix86_expand_branch (LEU, operands[0]); DONE;")
7643 (define_expand "bunordered"
7645 (if_then_else (match_dup 1)
7646 (label_ref (match_operand 0 "" ""))
7649 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
7651 (define_expand "bordered"
7653 (if_then_else (match_dup 1)
7654 (label_ref (match_operand 0 "" ""))
7657 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
7659 (define_expand "buneq"
7661 (if_then_else (match_dup 1)
7662 (label_ref (match_operand 0 "" ""))
7665 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
7667 (define_expand "bunge"
7669 (if_then_else (match_dup 1)
7670 (label_ref (match_operand 0 "" ""))
7673 "ix86_expand_branch (UNGE, operands[0]); DONE;")
7675 (define_expand "bungt"
7677 (if_then_else (match_dup 1)
7678 (label_ref (match_operand 0 "" ""))
7681 "ix86_expand_branch (UNGT, operands[0]); DONE;")
7683 (define_expand "bunle"
7685 (if_then_else (match_dup 1)
7686 (label_ref (match_operand 0 "" ""))
7689 "ix86_expand_branch (UNLE, operands[0]); DONE;")
7691 (define_expand "bunlt"
7693 (if_then_else (match_dup 1)
7694 (label_ref (match_operand 0 "" ""))
7697 "ix86_expand_branch (UNLT, operands[0]); DONE;")
7699 (define_expand "bltgt"
7701 (if_then_else (match_dup 1)
7702 (label_ref (match_operand 0 "" ""))
7705 "ix86_expand_branch (LTGT, operands[0]); DONE;")
7707 (define_insn "*jcc_1"
7709 (if_then_else (match_operator 1 "no_comparison_operator"
7710 [(reg 17) (const_int 0)])
7711 (label_ref (match_operand 0 "" ""))
7715 [(set_attr "type" "ibr")
7716 (set (attr "prefix_0f")
7717 (if_then_else (and (ge (minus (match_dup 0) (pc))
7719 (lt (minus (match_dup 0) (pc))
7724 (define_insn "*jcc_2"
7726 (if_then_else (match_operator 1 "no_comparison_operator"
7727 [(reg 17) (const_int 0)])
7729 (label_ref (match_operand 0 "" ""))))]
7732 [(set_attr "type" "ibr")
7733 (set (attr "prefix_0f")
7734 (if_then_else (and (ge (minus (match_dup 0) (pc))
7736 (lt (minus (match_dup 0) (pc))
7741 (define_insn "*jcc_3"
7743 (if_then_else (match_operator 1 "uno_comparison_operator"
7744 [(reg:CC 17) (const_int 0)])
7745 (label_ref (match_operand 0 "" ""))
7749 [(set_attr "type" "ibr")
7750 (set (attr "prefix_0f")
7751 (if_then_else (and (ge (minus (match_dup 0) (pc))
7753 (lt (minus (match_dup 0) (pc))
7758 (define_insn "*jcc_4"
7760 (if_then_else (match_operator 1 "uno_comparison_operator"
7761 [(reg:CC 17) (const_int 0)])
7763 (label_ref (match_operand 0 "" ""))))]
7766 [(set_attr "type" "ibr")
7767 (set (attr "prefix_0f")
7768 (if_then_else (and (ge (minus (match_dup 0) (pc))
7770 (lt (minus (match_dup 0) (pc))
7775 ;; Define combination compare-and-branch fp compare instructions to use
7776 ;; during early optimization. Splitting the operation apart early makes
7777 ;; for bad code when we want to reverse the operation.
7779 (define_insn "*fp_jcc_1"
7781 (if_then_else (match_operator 0 "comparison_operator"
7782 [(match_operand 1 "register_operand" "f")
7783 (match_operand 2 "register_operand" "f")])
7784 (label_ref (match_operand 3 "" ""))
7786 (clobber (reg:CCFP 18))
7787 (clobber (reg:CCFP 17))]
7788 "TARGET_CMOVE && TARGET_80387
7789 && FLOAT_MODE_P (GET_MODE (operands[1]))
7790 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7793 (define_insn "*fp_jcc_2"
7795 (if_then_else (match_operator 0 "comparison_operator"
7796 [(match_operand 1 "register_operand" "f")
7797 (match_operand 2 "register_operand" "f")])
7799 (label_ref (match_operand 3 "" ""))))
7800 (clobber (reg:CCFP 18))
7801 (clobber (reg:CCFP 17))]
7802 "TARGET_CMOVE && TARGET_80387
7803 && FLOAT_MODE_P (GET_MODE (operands[1]))
7804 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7807 (define_insn "*fp_jcc_3"
7809 (if_then_else (match_operator:CCFP 0 "comparison_operator"
7810 [(match_operand 1 "register_operand" "f")
7811 (match_operand 2 "nonimmediate_operand" "fm")])
7812 (label_ref (match_operand 3 "" ""))
7814 (clobber (reg:CCFP 18))
7815 (clobber (reg:CCFP 17))
7816 (clobber (match_scratch:HI 4 "=a"))]
7818 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
7819 && GET_MODE (operands[1]) == GET_MODE (operands[2])
7820 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))"
7823 (define_insn "*fp_jcc_4"
7825 (if_then_else (match_operator:CCFP 0 "comparison_operator"
7826 [(match_operand 1 "register_operand" "f")
7827 (match_operand 2 "nonimmediate_operand" "fm")])
7829 (label_ref (match_operand 3 "" ""))))
7830 (clobber (reg:CCFP 18))
7831 (clobber (reg:CCFP 17))
7832 (clobber (match_scratch:HI 4 "=a"))]
7834 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
7835 && GET_MODE (operands[1]) == GET_MODE (operands[2])
7836 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))"
7839 (define_insn "*fp_jcc_5"
7841 (if_then_else (match_operator 0 "comparison_operator"
7842 [(match_operand 1 "register_operand" "f")
7843 (match_operand 2 "register_operand" "f")])
7844 (label_ref (match_operand 3 "" ""))
7846 (clobber (reg:CCFP 18))
7847 (clobber (reg:CCFP 17))
7848 (clobber (match_scratch:HI 4 "=a"))]
7850 && FLOAT_MODE_P (GET_MODE (operands[1]))
7851 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7854 (define_insn "*fp_jcc_6"
7856 (if_then_else (match_operator 0 "comparison_operator"
7857 [(match_operand 1 "register_operand" "f")
7858 (match_operand 2 "register_operand" "f")])
7860 (label_ref (match_operand 3 "" ""))))
7861 (clobber (reg:CCFP 18))
7862 (clobber (reg:CCFP 17))
7863 (clobber (match_scratch:HI 4 "=a"))]
7865 && FLOAT_MODE_P (GET_MODE (operands[1]))
7866 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
7871 (if_then_else (match_operator 0 "comparison_operator"
7872 [(match_operand 1 "register_operand" "")
7873 (match_operand 2 "nonimmediate_operand" "")])
7874 (match_operand 3 "" "")
7875 (match_operand 4 "" "")))
7876 (clobber (reg:CCFP 18))
7877 (clobber (reg:CCFP 17))]
7880 (if_then_else (match_dup 5)
7885 operands[5] = ix86_expand_fp_compare (GET_CODE (operands[0]), operands[1],
7886 operands[2], NULL_RTX);
7891 (if_then_else (match_operator 0 "comparison_operator"
7892 [(match_operand 1 "register_operand" "")
7893 (match_operand 2 "nonimmediate_operand" "")])
7894 (match_operand 3 "" "")
7895 (match_operand 4 "" "")))
7896 (clobber (reg:CCFP 18))
7897 (clobber (reg:CCFP 17))
7898 (clobber (match_scratch:HI 5 "=a"))]
7901 (if_then_else (match_dup 6)
7906 operands[6] = ix86_expand_fp_compare (GET_CODE (operands[0]), operands[1],
7907 operands[2], operands[5]);
7910 ;; Unconditional and other jump instructions
7914 (label_ref (match_operand 0 "" "")))]
7917 [(set_attr "type" "ibr")])
7919 (define_insn "indirect_jump"
7920 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
7923 [(set_attr "type" "ibr")
7924 (set_attr "length_immediate" "0")])
7926 (define_insn "tablejump"
7927 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
7928 (use (label_ref (match_operand 1 "" "")))]
7931 [(set_attr "type" "ibr")
7932 (set_attr "length_immediate" "0")])
7934 ;; Implement switch statements when generating PIC code. Switches are
7935 ;; implemented by `tablejump' when not using -fpic.
7937 ;; Emit code here to do the range checking and make the index zero based.
7939 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
7942 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
7944 ;; 1. An expression involving an external reference may only use the
7945 ;; addition operator, and only with an assembly-time constant.
7946 ;; The example above satisfies this because ".-.L2" is a constant.
7948 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
7949 ;; given the value of "GOT - .", where GOT is the actual address of
7950 ;; the Global Offset Table. Therefore, the .long above actually
7951 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
7952 ;; expression "GOT - .L2" by itself would generate an error from as(1).
7954 ;; The pattern below emits code that looks like this:
7957 ;; subl TABLE@GOTOFF(%ebx,index,4),reg
7960 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
7961 ;; the addr_diff_vec is known to be part of this module.
7963 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
7964 ;; evaluates to just ".L2".
7966 (define_expand "casesi"
7968 (match_operand:SI 0 "general_operand" ""))
7969 (parallel [(set (match_dup 6)
7970 (minus:SI (match_dup 5)
7971 (match_operand:SI 1 "general_operand" "")))
7972 (clobber (reg:CC 17))])
7974 (compare:CC (match_dup 6)
7975 (match_operand:SI 2 "general_operand" "")))
7977 (if_then_else (gtu (reg:CC 17)
7979 (label_ref (match_operand 4 "" ""))
7983 (minus:SI (match_dup 8)
7984 (mem:SI (plus:SI (plus:SI (mult:SI (match_dup 6) (const_int 4))
7986 (const (unspec [(label_ref (match_operand 3 "" ""))] 7))))))
7987 (clobber (reg:CC 17))])
7988 (parallel [(set (pc) (match_dup 7))
7989 (use (label_ref (match_dup 3)))])]
7993 operands[5] = gen_reg_rtx (SImode);
7994 operands[6] = gen_reg_rtx (SImode);
7995 operands[7] = gen_reg_rtx (SImode);
7996 operands[8] = pic_offset_table_rtx;
7997 current_function_uses_pic_offset_table = 1;
8000 (define_insn "*tablejump_pic"
8001 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
8002 (use (label_ref (match_operand 1 "" "")))]
8005 [(set_attr "type" "ibr")
8006 (set_attr "length_immediate" "0")])
8010 ;; This is all complicated by the fact that since this is a jump insn
8011 ;; we must handle our own reloads.
8013 (define_expand "decrement_and_branch_on_count"
8014 [(parallel [(set (pc) (if_then_else
8015 (ne (match_operand:SI 0 "register_operand" "")
8017 (label_ref (match_operand 1 "" ""))
8020 (plus:SI (match_dup 0)
8022 (clobber (match_scratch:SI 2 ""))
8023 (clobber (reg:CC 17))])]
8027 (define_insn "*dbra_ne"
8029 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
8031 (label_ref (match_operand 0 "" ""))
8033 (set (match_operand:SI 2 "register_operand" "=1,*r,*m*r")
8034 (plus:SI (match_dup 1)
8036 (clobber (match_scratch:SI 3 "=X,X,r"))
8037 (clobber (reg:CC 17))]
8041 if (which_alternative != 0)
8043 if (get_attr_length (insn) == 2)
8044 return \"loop\\t%l0\";
8046 return \"dec{l}\\t%1\;jne\\t%l0\";
8048 [(set_attr "ppro_uops" "many")
8050 (if_then_else (and (eq_attr "alternative" "0")
8051 (and (ge (minus (match_dup 0) (pc))
8053 (lt (minus (match_dup 0) (pc))
8055 (const_string "ibr")
8056 (const_string "multi")))])
8058 (define_insn "*dbra_ge"
8060 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
8062 (label_ref (match_operand 0 "" ""))
8064 (set (match_operand:SI 2 "register_operand" "=1,*r,*m*r")
8065 (plus:SI (match_dup 1)
8067 (clobber (match_scratch:SI 3 "=X,X,r"))
8068 (clobber (reg:CC 17))]
8069 "TARGET_USE_LOOP && find_reg_note (insn, REG_NONNEG, 0)"
8072 if (which_alternative != 0)
8074 if (get_attr_length (insn) == 2)
8075 return \"loop\\t%l0\";
8077 return \"dec{l}\\t%1\;jne\\t%l0\";
8080 (if_then_else (and (eq_attr "alternative" "0")
8081 (and (ge (minus (match_dup 0) (pc))
8083 (lt (minus (match_dup 0) (pc))
8085 (const_string "ibr")
8086 (const_string "multi")))
8087 (set_attr "ppro_uops" "many")])
8091 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
8093 (match_operand 0 "" "")
8095 (set (match_operand:SI 2 "register_operand" "")
8096 (plus:SI (match_dup 1)
8098 (clobber (match_scratch:SI 3 ""))
8099 (clobber (reg:CC 17))]
8100 "TARGET_USE_LOOP && reload_completed
8101 && ! (REGNO (operands[1]) == 2 && rtx_equal_p (operands[1], operands[2]))"
8102 [(set (match_dup 2) (match_dup 1))
8103 (parallel [(set (reg:CCZ 17)
8104 (compare:CCZ (plus:SI (match_dup 2) (const_int -1))
8106 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
8107 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
8114 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
8116 (match_operand 0 "" "")
8118 (set (match_operand:SI 2 "memory_operand" "")
8119 (plus:SI (match_dup 1)
8121 (clobber (match_scratch:SI 3 ""))
8122 (clobber (reg:CC 17))]
8123 "TARGET_USE_LOOP && reload_completed"
8124 [(set (match_dup 3) (match_dup 1))
8125 (parallel [(set (reg:CCZ 17)
8126 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
8128 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
8129 (set (match_dup 2) (match_dup 3))
8130 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
8137 (if_then_else (ge (match_operand:SI 1 "register_operand" "")
8139 (match_operand 0 "" "")
8141 (set (match_operand:SI 2 "register_operand" "")
8142 (plus:SI (match_dup 1)
8144 (clobber (match_scratch:SI 3 ""))
8145 (clobber (reg:CC 17))]
8146 "TARGET_USE_LOOP && reload_completed
8147 && ! (REGNO (operands[1]) == 2 && rtx_equal_p (operands[1], operands[2]))"
8148 [(set (match_dup 2) (match_dup 1))
8149 (parallel [(set (reg:CCNO 17)
8150 (compare:CCNO (plus:SI (match_dup 2) (const_int -1))
8152 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
8153 (set (pc) (if_then_else (lt (reg:CCNO 17) (const_int 0))
8160 (if_then_else (ge (match_operand:SI 1 "register_operand" "")
8162 (match_operand 0 "" "")
8164 (set (match_operand:SI 2 "memory_operand" "")
8165 (plus:SI (match_dup 1)
8167 (clobber (match_scratch:SI 3 ""))
8168 (clobber (reg:CC 17))]
8169 "TARGET_USE_LOOP && reload_completed"
8170 [(set (match_dup 3) (match_dup 1))
8171 (parallel [(set (reg:CCNO 17)
8172 (compare:CCNO (plus:SI (match_dup 3) (const_int -1))
8174 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
8175 (set (match_dup 2) (match_dup 3))
8176 (set (pc) (if_then_else (lt (reg:CCNO 17) (const_int 0))
8181 ;; Call instructions.
8183 ;; The predicates normally associated with named expanders are not properly
8184 ;; checked for calls. This is a bug in the generic code, but it isn't that
8185 ;; easy to fix. Ignore it for now and be prepared to fix things up.
8187 ;; Call subroutine returning no value.
8189 (define_expand "call_pop"
8190 [(parallel [(call (match_operand:QI 0 "" "")
8191 (match_operand:SI 1 "" ""))
8194 (match_operand:SI 3 "" "")))])]
8198 if (operands[3] == const0_rtx)
8200 emit_insn (gen_call (operands[0], operands[1]));
8203 /* Static functions and indirect calls don't need
8204 current_function_uses_pic_offset_table. */
8206 && constant_call_address_operand (operands[0], SImode)
8207 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF
8208 || !SYMBOL_REF_FLAG (XEXP (operands[0], 0))))
8209 current_function_uses_pic_offset_table = 1;
8210 if (! call_insn_operand (operands[0], QImode))
8211 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
8214 (define_insn "*call_pop_0"
8215 [(call (match_operand:QI 0 "constant_call_address_operand" "")
8216 (match_operand:SI 1 "" ""))
8217 (set (reg:SI 7) (plus:SI (reg:SI 7)
8218 (match_operand:SI 3 "immediate_operand" "")))]
8222 if (SIBLING_CALL_P (insn))
8223 return \"jmp\\t%P0\";
8225 return \"call\\t%P0\";
8227 [(set_attr "type" "call")])
8229 (define_insn "*call_pop_1"
8230 [(call (match_operand:QI 0 "call_insn_operand" "m")
8231 (match_operand:SI 1 "" ""))
8232 (set (reg:SI 7) (plus:SI (reg:SI 7)
8233 (match_operand:SI 3 "immediate_operand" "i")))]
8237 if (constant_call_address_operand (operands[0], QImode))
8239 if (SIBLING_CALL_P (insn))
8240 return \"jmp\\t%P0\";
8242 return \"call\\t%P0\";
8244 operands[0] = XEXP (operands[0], 0);
8245 if (SIBLING_CALL_P (insn))
8246 return \"jmp\\t%*%0\";
8248 return \"call\\t%*%0\";
8250 [(set_attr "type" "call")])
8252 (define_expand "call"
8253 [(call (match_operand:QI 0 "" "")
8254 (match_operand:SI 1 "" ""))]
8255 ;; Operand 1 not used on the i386.
8259 /* Static functions and indirect calls don't need
8260 current_function_uses_pic_offset_table. */
8262 && constant_call_address_operand (operands[0], SImode)
8263 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF
8264 || !SYMBOL_REF_FLAG (XEXP (operands[0], 0))))
8265 current_function_uses_pic_offset_table = 1;
8266 if (! call_insn_operand (operands[0], QImode))
8267 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
8270 (define_insn "*call_0"
8271 [(call (match_operand:QI 0 "constant_call_address_operand" "")
8272 (match_operand:SI 1 "" ""))]
8276 if (SIBLING_CALL_P (insn))
8277 return \"jmp\\t%P0\";
8279 return \"call\\t%P0\";
8281 [(set_attr "type" "call")])
8283 (define_insn "*call_1"
8284 [(call (match_operand:QI 0 "call_insn_operand" "m")
8285 (match_operand:SI 1 "" ""))]
8289 if (constant_call_address_operand (operands[0], QImode))
8291 if (SIBLING_CALL_P (insn))
8292 return \"jmp\\t%P0\";
8294 return \"call\\t%P0\";
8296 operands[0] = XEXP (operands[0], 0);
8297 if (SIBLING_CALL_P (insn))
8298 return \"jmp\\t%*%0\";
8300 return \"call\\t%*%0\";
8302 [(set_attr "type" "call")])
8304 ;; Call subroutine, returning value in operand 0
8305 ;; (which must be a hard register).
8307 (define_expand "call_value_pop"
8308 [(parallel [(set (match_operand 0 "" "")
8309 (call (match_operand:QI 1 "" "")
8310 (match_operand:SI 2 "" "")))
8313 (match_operand:SI 4 "" "")))])]
8317 if (operands[4] == const0_rtx)
8319 emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
8322 /* Static functions and indirect calls don't need
8323 current_function_uses_pic_offset_table. */
8325 && constant_call_address_operand (operands[1], SImode)
8326 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF
8327 || !SYMBOL_REF_FLAG (XEXP (operands[1], 0))))
8328 current_function_uses_pic_offset_table = 1;
8329 if (! call_insn_operand (operands[1], QImode))
8330 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
8333 (define_expand "call_value"
8334 [(set (match_operand 0 "" "")
8335 (call (match_operand:QI 1 "" "")
8336 (match_operand:SI 2 "" "")))]
8337 ;; Operand 2 not used on the i386.
8341 /* Static functions and indirect calls don't need
8342 current_function_uses_pic_offset_table. */
8344 && constant_call_address_operand (operands[1], SImode)
8345 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF
8346 || !SYMBOL_REF_FLAG (XEXP (operands[1], 0))))
8347 current_function_uses_pic_offset_table = 1;
8348 if (! call_insn_operand (operands[1], QImode))
8349 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
8352 ;; Call subroutine returning any type.
8354 (define_expand "untyped_call"
8355 [(parallel [(call (match_operand 0 "" "")
8357 (match_operand 1 "" "")
8358 (match_operand 2 "" "")])]
8364 /* In order to give reg-stack an easier job in validating two
8365 coprocessor registers as containing a possible return value,
8366 simply pretend the untyped call returns a complex long double
8369 emit_call_insn (TARGET_80387
8370 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
8371 operands[0], const0_rtx)
8372 : gen_call (operands[0], const0_rtx));
8374 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8376 rtx set = XVECEXP (operands[2], 0, i);
8377 emit_move_insn (SET_DEST (set), SET_SRC (set));
8380 /* The optimizer does not know that the call sets the function value
8381 registers we stored in the result block. We avoid problems by
8382 claiming that all hard registers are used and clobbered at this
8384 emit_insn (gen_blockage ());
8389 ;; Prologue and epilogue instructions
8391 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8392 ;; all of memory. This blocks insns from being moved across this point.
8394 (define_insn "blockage"
8395 [(unspec_volatile [(const_int 0)] 0)]
8398 [(set_attr "length" "0")])
8400 ;; Insn emitted into the body of a function to return from a function.
8401 ;; This is only done if the function's epilogue is known to be simple.
8402 ;; See comments for simple_386_epilogue in i386.c.
8404 (define_expand "return"
8406 "ix86_can_use_return_insn_p ()"
8409 if (current_function_pops_args)
8411 rtx popc = GEN_INT (current_function_pops_args);
8412 emit_jump_insn (gen_return_pop_internal (popc));
8417 (define_insn "return_internal"
8421 [(set_attr "length" "1")
8422 (set_attr "length_immediate" "0")
8423 (set_attr "modrm" "0")])
8425 (define_insn "return_pop_internal"
8427 (use (match_operand:SI 0 "const_int_operand" ""))]
8430 [(set_attr "length" "3")
8431 (set_attr "length_immediate" "2")
8432 (set_attr "modrm" "0")])
8438 [(set_attr "length" "1")
8439 (set_attr "length_immediate" "0")
8440 (set_attr "modrm" "0")
8441 (set_attr "ppro_uops" "one")])
8443 (define_expand "prologue"
8446 "ix86_expand_prologue (); DONE;")
8448 (define_insn "prologue_set_got"
8449 [(set (match_operand:SI 0 "register_operand" "=r")
8451 [(plus:SI (match_dup 0)
8452 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
8453 (minus:SI (pc) (match_operand 2 "" ""))))] 1))
8454 (clobber (reg:CC 17))]
8458 if (GET_CODE (operands[2]) == LABEL_REF)
8459 operands[2] = XEXP (operands[2], 0);
8460 if (TARGET_DEEP_BRANCH_PREDICTION)
8461 return \"add{l}\\t{%1, %0|%0, %1}\";
8463 return \"add{l}\\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}\";
8465 [(set_attr "type" "alu")
8466 ; Since this insn may have two constant operands, we must set the
8468 (set_attr "length_immediate" "4")
8469 (set_attr "mode" "SI")])
8471 (define_insn "prologue_get_pc"
8472 [(set (match_operand:SI 0 "register_operand" "=r")
8473 (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
8477 if (GET_CODE (operands[1]) == LABEL_REF)
8478 operands[1] = XEXP (operands[1], 0);
8479 output_asm_insn (\"call\\t%X1\", operands);
8480 if (! TARGET_DEEP_BRANCH_PREDICTION)
8482 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
8483 CODE_LABEL_NUMBER (operands[1]));
8487 [(set_attr "type" "multi")])
8489 (define_expand "epilogue"
8492 "ix86_expand_epilogue (1); DONE;")
8494 (define_expand "sibcall_epilogue"
8497 "ix86_expand_epilogue (0); DONE;")
8499 (define_insn "leave"
8500 [(set (reg:SI 7) (reg:SI 6))
8501 (set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))]
8504 [(set_attr "length_immediate" "0")
8505 (set_attr "length" "1")
8506 (set_attr "modrm" "0")
8507 (set_attr "modrm" "0")
8508 (set_attr "athlon_decode" "vector")
8509 (set_attr "ppro_uops" "few")])
8511 (define_expand "ffssi2"
8512 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8513 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
8517 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
8518 rtx in = operands[1];
8522 emit_move_insn (tmp, constm1_rtx);
8523 emit_insn (gen_ffssi_1 (out, in));
8524 emit_insn (gen_rtx_SET (VOIDmode, out,
8525 gen_rtx_IF_THEN_ELSE (SImode,
8526 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
8530 emit_insn (gen_addsi3 (out, out, const1_rtx));
8531 emit_move_insn (operands[0], out);
8534 /* Pentium bsf instruction is extremly slow. The following code is
8535 recommended by the Intel Optimizing Manual as a reasonable replacement:
8539 MOV DWORD PTR [TEMP+4],ECX
8542 MOV DWORD PTR [TEMP],EAX
8543 FILD QWORD PTR [TEMP]
8544 FSTP QWORD PTR [TEMP]
8545 WAIT ; WAIT only needed for compatibility with
8546 ; earlier processors
8547 MOV ECX, DWORD PTR [TEMP+4]
8550 TEST EAX,EAX ; clear zero flag
8552 Following piece of code expand ffs to similar beast.
8555 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
8557 rtx label = gen_label_rtx ();
8559 rtx mem = assign_386_stack_local (DImode, 0);
8560 rtx fptmp = gen_reg_rtx (DFmode);
8561 split_di (&mem, 1, &lo, &hi);
8563 emit_move_insn (out, const0_rtx);
8565 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label);
8567 emit_move_insn (hi, out);
8568 emit_insn (gen_subsi3 (out, out, in));
8569 emit_insn (gen_andsi3 (out, out, in));
8570 emit_move_insn (lo, out);
8571 emit_insn (gen_floatdidf2 (fptmp,mem));
8572 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
8573 emit_move_insn (out, hi);
8574 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
8575 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
8578 LABEL_NUSES (label) = 1;
8580 emit_move_insn (operands[0], out);
8584 emit_move_insn (tmp, const0_rtx);
8585 emit_insn (gen_ffssi_1 (out, in));
8586 emit_insn (gen_rtx_SET (VOIDmode,
8587 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
8588 gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
8590 emit_insn (gen_negsi2 (tmp, tmp));
8591 emit_insn (gen_iorsi3 (out, out, tmp));
8592 emit_insn (gen_addsi3 (out, out, const1_rtx));
8593 emit_move_insn (operands[0], out);
8598 (define_insn "ffssi_1"
8600 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
8602 (set (match_operand:SI 0 "register_operand" "=r")
8603 (unspec:SI [(match_dup 1)] 5))]
8605 "bsf{l}\\t{%1, %0|%0, %1}"
8606 [(set_attr "prefix_0f" "1")
8607 (set_attr "ppro_uops" "few")])
8609 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
8610 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
8612 ;; These patterns match the binary 387 instructions for addM3, subM3,
8613 ;; mulM3 and divM3. There are three patterns for each of DFmode and
8614 ;; SFmode. The first is the normal insn, the second the same insn but
8615 ;; with one operand a conversion, and the third the same insn but with
8616 ;; the other operand a conversion. The conversion may be SFmode or
8617 ;; SImode if the target mode DFmode, but only SImode if the target mode
8620 ;; Gcc is slightly more smart about handling normal two address instructions
8621 ;; so use special patterns for add and mull.
8622 (define_insn "*fop_sf_comm"
8623 [(set (match_operand:SF 0 "register_operand" "=f")
8624 (match_operator:SF 3 "binary_fp_operator"
8625 [(match_operand:SF 1 "register_operand" "%0")
8626 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
8627 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
8628 "* return output_387_binary_op (insn, operands);"
8630 (if_then_else (match_operand:SF 3 "mult_operator" "")
8631 (const_string "fmul")
8632 (const_string "fop")))
8633 (set_attr "mode" "SF")])
8635 (define_insn "*fop_df_comm"
8636 [(set (match_operand:DF 0 "register_operand" "=f")
8637 (match_operator:DF 3 "binary_fp_operator"
8638 [(match_operand:DF 1 "register_operand" "%0")
8639 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
8640 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
8641 "* return output_387_binary_op (insn, operands);"
8643 (if_then_else (match_operand:DF 3 "mult_operator" "")
8644 (const_string "fmul")
8645 (const_string "fop")))
8646 (set_attr "mode" "DF")])
8648 (define_insn "*fop_xf_comm"
8649 [(set (match_operand:XF 0 "register_operand" "=f")
8650 (match_operator:XF 3 "binary_fp_operator"
8651 [(match_operand:XF 1 "register_operand" "%0")
8652 (match_operand:XF 2 "register_operand" "f")]))]
8653 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
8654 "* return output_387_binary_op (insn, operands);"
8656 (if_then_else (match_operand:XF 3 "mult_operator" "")
8657 (const_string "fmul")
8658 (const_string "fop")))
8659 (set_attr "mode" "XF")])
8661 (define_insn "*fop_sf_1"
8662 [(set (match_operand:SF 0 "register_operand" "=f,f")
8663 (match_operator:SF 3 "binary_fp_operator"
8664 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
8665 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
8667 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
8668 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8669 "* return output_387_binary_op (insn, operands);"
8671 (cond [(match_operand:SF 3 "mult_operator" "")
8672 (const_string "fmul")
8673 (match_operand:SF 3 "div_operator" "")
8674 (const_string "fdiv")
8676 (const_string "fop")))
8677 (set_attr "mode" "SF")])
8679 (define_insn "*fop_sf_2"
8680 [(set (match_operand:SF 0 "register_operand" "=f,f")
8681 (match_operator:SF 3 "binary_fp_operator"
8682 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
8683 (match_operand:SF 2 "register_operand" "0,0")]))]
8684 "TARGET_80387 && TARGET_USE_FIOP"
8685 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8687 (cond [(match_operand:SF 3 "mult_operator" "")
8688 (const_string "fmul")
8689 (match_operand:SF 3 "div_operator" "")
8690 (const_string "fdiv")
8692 (const_string "fop")))
8693 (set_attr "fp_int_src" "true")
8694 (set_attr "ppro_uops" "many")
8695 (set_attr "mode" "SI")])
8697 (define_insn "*fop_sf_3"
8698 [(set (match_operand:SF 0 "register_operand" "=f,f")
8699 (match_operator:SF 3 "binary_fp_operator"
8700 [(match_operand:SF 1 "register_operand" "0,0")
8701 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
8702 "TARGET_80387 && TARGET_USE_FIOP"
8703 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8705 (cond [(match_operand:SF 3 "mult_operator" "")
8706 (const_string "fmul")
8707 (match_operand:SF 3 "div_operator" "")
8708 (const_string "fdiv")
8710 (const_string "fop")))
8711 (set_attr "fp_int_src" "true")
8712 (set_attr "ppro_uops" "many")
8713 (set_attr "mode" "SI")])
8715 (define_insn "*fop_df_1"
8716 [(set (match_operand:DF 0 "register_operand" "=f,f")
8717 (match_operator:DF 3 "binary_fp_operator"
8718 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
8719 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
8721 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
8722 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8723 "* return output_387_binary_op (insn, operands);"
8725 (cond [(match_operand:DF 3 "mult_operator" "")
8726 (const_string "fmul")
8727 (match_operand:DF 3 "div_operator" "")
8728 (const_string "fdiv")
8730 (const_string "fop")))
8731 (set_attr "mode" "DF")])
8733 (define_insn "*fop_df_2"
8734 [(set (match_operand:DF 0 "register_operand" "=f,f")
8735 (match_operator:DF 3 "binary_fp_operator"
8736 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
8737 (match_operand:DF 2 "register_operand" "0,0")]))]
8738 "TARGET_80387 && TARGET_USE_FIOP"
8739 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8741 (cond [(match_operand:DF 3 "mult_operator" "")
8742 (const_string "fmul")
8743 (match_operand:DF 3 "div_operator" "")
8744 (const_string "fdiv")
8746 (const_string "fop")))
8747 (set_attr "fp_int_src" "true")
8748 (set_attr "ppro_uops" "many")
8749 (set_attr "mode" "SI")])
8751 (define_insn "*fop_df_3"
8752 [(set (match_operand:DF 0 "register_operand" "=f,f")
8753 (match_operator:DF 3 "binary_fp_operator"
8754 [(match_operand:DF 1 "register_operand" "0,0")
8755 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
8756 "TARGET_80387 && TARGET_USE_FIOP"
8757 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8759 (cond [(match_operand:DF 3 "mult_operator" "")
8760 (const_string "fmul")
8761 (match_operand:DF 3 "div_operator" "")
8762 (const_string "fdiv")
8764 (const_string "fop")))
8765 (set_attr "fp_int_src" "true")
8766 (set_attr "ppro_uops" "many")
8767 (set_attr "mode" "SI")])
8769 (define_insn "*fop_df_4"
8770 [(set (match_operand:DF 0 "register_operand" "=f,f")
8771 (match_operator:DF 3 "binary_fp_operator"
8772 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
8773 (match_operand:DF 2 "register_operand" "0,f")]))]
8775 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8776 "* return output_387_binary_op (insn, operands);"
8778 (cond [(match_operand:DF 3 "mult_operator" "")
8779 (const_string "fmul")
8780 (match_operand:DF 3 "div_operator" "")
8781 (const_string "fdiv")
8783 (const_string "fop")))
8784 (set_attr "mode" "SF")])
8786 (define_insn "*fop_df_5"
8787 [(set (match_operand:DF 0 "register_operand" "=f,f")
8788 (match_operator:DF 3 "binary_fp_operator"
8789 [(match_operand:DF 1 "register_operand" "0,f")
8791 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
8793 "* return output_387_binary_op (insn, operands);"
8795 (cond [(match_operand:DF 3 "mult_operator" "")
8796 (const_string "fmul")
8797 (match_operand:DF 3 "div_operator" "")
8798 (const_string "fdiv")
8800 (const_string "fop")))
8801 (set_attr "mode" "SF")])
8803 (define_insn "*fop_xf_1"
8804 [(set (match_operand:XF 0 "register_operand" "=f,f")
8805 (match_operator:XF 3 "binary_fp_operator"
8806 [(match_operand:XF 1 "register_operand" "0,f")
8807 (match_operand:XF 2 "register_operand" "f,0")]))]
8809 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
8810 "* return output_387_binary_op (insn, operands);"
8812 (cond [(match_operand:XF 3 "mult_operator" "")
8813 (const_string "fmul")
8814 (match_operand:XF 3 "div_operator" "")
8815 (const_string "fdiv")
8817 (const_string "fop")))
8818 (set_attr "mode" "XF")])
8820 (define_insn "*fop_xf_2"
8821 [(set (match_operand:XF 0 "register_operand" "=f,f")
8822 (match_operator:XF 3 "binary_fp_operator"
8823 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
8824 (match_operand:XF 2 "register_operand" "0,0")]))]
8825 "TARGET_80387 && TARGET_USE_FIOP"
8826 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8828 (cond [(match_operand:XF 3 "mult_operator" "")
8829 (const_string "fmul")
8830 (match_operand:XF 3 "div_operator" "")
8831 (const_string "fdiv")
8833 (const_string "fop")))
8834 (set_attr "fp_int_src" "true")
8835 (set_attr "mode" "SI")
8836 (set_attr "ppro_uops" "many")])
8838 (define_insn "*fop_xf_3"
8839 [(set (match_operand:XF 0 "register_operand" "=f,f")
8840 (match_operator:XF 3 "binary_fp_operator"
8841 [(match_operand:XF 1 "register_operand" "0,0")
8842 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
8843 "TARGET_80387 && TARGET_USE_FIOP"
8844 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
8846 (cond [(match_operand:XF 3 "mult_operator" "")
8847 (const_string "fmul")
8848 (match_operand:XF 3 "div_operator" "")
8849 (const_string "fdiv")
8851 (const_string "fop")))
8852 (set_attr "fp_int_src" "true")
8853 (set_attr "mode" "SI")
8854 (set_attr "ppro_uops" "many")])
8856 (define_insn "*fop_xf_4"
8857 [(set (match_operand:XF 0 "register_operand" "=f,f")
8858 (match_operator:XF 3 "binary_fp_operator"
8859 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
8860 (match_operand:XF 2 "register_operand" "0,f")]))]
8862 "* return output_387_binary_op (insn, operands);"
8864 (cond [(match_operand:XF 3 "mult_operator" "")
8865 (const_string "fmul")
8866 (match_operand:XF 3 "div_operator" "")
8867 (const_string "fdiv")
8869 (const_string "fop")))
8870 (set_attr "mode" "SF")])
8872 (define_insn "*fop_xf_5"
8873 [(set (match_operand:XF 0 "register_operand" "=f,f")
8874 (match_operator:XF 3 "binary_fp_operator"
8875 [(match_operand:XF 1 "register_operand" "0,f")
8877 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
8879 "* return output_387_binary_op (insn, operands);"
8881 (cond [(match_operand:XF 3 "mult_operator" "")
8882 (const_string "fmul")
8883 (match_operand:XF 3 "div_operator" "")
8884 (const_string "fdiv")
8886 (const_string "fop")))
8887 (set_attr "mode" "SF")])
8889 (define_insn "*fop_xf_6"
8890 [(set (match_operand:XF 0 "register_operand" "=f,f")
8891 (match_operator:XF 3 "binary_fp_operator"
8892 [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
8893 (match_operand:XF 2 "register_operand" "0,f")]))]
8895 "* return output_387_binary_op (insn, operands);"
8897 (cond [(match_operand:XF 3 "mult_operator" "")
8898 (const_string "fmul")
8899 (match_operand:XF 3 "div_operator" "")
8900 (const_string "fdiv")
8902 (const_string "fop")))
8903 (set_attr "mode" "DF")])
8905 (define_insn "*fop_xf_7"
8906 [(set (match_operand:XF 0 "register_operand" "=f,f")
8907 (match_operator:XF 3 "binary_fp_operator"
8908 [(match_operand:XF 1 "register_operand" "0,f")
8910 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
8912 "* return output_387_binary_op (insn, operands);"
8914 (cond [(match_operand:XF 3 "mult_operator" "")
8915 (const_string "fmul")
8916 (match_operand:XF 3 "div_operator" "")
8917 (const_string "fdiv")
8919 (const_string "fop")))
8920 (set_attr "mode" "DF")])
8923 [(set (match_operand 0 "register_operand" "")
8924 (match_operator 3 "binary_fp_operator"
8925 [(float (match_operand:SI 1 "register_operand" ""))
8926 (match_operand 2 "register_operand" "")]))]
8927 "TARGET_80387 && reload_completed
8928 && FLOAT_MODE_P (GET_MODE (operands[0]))"
8929 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
8931 (match_op_dup 3 [(match_dup 4) (match_dup 2)]))
8932 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
8933 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
8934 "operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]),
8935 gen_rtx_MEM (SImode, stack_pointer_rtx));")
8938 [(set (match_operand 0 "register_operand" "")
8939 (match_operator 3 "binary_fp_operator"
8940 [(match_operand 1 "register_operand" "")
8941 (float (match_operand:SI 2 "register_operand" ""))]))]
8942 "TARGET_80387 && reload_completed
8943 && FLOAT_MODE_P (GET_MODE (operands[0]))"
8944 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 2))
8946 (match_op_dup 3 [(match_dup 1) (match_dup 4)]))
8947 (parallel [(set (match_dup 2) (mem:SI (reg:SI 7)))
8948 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
8949 "operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]),
8950 gen_rtx_MEM (SImode, stack_pointer_rtx));")
8952 ;; FPU special functions.
8954 (define_insn "sqrtsf2"
8955 [(set (match_operand:SF 0 "register_operand" "=f")
8956 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
8957 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
8959 [(set_attr "type" "fpspc")
8960 (set_attr "mode" "SF")
8961 (set_attr "athlon_decode" "direct")])
8963 (define_insn "sqrtdf2"
8964 [(set (match_operand:DF 0 "register_operand" "=f")
8965 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
8966 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
8967 && (TARGET_IEEE_FP || flag_fast_math) "
8969 [(set_attr "type" "fpspc")
8970 (set_attr "mode" "DF")
8971 (set_attr "athlon_decode" "direct")])
8973 (define_insn "*sqrtextendsfdf2"
8974 [(set (match_operand:DF 0 "register_operand" "=f")
8975 (sqrt:DF (float_extend:DF
8976 (match_operand:SF 1 "register_operand" "0"))))]
8977 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
8979 [(set_attr "type" "fpspc")
8980 (set_attr "mode" "DF")
8981 (set_attr "athlon_decode" "direct")])
8983 (define_insn "sqrtxf2"
8984 [(set (match_operand:XF 0 "register_operand" "=f")
8985 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
8986 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
8987 && (TARGET_IEEE_FP || flag_fast_math) "
8989 [(set_attr "type" "fpspc")
8990 (set_attr "mode" "XF")
8991 (set_attr "athlon_decode" "direct")])
8993 (define_insn "*sqrtextenddfxf2"
8994 [(set (match_operand:XF 0 "register_operand" "=f")
8995 (sqrt:XF (float_extend:XF
8996 (match_operand:DF 1 "register_operand" "0"))))]
8997 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
8999 [(set_attr "type" "fpspc")
9000 (set_attr "mode" "XF")
9001 (set_attr "athlon_decode" "direct")])
9003 (define_insn "*sqrtextendsfxf2"
9004 [(set (match_operand:XF 0 "register_operand" "=f")
9005 (sqrt:XF (float_extend:XF
9006 (match_operand:SF 1 "register_operand" "0"))))]
9007 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
9009 [(set_attr "type" "fpspc")
9010 (set_attr "mode" "XF")
9011 (set_attr "athlon_decode" "direct")])
9013 (define_insn "sindf2"
9014 [(set (match_operand:DF 0 "register_operand" "=f")
9015 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
9016 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9018 [(set_attr "type" "fpspc")
9019 (set_attr "mode" "DF")])
9021 (define_insn "sinsf2"
9022 [(set (match_operand:SF 0 "register_operand" "=f")
9023 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
9024 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9026 [(set_attr "type" "fpspc")
9027 (set_attr "mode" "SF")])
9029 (define_insn "*sinextendsfdf2"
9030 [(set (match_operand:DF 0 "register_operand" "=f")
9031 (unspec:DF [(float_extend:DF
9032 (match_operand:SF 1 "register_operand" "0"))] 1))]
9033 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9035 [(set_attr "type" "fpspc")
9036 (set_attr "mode" "DF")])
9038 (define_insn "sinxf2"
9039 [(set (match_operand:XF 0 "register_operand" "=f")
9040 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
9041 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9043 [(set_attr "type" "fpspc")
9044 (set_attr "mode" "XF")])
9046 (define_insn "cosdf2"
9047 [(set (match_operand:DF 0 "register_operand" "=f")
9048 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
9049 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9051 [(set_attr "type" "fpspc")
9052 (set_attr "mode" "DF")])
9054 (define_insn "cossf2"
9055 [(set (match_operand:SF 0 "register_operand" "=f")
9056 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
9057 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9059 [(set_attr "type" "fpspc")
9060 (set_attr "mode" "SF")])
9062 (define_insn "*cosextendsfdf2"
9063 [(set (match_operand:DF 0 "register_operand" "=f")
9064 (unspec:DF [(float_extend:DF
9065 (match_operand:SF 1 "register_operand" "0"))] 2))]
9066 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9068 [(set_attr "type" "fpspc")
9069 (set_attr "mode" "DF")])
9071 (define_insn "cosxf2"
9072 [(set (match_operand:XF 0 "register_operand" "=f")
9073 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
9074 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
9076 [(set_attr "type" "fpspc")
9077 (set_attr "mode" "XF")])
9079 ;; Block operation instructions
9082 [(set (reg:SI 19) (const_int 0))]
9085 [(set_attr "type" "cld")])
9087 (define_expand "movstrsi"
9088 [(use (match_operand:BLK 0 "memory_operand" ""))
9089 (use (match_operand:BLK 1 "memory_operand" ""))
9090 (use (match_operand:SI 2 "nonmemory_operand" ""))
9091 (use (match_operand:SI 3 "const_int_operand" ""))]
9095 rtx srcreg, destreg, countreg;
9099 if (GET_CODE (operands[3]) == CONST_INT)
9100 align = INTVAL (operands[3]);
9102 /* This simple hack avoids all inlining code and simplifies code bellow. */
9103 if (!TARGET_ALIGN_STRINGOPS)
9106 if (GET_CODE (operands[2]) == CONST_INT)
9107 count = INTVAL (operands[2]);
9109 destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9110 srcreg = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
9112 emit_insn (gen_cld());
9114 /* When optimizing for size emit simple rep ; movsb instruction for
9115 counts not divisible by 4. */
9117 if ((!optimize || optimize_size)
9118 && (count < 0 || (count & 0x03)))
9120 countreg = copy_to_mode_reg (SImode, operands[2]);
9121 emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
9122 destreg, srcreg, countreg));
9125 /* For constant aligned (or small unaligned) copies use rep movsl
9126 followed by code copying the rest. For PentiumPro ensure 8 byte
9127 alignment to allow rep movsl acceleration. */
9131 || (!TARGET_PENTIUMPRO && align >= 4)
9132 || optimize_size || count < 64))
9136 countreg = copy_to_mode_reg (SImode,
9137 GEN_INT ((count >> 2)
9139 emit_insn (gen_rep_movsi (destreg, srcreg, countreg,
9140 destreg, srcreg, countreg));
9143 emit_insn (gen_strmovhi (destreg, srcreg));
9145 emit_insn (gen_strmovqi (destreg, srcreg));
9147 /* The generic code based on the glibc implementation:
9148 - align destination to 4 bytes (8 byte alignment is used for PentiumPro
9149 allowing accelerated copying there)
9150 - copy the data using rep movsl
9157 /* In case we don't know anything about the alignment, default to
9158 library version, since it is usually equally fast and result in
9160 if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
9163 if (TARGET_SINGLE_STRINGOP)
9164 emit_insn (gen_cld());
9166 countreg2 = gen_reg_rtx (SImode);
9167 countreg = copy_to_mode_reg (SImode, operands[2]);
9169 /* We don't use loops to align destination and to copy parts smaller
9170 than 4 bytes, because gcc is able to optimize such code better (in
9171 the case the destination or the count really is aligned, gcc is often
9172 able to predict the branches) and also it is friendlier to the
9173 hardware branch prediction.
9175 Using loops is benefical for generic case, because we can
9176 handle small counts using the loops. Many CPUs (such as Athlon)
9177 have large REP prefix setup costs.
9179 This is quite costy. Maybe we can revisit this decision later or
9180 add some customizability to this code. */
9183 && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
9185 label = gen_label_rtx ();
9186 emit_cmp_and_jump_insns (countreg, GEN_INT (3),
9187 LEU, 0, SImode, 1, 0, label);
9191 rtx label = gen_label_rtx ();
9192 rtx tmpcount = gen_reg_rtx (SImode);
9193 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
9194 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9195 SImode, 1, 0, label);
9196 emit_insn (gen_strmovqi (destreg, srcreg));
9197 emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
9199 LABEL_NUSES (label) = 1;
9203 rtx label = gen_label_rtx ();
9204 rtx tmpcount = gen_reg_rtx (SImode);
9205 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
9206 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9207 SImode, 1, 0, label);
9208 emit_insn (gen_strmovhi (destreg, srcreg));
9209 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
9211 LABEL_NUSES (label) = 1;
9213 if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
9215 rtx label = gen_label_rtx ();
9216 rtx tmpcount = gen_reg_rtx (SImode);
9217 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
9218 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9219 SImode, 1, 0, label);
9220 emit_insn (gen_strmovsi (destreg, srcreg));
9221 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
9223 LABEL_NUSES (label) = 1;
9226 if (!TARGET_SINGLE_STRINGOP)
9227 emit_insn (gen_cld());
9228 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
9229 emit_insn (gen_rep_movsi (destreg, srcreg, countreg2,
9230 destreg, srcreg, countreg2));
9235 LABEL_NUSES (label) = 1;
9237 if (align > 2 && count > 0 && (count & 2))
9238 emit_insn (gen_strmovhi (destreg, srcreg));
9239 if (align <= 2 || count < 0)
9241 rtx label = gen_label_rtx ();
9242 rtx tmpcount = gen_reg_rtx (SImode);
9243 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
9244 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9245 SImode, 1, 0, label);
9246 emit_insn (gen_strmovhi (destreg, srcreg));
9248 LABEL_NUSES (label) = 1;
9250 if (align > 1 && count > 0 && (count & 1))
9251 emit_insn (gen_strmovsi (destreg, srcreg));
9252 if (align <= 1 || count < 0)
9254 rtx label = gen_label_rtx ();
9255 rtx tmpcount = gen_reg_rtx (SImode);
9256 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
9257 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9258 SImode, 1, 0, label);
9259 emit_insn (gen_strmovqi (destreg, srcreg));
9261 LABEL_NUSES (label) = 1;
9267 ;; Most CPUs don't like single string operations
9268 ;; Handle this case here to simplify previous expander.
9270 (define_expand "strmovsi"
9272 (mem:SI (match_operand:SI 1 "register_operand" "")))
9273 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
9275 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
9276 (clobber (reg:CC 17))])
9277 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
9278 (clobber (reg:CC 17))])]
9282 if (TARGET_SINGLE_STRINGOP || optimize_size)
9284 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
9289 operands[2] = gen_reg_rtx (SImode);
9292 (define_expand "strmovhi"
9294 (mem:HI (match_operand:SI 1 "register_operand" "")))
9295 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
9297 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
9298 (clobber (reg:CC 17))])
9299 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
9300 (clobber (reg:CC 17))])]
9304 if (TARGET_SINGLE_STRINGOP || optimize_size)
9306 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
9311 operands[2] = gen_reg_rtx (HImode);
9314 (define_expand "strmovqi"
9316 (mem:QI (match_operand:SI 1 "register_operand" "")))
9317 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
9319 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
9320 (clobber (reg:CC 17))])
9321 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
9322 (clobber (reg:CC 17))])]
9326 if (TARGET_SINGLE_STRINGOP || optimize_size)
9328 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
9333 operands[2] = gen_reg_rtx (QImode);
9336 (define_insn "strmovsi_1"
9337 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
9338 (mem:SI (match_operand:SI 3 "register_operand" "1")))
9339 (set (match_operand:SI 0 "register_operand" "=D")
9340 (plus:SI (match_dup 0)
9342 (set (match_operand:SI 1 "register_operand" "=S")
9343 (plus:SI (match_dup 1)
9346 "TARGET_SINGLE_STRINGOP || optimize_size"
9348 [(set_attr "type" "str")
9349 (set_attr "mode" "SI")
9350 (set_attr "memory" "both")])
9352 (define_insn "strmovhi_1"
9353 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
9354 (mem:HI (match_operand:SI 3 "register_operand" "1")))
9355 (set (match_operand:SI 0 "register_operand" "=D")
9356 (plus:SI (match_dup 0)
9358 (set (match_operand:SI 1 "register_operand" "=S")
9359 (plus:SI (match_dup 1)
9362 "TARGET_SINGLE_STRINGOP || optimize_size"
9364 [(set_attr "type" "str")
9365 (set_attr "memory" "both")
9366 (set_attr "mode" "HI")])
9368 (define_insn "strmovqi_1"
9369 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
9370 (mem:QI (match_operand:SI 3 "register_operand" "1")))
9371 (set (match_operand:SI 0 "register_operand" "=D")
9372 (plus:SI (match_dup 0)
9374 (set (match_operand:SI 1 "register_operand" "=S")
9375 (plus:SI (match_dup 1)
9378 "TARGET_SINGLE_STRINGOP || optimize_size"
9380 [(set_attr "type" "str")
9381 (set_attr "memory" "both")
9382 (set_attr "mode" "QI")])
9384 ;; It might seem that operands 3 & 4 could use predicate register_operand.
9385 ;; But strength reduction might offset the MEM expression. So we let
9386 ;; reload put the address into %edi & %esi.
9388 (define_insn "rep_movsi"
9389 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
9390 (use (match_operand:SI 5 "register_operand" "2"))
9391 (set (match_operand:SI 0 "register_operand" "=D")
9392 (plus:SI (match_operand:SI 3 "address_operand" "0")
9393 (ashift:SI (match_dup 5) (const_int 2))))
9394 (set (match_operand:SI 1 "register_operand" "=S")
9395 (plus:SI (match_operand:SI 4 "address_operand" "1")
9396 (ashift:SI (match_dup 5) (const_int 2))))
9397 (set (mem:BLK (match_dup 3))
9398 (mem:BLK (match_dup 4)))
9401 "rep\;movsl|rep movsd"
9402 [(set_attr "type" "str")
9403 (set_attr "prefix_rep" "1")
9404 (set_attr "memory" "both")
9405 (set_attr "mode" "SI")])
9407 (define_insn "rep_movqi"
9408 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
9409 (use (match_operand:SI 5 "register_operand" "2"))
9410 (set (match_operand:SI 0 "register_operand" "=D")
9411 (plus:SI (match_operand:SI 3 "address_operand" "0") (match_dup 5)))
9412 (set (match_operand:SI 1 "register_operand" "=S")
9413 (plus:SI (match_operand:SI 4 "address_operand" "1") (match_dup 5)))
9414 (set (mem:BLK (match_dup 3))
9415 (mem:BLK (match_dup 4)))
9418 "rep\;movsb|rep movsb"
9419 [(set_attr "type" "str")
9420 (set_attr "prefix_rep" "1")
9421 (set_attr "memory" "both")
9422 (set_attr "mode" "SI")])
9424 (define_expand "clrstrsi"
9425 [(use (match_operand:BLK 0 "memory_operand" ""))
9426 (use (match_operand:SI 1 "nonmemory_operand" ""))
9427 (use (match_operand:SI 2 "const_int_operand" ""))]
9431 /* See comments in movstr expanders. The code is mostly identical. */
9433 rtx destreg, zeroreg, countreg;
9437 if (GET_CODE (operands[2]) == CONST_INT)
9438 align = INTVAL (operands[2]);
9440 /* This simple hack avoids all inlining code and simplifies code bellow. */
9441 if (!TARGET_ALIGN_STRINGOPS)
9444 if (GET_CODE (operands[1]) == CONST_INT)
9445 count = INTVAL (operands[1]);
9447 destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9449 emit_insn (gen_cld());
9451 /* When optimizing for size emit simple rep ; movsb instruction for
9452 counts not divisible by 4. */
9454 if ((!optimize || optimize_size)
9455 && (count < 0 || (count & 0x03)))
9457 countreg = copy_to_mode_reg (SImode, operands[1]);
9458 zeroreg = copy_to_mode_reg (QImode, const0_rtx);
9459 emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg,
9460 destreg, countreg));
9464 || (!TARGET_PENTIUMPRO && align >= 4)
9465 || optimize_size || count < 64))
9467 zeroreg = copy_to_mode_reg (SImode, const0_rtx);
9468 if (INTVAL (operands[1]) & ~0x03)
9470 countreg = copy_to_mode_reg (SImode,
9471 GEN_INT ((INTVAL (operands[1]) >> 2)
9473 emit_insn (gen_rep_stossi (destreg, countreg, zeroreg,
9474 destreg, countreg));
9476 if (INTVAL (operands[1]) & 0x02)
9477 emit_insn (gen_strsethi (destreg,
9478 gen_rtx_SUBREG (HImode, zeroreg, 0)));
9479 if (INTVAL (operands[1]) & 0x01)
9480 emit_insn (gen_strsetqi (destreg,
9481 gen_rtx_SUBREG (QImode, zeroreg, 0)));
9488 /* In case we don't know anything about the alignment, default to
9489 library version, since it is usually equally fast and result in
9491 if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
9494 if (TARGET_SINGLE_STRINGOP)
9495 emit_insn (gen_cld());
9497 countreg2 = gen_reg_rtx (SImode);
9498 countreg = copy_to_mode_reg (SImode, operands[1]);
9499 zeroreg = copy_to_mode_reg (SImode, const0_rtx);
9502 && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
9504 label = gen_label_rtx ();
9505 emit_cmp_and_jump_insns (countreg, GEN_INT (3),
9506 LEU, 0, SImode, 1, 0, label);
9510 rtx label = gen_label_rtx ();
9511 rtx tmpcount = gen_reg_rtx (SImode);
9512 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
9513 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9514 SImode, 1, 0, label);
9515 emit_insn (gen_strsetqi (destreg,
9516 gen_rtx_SUBREG (QImode, zeroreg, 0)));
9517 emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
9519 LABEL_NUSES (label) = 1;
9523 rtx label = gen_label_rtx ();
9524 rtx tmpcount = gen_reg_rtx (SImode);
9525 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
9526 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9527 SImode, 1, 0, label);
9528 emit_insn (gen_strsethi (destreg,
9529 gen_rtx_SUBREG (HImode, zeroreg, 0)));
9530 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
9532 LABEL_NUSES (label) = 1;
9534 if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
9536 rtx label = gen_label_rtx ();
9537 rtx tmpcount = gen_reg_rtx (SImode);
9538 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
9539 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9540 SImode, 1, 0, label);
9541 emit_insn (gen_strsetsi (destreg, zeroreg));
9542 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
9544 LABEL_NUSES (label) = 1;
9547 if (!TARGET_SINGLE_STRINGOP)
9548 emit_insn (gen_cld());
9549 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
9550 emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg,
9551 destreg, countreg2));
9556 LABEL_NUSES (label) = 1;
9558 if (align > 2 && count > 0 && (count & 2))
9559 emit_insn (gen_strsethi (destreg,
9560 gen_rtx_SUBREG (HImode, zeroreg, 0)));
9561 if (align <= 2 || count < 0)
9563 rtx label = gen_label_rtx ();
9564 rtx tmpcount = gen_reg_rtx (SImode);
9565 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
9566 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9567 SImode, 1, 0, label);
9568 emit_insn (gen_strsethi (destreg,
9569 gen_rtx_SUBREG (HImode, zeroreg, 0)));
9571 LABEL_NUSES (label) = 1;
9573 if (align > 1 && count > 0 && (count & 1))
9574 emit_insn (gen_strsetqi (destreg,
9575 gen_rtx_SUBREG (QImode, zeroreg, 0)));
9576 if (align <= 1 || count < 0)
9578 rtx label = gen_label_rtx ();
9579 rtx tmpcount = gen_reg_rtx (SImode);
9580 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
9581 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
9582 SImode, 1, 0, label);
9583 emit_insn (gen_strsetqi (destreg,
9584 gen_rtx_SUBREG (QImode, zeroreg, 0)));
9586 LABEL_NUSES (label) = 1;
9592 ;; Most CPUs don't like single string operations
9593 ;; Handle this case here to simplify previous expander.
9595 (define_expand "strsetsi"
9596 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
9597 (match_operand:SI 1 "register_operand" ""))
9598 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
9599 (clobber (reg:CC 17))])]
9603 if (TARGET_SINGLE_STRINGOP || optimize_size)
9605 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
9610 (define_expand "strsethi"
9611 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
9612 (match_operand:HI 1 "register_operand" ""))
9613 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
9614 (clobber (reg:CC 17))])]
9618 if (TARGET_SINGLE_STRINGOP || optimize_size)
9620 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
9625 (define_expand "strsetqi"
9626 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
9627 (match_operand:QI 1 "register_operand" ""))
9628 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
9629 (clobber (reg:CC 17))])]
9633 if (TARGET_SINGLE_STRINGOP || optimize_size)
9635 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
9640 (define_insn "strsetsi_1"
9641 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
9642 (match_operand:SI 2 "register_operand" "a"))
9643 (set (match_operand:SI 0 "register_operand" "=D")
9644 (plus:SI (match_dup 0)
9647 "TARGET_SINGLE_STRINGOP || optimize_size"
9649 [(set_attr "type" "str")
9650 (set_attr "memory" "store")
9651 (set_attr "mode" "SI")])
9653 (define_insn "strsethi_1"
9654 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
9655 (match_operand:HI 2 "register_operand" "a"))
9656 (set (match_operand:SI 0 "register_operand" "=D")
9657 (plus:SI (match_dup 0)
9660 "TARGET_SINGLE_STRINGOP || optimize_size"
9662 [(set_attr "type" "str")
9663 (set_attr "memory" "store")
9664 (set_attr "mode" "HI")])
9666 (define_insn "strsetqi_1"
9667 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
9668 (match_operand:QI 2 "register_operand" "a"))
9669 (set (match_operand:SI 0 "register_operand" "=D")
9670 (plus:SI (match_dup 0)
9673 "TARGET_SINGLE_STRINGOP || optimize_size"
9675 [(set_attr "type" "str")
9676 (set_attr "memory" "store")
9677 (set_attr "mode" "QI")])
9679 ;; It might seem that operand 0 could use predicate register_operand.
9680 ;; But strength reduction might offset the MEM expression. So we let
9681 ;; reload put the address into %edi.
9683 (define_insn "rep_stossi"
9684 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
9685 (use (match_operand:SI 2 "register_operand" "a"))
9686 (use (match_operand:SI 4 "register_operand" "1"))
9687 (set (match_operand:SI 0 "register_operand" "=D")
9688 (plus:SI (match_operand:SI 3 "address_operand" "0")
9689 (ashift:SI (match_dup 3) (const_int 2))))
9690 (set (mem:BLK (match_dup 3))
9694 "rep\;stosl|rep stosd"
9695 [(set_attr "type" "str")
9696 (set_attr "prefix_rep" "1")
9697 (set_attr "memory" "store")
9698 (set_attr "mode" "SI")])
9700 (define_insn "rep_stosqi"
9701 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
9702 (use (match_operand:QI 2 "register_operand" "a"))
9703 (use (match_operand:SI 4 "register_operand" "1"))
9704 (set (match_operand:SI 0 "register_operand" "=D")
9705 (plus:SI (match_operand:SI 3 "address_operand" "0") (match_dup 3)))
9706 (set (mem:BLK (match_dup 3))
9710 "rep\;stosb|rep stosb"
9711 [(set_attr "type" "str")
9712 (set_attr "prefix_rep" "1")
9713 (set_attr "memory" "store")
9714 (set_attr "mode" "QI")])
9716 (define_expand "cmpstrsi"
9717 [(set (match_operand:SI 0 "register_operand" "")
9718 (compare:SI (match_operand:BLK 1 "general_operand" "")
9719 (match_operand:BLK 2 "general_operand" "")))
9720 (use (match_operand:SI 3 "general_operand" ""))
9721 (use (match_operand:SI 4 "immediate_operand" ""))]
9725 rtx addr1, addr2, out, outlow, count, countreg, align;
9728 if (GET_CODE (out) != REG)
9729 out = gen_reg_rtx (SImode);
9731 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
9732 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
9734 count = operands[3];
9735 countreg = copy_to_mode_reg (SImode, count);
9737 /* %%% Iff we are testing strict equality, we can use known alignment
9738 to good advantage. This may be possible with combine, particularly
9739 once cc0 is dead. */
9740 align = operands[4];
9742 emit_insn (gen_cld ());
9743 if (GET_CODE (count) == CONST_INT)
9745 if (INTVAL (count) == 0)
9747 emit_move_insn (operands[0], const0_rtx);
9750 emit_insn (gen_cmpstrsi_nz_1 (addr1, addr2, countreg, align));
9754 emit_insn (gen_cmpsi_1 (countreg, countreg));
9755 emit_insn (gen_cmpstrsi_1 (addr1, addr2, countreg, align));
9758 outlow = gen_lowpart (QImode, out);
9759 emit_insn (gen_cmpintqi (outlow));
9760 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
9762 if (operands[0] != out)
9763 emit_move_insn (operands[0], out);
9768 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
9770 (define_expand "cmpintqi"
9772 (gtu:QI (reg:CC 17) (const_int 0)))
9774 (ltu:QI (reg:CC 17) (const_int 0)))
9775 (parallel [(set (match_operand:QI 0 "register_operand" "")
9776 (minus:QI (match_dup 1)
9778 (clobber (reg:CC 17))])]
9780 "operands[1] = gen_reg_rtx (QImode);
9781 operands[2] = gen_reg_rtx (QImode);")
9783 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
9784 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
9786 ;; It might seem that operands 0 & 1 could use predicate register_operand.
9787 ;; But strength reduction might offset the MEM expression. So we let
9788 ;; reload put the address into %edi & %esi.
9790 (define_insn "cmpstrsi_nz_1"
9792 (compare:CC (mem:BLK (match_operand:SI 0 "address_operand" "S"))
9793 (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
9794 (use (match_operand:SI 2 "register_operand" "c"))
9795 (use (match_operand:SI 3 "immediate_operand" "i"))
9797 (clobber (match_dup 0))
9798 (clobber (match_dup 1))
9799 (clobber (match_dup 2))]
9802 [(set_attr "type" "str")
9803 (set_attr "mode" "QI")
9804 (set_attr "prefix_rep" "1")])
9806 ;; The same, but the count is not known to not be zero.
9808 (define_insn "cmpstrsi_1"
9810 (if_then_else:CC (ne (match_operand:SI 2 "register_operand" "c")
9812 (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
9813 (mem:BLK (match_operand:SI 1 "address_operand" "D")))
9815 (use (match_operand:SI 3 "immediate_operand" "i"))
9818 (clobber (match_dup 0))
9819 (clobber (match_dup 1))
9820 (clobber (match_dup 2))]
9823 [(set_attr "type" "str")
9824 (set_attr "mode" "QI")
9825 (set_attr "prefix_rep" "1")])
9827 (define_expand "strlensi"
9828 [(set (match_operand:SI 0 "register_operand" "")
9829 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
9830 (match_operand:QI 2 "immediate_operand" "")
9831 (match_operand:SI 3 "immediate_operand" "")] 0))]
9835 rtx out, addr, scratch1, scratch2, scratch3;
9836 rtx eoschar = operands[2];
9837 rtx align = operands[3];
9839 /* The generic case of strlen expander is long. Avoid it's
9840 expanding unless TARGET_INLINE_ALL_STRINGOPS. */
9842 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
9843 && !TARGET_INLINE_ALL_STRINGOPS
9845 && (GET_CODE (align) != CONST_INT || INTVAL (align) < 4))
9849 addr = force_reg (Pmode, XEXP (operands[1], 0));
9850 scratch1 = gen_reg_rtx (SImode);
9852 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
9855 /* Well it seems that some optimizer does not combine a call like
9856 foo(strlen(bar), strlen(bar));
9857 when the move and the subtraction is done here. It does calculate
9858 the length just once when these instructions are done inside of
9859 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
9860 often used and I use one fewer register for the lifetime of
9861 output_strlen_unroll() this is better. */
9863 if (GET_CODE (align) != CONST_INT || INTVAL (align) < 4)
9864 emit_move_insn (scratch1, addr);
9866 emit_move_insn (out, addr);
9868 ix86_expand_strlensi_unroll_1 (out, align, scratch1);
9870 /* strlensi_unroll_1 returns the address of the zero at the end of
9871 the string, like memchr(), so compute the length by subtracting
9872 the start address. */
9873 emit_insn (gen_subsi3 (out, out, addr));
9877 scratch2 = gen_reg_rtx (SImode);
9878 scratch3 = gen_reg_rtx (SImode);
9880 emit_move_insn (scratch3, addr);
9882 emit_insn (gen_cld ());
9883 emit_insn (gen_strlensi_1 (scratch1, scratch3, eoschar,
9884 align, constm1_rtx));
9885 emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
9886 emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
9891 ;; It might seem that operands 0 & 1 could use predicate register_operand.
9892 ;; But strength reduction might offset the MEM expression. So we let
9893 ;; reload put the address into %edi.
9895 (define_insn "strlensi_1"
9896 [(set (match_operand:SI 0 "register_operand" "=&c")
9897 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
9898 (match_operand:QI 2 "general_operand" "a")
9899 (match_operand:SI 3 "immediate_operand" "i")
9900 (match_operand:SI 4 "immediate_operand" "0")] 0))
9902 (clobber (match_dup 1))
9903 (clobber (reg:CC 17))]
9906 [(set_attr "type" "str")
9907 (set_attr "mode" "QI")
9908 (set_attr "prefix_rep" "1")])
9910 ;; Conditional move instructions.
9912 (define_expand "movsicc"
9913 [(set (match_operand:SI 0 "register_operand" "")
9914 (if_then_else:SI (match_operand 1 "comparison_operator" "")
9915 (match_operand:SI 2 "general_operand" "")
9916 (match_operand:SI 3 "general_operand" "")))]
9918 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
9920 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
9921 ;; the register first winds up with `sbbl $0,reg', which is also weird.
9922 ;; So just document what we're doing explicitly.
9924 (define_insn "x86_movsicc_0_m1"
9925 [(set (match_operand:SI 0 "register_operand" "=r")
9926 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
9929 (clobber (reg:CC 17))]
9932 ; Since we don't have the proper number of operands for an alu insn,
9933 ; fill in all the blanks.
9934 [(set_attr "type" "alu")
9935 (set_attr "memory" "none")
9936 (set_attr "imm_disp" "false")
9937 (set_attr "mode" "SI")
9938 (set_attr "length_immediate" "0")])
9940 (define_insn "*movsicc_noc"
9941 [(set (match_operand:SI 0 "register_operand" "=r,r")
9942 (if_then_else:SI (match_operator 1 "no_comparison_operator"
9943 [(reg 17) (const_int 0)])
9944 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
9945 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
9947 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
9949 cmov%C1\\t{%2, %0|%0, %2}
9950 cmov%c1\\t{%3, %0|%0, %3}"
9951 [(set_attr "type" "icmov")
9952 (set_attr "mode" "SI")])
9954 (define_insn "*movsicc_c"
9955 [(set (match_operand:SI 0 "register_operand" "=r,r")
9956 (if_then_else:SI (match_operator 1 "uno_comparison_operator"
9957 [(reg:CC 17) (const_int 0)])
9958 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
9959 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
9961 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
9963 cmov%C1\\t{%2, %0|%0, %2}
9964 cmov%c1\\t{%3, %0|%0, %3}"
9965 [(set_attr "type" "icmov")
9966 (set_attr "mode" "SI")])
9968 (define_expand "movhicc"
9969 [(set (match_operand:HI 0 "register_operand" "")
9970 (if_then_else:HI (match_operand 1 "comparison_operator" "")
9971 (match_operand:HI 2 "nonimmediate_operand" "")
9972 (match_operand:HI 3 "nonimmediate_operand" "")))]
9973 "TARGET_CMOVE && TARGET_HIMODE_MATH"
9974 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
9976 (define_insn "*movhicc_noc"
9977 [(set (match_operand:HI 0 "register_operand" "=r,r")
9978 (if_then_else:HI (match_operator 1 "no_comparison_operator"
9979 [(reg 17) (const_int 0)])
9980 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
9981 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
9983 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
9985 cmov%C1\\t{%2, %0|%0, %2}
9986 cmov%c1\\t{%3, %0|%0, %3}"
9987 [(set_attr "type" "icmov")
9988 (set_attr "mode" "HI")])
9990 (define_insn "*movhicc_c"
9991 [(set (match_operand:HI 0 "register_operand" "=r,r")
9992 (if_then_else:HI (match_operator 1 "uno_comparison_operator"
9993 [(reg:CC 17) (const_int 0)])
9994 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
9995 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
9997 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
9999 cmov%C1\\t{%2, %0|%0, %2}
10000 cmov%c1\\t{%3, %0|%0, %3}"
10001 [(set_attr "type" "icmov")
10002 (set_attr "mode" "HI")])
10004 (define_expand "movsfcc"
10005 [(set (match_operand:SF 0 "register_operand" "")
10006 (if_then_else:SF (match_operand 1 "comparison_operator" "")
10007 (match_operand:SF 2 "register_operand" "")
10008 (match_operand:SF 3 "register_operand" "")))]
10010 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
10012 (define_insn "*movsfcc_1"
10013 [(set (match_operand:SF 0 "register_operand" "=f,f")
10014 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
10015 [(reg 17) (const_int 0)])
10016 (match_operand:SF 2 "register_operand" "f,0")
10017 (match_operand:SF 3 "register_operand" "0,f")))]
10020 fcmov%F1\\t{%2, %0|%0, %2}
10021 fcmov%f1\\t{%3, %0|%0, %3}"
10022 [(set_attr "type" "fcmov")
10023 (set_attr "mode" "SF")])
10025 (define_expand "movdfcc"
10026 [(set (match_operand:DF 0 "register_operand" "")
10027 (if_then_else:DF (match_operand 1 "comparison_operator" "")
10028 (match_operand:DF 2 "register_operand" "")
10029 (match_operand:DF 3 "register_operand" "")))]
10031 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
10033 (define_insn "*movdfcc_1"
10034 [(set (match_operand:DF 0 "register_operand" "=f,f")
10035 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
10036 [(reg 17) (const_int 0)])
10037 (match_operand:DF 2 "register_operand" "f,0")
10038 (match_operand:DF 3 "register_operand" "0,f")))]
10041 fcmov%F1\\t{%2, %0|%0, %2}
10042 fcmov%f1\\t{%3, %0|%0, %3}"
10043 [(set_attr "type" "fcmov")
10044 (set_attr "mode" "DF")])
10046 (define_expand "movxfcc"
10047 [(set (match_operand:XF 0 "register_operand" "")
10048 (if_then_else:XF (match_operand 1 "comparison_operator" "")
10049 (match_operand:XF 2 "register_operand" "")
10050 (match_operand:XF 3 "register_operand" "")))]
10052 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
10054 (define_insn "*movxfcc_1"
10055 [(set (match_operand:XF 0 "register_operand" "=f,f")
10056 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
10057 [(reg 17) (const_int 0)])
10058 (match_operand:XF 2 "register_operand" "f,0")
10059 (match_operand:XF 3 "register_operand" "0,f")))]
10062 fcmov%F1\\t{%2, %0|%0, %2}
10063 fcmov%f1\\t{%3, %0|%0, %3}"
10064 [(set_attr "type" "fcmov")
10065 (set_attr "mode" "XF")])
10067 ;; Misc patterns (?)
10069 ;; This pattern exists to put a dependancy on all ebp-based memory accesses.
10070 ;; Otherwise there will be nothing to keep
10072 ;; [(set (reg ebp) (reg esp))]
10073 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
10074 ;; (clobber (eflags)]
10075 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
10077 ;; in proper program order.
10079 (define_insn "pro_epilogue_adjust_stack"
10080 [(set (match_operand:SI 0 "register_operand" "=r,r")
10081 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
10082 (match_operand:SI 2 "immediate_operand" "i,i")))
10083 (set (match_operand:SI 3 "register_operand" "+r,r")
10085 (clobber (reg:CC 17))]
10089 switch (get_attr_type (insn))
10092 return \"mov{l}\\t{%1, %0|%0, %1}\";
10095 if (GET_CODE (operands[2]) == CONST_INT
10096 && (INTVAL (operands[2]) == 128
10097 || (INTVAL (operands[2]) < 0
10098 && INTVAL (operands[2]) != -128)))
10100 operands[2] = GEN_INT (-INTVAL (operands[2]));
10101 return \"sub{l}\\t{%2, %0|%0, %2}\";
10103 return \"add{l}\\t{%2, %0|%0, %2}\";
10106 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
10107 return \"lea{l}\\t{%a2, %0|%0, %a2}\";
10113 [(set (attr "type")
10114 (cond [(eq_attr "alternative" "0")
10115 (const_string "alu")
10116 (match_operand:SI 2 "const0_operand" "")
10117 (const_string "imov")
10119 (const_string "lea")))
10120 (set_attr "mode" "SI")])
10122 (define_insn "allocate_stack_worker"
10123 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
10124 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
10125 (clobber (match_dup 0))
10126 (clobber (reg:CC 17))]
10127 "TARGET_STACK_PROBE"
10129 [(set_attr "type" "multi")
10130 (set_attr "length" "5")])
10132 (define_expand "allocate_stack"
10133 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
10134 (minus:SI (reg:SI 7)
10135 (match_operand:SI 1 "general_operand" "")))
10136 (clobber (reg:CC 17))])
10137 (parallel [(set (reg:SI 7)
10138 (minus:SI (reg:SI 7) (match_dup 1)))
10139 (clobber (reg:CC 17))])]
10140 "TARGET_STACK_PROBE"
10143 #ifdef CHECK_STACK_LIMIT
10144 if (GET_CODE (operands[1]) == CONST_INT
10145 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
10146 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
10150 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
10153 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10157 (define_expand "exception_receiver"
10162 load_pic_register ();
10166 (define_expand "builtin_setjmp_receiver"
10167 [(label_ref (match_operand 0 "" ""))]
10171 load_pic_register ();
10175 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
10178 [(set (match_operand 0 "register_operand" "")
10179 (match_operator 3 "promotable_binary_operator"
10180 [(match_operand 1 "register_operand" "")
10181 (match_operand 2 "aligned_operand" "")]))
10182 (clobber (reg:CC 17))]
10183 "! TARGET_PARTIAL_REG_STALL && reload_completed
10184 && ((GET_MODE (operands[0]) == HImode
10185 && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
10186 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
10187 || (GET_MODE (operands[0]) == QImode
10188 && (TARGET_PROMOTE_QImode || optimize_size)))"
10189 [(parallel [(set (match_dup 0)
10190 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
10191 (clobber (reg:CC 17))])]
10192 "operands[0] = gen_lowpart (SImode, operands[0]);
10193 operands[1] = gen_lowpart (SImode, operands[1]);
10194 if (GET_CODE (operands[3]) != ASHIFT)
10195 operands[2] = gen_lowpart (SImode, operands[2]);
10196 GET_MODE (operands[3]) = SImode;")
10200 (compare (and (match_operand 1 "aligned_operand" "")
10201 (match_operand 2 "const_int_operand" ""))
10203 (set (match_operand 0 "register_operand" "")
10204 (and (match_dup 1) (match_dup 2)))]
10205 "! TARGET_PARTIAL_REG_STALL && reload_completed
10206 && ix86_match_ccmode (insn, CCNOmode)
10207 && (GET_MODE (operands[0]) == HImode
10208 || (GET_MODE (operands[0]) == QImode
10209 && (TARGET_PROMOTE_QImode || optimize_size)))"
10210 [(parallel [(set (reg:CCNO 17)
10211 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
10214 (and:SI (match_dup 1) (match_dup 2)))])]
10216 = GEN_INT (INTVAL (operands[2]) & GET_MODE_MASK (GET_MODE (operands[0])));
10217 operands[0] = gen_lowpart (SImode, operands[0]);
10218 operands[1] = gen_lowpart (SImode, operands[1]);")
10222 (compare (and (match_operand 0 "aligned_operand" "")
10223 (match_operand 1 "const_int_operand" ""))
10225 "! TARGET_PARTIAL_REG_STALL && reload_completed
10226 && ix86_match_ccmode (insn, CCNOmode)
10227 && (GET_MODE (operands[0]) == HImode
10228 || (GET_MODE (operands[0]) == QImode
10229 && (TARGET_PROMOTE_QImode || optimize_size)))"
10230 [(set (reg:CCNO 17)
10231 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
10234 = GEN_INT (INTVAL (operands[1]) & GET_MODE_MASK (GET_MODE (operands[0])));
10235 operands[0] = gen_lowpart (SImode, operands[0]);")
10238 [(set (match_operand 0 "register_operand" "")
10239 (neg (match_operand 1 "register_operand" "")))
10240 (clobber (reg:CC 17))]
10241 "! TARGET_PARTIAL_REG_STALL && reload_completed
10242 && (GET_MODE (operands[0]) == HImode
10243 || (GET_MODE (operands[0]) == QImode
10244 && (TARGET_PROMOTE_QImode || optimize_size)))"
10245 [(parallel [(set (match_dup 0)
10246 (neg:SI (match_dup 1)))
10247 (clobber (reg:CC 17))])]
10248 "operands[0] = gen_lowpart (SImode, operands[0]);
10249 operands[1] = gen_lowpart (SImode, operands[1]);")
10252 [(set (match_operand 0 "register_operand" "")
10253 (not (match_operand 1 "register_operand" "")))]
10254 "! TARGET_PARTIAL_REG_STALL && reload_completed
10255 && (GET_MODE (operands[0]) == HImode
10256 || (GET_MODE (operands[0]) == QImode
10257 && (TARGET_PROMOTE_QImode || optimize_size)))"
10258 [(set (match_dup 0)
10259 (not:SI (match_dup 1)))]
10260 "operands[0] = gen_lowpart (SImode, operands[0]);
10261 operands[1] = gen_lowpart (SImode, operands[1]);")
10264 [(set (match_operand 0 "register_operand" "")
10265 (if_then_else (match_operator 1 "comparison_operator"
10266 [(reg 17) (const_int 0)])
10267 (match_operand 2 "register_operand" "")
10268 (match_operand 3 "register_operand" "")))]
10269 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
10270 && (GET_MODE (operands[0]) == HImode
10271 || (GET_MODE (operands[0]) == QImode
10272 && (TARGET_PROMOTE_QImode || optimize_size)))"
10273 [(set (match_dup 0)
10274 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
10275 "operands[0] = gen_lowpart (SImode, operands[0]);
10276 operands[2] = gen_lowpart (SImode, operands[2]);
10277 operands[3] = gen_lowpart (SImode, operands[3]);")
10280 ;; RTL Peephole optimizations, run before sched2. These primarily look to
10281 ;; transform a complex memory operation into two memory to register operations.
10283 ;; Don't push memory operands
10285 [(set (match_operand:SI 0 "push_operand" "")
10286 (match_operand:SI 1 "memory_operand" ""))
10287 (match_scratch:SI 2 "r")]
10288 "! optimize_size && ! TARGET_PUSH_MEMORY"
10289 [(set (match_dup 2) (match_dup 1))
10290 (set (match_dup 0) (match_dup 2))]
10293 ;; We need to handle SFmode only, because DFmode and XFmode is split to
10296 [(set (match_operand:SF 0 "push_operand" "")
10297 (match_operand:SF 1 "memory_operand" ""))
10298 (match_scratch:SF 2 "r")]
10299 "! optimize_size && ! TARGET_PUSH_MEMORY"
10300 [(set (match_dup 2) (match_dup 1))
10301 (set (match_dup 0) (match_dup 2))]
10305 [(set (match_operand:HI 0 "push_operand" "")
10306 (match_operand:HI 1 "memory_operand" ""))
10307 (match_scratch:HI 2 "r")]
10308 "! optimize_size && ! TARGET_PUSH_MEMORY"
10309 [(set (match_dup 2) (match_dup 1))
10310 (set (match_dup 0) (match_dup 2))]
10314 [(set (match_operand:QI 0 "push_operand" "")
10315 (match_operand:QI 1 "memory_operand" ""))
10316 (match_scratch:QI 2 "q")]
10317 "! optimize_size && ! TARGET_PUSH_MEMORY"
10318 [(set (match_dup 2) (match_dup 1))
10319 (set (match_dup 0) (match_dup 2))]
10322 ;; Don't move an immediate directly to memory when the instruction
10325 [(match_scratch:SI 1 "r")
10326 (set (match_operand:SI 0 "memory_operand" "")
10329 && ! TARGET_USE_MOV0
10330 && TARGET_SPLIT_LONG_MOVES
10331 && get_attr_length (insn) >= ix86_cost->large_insn
10332 && peep2_regno_dead_p (0, FLAGS_REG)"
10333 [(parallel [(set (match_dup 1) (const_int 0))
10334 (clobber (reg:CC 17))])
10335 (set (match_dup 0) (match_dup 1))]
10339 [(match_scratch:HI 1 "r")
10340 (set (match_operand:HI 0 "memory_operand" "")
10343 && ! TARGET_USE_MOV0
10344 && TARGET_SPLIT_LONG_MOVES
10345 && get_attr_length (insn) >= ix86_cost->large_insn
10346 && peep2_regno_dead_p (0, FLAGS_REG)"
10347 [(parallel [(set (match_dup 2) (const_int 0))
10348 (clobber (reg:CC 17))])
10349 (set (match_dup 0) (match_dup 1))]
10350 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
10353 [(match_scratch:QI 1 "q")
10354 (set (match_operand:QI 0 "memory_operand" "")
10357 && ! TARGET_USE_MOV0
10358 && TARGET_SPLIT_LONG_MOVES
10359 && get_attr_length (insn) >= ix86_cost->large_insn
10360 && peep2_regno_dead_p (0, FLAGS_REG)"
10361 [(parallel [(set (match_dup 2) (const_int 0))
10362 (clobber (reg:CC 17))])
10363 (set (match_dup 0) (match_dup 1))]
10364 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
10367 [(match_scratch:SI 2 "r")
10368 (set (match_operand:SI 0 "memory_operand" "")
10369 (match_operand:SI 1 "immediate_operand" ""))]
10371 && get_attr_length (insn) >= ix86_cost->large_insn
10372 && TARGET_SPLIT_LONG_MOVES"
10373 [(set (match_dup 2) (match_dup 1))
10374 (set (match_dup 0) (match_dup 2))]
10378 [(match_scratch:HI 2 "r")
10379 (set (match_operand:HI 0 "memory_operand" "")
10380 (match_operand:HI 1 "immediate_operand" ""))]
10381 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
10382 && TARGET_SPLIT_LONG_MOVES"
10383 [(set (match_dup 2) (match_dup 1))
10384 (set (match_dup 0) (match_dup 2))]
10388 [(match_scratch:QI 2 "q")
10389 (set (match_operand:QI 0 "memory_operand" "")
10390 (match_operand:QI 1 "immediate_operand" ""))]
10391 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
10392 && TARGET_SPLIT_LONG_MOVES"
10393 [(set (match_dup 2) (match_dup 1))
10394 (set (match_dup 0) (match_dup 2))]
10397 ;; Don't compare memory with zero, load and use a test instead.
10400 (compare (match_operand:SI 0 "memory_operand" "")
10402 (match_scratch:SI 3 "r")]
10403 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
10404 [(set (match_dup 3) (match_dup 0))
10405 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
10408 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
10409 ;; Don't split NOTs with a displacement operand, because resulting XOR
10410 ;; will not be pariable anyway.
10412 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
10413 ;; represented using a modRM byte. The XOR replacement is long decoded,
10414 ;; so this split helps here as well.
10416 ;; Note: Can't do this as a regular split because we can't get proper
10417 ;; lifetime information then.
10420 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10421 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10423 && peep2_regno_dead_p (0, FLAGS_REG)
10424 && ((TARGET_PENTIUM
10425 && (GET_CODE (operands[0]) != MEM
10426 || !memory_displacement_operand (operands[0], SImode)))
10427 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
10428 [(parallel [(set (match_dup 0)
10429 (xor:SI (match_dup 1) (const_int -1)))
10430 (clobber (reg:CC 17))])]
10434 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10435 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10437 && peep2_regno_dead_p (0, FLAGS_REG)
10438 && ((TARGET_PENTIUM
10439 && (GET_CODE (operands[0]) != MEM
10440 || !memory_displacement_operand (operands[0], HImode)))
10441 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
10442 [(parallel [(set (match_dup 0)
10443 (xor:HI (match_dup 1) (const_int -1)))
10444 (clobber (reg:CC 17))])]
10448 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
10449 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
10451 && peep2_regno_dead_p (0, FLAGS_REG)
10452 && ((TARGET_PENTIUM
10453 && (GET_CODE (operands[0]) != MEM
10454 || !memory_displacement_operand (operands[0], QImode)))
10455 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
10456 [(parallel [(set (match_dup 0)
10457 (xor:QI (match_dup 1) (const_int -1)))
10458 (clobber (reg:CC 17))])]
10461 ;; Non pairable "test imm, reg" instructions can be translated to
10462 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
10463 ;; byte opcode instead of two, have a short form for byte operands),
10464 ;; so do it for other CPUs as well. Given that the value was dead,
10465 ;; this should not create any new dependancies. Pass on the sub-word
10466 ;; versions if we're concerned about partial register stalls.
10470 (compare (and:SI (match_operand:SI 0 "register_operand" "")
10471 (match_operand:SI 1 "immediate_operand" ""))
10473 "ix86_match_ccmode (insn, CCNOmode)
10474 && (true_regnum (operands[0]) != 0
10475 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
10476 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
10478 [(set (reg:CCNO 17)
10479 (compare:CCNO (and:SI (match_dup 0)
10483 (and:SI (match_dup 0) (match_dup 1)))])]
10486 ;; We don't need to handle HImode case, because it will be promoted to SImode
10487 ;; on ! TARGET_PARTIAL_REG_STALL
10491 (compare (and:QI (match_operand:QI 0 "register_operand" "")
10492 (match_operand:QI 1 "immediate_operand" ""))
10494 "! TARGET_PARTIAL_REG_STALL
10495 && ix86_match_ccmode (insn, CCNOmode)
10496 && true_regnum (operands[0]) != 0
10497 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
10499 [(set (reg:CCNO 17)
10500 (compare:CCNO (and:QI (match_dup 0)
10504 (and:QI (match_dup 0) (match_dup 1)))])]
10512 (match_operand 0 "ext_register_operand" "q")
10515 (match_operand 1 "const_int_operand" "n"))
10517 "! TARGET_PARTIAL_REG_STALL
10518 && ix86_match_ccmode (insn, CCNOmode)
10519 && true_regnum (operands[0]) != 0
10520 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
10521 [(parallel [(set (reg:CCNO 17)
10530 (set (zero_extract:SI (match_dup 0)
10541 ;; Don't do logical operations with memory inputs.
10543 [(match_scratch:SI 2 "r")
10544 (parallel [(set (match_operand:SI 0 "register_operand" "")
10545 (match_operator:SI 3 "arith_or_logical_operator"
10547 (match_operand:SI 1 "memory_operand" "")]))
10548 (clobber (reg:CC 17))])]
10549 "! optimize_size && ! TARGET_READ_MODIFY"
10550 [(set (match_dup 2) (match_dup 1))
10551 (parallel [(set (match_dup 0)
10552 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
10553 (clobber (reg:CC 17))])]
10557 [(match_scratch:SI 2 "r")
10558 (parallel [(set (match_operand:SI 0 "register_operand" "")
10559 (match_operator:SI 3 "arith_or_logical_operator"
10560 [(match_operand:SI 1 "memory_operand" "")
10562 (clobber (reg:CC 17))])]
10563 "! optimize_size && ! TARGET_READ_MODIFY"
10564 [(set (match_dup 2) (match_dup 1))
10565 (parallel [(set (match_dup 0)
10566 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
10567 (clobber (reg:CC 17))])]
10570 ; Don't do logical operations with memory outputs
10572 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
10573 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
10574 ; the same decoder scheduling characteristics as the original.
10577 [(match_scratch:SI 2 "r")
10578 (parallel [(set (match_operand:SI 0 "memory_operand" "")
10579 (match_operator:SI 3 "arith_or_logical_operator"
10581 (match_operand:SI 1 "nonmemory_operand" "")]))
10582 (clobber (reg:CC 17))])]
10583 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
10584 [(set (match_dup 2) (match_dup 0))
10585 (parallel [(set (match_dup 2)
10586 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
10587 (clobber (reg:CC 17))])
10588 (set (match_dup 0) (match_dup 2))]
10592 [(match_scratch:SI 2 "r")
10593 (parallel [(set (match_operand:SI 0 "memory_operand" "")
10594 (match_operator:SI 3 "arith_or_logical_operator"
10595 [(match_operand:SI 1 "nonmemory_operand" "")
10597 (clobber (reg:CC 17))])]
10598 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
10599 [(set (match_dup 2) (match_dup 0))
10600 (parallel [(set (match_dup 2)
10601 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
10602 (clobber (reg:CC 17))])
10603 (set (match_dup 0) (match_dup 2))]
10606 ;; Attempt to always use XOR for zeroing registers.
10608 [(set (match_operand 0 "register_operand" "")
10610 "(GET_MODE (operands[0]) == QImode
10611 || GET_MODE (operands[0]) == HImode
10612 || GET_MODE (operands[0]) == SImode)
10613 && (! TARGET_USE_MOV0 || optimize_size)
10614 && peep2_regno_dead_p (0, FLAGS_REG)"
10615 [(parallel [(set (match_dup 0) (const_int 0))
10616 (clobber (reg:CC 17))])]
10617 "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
10620 [(set (strict_low_part (match_operand 0 "register_operand" ""))
10622 "(GET_MODE (operands[0]) == QImode
10623 || GET_MODE (operands[0]) == HImode)
10624 && (! TARGET_USE_MOV0 || optimize_size)
10625 && peep2_regno_dead_p (0, FLAGS_REG)"
10626 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
10627 (clobber (reg:CC 17))])])
10629 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
10631 [(set (match_operand 0 "register_operand" "")
10633 "(GET_MODE (operands[0]) == HImode
10634 || GET_MODE (operands[0]) == SImode)
10635 && (optimize_size || TARGET_PENTIUM)
10636 && peep2_regno_dead_p (0, FLAGS_REG)"
10637 [(parallel [(set (match_dup 0) (const_int -1))
10638 (clobber (reg:CC 17))])]
10639 "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
10641 ;; Attempt to convert simple leas to adds. These can be created by
10644 [(set (match_operand:SI 0 "register_operand" "")
10645 (plus:SI (match_dup 0)
10646 (match_operand:SI 1 "nonmemory_operand" "")))]
10647 "peep2_regno_dead_p (0, FLAGS_REG)"
10648 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
10649 (clobber (reg:CC 17))])]
10653 [(set (match_operand:SI 0 "register_operand" "")
10654 (mult:SI (match_dup 0)
10655 (match_operand:SI 1 "immediate_operand" "")))]
10656 "exact_log2 (INTVAL (operands[1])) >= 0
10657 && peep2_regno_dead_p (0, FLAGS_REG)"
10658 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
10659 (clobber (reg:CC 17))])]
10660 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
10662 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
10663 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
10664 ;; many CPUs it is also faster, since special hardware to avoid esp
10665 ;; dependancies is present.
10667 ;; While some of these converisons may be done using splitters, we use peepholes
10668 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
10670 ;; Convert prologue esp substractions to push.
10671 ;; We need register to push. In order to keep verify_flow_info happy we have
10673 ;; - use scratch and clobber it in order to avoid dependencies
10674 ;; - use already live register
10675 ;; We can't use the second way right now, since there is no reliable way how to
10676 ;; verify that given register is live. First choice will also most likely in
10677 ;; fewer dependencies. On the place of esp adjustments it is very likely that
10678 ;; call clobbered registers are dead. We may want to use base pointer as an
10679 ;; alternative when no register is available later.
10682 [(match_scratch:SI 0 "r")
10683 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
10684 (set (reg:SI 6) (reg:SI 6))
10685 (clobber (reg:CC 17))])]
10686 "optimize_size || !TARGET_SUB_ESP_4"
10687 [(clobber (match_dup 0))
10688 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
10689 (set (reg:SI 6) (reg:SI 6))])])
10692 [(match_scratch:SI 0 "r")
10693 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
10694 (set (reg:SI 6) (reg:SI 6))
10695 (clobber (reg:CC 17))])]
10696 "optimize_size || !TARGET_SUB_ESP_8"
10697 [(clobber (match_dup 0))
10698 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
10699 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
10700 (set (reg:SI 6) (reg:SI 6))])])
10702 ;; Convert esp substractions to push.
10704 [(match_scratch:SI 0 "r")
10705 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
10706 (clobber (reg:CC 17))])]
10707 "optimize_size || !TARGET_SUB_ESP_4"
10708 [(clobber (match_dup 0))
10709 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
10712 [(match_scratch:SI 0 "r")
10713 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
10714 (clobber (reg:CC 17))])]
10715 "optimize_size || !TARGET_SUB_ESP_8"
10716 [(clobber (match_dup 0))
10717 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
10718 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
10720 ;; Convert epilogue deallocator to pop.
10722 [(match_scratch:SI 0 "r")
10723 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
10724 (set (reg:SI 6) (reg:SI 6))
10725 (clobber (reg:CC 17))])]
10726 "optimize_size || !TARGET_ADD_ESP_4"
10727 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10728 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
10729 (set (reg:SI 6) (reg:SI 6))])]
10732 ;; Two pops case is tricky, since pop causes dependency on destination register.
10733 ;; We use two registers if available.
10735 [(match_scratch:SI 0 "r")
10736 (match_scratch:SI 1 "r")
10737 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
10738 (set (reg:SI 6) (reg:SI 6))
10739 (clobber (reg:CC 17))])]
10740 "optimize_size || !TARGET_ADD_ESP_8"
10741 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10742 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
10743 (set (reg:SI 6) (reg:SI 6))])
10744 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
10745 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10749 [(match_scratch:SI 0 "r")
10750 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
10751 (set (reg:SI 6) (reg:SI 6))
10752 (clobber (reg:CC 17))])]
10754 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10755 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
10756 (set (reg:SI 6) (reg:SI 6))])
10757 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10758 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10761 ;; Convert esp additions to pop.
10763 [(match_scratch:SI 0 "r")
10764 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
10765 (clobber (reg:CC 17))])]
10767 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10768 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10771 ;; Two pops case is tricky, since pop causes dependency on destination register.
10772 ;; We use two registers if available.
10774 [(match_scratch:SI 0 "r")
10775 (match_scratch:SI 1 "r")
10776 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
10777 (clobber (reg:CC 17))])]
10779 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10780 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
10781 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
10782 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10786 [(match_scratch:SI 0 "r")
10787 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
10788 (clobber (reg:CC 17))])]
10790 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10791 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
10792 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
10793 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
10796 ;; Call-value patterns last so that the wildcard operand does not
10797 ;; disrupt insn-recog's switch tables.
10799 (define_insn "*call_value_pop_0"
10800 [(set (match_operand 0 "" "")
10801 (call (match_operand:QI 1 "constant_call_address_operand" "")
10802 (match_operand:SI 2 "" "")))
10803 (set (reg:SI 7) (plus:SI (reg:SI 7)
10804 (match_operand:SI 4 "immediate_operand" "")))]
10808 if (SIBLING_CALL_P (insn))
10809 return \"jmp\\t%P1\";
10811 return \"call\\t%P1\";
10813 [(set_attr "type" "callv")])
10815 (define_insn "*call_value_pop_1"
10816 [(set (match_operand 0 "" "")
10817 (call (match_operand:QI 1 "call_insn_operand" "m")
10818 (match_operand:SI 2 "" "")))
10819 (set (reg:SI 7) (plus:SI (reg:SI 7)
10820 (match_operand:SI 4 "immediate_operand" "i")))]
10824 if (constant_call_address_operand (operands[1], QImode))
10826 if (SIBLING_CALL_P (insn))
10827 return \"jmp\\t%P1\";
10829 return \"call\\t%P1\";
10831 operands[1] = XEXP (operands[1], 0);
10832 if (SIBLING_CALL_P (insn))
10833 return \"jmp\\t%*%1\";
10835 return \"call\\t%*%1\";
10837 [(set_attr "type" "callv")])
10839 (define_insn "*call_value_0"
10840 [(set (match_operand 0 "" "")
10841 (call (match_operand:QI 1 "constant_call_address_operand" "")
10842 (match_operand:SI 2 "" "")))]
10846 if (SIBLING_CALL_P (insn))
10847 return \"jmp\\t%P1\";
10849 return \"call\\t%P1\";
10851 [(set_attr "type" "callv")])
10853 (define_insn "*call_value_1"
10854 [(set (match_operand 0 "" "")
10855 (call (match_operand:QI 1 "call_insn_operand" "m")
10856 (match_operand:SI 2 "" "")))]
10860 if (constant_call_address_operand (operands[1], QImode))
10862 if (SIBLING_CALL_P (insn))
10863 return \"jmp\\t%P1\";
10865 return \"call\\t%P1\";
10867 operands[1] = XEXP (operands[1], 0);
10868 if (SIBLING_CALL_P (insn))
10869 return \"jmp\\t%*%1\";
10871 return \"call\\t%*%1\";
10873 [(set_attr "type" "callv")])