1 ;; GCC machine description for IA-32.
2 ;; Copyright (C) 1988, 94-99, 2000 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
5 ;; This file is part of GNU CC.
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
28 ;; updates for most instructions.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
52 ;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode.
53 ;; operand 0 is the memory address to scan.
54 ;; operand 1 is a register containing the value to scan for. The mode
55 ;; of the scas opcode will be the same as the mode of this operand.
56 ;; operand 2 is the known alignment of operand 0.
57 ;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT.
58 ;; operand 0 is the argument for `sin'.
59 ;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT.
60 ;; operand 0 is the argument for `cos'.
61 ;; 3 This is part of a `stack probe' operation. The mode of the UNSPEC is
62 ;; always SImode. operand 0 is the size of the stack allocation.
63 ;; 4 This is the source of a fake SET of the frame pointer which is used to
64 ;; prevent insns referencing it being scheduled across the initial
65 ;; decrement of the stack pointer.
66 ;; 5 This is a `bsf' operation.
67 ;; 6 This is the @GOT offset of a PIC address.
68 ;; 7 This is the @GOTOFF offset of a PIC address.
69 ;; 8 This is a reference to a symbol's @PLT address.
70 ;; 9 This is an `fnstsw' operation.
71 ;; 10 This is a `sahf' operation.
72 ;; 11 This is a `fstcw' operation
74 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
78 ;; Processor type. This attribute must exactly match the processor_type
79 ;; enumeration in i386.h.
80 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon"
81 (const (symbol_ref "ix86_cpu")))
83 ;; A basic instruction type. Refinements due to arguments to be
84 ;; provided in other attributes.
86 "other,multi,alu1,negnot,alu,icmp,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"
87 (const_string "other"))
89 ;; The (bounding maximum) length of an instruction in bytes.
90 (define_attr "length" ""
91 (symbol_ref "ix86_attr_length_default(insn)"))
93 ;; Supporting: number of prefix bytes
94 (define_attr "length_prefix" ""
95 (cond [(and (eq_attr "type" "alu,alu1,negnot,icmp,imovx,incdec,ishift,imul,idiv,imov,pop")
96 (match_operand:HI 0 "general_operand" ""))
98 (and (eq_attr "type" "push")
99 (match_operand:HI 1 "general_operand" ""))
104 ;; Supporting: bytes in the opcode+modrm.
105 (define_attr "length_opcode" ""
106 (cond [(eq_attr "type" "imovx,setcc,icmov")
108 (eq_attr "type" "str,cld")
110 (and (eq_attr "type" "incdec")
111 (ior (match_operand:SI 1 "register_operand" "")
112 (match_operand:HI 1 "register_operand" "")))
114 (and (eq_attr "type" "push")
115 (not (match_operand 1 "memory_operand" "")))
117 (and (eq_attr "type" "pop")
118 (not (match_operand 0 "memory_operand" "")))
120 (and (eq_attr "type" "imov")
121 (and (match_operand 0 "register_operand" "")
122 (match_operand 1 "immediate_operand" "")))
127 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
128 ;; `store' if there is a simple memory reference therein, or `unknown'
129 ;; if the instruction is complex.
131 (define_attr "memory" "none,load,store,both,unknown"
132 (cond [(eq_attr "type" "other,multi,str")
133 (const_string "unknown")
134 (eq_attr "type" "lea,fcmov,fpspc,cld")
135 (const_string "none")
136 (eq_attr "type" "push")
137 (if_then_else (match_operand 1 "memory_operand" "")
138 (const_string "both")
139 (const_string "store"))
140 (eq_attr "type" "pop,setcc")
141 (if_then_else (match_operand 0 "memory_operand" "")
142 (const_string "both")
143 (const_string "load"))
144 (eq_attr "type" "icmp")
145 (if_then_else (ior (match_operand 0 "memory_operand" "")
146 (match_operand 1 "memory_operand" ""))
147 (const_string "load")
148 (const_string "none"))
149 (eq_attr "type" "ibr")
150 (if_then_else (match_operand 0 "memory_operand" "")
151 (const_string "load")
152 (const_string "none"))
153 (eq_attr "type" "call")
154 (if_then_else (match_operand 0 "constant_call_address_operand" "")
155 (const_string "none")
156 (const_string "load"))
157 (eq_attr "type" "callv")
158 (if_then_else (match_operand 1 "constant_call_address_operand" "")
159 (const_string "none")
160 (const_string "load"))
161 (and (eq_attr "type" "alu1,negnot")
162 (match_operand 1 "memory_operand" ""))
163 (const_string "both")
164 (and (match_operand 0 "memory_operand" "")
165 (match_operand 1 "memory_operand" ""))
166 (const_string "both")
167 (match_operand 0 "memory_operand" "")
168 (const_string "store")
169 (match_operand 1 "memory_operand" "")
170 (const_string "load")
171 (and (eq_attr "type" "!icmp,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp")
172 (match_operand 2 "memory_operand" ""))
173 (const_string "load")
174 (and (eq_attr "type" "icmov")
175 (match_operand 3 "memory_operand" ""))
176 (const_string "load")
178 (const_string "none")))
180 ;; Indicates if an instruction has both an immediate and a displacement.
182 (define_attr "imm_disp" "false,true,unknown"
183 (cond [(eq_attr "type" "other,multi")
184 (const_string "unknown")
185 (and (eq_attr "type" "icmp,imov")
186 (and (match_operand 0 "memory_displacement_operand" "")
187 (match_operand 1 "immediate_operand" "")))
188 (const_string "true")
189 (and (eq_attr "type" "alu,ishift,imul,idiv")
190 (and (match_operand 0 "memory_displacement_operand" "")
191 (match_operand 2 "immediate_operand" "")))
192 (const_string "true")
194 (const_string "false")))
196 ;; Indicates if an FP operation has an integer source.
198 (define_attr "fp_int_src" "false,true"
199 (const_string "false"))
201 ;; Describe a user's asm statement.
202 (define_asm_attributes
203 [(set_attr "length" "128")
204 (set_attr "type" "multi")])
206 ;; Pentium Scheduling
208 ;; The Pentium is an in-order core with two integer pipelines.
210 ;; Categorize how an instruction slots.
212 ;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
213 ;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium
214 ;; rules, because it results in noticeably better code on non-MMX Pentium
215 ;; and doesn't hurt much on MMX. (Prefixed instructions are not very
216 ;; common, so the scheduler usualy has a non-prefixed insn to pair).
218 (define_attr "pent_pair" "uv,pu,pv,np"
219 (cond [(eq_attr "imm_disp" "true")
221 (eq_attr "type" "alu1,alu,imov,icmp,lea,incdec")
222 (if_then_else (eq_attr "length_prefix" "1")
225 (eq_attr "type" "ibr")
227 (and (eq_attr "type" "ishift")
228 (match_operand 2 "const_int_operand" ""))
230 (and (eq_attr "type" "pop,push")
231 (eq_attr "memory" "!both"))
232 (if_then_else (eq_attr "length_prefix" "1")
235 (and (eq_attr "type" "call")
236 (match_operand 0 "constant_call_address_operand" ""))
238 (and (eq_attr "type" "callv")
239 (match_operand 1 "constant_call_address_operand" ""))
242 (const_string "np")))
244 ;; Rough readiness numbers. Fine tuning happens in i386.c.
246 ;; u describes pipe U
247 ;; v describes pipe V
248 ;; uv describes either pipe U or V for those that can issue to either
249 ;; np describes not paring
251 ;; fpm describes fp insns of different types are not pipelined.
253 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
255 (define_function_unit "pent_np" 1 0
256 (and (eq_attr "cpu" "pentium")
257 (eq_attr "type" "imul"))
260 (define_function_unit "pent_mul" 1 1
261 (and (eq_attr "cpu" "pentium")
262 (eq_attr "type" "imul"))
265 ;; Rep movs takes minimally 12 cycles.
266 (define_function_unit "pent_np" 1 0
267 (and (eq_attr "cpu" "pentium")
268 (eq_attr "type" "str"))
271 ; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
272 (define_function_unit "pent_np" 1 0
273 (and (eq_attr "cpu" "pentium")
274 (eq_attr "type" "idiv"))
277 ; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
278 ; 3 cycles for XFmode. Stores takes 2 cycles for SF/DF and 3 for XF.
279 ; fldz and fld1 takes 2 cycles. Only reg-reg moves are pairable.
280 ; The integer <-> fp conversion is not modeled correctly. Fild behaves
281 ; like normal fp operation and fist takes 6 cycles.
283 (define_function_unit "fpu" 1 0
284 (and (eq_attr "cpu" "pentium")
285 (and (eq_attr "type" "fmov")
286 (ior (and (eq_attr "memory" "store")
287 (match_operand:XF 0 "memory_operand" ""))
288 (and (eq_attr "memory" "load")
289 (match_operand:XF 1 "memory_operand" "")))))
292 (define_function_unit "pent_np" 1 0
293 (and (eq_attr "cpu" "pentium")
294 (and (eq_attr "type" "fmov")
295 (ior (and (eq_attr "memory" "store")
296 (match_operand:XF 0 "memory_operand" ""))
297 (and (eq_attr "memory" "load")
298 (match_operand:XF 1 "memory_operand" "")))))
301 (define_function_unit "fpu" 1 0
302 (and (eq_attr "cpu" "pentium")
303 (and (eq_attr "type" "fmov")
304 (ior (match_operand 1 "immediate_operand" "")
305 (eq_attr "memory" "store"))))
308 (define_function_unit "pent_np" 1 0
309 (and (eq_attr "cpu" "pentium")
310 (and (eq_attr "type" "fmov")
311 (ior (match_operand 1 "immediate_operand" "")
312 (eq_attr "memory" "store"))))
315 (define_function_unit "pent_np" 1 0
316 (and (eq_attr "cpu" "pentium")
317 (eq_attr "type" "cld"))
320 (define_function_unit "fpu" 1 0
321 (and (eq_attr "cpu" "pentium")
322 (and (eq_attr "type" "fmov")
323 (eq_attr "memory" "none,load")))
326 ; Read/Modify/Write instructions usually take 3 cycles.
327 (define_function_unit "pent_u" 1 0
328 (and (eq_attr "cpu" "pentium")
329 (and (eq_attr "type" "alu,alu1,ishift")
330 (and (eq_attr "pent_pair" "pu")
331 (eq_attr "memory" "both"))))
334 (define_function_unit "pent_uv" 2 0
335 (and (eq_attr "cpu" "pentium")
336 (and (eq_attr "type" "alu,alu1,ishift")
337 (and (eq_attr "pent_pair" "!np")
338 (eq_attr "memory" "both"))))
341 (define_function_unit "pent_np" 1 0
342 (and (eq_attr "cpu" "pentium")
343 (and (eq_attr "type" "alu,alu1,negnot,ishift")
344 (and (eq_attr "pent_pair" "np")
345 (eq_attr "memory" "both"))))
348 ; Read/Modify or Modify/Write instructions usually take 2 cycles.
349 (define_function_unit "pent_u" 1 0
350 (and (eq_attr "cpu" "pentium")
351 (and (eq_attr "type" "alu,ishift")
352 (and (eq_attr "pent_pair" "pu")
353 (eq_attr "memory" "load,store"))))
356 (define_function_unit "pent_uv" 2 0
357 (and (eq_attr "cpu" "pentium")
358 (and (eq_attr "type" "alu,ishift")
359 (and (eq_attr "pent_pair" "!np")
360 (eq_attr "memory" "load,store"))))
363 (define_function_unit "pent_np" 1 0
364 (and (eq_attr "cpu" "pentium")
365 (and (eq_attr "type" "alu,ishift")
366 (and (eq_attr "pent_pair" "np")
367 (eq_attr "memory" "load,store"))))
370 ; Insns w/o memory operands and move instructions usually take one cycle.
371 (define_function_unit "pent_u" 1 0
372 (and (eq_attr "cpu" "pentium")
373 (eq_attr "pent_pair" "pu"))
376 (define_function_unit "pent_v" 1 0
377 (and (eq_attr "cpu" "pentium")
378 (eq_attr "pent_pair" "pv"))
381 (define_function_unit "pent_uv" 2 0
382 (and (eq_attr "cpu" "pentium")
383 (eq_attr "pent_pair" "!np"))
386 (define_function_unit "pent_np" 1 0
387 (and (eq_attr "cpu" "pentium")
388 (eq_attr "pent_pair" "np"))
391 ; Pairable insns only conflict with other non-pairable insns.
392 (define_function_unit "pent_np" 1 0
393 (and (eq_attr "cpu" "pentium")
394 (and (eq_attr "type" "alu,alu1,ishift")
395 (and (eq_attr "pent_pair" "!np")
396 (eq_attr "memory" "both"))))
398 [(eq_attr "pent_pair" "np")])
400 (define_function_unit "pent_np" 1 0
401 (and (eq_attr "cpu" "pentium")
402 (and (eq_attr "type" "alu,alu1,ishift")
403 (and (eq_attr "pent_pair" "!np")
404 (eq_attr "memory" "load,store"))))
406 [(eq_attr "pent_pair" "np")])
408 (define_function_unit "pent_np" 1 0
409 (and (eq_attr "cpu" "pentium")
410 (eq_attr "pent_pair" "!np"))
412 [(eq_attr "pent_pair" "np")])
414 ; Floating point instructions usually blocks cycle longer when combined with
415 ; integer instructions, because of the inpaired fxch instruction.
416 (define_function_unit "pent_np" 1 0
417 (and (eq_attr "cpu" "pentium")
418 (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp"))
420 [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp")])
422 (define_function_unit "fpu" 1 0
423 (and (eq_attr "cpu" "pentium")
424 (eq_attr "type" "fcmp,fxch,fsgn"))
427 ; Addition takes 3 cycles; assume other random cruft does as well.
428 ; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
429 (define_function_unit "fpu" 1 0
430 (and (eq_attr "cpu" "pentium")
431 (eq_attr "type" "fop,fop1"))
434 ; Multiplication takes 3 cycles and is only half pipelined.
435 (define_function_unit "fpu" 1 0
436 (and (eq_attr "cpu" "pentium")
437 (eq_attr "type" "fmul"))
440 (define_function_unit "pent_mul" 1 1
441 (and (eq_attr "cpu" "pentium")
442 (eq_attr "type" "fmul"))
445 ; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles.
446 ; They can overlap with integer insns. Only the last two cycles can overlap
447 ; with other fp insns. Only fsin/fcos can overlap with multiplies.
448 ; Only last two cycles of fsin/fcos can overlap with other instructions.
449 (define_function_unit "fpu" 1 0
450 (and (eq_attr "cpu" "pentium")
451 (eq_attr "type" "fdiv"))
454 (define_function_unit "pent_mul" 1 1
455 (and (eq_attr "cpu" "pentium")
456 (eq_attr "type" "fdiv"))
459 (define_function_unit "fpu" 1 0
460 (and (eq_attr "cpu" "pentium")
461 (eq_attr "type" "fpspc"))
464 (define_function_unit "pent_mul" 1 1
465 (and (eq_attr "cpu" "pentium")
466 (eq_attr "type" "fpspc"))
469 ;; Pentium Pro/PII Scheduling
471 ;; The PPro has an out-of-order core, but the instruction decoders are
472 ;; naturally in-order and asymmetric. We get best performance by scheduling
473 ;; for the decoders, for in doing so we give the oo execution unit the
476 ;; Categorize how many uops an ia32 instruction evaluates to:
477 ;; one -- an instruction with 1 uop can be decoded by any of the
479 ;; few -- an instruction with 1 to 4 uops can be decoded only by
481 ;; many -- a complex instruction may take an unspecified number of
482 ;; cycles to decode in decoder 0.
484 (define_attr "ppro_uops" "one,few,many"
485 (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
486 (const_string "many")
487 (eq_attr "type" "icmov,fcmov,str,cld")
489 (eq_attr "type" "imov")
490 (if_then_else (eq_attr "memory" "store,both")
492 (const_string "one"))
493 (eq_attr "memory" "!none")
496 (const_string "one")))
498 ;; Rough readiness numbers. Fine tuning happens in i386.c.
500 ;; p0 describes port 0.
501 ;; p01 describes ports 0 and 1 as a pair; alu insns can issue to either.
502 ;; p2 describes port 2 for loads.
503 ;; p34 describes ports 3 and 4 for stores.
504 ;; fpu describes the fpu accessed via port 0.
505 ;; ??? It is less than clear if there are separate fadd and fmul units
506 ;; that could operate in parallel.
508 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
510 (define_function_unit "ppro_p0" 1 0
511 (and (eq_attr "cpu" "pentiumpro")
512 (eq_attr "type" "ishift,lea,ibr,cld"))
515 (define_function_unit "ppro_p0" 1 0
516 (and (eq_attr "cpu" "pentiumpro")
517 (eq_attr "type" "imul"))
520 ;; ??? Does the divider lock out the pipe while it works,
521 ;; or is there a disconnected unit?
522 (define_function_unit "ppro_p0" 1 0
523 (and (eq_attr "cpu" "pentiumpro")
524 (eq_attr "type" "idiv"))
527 (define_function_unit "ppro_p0" 1 0
528 (and (eq_attr "cpu" "pentiumpro")
529 (eq_attr "type" "fop,fop1,fsgn"))
532 (define_function_unit "ppro_p0" 1 0
533 (and (eq_attr "cpu" "pentiumpro")
534 (eq_attr "type" "fcmov"))
537 (define_function_unit "ppro_p0" 1 0
538 (and (eq_attr "cpu" "pentiumpro")
539 (eq_attr "type" "fcmp"))
542 (define_function_unit "ppro_p0" 1 0
543 (and (eq_attr "cpu" "pentiumpro")
544 (eq_attr "type" "fmov"))
547 (define_function_unit "ppro_p0" 1 0
548 (and (eq_attr "cpu" "pentiumpro")
549 (eq_attr "type" "fmul"))
552 (define_function_unit "ppro_p0" 1 0
553 (and (eq_attr "cpu" "pentiumpro")
554 (eq_attr "type" "fdiv,fpspc"))
557 (define_function_unit "ppro_p01" 2 0
558 (and (eq_attr "cpu" "pentiumpro")
559 (eq_attr "type" "!imov,fmov"))
562 (define_function_unit "ppro_p01" 2 0
563 (and (and (eq_attr "cpu" "pentiumpro")
564 (eq_attr "type" "imov,fmov"))
565 (eq_attr "memory" "none"))
568 (define_function_unit "ppro_p2" 1 0
569 (and (eq_attr "cpu" "pentiumpro")
570 (ior (eq_attr "type" "pop")
571 (eq_attr "memory" "load,both")))
574 (define_function_unit "ppro_p34" 1 0
575 (and (eq_attr "cpu" "pentiumpro")
576 (ior (eq_attr "type" "push")
577 (eq_attr "memory" "store,both")))
580 (define_function_unit "fpu" 1 0
581 (and (eq_attr "cpu" "pentiumpro")
582 (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov"))
585 (define_function_unit "fpu" 1 0
586 (and (eq_attr "cpu" "pentiumpro")
587 (eq_attr "type" "fmul"))
590 (define_function_unit "fpu" 1 0
591 (and (eq_attr "cpu" "pentiumpro")
592 (eq_attr "type" "fdiv,fpspc"))
595 ;; imul uses the fpu. ??? does it have the same throughput as fmul?
596 (define_function_unit "fpu" 1 0
597 (and (eq_attr "cpu" "pentiumpro")
598 (eq_attr "type" "imul"))
601 ;; AMD K6/K6-2 Scheduling
603 ;; The K6 has similar architecture to PPro. Important difference is, that
604 ;; there are only two decoders and they seems to be much slower than execution
605 ;; units. So we have to pay much more attention to proper decoding for
606 ;; schedulers. We share most of scheduler code for PPro in i386.c
608 ;; The fp unit is not pipelined and do one operation per two cycles including
611 ;; alu describes both ALU units (ALU-X and ALU-Y).
612 ;; alux describes X alu unit
613 ;; fpu describes FPU unit
614 ;; load describes load unit.
615 ;; branch describes branch unit.
616 ;; store decsribes store unit. This unit is not modelled completely and only
617 ;; used to model lea operation. Otherwise it lie outside of the critical
620 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
622 ;; The decoder specification is in the PPro section above!
624 ;; Shift instructions and certain arithmetic are issued only to X pipe.
625 (define_function_unit "k6_alux" 1 0
626 (and (eq_attr "cpu" "k6")
627 (eq_attr "type" "ishift,alu1,negnot,cld"))
630 ;; The QI mode arithmetic is issued to X pipe only.
631 (define_function_unit "k6_alux" 1 0
632 (and (eq_attr "cpu" "k6")
633 (and (eq_attr "type" "alu,alu1,negnot,icmp,imovx,incdec")
634 (match_operand:QI 0 "general_operand" "")))
637 (define_function_unit "k6_alu" 2 0
638 (and (eq_attr "cpu" "k6")
639 (eq_attr "type" "ishift,alu1,negnot,alu,icmp,imovx,incdec,setcc,lea"))
642 (define_function_unit "k6_alu" 2 0
643 (and (eq_attr "cpu" "k6")
644 (and (eq_attr "type" "imov")
645 (eq_attr "memory" "none")))
648 (define_function_unit "k6_branch" 1 0
649 (and (eq_attr "cpu" "k6")
650 (eq_attr "type" "call,callv,ibr"))
653 ;; Load unit have two cycle latency, but we take care for it in adjust_cost
654 (define_function_unit "k6_load" 1 0
655 (and (eq_attr "cpu" "k6")
656 (ior (eq_attr "type" "pop")
657 (eq_attr "memory" "load,both")))
660 (define_function_unit "k6_load" 1 0
661 (and (eq_attr "cpu" "k6")
662 (and (eq_attr "type" "str")
663 (eq_attr "memory" "load,both")))
666 ;; Lea have two instructions, so latency is probably 2
667 (define_function_unit "k6_store" 1 0
668 (and (eq_attr "cpu" "k6")
669 (eq_attr "type" "lea"))
672 (define_function_unit "k6_store" 1 0
673 (and (eq_attr "cpu" "k6")
674 (eq_attr "type" "str"))
677 (define_function_unit "k6_store" 1 0
678 (and (eq_attr "cpu" "k6")
679 (ior (eq_attr "type" "push")
680 (eq_attr "memory" "store,both")))
683 (define_function_unit "k6_fpu" 1 1
684 (and (eq_attr "cpu" "k6")
685 (eq_attr "type" "fop,fop1,fmov,fcmp"))
688 (define_function_unit "k6_fpu" 1 1
689 (and (eq_attr "cpu" "k6")
690 (eq_attr "type" "fmul"))
694 (define_function_unit "k6_fpu" 1 1
695 (and (eq_attr "cpu" "k6")
696 (eq_attr "type" "fdiv,fpspc"))
699 (define_function_unit "k6_alu" 2 0
700 (and (eq_attr "cpu" "k6")
701 (eq_attr "type" "imul"))
704 (define_function_unit "k6_alux" 1 0
705 (and (eq_attr "cpu" "k6")
706 (eq_attr "type" "imul"))
710 (define_function_unit "k6_alu" 2 0
711 (and (eq_attr "cpu" "k6")
712 (eq_attr "type" "idiv"))
715 (define_function_unit "k6_alux" 1 0
716 (and (eq_attr "cpu" "k6")
717 (eq_attr "type" "idiv"))
720 ;; AMD Athlon Scheduling
722 ;; The Athlon does contain three pipelined FP units, three integer units and
723 ;; three address generation units.
725 ;; The predecode logic is determining boundaries of instructions in the 64
726 ;; byte cache line. So the cache line straddling problem of K6 might be issue
727 ;; here as well, but it is not noted in the documentation.
729 ;; Three DirectPath instructions decoders and only one VectorPath decoder
730 ;; is available. They can decode three DirectPath instructions or one VectorPath
731 ;; instruction per cycle.
732 ;; Decoded macro instructions are then passed to 72 entry instruction control
734 ;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
736 ;; The load/store queue unit is not attached to the schedulers but
737 ;; communicates with all the execution units seperately instead.
739 (define_attr "athlon_decode" "direct,vector"
740 (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str")
741 (const_string "vector")
742 (and (eq_attr "type" "push")
743 (match_operand 1 "memory_operand" ""))
744 (const_string "vector")
745 (and (eq_attr "type" "fmov")
746 (ior (match_operand:XF 0 "memory_operand" "")
747 (match_operand:XF 1 "memory_operand" "")))
748 (const_string "vector")]
749 (const_string "direct")))
751 (define_function_unit "athlon_vectordec" 1 0
752 (and (eq_attr "cpu" "athlon")
753 (eq_attr "athlon_decode" "vector"))
756 (define_function_unit "athlon_directdec" 3 0
757 (and (eq_attr "cpu" "athlon")
758 (eq_attr "athlon_decode" "direct"))
761 (define_function_unit "athlon_vectordec" 1 0
762 (and (eq_attr "cpu" "athlon")
763 (eq_attr "athlon_decode" "direct"))
764 1 1 [(eq_attr "athlon_decode" "vector")])
766 (define_function_unit "athlon_ieu" 3 0
767 (and (eq_attr "cpu" "athlon")
768 (eq_attr "type" "alu1,negnot,alu,icmp,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,str,cld"))
771 (define_function_unit "athlon_ieu" 3 0
772 (and (eq_attr "cpu" "athlon")
773 (eq_attr "type" "str"))
776 (define_function_unit "athlon_ieu" 3 0
777 (and (eq_attr "cpu" "athlon")
778 (eq_attr "type" "imul"))
781 (define_function_unit "athlon_ieu" 3 0
782 (and (eq_attr "cpu" "athlon")
783 (eq_attr "type" "idiv"))
786 (define_function_unit "athlon_muldiv" 1 0
787 (and (eq_attr "cpu" "athlon")
788 (eq_attr "type" "imul"))
791 (define_function_unit "athlon_muldiv" 1 0
792 (and (eq_attr "cpu" "athlon")
793 (eq_attr "type" "idiv"))
796 (define_attr "athlon_fpunits" "none,store,mul,add,muladd,all"
797 (cond [(eq_attr "type" "fop,fop1,fcmp")
799 (eq_attr "type" "fmul,fdiv,fpspc,fsgn")
801 (and (eq_attr "type" "fmov") (eq_attr "memory" "!none"))
802 (const_string "store")
803 (and (eq_attr "type" "fmov")
804 (ior (match_operand:SI 1 "register_operand" "")
805 (match_operand 1 "immediate_operand" "")))
806 (const_string "store")
807 (eq_attr "type" "fmov")
808 (const_string "muladd")
809 (eq_attr "type" "fcmov")
810 (const_string "all")]
811 (const_string "none")))
813 (define_function_unit "athlon_fp_mul" 1 0
814 (and (eq_attr "cpu" "athlon")
815 (eq_attr "athlon_fpunits" "mul,all"))
818 (define_function_unit "athlon_fp_add" 1 0
819 (and (eq_attr "cpu" "athlon")
820 (eq_attr "athlon_fpunits" "add,all"))
823 (define_function_unit "athlon_fp_muladd" 2 0
824 (and (eq_attr "cpu" "athlon")
825 (and (eq_attr "type" "fmov")
826 (eq_attr "athlon_fpunits" "muladd,mul,add,all")))
829 (define_function_unit "athlon_fp_muladd" 2 0
830 (and (eq_attr "cpu" "athlon")
831 (and (eq_attr "type" "!fmov")
832 (eq_attr "athlon_fpunits" "muladd,mul,add,all")))
835 (define_function_unit "athlon_fp_store" 1 0
836 (and (eq_attr "cpu" "athlon")
837 (eq_attr "athlon_fpunits" "store,all"))
840 (define_function_unit "athlon_agu" 3 0
841 (and (eq_attr "cpu" "athlon")
842 (and (eq_attr "memory" "!none")
843 (eq_attr "athlon_fpunits" "none")))
847 ;; Compare instructions.
849 ;; All compare insns have expanders that save the operands away without
850 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
851 ;; after the cmp) will actually emit the cmpM.
853 (define_expand "cmpdi"
855 (compare:CC (match_operand:DI 0 "general_operand" "")
856 (match_operand:DI 1 "general_operand" "")))]
860 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
861 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
862 operands[0] = force_reg (DImode, operands[0]);
863 ix86_compare_op0 = operands[0];
864 ix86_compare_op1 = operands[1];
868 (define_expand "cmpsi"
870 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
871 (match_operand:SI 1 "general_operand" "")))]
875 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
876 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
877 operands[0] = force_reg (SImode, operands[0]);
878 ix86_compare_op0 = operands[0];
879 ix86_compare_op1 = operands[1];
883 (define_expand "cmphi"
885 (compare:CC (match_operand:HI 0 "general_operand" "")
886 (match_operand:HI 1 "general_operand" "")))]
890 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
891 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
892 operands[0] = force_reg (HImode, operands[0]);
893 ix86_compare_op0 = operands[0];
894 ix86_compare_op1 = operands[1];
898 (define_expand "cmpqi"
900 (compare:CC (match_operand:QI 0 "general_operand" "")
901 (match_operand:QI 1 "general_operand" "")))]
905 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
906 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
907 operands[0] = force_reg (QImode, operands[0]);
908 ix86_compare_op0 = operands[0];
909 ix86_compare_op1 = operands[1];
913 (define_insn "cmpsi_0"
915 (compare:CCNO (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
916 (match_operand:SI 1 "const0_operand" "n,n")))]
919 test{l}\\t{%0, %0|%0, %0}
920 cmp{l}\\t{%1, %0|%0, %1}"
921 [(set_attr "type" "icmp")])
923 (define_insn "cmpsi_1"
925 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
926 (match_operand:SI 1 "general_operand" "ri,mr")))]
927 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
928 "cmp{l}\\t{%1, %0|%0, %1}"
929 [(set_attr "type" "icmp")])
931 (define_insn "cmphi_0"
933 (compare:CCNO (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
934 (match_operand:HI 1 "const0_operand" "n,n")))]
937 test{w}\\t{%0, %0|%0, %0}
938 cmp{w}\\t{%1, %0|%0, %1}"
939 [(set_attr "type" "icmp")])
941 (define_insn "cmphi_1"
943 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "rm,r")
944 (match_operand:HI 1 "general_operand" "ri,mr")))]
945 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
946 "cmp{w}\\t{%1, %0|%0, %1}"
947 [(set_attr "type" "icmp")])
949 (define_insn "cmpqi_0"
951 (compare:CCNO (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
952 (match_operand:QI 1 "const0_operand" "n,n")))]
955 test{b}\\t{%0, %0|%0, %0}
956 cmp{b}\\t{$0, %0|%0, 0}"
957 [(set_attr "type" "icmp")])
959 (define_insn "cmpqi_1"
961 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "qm,q")
962 (match_operand:QI 1 "general_operand" "qi,mq")))]
963 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
964 "cmp{b}\\t{%1, %0|%0, %1}"
965 [(set_attr "type" "icmp")])
967 (define_insn "*cmpqi_ext_1"
970 (match_operand:QI 0 "general_operand" "qm")
973 (match_operand 1 "ext_register_operand" "q")
977 "cmp{b}\\t{%h1, %0|%0, %h1}"
978 [(set_attr "type" "icmp")])
980 (define_insn "*cmpqi_ext_2"
985 (match_operand 0 "ext_register_operand" "q")
988 (match_operand:QI 1 "const0_operand" "n")))]
991 [(set_attr "type" "icmp")])
993 (define_insn "cmpqi_ext_3"
998 (match_operand 0 "ext_register_operand" "q")
1001 (match_operand:QI 1 "general_operand" "qmn")))]
1003 "cmp{b}\\t{%1, %h0|%h0, %1}"
1004 [(set_attr "type" "icmp")])
1006 (define_insn "*cmpqi_ext_4"
1011 (match_operand 0 "ext_register_operand" "q")
1016 (match_operand 1 "ext_register_operand" "q")
1018 (const_int 8)) 0)))]
1020 "cmp{b}\\t{%h1, %h0|%h0, %h1}"
1021 [(set_attr "type" "icmp")])
1023 ;; These implement float point compares.
1024 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1025 ;; which would allow mix and match FP modes on the compares. Which is what
1026 ;; the old patterns did, but with many more of them.
1028 (define_expand "cmpxf"
1030 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1031 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1035 ix86_compare_op0 = operands[0];
1036 ix86_compare_op1 = operands[1];
1040 (define_expand "cmpdf"
1042 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1043 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
1047 ix86_compare_op0 = operands[0];
1048 ix86_compare_op1 = operands[1];
1052 (define_expand "cmpsf"
1054 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1055 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
1059 ix86_compare_op0 = operands[0];
1060 ix86_compare_op1 = operands[1];
1064 ;; FP compares, step 1:
1065 ;; Set the FP condition codes.
1067 ;; CCFPmode compare with exceptions
1068 ;; CCFPUmode compare with no exceptions
1070 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1071 ;; and that fp moves clobber the condition codes, and that there is
1072 ;; currently no way to describe this fact to reg-stack. So there are
1073 ;; no splitters yet for this.
1075 ;; %%% YIKES! This scheme does not retain a strong connection between
1076 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1077 ;; work! Only allow tos/mem with tos in op 0.
1079 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
1080 ;; things aren't as bad as they sound...
1082 (define_insn "*cmpfp_0"
1083 [(set (match_operand:HI 0 "register_operand" "=a")
1085 [(compare:CCFP (match_operand 1 "register_operand" "f")
1086 (match_operand 2 "const0_operand" "X"))] 9))]
1088 && FLOAT_MODE_P (GET_MODE (operands[1]))
1089 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1092 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1093 return \"ftst\;fnstsw\\t%0\;fstp\\t%y0\";
1095 return \"ftst\;fnstsw\\t%0\";
1097 [(set_attr "type" "multi")])
1099 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1100 ;; used to manage the reg stack popping would not be preserved.
1102 (define_insn "*cmpfp_2_sf"
1105 (match_operand:SF 0 "register_operand" "f")
1106 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1108 "* return output_fp_compare (insn, operands, 0, 0);"
1109 [(set_attr "type" "fcmp")])
1111 (define_insn "*cmpfp_2_sf_1"
1112 [(set (match_operand:HI 0 "register_operand" "=a")
1115 (match_operand:SF 1 "register_operand" "f")
1116 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
1118 "* return output_fp_compare (insn, operands, 2, 0);"
1119 [(set_attr "type" "fcmp")])
1121 (define_insn "*cmpfp_2_df"
1124 (match_operand:DF 0 "register_operand" "f")
1125 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1127 "* return output_fp_compare (insn, operands, 0, 0);"
1128 [(set_attr "type" "fcmp")])
1130 (define_insn "*cmpfp_2_df_1"
1131 [(set (match_operand:HI 0 "register_operand" "=a")
1134 (match_operand:DF 1 "register_operand" "f")
1135 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
1137 "* return output_fp_compare (insn, operands, 2, 0);"
1138 [(set_attr "type" "multi")])
1140 (define_insn "*cmpfp_2_xf"
1143 (match_operand:XF 0 "register_operand" "f")
1144 (match_operand:XF 1 "register_operand" "f")))]
1146 "* return output_fp_compare (insn, operands, 0, 0);"
1147 [(set_attr "type" "fcmp")])
1149 (define_insn "*cmpfp_2_xf_1"
1150 [(set (match_operand:HI 0 "register_operand" "=a")
1153 (match_operand:XF 1 "register_operand" "f")
1154 (match_operand:XF 2 "register_operand" "f"))] 9))]
1156 "* return output_fp_compare (insn, operands, 2, 0);"
1157 [(set_attr "type" "multi")])
1159 (define_insn "*cmpfp_2u"
1160 [(set (reg:CCFPU 18)
1162 (match_operand 0 "register_operand" "f")
1163 (match_operand 1 "register_operand" "f")))]
1165 && FLOAT_MODE_P (GET_MODE (operands[0]))
1166 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1167 "* return output_fp_compare (insn, operands, 0, 1);"
1168 [(set_attr "type" "fcmp")])
1170 (define_insn "*cmpfp_2u_1"
1171 [(set (match_operand:HI 0 "register_operand" "=a")
1174 (match_operand 1 "register_operand" "f")
1175 (match_operand 2 "register_operand" "f"))] 9))]
1177 && FLOAT_MODE_P (GET_MODE (operands[1]))
1178 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1179 "* return output_fp_compare (insn, operands, 2, 1);"
1180 [(set_attr "type" "multi")])
1182 ;; Patterns to match the SImode-in-memory ficom instructions.
1184 ;; %%% Play games with accepting gp registers, as otherwise we have to
1185 ;; force them to memory during rtl generation, which is no good. We
1186 ;; can get rid of this once we teach reload to do memory input reloads
1189 (define_insn "*ficom_1"
1192 (match_operand 0 "register_operand" "f,f")
1193 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1194 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1195 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1198 ;; Split the not-really-implemented gp register case into a
1199 ;; push-op-pop sequence.
1201 ;; %%% This is most efficient, but am I gonna get in trouble
1202 ;; for separating cc0_setter and cc0_user?
1207 (match_operand:SF 0 "register_operand" "")
1208 (float (match_operand:SI 1 "register_operand" ""))))]
1209 "0 && TARGET_80387 && reload_completed"
1210 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1211 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1212 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1213 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1214 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1215 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1217 ;; FP compares, step 2
1218 ;; Move the fpsw to ax.
1220 (define_insn "x86_fnstsw_1"
1221 [(set (match_operand:HI 0 "register_operand" "=a")
1222 (unspec:HI [(reg 18)] 9))]
1225 [(set_attr "length" "2")
1226 (set_attr "ppro_uops" "few")])
1228 ;; FP compares, step 3
1229 ;; Get ax into flags, general case.
1231 (define_insn "x86_sahf_1"
1233 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1236 [(set_attr "length" "1")
1237 (set_attr "ppro_uops" "one")])
1239 ;; Pentium Pro can do steps 1 through 3 in one go.
1241 (define_insn "*cmpfp_i"
1243 (compare:CCFP (match_operand 0 "register_operand" "f")
1244 (match_operand 1 "register_operand" "f")))]
1245 "TARGET_80387 && TARGET_CMOVE
1246 && FLOAT_MODE_P (GET_MODE (operands[0]))
1247 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1248 "* return output_fp_compare (insn, operands, 1, 0);"
1249 [(set_attr "type" "fcmp")
1250 (set_attr "athlon_decode" "vector")])
1252 (define_insn "*cmpfp_iu"
1253 [(set (reg:CCFPU 17)
1254 (compare:CCFPU (match_operand 0 "register_operand" "f")
1255 (match_operand 1 "register_operand" "f")))]
1256 "TARGET_80387 && TARGET_CMOVE
1257 && FLOAT_MODE_P (GET_MODE (operands[0]))
1258 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1259 "* return output_fp_compare (insn, operands, 1, 1);"
1260 [(set_attr "type" "fcmp")
1261 (set_attr "athlon_decode" "vector")])
1263 ;; Move instructions.
1265 ;; General case of fullword move.
1267 (define_expand "movsi"
1268 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1269 (match_operand:SI 1 "general_operand" ""))]
1271 "ix86_expand_move (SImode, operands); DONE;")
1273 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1276 ;; %%% We don't use a post-inc memory reference because x86 is not a
1277 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1278 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1279 ;; targets without our curiosities, and it is just as easy to represent
1280 ;; this differently.
1282 (define_insn "pushsi2"
1283 [(set (match_operand:SI 0 "push_operand" "=<")
1284 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1287 [(set_attr "type" "push")])
1289 (define_insn "popsi1"
1290 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1291 (mem:SI (reg:SI 7)))
1293 (plus:SI (reg:SI 7) (const_int 4)))]
1296 [(set_attr "type" "pop")])
1298 (define_insn "*movsi_xor"
1299 [(set (match_operand:SI 0 "register_operand" "=r")
1300 (match_operand:SI 1 "const0_operand" "i"))
1301 (clobber (reg:CC 17))]
1302 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1303 "xor{l}\\t{%0, %0|%0, %0}"
1304 [(set_attr "type" "alu1")
1305 (set_attr "length" "2")])
1307 (define_insn "*movsi_or"
1308 [(set (match_operand:SI 0 "register_operand" "=r")
1309 (match_operand:SI 1 "immediate_operand" "i"))
1310 (clobber (reg:CC 17))]
1311 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1312 && INTVAL (operands[1]) == -1
1313 && (TARGET_PENTIUM || optimize_size)"
1316 operands[1] = constm1_rtx;
1317 return \"or{l}\\t{%1, %0|%1, %0}\";
1319 [(set_attr "type" "alu1")
1320 (set_attr "length" "3")])
1322 (define_insn "*movsi_1"
1323 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
1324 (match_operand:SI 1 "general_operand" "rinm,rin"))]
1325 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1328 switch (get_attr_type (insn))
1331 return \"lea{l}\\t{%1, %0|%0, %1}\";
1333 if (flag_pic && SYMBOLIC_CONST (operands[1]))
1335 return \"mov{l}\\t{%1, %0|%0, %1}\";
1339 (cond [(and (ne (symbol_ref "flag_pic") (const_int 0))
1340 (match_operand:SI 1 "symbolic_operand" ""))
1341 (const_string "lea")
1343 (const_string "imov")))])
1345 (define_insn "*swapsi"
1346 [(set (match_operand:SI 0 "register_operand" "+r")
1347 (match_operand:SI 1 "register_operand" "+r"))
1352 [(set_attr "type" "imov")
1353 (set_attr "pent_pair" "np")
1354 (set_attr "ppro_uops" "few")])
1356 (define_expand "movhi"
1357 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1358 (match_operand:HI 1 "general_operand" ""))]
1360 "ix86_expand_move (HImode, operands); DONE;")
1362 (define_insn "pushhi2"
1363 [(set (match_operand:HI 0 "push_operand" "=<,<")
1364 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1367 push{w}\\t{|WORD PTR }%1
1369 [(set_attr "type" "push")])
1371 (define_insn "pophi1"
1372 [(set (match_operand:HI 0 "nonimmediate_operand" "=r*m")
1373 (mem:HI (reg:SI 7)))
1375 (plus:SI (reg:SI 7) (const_int 2)))]
1378 [(set_attr "type" "pop")])
1380 (define_insn "*movhi_1"
1381 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m")
1382 (match_operand:HI 1 "general_operand" "rn,rm,rn"))]
1383 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1386 switch (get_attr_type (insn))
1389 /* movzwl is faster than movw on p2 due to partial word stalls,
1390 though not as fast as an aligned movl. */
1391 return \"movz{wl|x}\\t{%1, %k0|%k0, %1}\";
1393 if (get_attr_length_prefix (insn) == 0)
1394 return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1396 return \"mov{w}\\t{%1, %0|%0, %1}\";
1400 (cond [(and (eq_attr "alternative" "0,1")
1401 (match_operand:HI 1 "aligned_operand" ""))
1402 (const_string "imov")
1403 (and (ne (symbol_ref "TARGET_MOVX")
1405 (eq_attr "alternative" "1"))
1406 (const_string "imovx")
1408 (const_string "imov")))
1409 (set (attr "length_prefix")
1410 (cond [(eq_attr "type" "imovx")
1412 (and (eq_attr "alternative" "0,1")
1413 (and (match_operand:HI 1 "aligned_operand" "")
1414 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1418 (const_string "1")))
1419 ; There's no place to override just the immediate length
1420 (set (attr "length")
1421 (cond [(and (eq_attr "type" "imov")
1422 (and (eq_attr "length_prefix" "0")
1423 (match_operand:HI 1 "immediate_operand" "")))
1426 (const_string "*")))])
1428 (define_insn "*swaphi_1"
1429 [(set (match_operand:HI 0 "register_operand" "+r")
1430 (match_operand:HI 1 "register_operand" "+r"))
1433 "TARGET_PARTIAL_REG_STALL"
1435 [(set_attr "type" "imov")
1436 (set_attr "pent_pair" "np")
1437 (set_attr "ppro_uops" "few")])
1439 (define_insn "*swaphi_2"
1440 [(set (match_operand:HI 0 "register_operand" "+r")
1441 (match_operand:HI 1 "register_operand" "+r"))
1444 "! TARGET_PARTIAL_REG_STALL"
1445 "xchg{l}\\t%k1, %k0"
1446 [(set_attr "type" "imov")
1447 (set_attr "length_prefix" "0")
1448 (set_attr "pent_pair" "np")
1449 (set_attr "ppro_uops" "few")])
1451 (define_expand "movstricthi"
1452 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1453 (match_operand:HI 1 "general_operand" ""))]
1454 "! TARGET_PARTIAL_REG_STALL"
1457 /* Don't generate memory->memory moves, go through a register */
1458 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1459 operands[1] = force_reg (HImode, operands[1]);
1462 (define_insn "*movstricthi_1"
1463 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1464 (match_operand:HI 1 "general_operand" "rn,m"))]
1465 "! TARGET_PARTIAL_REG_STALL
1466 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1467 "mov{w}\\t{%1, %0|%0, %1}"
1468 [(set_attr "type" "imov")])
1470 (define_expand "movqi"
1471 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1472 (match_operand:QI 1 "general_operand" ""))]
1474 "ix86_expand_move (QImode, operands); DONE;")
1476 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1477 ;; "push a byte". But actually we use pushw, which has the effect
1478 ;; of rounding the amount pushed up to a halfword.
1480 (define_insn "pushqi2"
1481 [(set (match_operand:QI 0 "push_operand" "=<,<")
1482 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1485 push{w}\\t{|word ptr }%1
1487 [(set_attr "type" "push")
1488 (set_attr "length_prefix" "1")
1489 ; There's no place to override just the immediate length
1490 (set (attr "length")
1491 (if_then_else (eq_attr "length_prefix" "0")
1493 (const_string "*")))])
1495 (define_insn "popqi1"
1496 [(set (match_operand:QI 0 "nonimmediate_operand" "=r*m")
1497 (mem:QI (reg:SI 7)))
1499 (plus:SI (reg:SI 7) (const_int 2)))]
1502 [(set_attr "type" "pop")
1503 (set_attr "length_prefix" "1")])
1505 (define_insn "*movqi_1"
1506 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q,r,?r,m")
1507 (match_operand:QI 1 "general_operand" "qn,qm,rn,qm,qn"))]
1508 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1511 switch (get_attr_type (insn))
1514 if (!QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1516 return \"movz{bl|x}\\t{%1, %k0|%k0, %1}\";
1518 if (which_alternative == 2)
1519 return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1521 return \"mov{b}\\t{%1, %0|%0, %1}\";
1525 (cond [(eq_attr "alternative" "3")
1526 (const_string "imovx")
1527 (and (ne (symbol_ref "TARGET_MOVX")
1529 (eq_attr "alternative" "1"))
1530 (const_string "imovx")
1532 (const_string "imov")))
1533 ; There's no place to override just the immediate length
1534 (set (attr "length")
1535 (cond [(and (eq_attr "type" "imov")
1536 (and (eq_attr "alternative" "2")
1537 (match_operand:HI 1 "immediate_operand" "")))
1540 (const_string "*")))])
1542 (define_expand "reload_outqi"
1543 [(parallel [(match_operand:QI 0 "" "=m")
1544 (match_operand:QI 1 "register_operand" "r")
1545 (match_operand:QI 2 "register_operand" "=&q")])]
1550 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1552 if (reg_overlap_mentioned_p (op2, op0))
1554 if (! q_regs_operand (op1, QImode))
1556 emit_insn (gen_movqi (op2, op1));
1559 emit_insn (gen_movqi (op0, op1));
1563 (define_insn "*swapqi"
1564 [(set (match_operand:QI 0 "register_operand" "+r")
1565 (match_operand:QI 1 "register_operand" "+r"))
1570 [(set_attr "type" "imov")
1571 (set_attr "pent_pair" "np")
1572 (set_attr "ppro_uops" "few")])
1574 (define_expand "movstrictqi"
1575 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1576 (match_operand:QI 1 "general_operand" ""))]
1577 "! TARGET_PARTIAL_REG_STALL"
1580 /* Don't generate memory->memory moves, go through a register */
1581 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1582 operands[1] = force_reg (QImode, operands[1]);
1585 (define_insn "*movstrictqi_1"
1586 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1587 (match_operand:QI 1 "general_operand" "*qn,m"))]
1588 "! TARGET_PARTIAL_REG_STALL
1589 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1590 "mov{b}\\t{%1, %0|%0, %1}"
1591 [(set_attr "type" "imov")])
1593 (define_insn "*movsi_extv_1"
1594 [(set (match_operand:SI 0 "register_operand" "=r")
1595 (sign_extract:SI (match_operand:SI 1 "register_operand" "q")
1599 "movs{bl|x}\\t{%h1, %0|%0, %h1}"
1600 [(set_attr "type" "imovx")])
1602 (define_insn "*movhi_extv_1"
1603 [(set (match_operand:HI 0 "register_operand" "=r")
1604 (sign_extract:HI (match_operand:SI 1 "register_operand" "q")
1608 "movs{bl|x}\\t{%h1, %k0|%k0, %h1}"
1609 [(set_attr "type" "imovx")])
1611 (define_insn "*movqi_extv_1"
1612 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
1613 (sign_extract:QI (match_operand:SI 1 "register_operand" "q,q")
1619 switch (get_attr_type (insn))
1622 return \"movs{bl|x}\\t{%h1, %k0|%k0, %h1}\";
1624 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
1628 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1629 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1630 (ne (symbol_ref "TARGET_MOVX")
1632 (const_string "imovx")
1633 (const_string "imov")))])
1635 (define_insn "*movsi_extzv_1"
1636 [(set (match_operand:SI 0 "register_operand" "=r")
1637 (zero_extract:SI (match_operand 1 "ext_register_operand" "q")
1641 "movz{bl|x}\\t{%h1, %0|%0, %h1}"
1642 [(set_attr "type" "imovx")])
1644 (define_insn "*movqi_extzv_1"
1645 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
1646 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "q,q")
1652 switch (get_attr_type (insn))
1655 return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\";
1657 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
1661 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1662 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1663 (ne (symbol_ref "TARGET_MOVX")
1665 (const_string "imovx")
1666 (const_string "imov")))])
1668 (define_insn "*movsi_insv_1"
1669 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
1672 (match_operand:SI 1 "nonimmediate_operand" "qm"))]
1674 "mov{b}\\t{%b1, %h0|%h0, %b1}"
1675 [(set_attr "type" "imov")])
1677 (define_insn "*movqi_insv_2"
1678 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
1681 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "q")
1685 "mov{b}\\t{%h1, %h0|%h0, %h1}"
1686 [(set_attr "type" "imov")])
1688 (define_expand "movdi"
1689 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1690 (match_operand:DI 1 "general_operand" ""))]
1692 "ix86_expand_move (DImode, operands); DONE;")
1694 (define_insn "*pushdi"
1695 [(set (match_operand:DI 0 "push_operand" "=<")
1696 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1700 (define_insn "*movdi_2"
1701 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
1702 (match_operand:DI 1 "general_operand" "riFo,riF"))]
1703 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1707 [(set (match_operand:DI 0 "push_operand" "")
1708 (match_operand:DI 1 "general_operand" ""))]
1711 "if (!ix86_split_long_move (operands)) abort (); DONE;")
1713 ;; %%% This multiword shite has got to go.
1715 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1716 (match_operand:DI 1 "general_operand" ""))]
1718 [(set (match_dup 2) (match_dup 5))
1719 (set (match_dup 3) (match_dup 6))]
1720 "if (ix86_split_long_move (operands)) DONE;")
1722 (define_expand "movsf"
1723 [(set (match_operand:SF 0 "nonimmediate_operand" "")
1724 (match_operand:SF 1 "general_operand" ""))]
1726 "ix86_expand_move (SFmode, operands); DONE;")
1728 (define_insn "*pushsf"
1729 [(set (match_operand:SF 0 "push_operand" "=<,<")
1730 (match_operand:SF 1 "general_no_elim_operand" "f#r,rFm#f"))]
1734 switch (which_alternative)
1737 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
1738 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
1739 operands[2] = stack_pointer_rtx;
1740 operands[3] = GEN_INT (4);
1741 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1742 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
1744 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
1747 return \"push{l}\\t%1\";
1753 [(set_attr "type" "multi,push")])
1756 [(set (match_operand:SF 0 "push_operand" "")
1757 (match_operand:SF 1 "memory_operand" ""))]
1759 && GET_CODE (operands[1]) == MEM
1760 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1761 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
1764 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
1767 ;; %%% Kill this when call knows how to work this out.
1769 [(set (match_operand:SF 0 "push_operand" "")
1770 (match_operand:SF 1 "register_operand" ""))]
1771 "FP_REGNO_P (REGNO (operands[1]))"
1772 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
1773 (set (mem:SF (reg:SI 7)) (match_dup 1))])
1775 (define_insn "*movsf_1"
1776 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,m")
1777 (match_operand:SF 1 "general_operand" "fm#r,f#r,G,rmF#f,Fr#f"))]
1778 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1779 && (reload_in_progress || reload_completed
1780 || GET_CODE (operands[1]) != CONST_DOUBLE
1781 || memory_operand (operands[0], SFmode))"
1784 switch (which_alternative)
1787 if (REG_P (operands[1])
1788 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1789 return \"fstp\\t%y0\";
1790 else if (STACK_TOP_P (operands[0]))
1791 return \"fld%z1\\t%y1\";
1793 return \"fst\\t%y0\";
1796 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1797 return \"fstp%z0\\t%y0\";
1799 return \"fst%z0\\t%y0\";
1802 switch (standard_80387_constant_p (operands[1]))
1813 return \"mov{l}\\t{%1, %0|%0, %1}\";
1819 [(set_attr "type" "fmov,fmov,fmov,imov,imov")])
1822 [(set (match_operand:SF 0 "nonimmediate_operand" "")
1823 (match_operand:SF 1 "memory_operand" ""))]
1825 && GET_CODE (operands[1]) == MEM
1826 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1827 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
1828 && (!(FP_REG_P (operands[0]) ||
1829 (GET_CODE (operands[0]) == SUBREG
1830 && FP_REG_P (SUBREG_REG (operands[0]))))
1831 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
1834 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
1836 (define_insn "swapsf"
1837 [(set (match_operand:SF 0 "register_operand" "+f")
1838 (match_operand:SF 1 "register_operand" "+f"))
1844 if (STACK_TOP_P (operands[0]))
1845 return \"fxch\\t%1\";
1847 return \"fxch\\t%0\";
1849 [(set_attr "type" "fxch")])
1851 (define_expand "movdf"
1852 [(set (match_operand:DF 0 "nonimmediate_operand" "")
1853 (match_operand:DF 1 "general_operand" ""))]
1855 "ix86_expand_move (DFmode, operands); DONE;")
1857 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
1858 ;; Size of pushdf using integer insturctions is 2+2*memory operand size
1859 ;; On the average, pushdf using integers can be still shorter. Allow this
1860 ;; pattern for optimize_size too.
1862 (define_insn "*pushdf"
1863 [(set (match_operand:DF 0 "push_operand" "=<,<")
1864 (match_operand:DF 1 "general_no_elim_operand" "f#r,rFo#f"))]
1868 switch (which_alternative)
1871 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
1872 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
1873 operands[2] = stack_pointer_rtx;
1874 operands[3] = GEN_INT (8);
1875 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1876 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
1878 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
1887 [(set_attr "type" "multi")])
1889 ;; %%% Kill this when call knows how to work this out.
1891 [(set (match_operand:DF 0 "push_operand" "")
1892 (match_operand:DF 1 "register_operand" ""))]
1893 "reload_completed && FP_REGNO_P (REGNO (operands[1]))"
1894 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1895 (set (mem:DF (reg:SI 7)) (match_dup 1))]
1899 [(set (match_operand:DF 0 "push_operand" "")
1900 (match_operand:DF 1 "general_operand" ""))]
1903 "if (!ix86_split_long_move (operands)) abort (); DONE;")
1905 ;; Moving is usually shorter when only FP registers are used. This separate
1906 ;; movdf pattern avoids the use of integer registers for FP operations
1907 ;; when optimizing for size.
1909 (define_insn "*movdf_nointeger"
1910 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,*r,o")
1911 (match_operand:DF 1 "general_operand" "fm,f,G,*roF,F*r"))]
1912 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1914 && (reload_in_progress || reload_completed
1915 || GET_CODE (operands[1]) != CONST_DOUBLE
1916 || memory_operand (operands[0], DFmode))"
1919 switch (which_alternative)
1922 if (REG_P (operands[1])
1923 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1924 return \"fstp\\t%y0\";
1925 else if (STACK_TOP_P (operands[0]))
1926 return \"fld%z1\\t%y1\";
1928 return \"fst\\t%y0\";
1931 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1932 return \"fstp%z0\\t%y0\";
1934 return \"fst%z0\\t%y0\";
1937 switch (standard_80387_constant_p (operands[1]))
1954 [(set_attr "type" "fmov,fmov,fmov,multi,multi")])
1956 (define_insn "*movdf_integer"
1957 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
1958 (match_operand:DF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
1959 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1961 && (reload_in_progress || reload_completed
1962 || GET_CODE (operands[1]) != CONST_DOUBLE
1963 || memory_operand (operands[0], DFmode))"
1966 switch (which_alternative)
1969 if (REG_P (operands[1])
1970 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1971 return \"fstp\\t%y0\";
1972 else if (STACK_TOP_P (operands[0]))
1973 return \"fld%z1\\t%y1\";
1975 return \"fst\\t%y0\";
1978 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1979 return \"fstp%z0\\t%y0\";
1981 return \"fst%z0\\t%y0\";
1984 switch (standard_80387_constant_p (operands[1]))
2001 [(set_attr "type" "fmov,fmov,fmov,multi,multi")])
2004 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2005 (match_operand:DF 1 "general_operand" ""))]
2007 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2008 && ! (FP_REG_P (operands[0]) ||
2009 (GET_CODE (operands[0]) == SUBREG
2010 && FP_REG_P (SUBREG_REG (operands[0]))))
2011 && ! (FP_REG_P (operands[1]) ||
2012 (GET_CODE (operands[1]) == SUBREG
2013 && FP_REG_P (SUBREG_REG (operands[1]))))"
2014 [(set (match_dup 2) (match_dup 5))
2015 (set (match_dup 3) (match_dup 6))]
2016 "if (ix86_split_long_move (operands)) DONE;")
2019 [(set (match_operand:DF 0 "register_operand" "")
2020 (match_operand:DF 1 "memory_operand" ""))]
2022 && GET_CODE (operands[1]) == MEM
2023 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2024 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2025 && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
2028 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2030 (define_insn "swapdf"
2031 [(set (match_operand:DF 0 "register_operand" "+f")
2032 (match_operand:DF 1 "register_operand" "+f"))
2038 if (STACK_TOP_P (operands[0]))
2039 return \"fxch\\t%1\";
2041 return \"fxch\\t%0\";
2043 [(set_attr "type" "fxch")])
2045 (define_expand "movxf"
2046 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2047 (match_operand:XF 1 "general_operand" ""))]
2049 "ix86_expand_move (XFmode, operands); DONE;")
2051 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2052 ;; Size of pushdf using integer insturctions is 3+3*memory operand size
2053 ;; Pushing using integer instructions is longer except for constants
2054 ;; and direct memory references.
2055 ;; (assuming that any given constant is pushed only once, but this ought to be
2056 ;; handled elsewhere).
2058 (define_insn "*pushxf_nointeger"
2059 [(set (match_operand:XF 0 "push_operand" "=<,<,<")
2060 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2064 switch (which_alternative)
2067 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2068 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2069 operands[2] = stack_pointer_rtx;
2070 operands[3] = GEN_INT (12);
2071 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2072 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2074 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2084 [(set_attr "type" "multi")])
2086 (define_insn "*pushxf_integer"
2087 [(set (match_operand:XF 0 "push_operand" "=<,<")
2088 (match_operand:XF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2092 switch (which_alternative)
2095 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2096 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2097 operands[2] = stack_pointer_rtx;
2098 operands[3] = GEN_INT (12);
2099 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2100 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2102 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2111 [(set_attr "type" "multi")])
2114 [(set (match_operand:XF 0 "push_operand" "")
2115 (match_operand:XF 1 "general_operand" ""))]
2117 && (!REG_P (operands[1]) || !FP_REGNO_P (REGNO (operands[1])))"
2119 "if (!ix86_split_long_move (operands)) abort (); DONE;")
2122 [(set (match_operand:XF 0 "push_operand" "")
2123 (match_operand:XF 1 "register_operand" ""))]
2124 "FP_REGNO_P (REGNO (operands[1]))"
2125 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2126 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2128 ;; Do not use integer registers when optimizing for size
2129 (define_insn "*movxf_nointeger"
2130 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2131 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2132 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2134 && (reload_in_progress || reload_completed
2135 || GET_CODE (operands[1]) != CONST_DOUBLE
2136 || memory_operand (operands[0], XFmode))"
2139 switch (which_alternative)
2142 if (REG_P (operands[1])
2143 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2144 return \"fstp\\t%y0\";
2145 else if (STACK_TOP_P (operands[0]))
2146 return \"fld%z1\\t%y1\";
2148 return \"fst\\t%y0\";
2151 /* There is no non-popping store to memory for XFmode. So if
2152 we need one, follow the store with a load. */
2153 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2154 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2156 return \"fstp%z0\\t%y0\";
2159 switch (standard_80387_constant_p (operands[1]))
2173 [(set_attr "type" "fmov,fmov,fmov,multi,multi")])
2175 (define_insn "*movxf_integer"
2176 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2177 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2178 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2180 && (reload_in_progress || reload_completed
2181 || GET_CODE (operands[1]) != CONST_DOUBLE
2182 || memory_operand (operands[0], XFmode))"
2185 switch (which_alternative)
2188 if (REG_P (operands[1])
2189 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2190 return \"fstp\\t%y0\";
2191 else if (STACK_TOP_P (operands[0]))
2192 return \"fld%z1\\t%y1\";
2194 return \"fst\\t%y0\";
2197 /* There is no non-popping store to memory for XFmode. So if
2198 we need one, follow the store with a load. */
2199 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2200 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2202 return \"fstp%z0\\t%y0\";
2205 switch (standard_80387_constant_p (operands[1]))
2219 [(set_attr "type" "fmov,fmov,fmov,multi,multi")])
2222 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2223 (match_operand:XF 1 "general_operand" ""))]
2225 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2226 && ! (FP_REG_P (operands[0]) ||
2227 (GET_CODE (operands[0]) == SUBREG
2228 && FP_REG_P (SUBREG_REG (operands[0]))))
2229 && ! (FP_REG_P (operands[1]) ||
2230 (GET_CODE (operands[1]) == SUBREG
2231 && FP_REG_P (SUBREG_REG (operands[1]))))"
2232 [(set (match_dup 2) (match_dup 5))
2233 (set (match_dup 3) (match_dup 6))
2234 (set (match_dup 4) (match_dup 7))]
2235 "if (ix86_split_long_move (operands)) DONE;")
2238 [(set (match_operand:XF 0 "register_operand" "")
2239 (match_operand:XF 1 "memory_operand" ""))]
2241 && GET_CODE (operands[1]) == MEM
2242 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2243 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2244 && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
2247 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2249 (define_insn "swapxf"
2250 [(set (match_operand:XF 0 "register_operand" "+f")
2251 (match_operand:XF 1 "register_operand" "+f"))
2257 if (STACK_TOP_P (operands[0]))
2258 return \"fxch\\t%1\";
2260 return \"fxch\\t%0\";
2262 [(set_attr "type" "fxch")])
2264 ;; Zero extension instructions
2266 (define_expand "zero_extendhisi2"
2267 [(set (match_operand:SI 0 "register_operand" "")
2268 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2272 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2274 operands[1] = force_reg (HImode, operands[1]);
2275 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2280 (define_insn "zero_extendhisi2_and"
2281 [(set (match_operand:SI 0 "register_operand" "=r")
2282 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2283 (clobber (reg:CC 17))]
2284 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2286 [(set_attr "type" "alu1")])
2289 [(set (match_operand:SI 0 "register_operand" "")
2290 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2291 (clobber (reg:CC 17))]
2292 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2293 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2294 (clobber (reg:CC 17))])]
2297 (define_insn "*zero_extendhisi2_movzwl"
2298 [(set (match_operand:SI 0 "register_operand" "=r")
2299 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2300 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2301 "movz{wl|x}\\t{%1, %0|%0, %1}"
2302 [(set_attr "type" "imovx")])
2304 (define_expand "zero_extendqihi2"
2306 [(set (match_operand:HI 0 "register_operand" "")
2307 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2308 (clobber (reg:CC 17))])]
2312 (define_insn "*zero_extendqihi2_and"
2313 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2314 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2315 (clobber (reg:CC 17))]
2316 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2318 [(set_attr "type" "alu1")])
2320 (define_insn "*zero_extendqihi2_movzbw_and"
2321 [(set (match_operand:HI 0 "register_operand" "=r,r")
2322 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2323 (clobber (reg:CC 17))]
2324 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2326 [(set_attr "type" "imovx,alu1")])
2328 (define_insn "*zero_extendqihi2_movzbw"
2329 [(set (match_operand:HI 0 "register_operand" "=r")
2330 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2331 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2332 "movz{bw|x}\\t{%1, %0|%0, %1}"
2333 [(set_attr "type" "imovx")])
2335 ;; For the movzbw case strip only the clobber
2337 [(set (match_operand:HI 0 "register_operand" "")
2338 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2339 (clobber (reg:CC 17))]
2341 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2342 && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
2343 [(set (match_operand:HI 0 "register_operand" "")
2344 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2346 ;; When source and destination does not overlap, clear destination
2347 ;; first and then do the movb
2349 [(set (match_operand:HI 0 "register_operand" "")
2350 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2351 (clobber (reg:CC 17))]
2353 && QI_REG_P (operands[0])
2354 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2355 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2356 [(set (match_dup 0) (const_int 0))
2357 (set (strict_low_part (match_dup 2)) (match_dup 1))]
2358 "operands[2] = gen_lowpart (QImode, operands[0]);")
2360 ;; Rest is handled by single and.
2362 [(set (match_operand:HI 0 "register_operand" "")
2363 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2364 (clobber (reg:CC 17))]
2366 && true_regnum (operands[0]) == true_regnum (operands[1])"
2367 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2368 (clobber (reg:CC 17))])]
2371 (define_expand "zero_extendqisi2"
2373 [(set (match_operand:SI 0 "register_operand" "")
2374 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2375 (clobber (reg:CC 17))])]
2379 (define_insn "*zero_extendqisi2_and"
2380 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2381 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2382 (clobber (reg:CC 17))]
2383 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2385 [(set_attr "type" "alu1")])
2387 (define_insn "*zero_extendqisi2_movzbw_and"
2388 [(set (match_operand:SI 0 "register_operand" "=r,r")
2389 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2390 (clobber (reg:CC 17))]
2391 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2393 [(set_attr "type" "imovx,alu1")])
2395 (define_insn "*zero_extendqisi2_movzbw"
2396 [(set (match_operand:SI 0 "register_operand" "=r")
2397 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2398 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2399 "movz{bl|x}\\t{%1, %0|%0, %1}"
2400 [(set_attr "type" "imovx")])
2402 ;; For the movzbl case strip only the clobber
2404 [(set (match_operand:SI 0 "register_operand" "")
2405 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2406 (clobber (reg:CC 17))]
2408 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2409 && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
2411 (zero_extend:SI (match_dup 1)))])
2413 ;; When source and destination does not overlap, clear destination
2414 ;; first and then do the movb
2416 [(set (match_operand:SI 0 "register_operand" "")
2417 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2418 (clobber (reg:CC 17))]
2420 && QI_REG_P (operands[0])
2421 && (QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
2422 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2423 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2424 [(set (match_dup 0) (const_int 0))
2425 (set (strict_low_part (match_dup 2)) (match_dup 1))]
2426 "operands[2] = gen_lowpart (QImode, operands[0]);")
2428 ;; Rest is handled by single and.
2430 [(set (match_operand:SI 0 "register_operand" "")
2431 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
2432 (clobber (reg:CC 17))]
2434 && true_regnum (operands[0]) == true_regnum (operands[1])"
2435 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
2436 (clobber (reg:CC 17))])]
2439 ;; %%% Kill me once multi-word ops are sane.
2440 (define_insn "zero_extendsidi2"
2441 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
2442 (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))
2443 (clobber (reg:CC 17))]
2448 [(set (match_operand:DI 0 "register_operand" "")
2449 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
2450 (clobber (reg:CC 17))]
2451 "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
2452 [(set (match_dup 4) (const_int 0))]
2453 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2456 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2457 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
2458 (clobber (reg:CC 17))]
2460 [(set (match_dup 3) (match_dup 1))
2461 (set (match_dup 4) (const_int 0))]
2462 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2464 ;; Sign extension instructions
2466 (define_insn "extendsidi2"
2467 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
2468 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
2469 (clobber (match_scratch:SI 2 "=X,X,X,&r"))
2470 (clobber (reg:CC 17))]
2474 ;; Extend to memory case when source register does die.
2476 [(set (match_operand:DI 0 "memory_operand" "")
2477 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2478 (clobber (match_operand:SI 2 "register_operand" ""))
2479 (clobber (reg:CC 17))]
2481 && dead_or_set_p (insn, operands[1])
2482 && !reg_mentioned_p (operands[1], operands[0]))"
2483 [(set (match_dup 3) (match_dup 1))
2484 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
2485 (clobber (reg:CC 17))])
2486 (set (match_dup 4) (match_dup 1))]
2487 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2489 ;; Extend to memory case when source register does not die.
2491 [(set (match_operand:DI 0 "memory_operand" "")
2492 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2493 (clobber (match_operand:SI 2 "register_operand" ""))
2494 (clobber (reg:CC 17))]
2499 split_di (&operands[0], 1, &operands[3], &operands[4]);
2501 emit_move_insn (operands[3], operands[1]);
2503 /* Generate a cltd if possible and doing so it profitable. */
2504 if (true_regnum (operands[1]) == 0
2505 && true_regnum (operands[2]) == 1
2506 && (optimize_size || TARGET_USE_CLTD))
2508 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
2512 emit_move_insn (operands[2], operands[1]);
2513 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
2515 emit_move_insn (operands[4], operands[2]);
2519 ;; Extend to register case. Optimize case where source and destination
2520 ;; registers match and cases where we can use cltd.
2522 [(set (match_operand:DI 0 "register_operand" "")
2523 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2524 (clobber (match_scratch:SI 2 ""))
2525 (clobber (reg:CC 17))]
2530 split_di (&operands[0], 1, &operands[3], &operands[4]);
2532 if (true_regnum (operands[3]) != true_regnum (operands[1]))
2533 emit_move_insn (operands[3], operands[1]);
2535 /* Generate a cltd if possible and doing so it profitable. */
2536 if (true_regnum (operands[3]) == 0
2537 && (optimize_size || TARGET_USE_CLTD))
2539 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
2543 if (true_regnum (operands[4]) != true_regnum (operands[1]))
2544 emit_move_insn (operands[4], operands[1]);
2546 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
2550 (define_insn "extendhisi2"
2551 [(set (match_operand:SI 0 "register_operand" "=*a,r")
2552 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
2556 switch (get_attr_length (insn))
2559 return \"{cwtl|cwde}\";
2561 return \"movs{wl|x}\\t{%1,%0|%0, %1}\";
2564 [(set_attr "type" "imovx")
2565 (set (attr "length")
2566 ;; movsx is short decodable while cwtl is vector decoded.
2567 (cond [(and (eq_attr "cpu" "!k6")
2568 (eq_attr "alternative" "0"))
2571 (const_string "*")))])
2573 (define_insn "extendqihi2"
2574 [(set (match_operand:HI 0 "register_operand" "=*a,r")
2575 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
2579 switch (get_attr_length (insn))
2582 return \"{cbtw|cbw}\";
2584 return \"movs{bw|x}\\t{%1,%0|%0, %1}\";
2587 [(set_attr "type" "imovx")
2588 (set (attr "length")
2589 ;; movsx is short decodable while cwtl is vector decoded.
2590 (cond [(and (eq_attr "cpu" "!k6")
2591 (eq_attr "alternative" "0"))
2594 (const_string "*")))])
2596 (define_insn "extendqisi2"
2597 [(set (match_operand:SI 0 "register_operand" "=r")
2598 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2600 "movs{bl|x}\\t{%1,%0|%0, %1}"
2601 [(set_attr "type" "imovx")])
2603 ;; Conversions between float and double.
2605 ;; These are all no-ops in the model used for the 80387. So just
2608 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
2609 (define_insn "*dummy_extendsfdf2"
2610 [(set (match_operand:DF 0 "push_operand" "=<")
2611 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f")))]
2616 [(set (match_operand:DF 0 "push_operand" "")
2617 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
2618 "FP_REGNO_P (REGNO (operands[1]))"
2619 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2620 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
2622 (define_insn "*dummy_extendsfxf2"
2623 [(set (match_operand:XF 0 "push_operand" "=<")
2624 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
2629 [(set (match_operand:XF 0 "push_operand" "")
2630 (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
2631 "FP_REGNO_P (REGNO (operands[1]))"
2632 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2633 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
2635 (define_insn "*dummy_extenddfxf2"
2636 [(set (match_operand:XF 0 "push_operand" "=<")
2637 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
2642 [(set (match_operand:XF 0 "push_operand" "")
2643 (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
2644 "FP_REGNO_P (REGNO (operands[1]))"
2645 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2646 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
2648 (define_expand "extendsfdf2"
2649 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2650 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
2654 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2655 operands[1] = force_reg (SFmode, operands[1]);
2658 (define_insn "*extendsfdf2_1"
2659 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
2660 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2662 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2665 switch (which_alternative)
2668 if (REG_P (operands[1])
2669 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2670 return \"fstp\\t%y0\";
2671 else if (STACK_TOP_P (operands[0]))
2672 return \"fld%z1\\t%y1\";
2674 return \"fst\\t%y0\";
2677 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2678 return \"fstp%z0\\t%y0\";
2681 return \"fst%z0\\t%y0\";
2687 [(set_attr "type" "fmov")])
2689 (define_expand "extendsfxf2"
2690 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2691 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
2695 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2696 operands[1] = force_reg (SFmode, operands[1]);
2699 (define_insn "*extendsfxf2_1"
2700 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
2701 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2703 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2706 switch (which_alternative)
2709 if (REG_P (operands[1])
2710 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2711 return \"fstp\\t%y0\";
2712 else if (STACK_TOP_P (operands[0]))
2713 return \"fld%z1\\t%y1\";
2715 return \"fst\\t%y0\";
2718 /* There is no non-popping store to memory for XFmode. So if
2719 we need one, follow the store with a load. */
2720 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2721 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
2723 return \"fstp%z0\\t%y0\";
2729 [(set_attr "type" "fmov")])
2731 (define_expand "extenddfxf2"
2732 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2733 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
2737 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2738 operands[1] = force_reg (DFmode, operands[1]);
2741 (define_insn "*extenddfxf2_1"
2742 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
2743 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
2745 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2748 switch (which_alternative)
2751 if (REG_P (operands[1])
2752 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2753 return \"fstp\\t%y0\";
2754 else if (STACK_TOP_P (operands[0]))
2755 return \"fld%z1\\t%y1\";
2757 return \"fst\\t%y0\";
2760 /* There is no non-popping store to memory for XFmode. So if
2761 we need one, follow the store with a load. */
2762 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2763 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
2765 return \"fstp%z0\\t%y0\";
2771 [(set_attr "type" "fmov")])
2773 ;; %%% This seems bad bad news.
2774 ;; This cannot output into an f-reg because there is no way to be sure
2775 ;; of truncating in that case. Otherwise this is just like a simple move
2776 ;; insn. So we pretend we can output to a reg in order to get better
2777 ;; register preferencing, but we really use a stack slot.
2779 (define_expand "truncdfsf2"
2780 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2782 (match_operand:DF 1 "register_operand" "")))
2783 (clobber (match_dup 2))])]
2785 "operands[2] = assign_386_stack_local (SFmode, 0);")
2787 (define_insn "*truncdfsf2_1"
2788 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
2790 (match_operand:DF 1 "register_operand" "f,0")))
2791 (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
2795 switch (which_alternative)
2798 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2799 return \"fstp%z0\\t%y0\";
2801 return \"fst%z0\\t%y0\";
2803 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
2807 [(set_attr "type" "fmov,multi")])
2809 (define_insn "*truncdfsf2_2"
2810 [(set (match_operand:SF 0 "memory_operand" "=m")
2812 (match_operand:DF 1 "register_operand" "f")))]
2816 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2817 return \"fstp%z0\\t%y0\";
2819 return \"fst%z0\\t%y0\";
2821 [(set_attr "type" "fmov")])
2824 [(set (match_operand:SF 0 "memory_operand" "")
2826 (match_operand:DF 1 "register_operand" "")))
2827 (clobber (match_operand:SF 2 "memory_operand" ""))]
2829 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
2833 [(set (match_operand:SF 0 "register_operand" "")
2835 (match_operand:DF 1 "register_operand" "")))
2836 (clobber (match_operand:SF 2 "memory_operand" ""))]
2837 "TARGET_80387 && reload_completed"
2838 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
2839 (set (match_dup 0) (match_dup 2))]
2842 (define_expand "truncxfsf2"
2843 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2845 (match_operand:XF 1 "register_operand" "")))
2846 (clobber (match_dup 2))])]
2848 "operands[2] = assign_386_stack_local (SFmode, 0);")
2850 (define_insn "*truncxfsf2_1"
2851 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
2853 (match_operand:XF 1 "register_operand" "f,0")))
2854 (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
2858 switch (which_alternative)
2861 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2862 return \"fstp%z0\\t%y0\";
2864 return \"fst%z0\\t%y0\";
2866 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
2870 [(set_attr "type" "fmov,multi")])
2872 (define_insn "*truncxfsf2_2"
2873 [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
2875 (match_operand:XF 1 "register_operand" "f")))]
2879 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2880 return \"fstp%z0\\t%y0\";
2882 return \"fst%z0\\t%y0\";
2884 [(set_attr "type" "fmov")])
2887 [(set (match_operand:SF 0 "memory_operand" "")
2889 (match_operand:XF 1 "register_operand" "")))
2890 (clobber (match_operand:SF 2 "memory_operand" ""))]
2892 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
2896 [(set (match_operand:SF 0 "register_operand" "")
2898 (match_operand:XF 1 "register_operand" "")))
2899 (clobber (match_operand:SF 2 "memory_operand" ""))]
2900 "TARGET_80387 && reload_completed"
2901 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
2902 (set (match_dup 0) (match_dup 2))]
2905 (define_expand "truncxfdf2"
2906 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2908 (match_operand:XF 1 "register_operand" "")))
2909 (clobber (match_dup 2))])]
2911 "operands[2] = assign_386_stack_local (DFmode, 0);")
2913 (define_insn "*truncxfdf2_1"
2914 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
2916 (match_operand:XF 1 "register_operand" "f,0")))
2917 (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
2921 switch (which_alternative)
2924 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2925 return \"fstp%z0\\t%y0\";
2927 return \"fst%z0\\t%y0\";
2929 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
2933 [(set_attr "type" "fmov,multi")])
2935 (define_insn "*truncxfdf2_2"
2936 [(set (match_operand:DF 0 "memory_operand" "=m")
2938 (match_operand:XF 1 "register_operand" "f")))]
2942 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2943 return \"fstp%z0\\t%y0\";
2945 return \"fst%z0\\t%y0\";
2947 [(set_attr "type" "fmov")])
2950 [(set (match_operand:DF 0 "memory_operand" "")
2952 (match_operand:XF 1 "register_operand" "")))
2953 (clobber (match_operand:DF 2 "memory_operand" ""))]
2955 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
2959 [(set (match_operand:DF 0 "register_operand" "")
2961 (match_operand:XF 1 "register_operand" "")))
2962 (clobber (match_operand:DF 2 "memory_operand" ""))]
2963 "TARGET_80387 && reload_completed"
2964 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
2965 (set (match_dup 0) (match_dup 2))]
2969 ;; %%% Break up all these bad boys.
2971 ;; Signed conversion to DImode.
2973 (define_expand "fix_truncxfdi2"
2974 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2975 (fix:DI (match_operand:XF 1 "register_operand" "")))
2976 (clobber (match_dup 2))
2977 (clobber (match_dup 3))
2978 (clobber (match_scratch:SI 4 ""))
2979 (clobber (match_scratch:XF 5 ""))])]
2981 "operands[2] = assign_386_stack_local (SImode, 0);
2982 operands[3] = assign_386_stack_local (DImode, 1);")
2984 (define_expand "fix_truncdfdi2"
2985 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2986 (fix:DI (match_operand:DF 1 "register_operand" "")))
2987 (clobber (match_dup 2))
2988 (clobber (match_dup 3))
2989 (clobber (match_scratch:SI 4 ""))
2990 (clobber (match_scratch:DF 5 ""))])]
2992 "operands[2] = assign_386_stack_local (SImode, 0);
2993 operands[3] = assign_386_stack_local (DImode, 1);")
2995 (define_expand "fix_truncsfdi2"
2996 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2997 (fix:DI (match_operand:SF 1 "register_operand" "")))
2998 (clobber (match_dup 2))
2999 (clobber (match_dup 3))
3000 (clobber (match_scratch:SI 4 ""))
3001 (clobber (match_scratch:SF 5 ""))])]
3003 "operands[2] = assign_386_stack_local (SImode, 0);
3004 operands[3] = assign_386_stack_local (DImode, 1);")
3006 (define_insn "*fix_truncdi_1"
3007 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
3008 (fix:DI (match_operand 1 "register_operand" "f,f")))
3009 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3010 (clobber (match_operand:DI 3 "memory_operand" "=m,m"))
3011 (clobber (match_scratch:SI 4 "=&r,&r"))
3012 (clobber (match_scratch 5 "=&f,&f"))]
3013 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3014 "* return output_fix_trunc (insn, operands);"
3015 [(set_attr "type" "multi")])
3018 [(set (match_operand:DI 0 "register_operand" "")
3019 (fix:DI (match_operand 1 "register_operand" "")))
3020 (clobber (match_operand:SI 2 "memory_operand" ""))
3021 (clobber (match_operand:DI 3 "memory_operand" ""))
3022 (clobber (match_scratch:SI 4 ""))
3023 (clobber (match_scratch 5 ""))]
3024 "reload_completed && !reg_overlap_mentioned_p (operands[4], operands[3])"
3025 [(parallel [(set (match_dup 3) (fix:DI (match_dup 1)))
3026 (clobber (match_dup 2))
3027 (clobber (match_dup 3))
3028 (clobber (match_dup 4))
3029 (clobber (match_dup 5))])
3030 (set (match_dup 0) (match_dup 3))]
3033 ;; Signed conversion to SImode.
3035 (define_expand "fix_truncxfsi2"
3036 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3037 (fix:SI (match_operand:XF 1 "register_operand" "")))
3038 (clobber (match_dup 2))
3039 (clobber (match_dup 3))
3040 (clobber (match_scratch:SI 4 ""))])]
3042 "operands[2] = assign_386_stack_local (SImode, 0);
3043 operands[3] = assign_386_stack_local (SImode, 1);")
3045 (define_expand "fix_truncdfsi2"
3046 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3047 (fix:SI (match_operand:DF 1 "register_operand" "")))
3048 (clobber (match_dup 2))
3049 (clobber (match_dup 3))
3050 (clobber (match_scratch:SI 4 ""))])]
3052 "operands[2] = assign_386_stack_local (SImode, 0);
3053 operands[3] = assign_386_stack_local (SImode, 1);")
3055 (define_expand "fix_truncsfsi2"
3056 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3057 (fix:SI (match_operand:SF 1 "register_operand" "")))
3058 (clobber (match_dup 2))
3059 (clobber (match_dup 3))
3060 (clobber (match_scratch:SI 4 ""))])]
3062 "operands[2] = assign_386_stack_local (SImode, 0);
3063 operands[3] = assign_386_stack_local (SImode, 1);")
3065 (define_insn "*fix_truncsi_1"
3066 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
3067 (fix:SI (match_operand 1 "register_operand" "f,f")))
3068 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
3069 (clobber (match_operand:SI 3 "memory_operand" "=m,m"))
3070 (clobber (match_scratch:SI 4 "=&r,r"))]
3071 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
3072 "* return output_fix_trunc (insn, operands);"
3073 [(set_attr "type" "multi")])
3076 [(set (match_operand:SI 0 "register_operand" "")
3077 (fix:SI (match_operand 1 "register_operand" "")))
3078 (clobber (match_operand:SI 2 "memory_operand" ""))
3079 (clobber (match_operand:SI 3 "memory_operand" ""))
3080 (clobber (match_scratch:SI 4 ""))]
3082 [(parallel [(set (match_dup 3) (fix:SI (match_dup 1)))
3083 (clobber (match_dup 2))
3084 (clobber (match_dup 3))
3085 (clobber (match_dup 4))])
3086 (set (match_dup 0) (match_dup 3))]
3090 (define_insn "x86_fnstcw_1"
3091 [(set (match_operand:HI 0 "memory_operand" "=m")
3092 (unspec:HI [(reg:HI 18)] 11))]
3095 [(set_attr "length_opcode" "2")
3096 (set_attr "ppro_uops" "few")])
3098 (define_insn "x86_fldcw_1"
3100 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
3103 [(set_attr "length_opcode" "2")
3104 (set_attr "ppro_uops" "few")])
3106 ;; Conversion between fixed point and floating point.
3108 ;; Even though we only accept memory inputs, the backend _really_
3109 ;; wants to be able to do this between registers.
3111 (define_insn "floatsisf2"
3112 [(set (match_operand:SF 0 "register_operand" "=f,f")
3113 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
3118 [(set_attr "type" "fmov,multi")
3119 (set_attr "fp_int_src" "true")])
3121 (define_insn "floatdisf2"
3122 [(set (match_operand:SF 0 "register_operand" "=f,f")
3123 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
3128 [(set_attr "type" "fmov,multi")
3129 (set_attr "fp_int_src" "true")])
3131 (define_insn "floatsidf2"
3132 [(set (match_operand:DF 0 "register_operand" "=f,f")
3133 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
3138 [(set_attr "type" "fmov,multi")
3139 (set_attr "fp_int_src" "true")])
3141 (define_insn "floatdidf2"
3142 [(set (match_operand:DF 0 "register_operand" "=f,f")
3143 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
3148 [(set_attr "type" "fmov,multi")
3149 (set_attr "fp_int_src" "true")])
3151 (define_insn "floatsixf2"
3152 [(set (match_operand:XF 0 "register_operand" "=f,f")
3153 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
3158 [(set_attr "type" "fmov,multi")
3159 (set_attr "fp_int_src" "true")])
3161 (define_insn "floatdixf2"
3162 [(set (match_operand:XF 0 "register_operand" "=f,f")
3163 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
3168 [(set_attr "type" "fmov,multi")
3169 (set_attr "fp_int_src" "true")])
3171 ;; %%% Kill these when reload knows how to do it.
3173 [(set (match_operand 0 "register_operand" "")
3174 (float (match_operand:SI 1 "register_operand" "")))]
3175 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
3176 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
3177 (set (match_dup 0) (match_dup 2))
3178 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
3179 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
3180 "operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]),
3181 gen_rtx_MEM (SImode, stack_pointer_rtx));")
3184 [(set (match_operand 0 "register_operand" "")
3185 (float (match_operand:DI 1 "nonmemory_operand" "")))]
3186 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
3187 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 2))
3188 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
3189 (set (match_dup 0) (match_dup 3))
3190 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
3191 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
3192 (parallel [(set (match_dup 2) (mem:SI (reg:SI 7)))
3193 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
3194 "split_di (operands+1, 1, operands+1, operands+2);
3195 operands[3] = gen_rtx_FLOAT (GET_MODE (operands[0]),
3196 gen_rtx_MEM (DImode, stack_pointer_rtx));")
3200 ;; %%% define_expand from the very first?
3201 ;; %%% splits for addsidi3
3202 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
3203 ; (plus:DI (match_operand:DI 1 "general_operand" "")
3204 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
3206 (define_insn "adddi3"
3207 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3208 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
3209 (match_operand:DI 2 "general_operand" "roiF,riF")))
3210 (clobber (reg:CC 17))]
3215 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3216 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
3217 (match_operand:DI 2 "general_operand" "")))
3218 (clobber (reg:CC 17))]
3220 [(parallel [(set (reg:CC 17) (plus:CC (match_dup 1) (match_dup 2)))
3221 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
3222 (parallel [(set (match_dup 3)
3223 (plus:SI (match_dup 4)
3224 (plus:SI (match_dup 5)
3225 (ltu:SI (reg:CC 17) (const_int 0)))))
3226 (clobber (reg:CC 17))])]
3227 "split_di (operands+0, 1, operands+0, operands+3);
3228 split_di (operands+1, 1, operands+1, operands+4);
3229 split_di (operands+2, 1, operands+2, operands+5);")
3231 (define_insn "*addsi3_cc"
3232 [(set (reg:CC 17) (plus:CC (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3233 (match_operand:SI 2 "general_operand" "ri,rm")))
3234 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3235 (plus:SI (match_dup 1) (match_dup 2)))]
3236 "ix86_binary_operator_ok (PLUS, SImode, operands)"
3237 "add{l}\\t{%2, %0|%0, %2}"
3238 [(set_attr "type" "alu")])
3240 (define_insn "addqi3_cc"
3241 [(set (reg:CC 17) (plus:CC (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3242 (match_operand:QI 2 "general_operand" "qi,qm")))
3243 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3244 (plus:QI (match_dup 1) (match_dup 2)))]
3245 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3246 "add{b}\\t{%2, %0|%0, %2}"
3247 [(set_attr "type" "alu")])
3249 (define_insn "*addsi3_carry"
3250 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3251 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3252 (plus:SI (match_operand:SI 2 "general_operand" "ri,rm")
3253 (ltu:SI (reg:CC 17) (const_int 0)))))
3254 (clobber (reg:CC 17))]
3255 "ix86_binary_operator_ok (PLUS, SImode, operands)"
3256 "adc{l}\\t{%2, %0|%0, %2}"
3257 [(set_attr "type" "alu")
3258 (set_attr "pent_pair" "pu")
3259 (set_attr "ppro_uops" "few")])
3261 (define_expand "addsi3"
3262 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3263 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3264 (match_operand:SI 2 "general_operand" "")))
3265 (clobber (reg:CC 17))])]
3267 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
3269 (define_insn "*lea_0"
3270 [(set (match_operand:SI 0 "register_operand" "=r")
3271 (match_operand:SI 1 "address_operand" "p"))]
3273 "lea{l}\\t{%a1, %0|%0, %a1}"
3274 [(set_attr "type" "lea")])
3276 (define_insn "*addsi_1"
3277 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
3278 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
3279 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
3280 (clobber (reg:CC 17))]
3281 "ix86_binary_operator_ok (PLUS, SImode, operands)"
3284 switch (get_attr_type (insn))
3287 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
3288 return \"lea{l}\\t{%a2, %0|%0, %a2}\";
3291 if (! rtx_equal_p (operands[0], operands[1]))
3293 if (operands[2] == const1_rtx)
3294 return \"inc{l}\\t%0\";
3295 else if (operands[2] == constm1_rtx)
3296 return \"dec{l}\\t%0\";
3301 if (! rtx_equal_p (operands[0], operands[1]))
3304 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3305 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
3306 if (GET_CODE (operands[2]) == CONST_INT
3307 && (INTVAL (operands[2]) == 128
3308 || (INTVAL (operands[2]) < 0
3309 && INTVAL (operands[2]) != -128)))
3311 operands[2] = GEN_INT (-INTVAL (operands[2]));
3312 return \"sub{l}\\t{%2, %0|%0, %2}\";
3314 return \"add{l}\\t{%2, %0|%0, %2}\";
3318 (cond [(eq_attr "alternative" "2")
3319 (const_string "lea")
3320 ; Current assemblers are broken and do not allow @GOTOFF in
3321 ; ought but a memory context.
3322 (match_operand:SI 2 "pic_symbolic_operand" "")
3323 (const_string "lea")
3324 (match_operand:SI 2 "incdec_operand" "")
3325 (const_string "incdec")
3327 (const_string "alu")))])
3329 ;; Convert lea to the lea pattern to avoid flags dependency.
3331 [(set (match_operand:SI 0 "register_operand" "")
3332 (plus:SI (match_operand:SI 1 "register_operand" "")
3333 (match_operand:SI 2 "nonmemory_operand" "")))
3334 (clobber (reg:CC 17))]
3336 && true_regnum (operands[0]) != true_regnum (operands[1])"
3338 (plus:SI (match_dup 1)
3342 (define_insn "*addsi_2"
3345 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3346 (match_operand:SI 2 "general_operand" "rmni,rni"))
3348 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
3349 (plus:SI (match_dup 1) (match_dup 2)))]
3350 "ix86_binary_operator_ok (PLUS, SImode, operands)
3351 /* Current assemblers are broken and do not allow @GOTOFF in
3352 ought but a memory context. */
3353 && ! pic_symbolic_operand (operands[2], VOIDmode)"
3356 switch (get_attr_type (insn))
3359 if (! rtx_equal_p (operands[0], operands[1]))
3361 if (operands[2] == const1_rtx)
3362 return \"inc{l}\\t%0\";
3363 else if (operands[2] == constm1_rtx)
3364 return \"dec{l}\\t%0\";
3369 if (! rtx_equal_p (operands[0], operands[1]))
3371 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3372 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
3373 if (GET_CODE (operands[2]) == CONST_INT
3374 && (INTVAL (operands[2]) == 128
3375 || (INTVAL (operands[2]) < 0
3376 && INTVAL (operands[2]) != -128)))
3378 operands[2] = GEN_INT (-INTVAL (operands[2]));
3379 return \"sub{l}\\t{%2, %0|%0, %2}\";
3381 return \"add{l}\\t{%2, %0|%0, %2}\";
3385 (if_then_else (match_operand:SI 2 "incdec_operand" "")
3386 (const_string "incdec")
3387 (const_string "alu")))])
3389 (define_insn "*addsi_3"
3391 (compare:CC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3392 (match_operand:SI 2 "general_operand" "rmni,rni"))
3394 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
3395 (plus:SI (match_dup 1) (match_dup 2)))]
3396 "ix86_binary_operator_ok (PLUS, SImode, operands)
3397 /* Current assemblers are broken and do not allow @GOTOFF in
3398 ought but a memory context. */
3399 && ! pic_symbolic_operand (operands[2], VOIDmode)"
3400 "add{l}\\t{%2, %0|%0, %2}"
3401 [(set_attr "type" "alu")])
3403 (define_expand "addhi3"
3404 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3405 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3406 (match_operand:HI 2 "general_operand" "")))
3407 (clobber (reg:CC 17))])]
3409 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
3411 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
3412 ;; type optimizations enabled by define-splits. This is not important
3413 ;; for PII, and in fact harmful because of partial register stalls.
3415 (define_insn "*addhi_1"
3416 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3417 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3418 (match_operand:HI 2 "general_operand" "ri,rm")))
3419 (clobber (reg:CC 17))]
3420 "ix86_binary_operator_ok (PLUS, HImode, operands)"
3423 switch (get_attr_type (insn))
3426 if (operands[2] == const1_rtx)
3427 return \"inc{w}\\t%0\";
3428 else if (operands[2] == constm1_rtx
3429 || (GET_CODE (operands[2]) == CONST_INT
3430 && INTVAL (operands[2]) == 65535))
3431 return \"dec{w}\\t%0\";
3435 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3436 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
3437 if (GET_CODE (operands[2]) == CONST_INT
3438 && (INTVAL (operands[2]) == 128
3439 || (INTVAL (operands[2]) < 0
3440 && INTVAL (operands[2]) != -128)))
3442 operands[2] = GEN_INT (-INTVAL (operands[2]));
3443 return \"sub{w}\\t{%2, %0|%0, %2}\";
3445 return \"add{w}\\t{%2, %0|%0, %2}\";
3449 (if_then_else (match_operand:HI 2 "incdec_operand" "")
3450 (const_string "incdec")
3451 (const_string "alu")))])
3453 (define_insn "*addhi_2"
3456 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3457 (match_operand:HI 2 "general_operand" "rmni,rni"))
3459 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
3460 (plus:HI (match_dup 1) (match_dup 2)))]
3461 "ix86_binary_operator_ok (PLUS, HImode, operands)"
3464 switch (get_attr_type (insn))
3467 if (operands[2] == const1_rtx)
3468 return \"inc{w}\\t%0\";
3469 else if (operands[2] == constm1_rtx
3470 || (GET_CODE (operands[2]) == CONST_INT
3471 && INTVAL (operands[2]) == 65535))
3472 return \"dec{w}\\t%0\";
3476 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3477 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
3478 if (GET_CODE (operands[2]) == CONST_INT
3479 && (INTVAL (operands[2]) == 128
3480 || (INTVAL (operands[2]) < 0
3481 && INTVAL (operands[2]) != -128)))
3483 operands[2] = GEN_INT (-INTVAL (operands[2]));
3484 return \"sub{w}\\t{%2, %0|%0, %2}\";
3486 return \"add{w}\\t{%2, %0|%0, %2}\";
3490 (if_then_else (match_operand:HI 2 "incdec_operand" "")
3491 (const_string "incdec")
3492 (const_string "alu")))])
3494 (define_insn "*addhi_3"
3496 (compare:CC (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3497 (match_operand:HI 2 "general_operand" "rmni,rni"))
3499 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
3500 (plus:HI (match_dup 1) (match_dup 2)))]
3501 "ix86_binary_operator_ok (PLUS, HImode, operands)"
3502 "add{w}\\t{%2, %0|%0, %2}"
3503 [(set_attr "type" "alu")])
3505 (define_expand "addqi3"
3506 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
3507 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
3508 (match_operand:QI 2 "general_operand" "")))
3509 (clobber (reg:CC 17))])]
3511 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
3513 ;; %%% Potential partial reg stall on alternative 2. What to do?
3514 (define_insn "*addqi_1"
3515 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
3516 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
3517 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
3518 (clobber (reg:CC 17))]
3519 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3522 int widen = (which_alternative == 2);
3523 switch (get_attr_type (insn))
3526 if (operands[2] == const1_rtx)
3527 return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
3528 else if (operands[2] == constm1_rtx
3529 || (GET_CODE (operands[2]) == CONST_INT
3530 && INTVAL (operands[2]) == 255))
3531 return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
3535 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
3536 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
3537 if (GET_CODE (operands[2]) == CONST_INT
3538 && (INTVAL (operands[2]) == 128
3539 || (INTVAL (operands[2]) < 0
3540 && INTVAL (operands[2]) != -128)))
3542 operands[2] = GEN_INT (-INTVAL (operands[2]));
3544 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
3546 return \"sub{b}\\t{%2, %0|%0, %2}\";
3549 return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
3551 return \"add{b}\\t{%2, %0|%0, %2}\";
3555 (if_then_else (match_operand:QI 2 "incdec_operand" "")
3556 (const_string "incdec")
3557 (const_string "alu")))])
3559 (define_insn "*addqi_2"
3562 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3563 (match_operand:QI 2 "general_operand" "qmni,qni"))
3565 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
3566 (plus:QI (match_dup 1) (match_dup 2)))]
3567 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3570 switch (get_attr_type (insn))
3573 if (operands[2] == const1_rtx)
3574 return \"inc{b}\\t%0\";
3575 else if (operands[2] == constm1_rtx
3576 || (GET_CODE (operands[2]) == CONST_INT
3577 && INTVAL (operands[2]) == 255))
3578 return \"dec{b}\\t%0\";
3582 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
3583 if (GET_CODE (operands[2]) == CONST_INT
3584 && INTVAL (operands[2]) < 0)
3586 operands[2] = GEN_INT (-INTVAL (operands[2]));
3587 return \"sub{b}\\t{%2, %0|%0, %2}\";
3589 return \"add{b}\\t{%2, %0|%0, %2}\";
3593 (if_then_else (match_operand:QI 2 "incdec_operand" "")
3594 (const_string "incdec")
3595 (const_string "alu")))])
3597 (define_insn "*addqi_3"
3599 (compare:CC (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3600 (match_operand:QI 2 "general_operand" "qmni,qni"))
3602 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
3603 (plus:QI (match_dup 1) (match_dup 2)))]
3604 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3605 "add{b}\\t{%2, %0|%0, %2}"
3606 [(set_attr "type" "alu")])
3608 (define_insn "*addqi_low_1"
3609 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
3610 (plus:QI (match_operand:QI 1 "register_operand" "0")
3611 (match_operand:QI 2 "general_operand" "qmn")))
3612 (clobber (reg:CC 17))]
3616 switch (get_attr_type (insn))
3619 if (operands[2] == const1_rtx)
3620 return \"inc{b}\\t%b0\";
3621 else if (operands[2] == constm1_rtx
3622 || (GET_CODE (operands[2]) == CONST_INT
3623 && INTVAL (operands[2]) == 255))
3624 return \"dec{b}\\t%b0\";
3628 return \"add{b}\\t{%2, %b0|%b0, %2}\";
3632 (if_then_else (match_operand:QI 2 "incdec_operand" "")
3633 (const_string "incdec")
3634 (const_string "alu")))])
3636 (define_insn "addqi_ext_1"
3637 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
3642 (match_operand 1 "ext_register_operand" "0")
3645 (match_operand:QI 2 "general_operand" "qmn")))
3646 (clobber (reg:CC 17))]
3650 switch (get_attr_type (insn))
3653 if (operands[2] == const1_rtx)
3654 return \"inc{b}\\t%h0\";
3655 else if (operands[2] == constm1_rtx
3656 || (GET_CODE (operands[2]) == CONST_INT
3657 && INTVAL (operands[2]) == 255))
3658 return \"dec{b}\\t%h0\";
3662 return \"add{b}\\t{%2, %h0|%h0, %2}\";
3666 (if_then_else (match_operand:QI 2 "incdec_operand" "")
3667 (const_string "incdec")
3668 (const_string "alu")))])
3670 (define_insn "*addqi_ext_2"
3671 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
3676 (match_operand 1 "ext_register_operand" "%0")
3680 (match_operand 2 "ext_register_operand" "q")
3683 (clobber (reg:CC 17))]
3685 "add{b}\\t{%h2, %h0|%h0, %h2}"
3686 [(set_attr "type" "alu")])
3688 ;; The patterns that match these are at the end of this file.
3690 (define_expand "addxf3"
3691 [(set (match_operand:XF 0 "register_operand" "")
3692 (plus:XF (match_operand:XF 1 "register_operand" "")
3693 (match_operand:XF 2 "register_operand" "")))]
3697 (define_expand "adddf3"
3698 [(set (match_operand:DF 0 "register_operand" "")
3699 (plus:DF (match_operand:DF 1 "register_operand" "")
3700 (match_operand:DF 2 "nonimmediate_operand" "")))]
3704 (define_expand "addsf3"
3705 [(set (match_operand:SF 0 "register_operand" "")
3706 (plus:SF (match_operand:SF 1 "register_operand" "")
3707 (match_operand:SF 2 "nonimmediate_operand" "")))]
3711 ;; Subtract instructions
3713 ;; %%% define_expand from the very first?
3714 ;; %%% splits for subsidi3
3716 (define_insn "subdi3"
3717 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3718 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
3719 (match_operand:DI 2 "general_operand" "roiF,riF")))
3720 (clobber (reg:CC 17))]
3725 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3726 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
3727 (match_operand:DI 2 "general_operand" "")))
3728 (clobber (reg:CC 17))]
3730 [(parallel [(set (reg:CC 17) (minus:CC (match_dup 1) (match_dup 2)))
3731 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
3732 (parallel [(set (match_dup 3)
3733 (minus:SI (match_dup 4)
3734 (plus:SI (match_dup 5)
3735 (ltu:SI (reg:CC 17) (const_int 0)))))
3736 (clobber (reg:CC 17))])]
3737 "split_di (operands+0, 1, operands+0, operands+3);
3738 split_di (operands+1, 1, operands+1, operands+4);
3739 split_di (operands+2, 1, operands+2, operands+5);")
3741 (define_insn "*subsi3_cc"
3742 [(set (reg:CC 17) (minus:CC (match_operand:SI 1 "nonimmediate_operand" "0,0")
3743 (match_operand:SI 2 "general_operand" "ri,rm")))
3744 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3745 (minus:SI (match_dup 1) (match_dup 2)))]
3746 "ix86_binary_operator_ok (MINUS, SImode, operands)"
3747 "sub{l}\\t{%2, %0|%0, %2}"
3748 [(set_attr "type" "alu")])
3750 (define_insn "subsi3_carry"
3751 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3752 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
3753 (plus:SI (match_operand:SI 2 "general_operand" "ri,rm")
3754 (ltu:SI (reg:CC 17) (const_int 0)))))
3755 (clobber (reg:CC 17))]
3756 "ix86_binary_operator_ok (MINUS, SImode, operands)"
3757 "sbb{l}\\t{%2, %0|%0, %2}"
3758 [(set_attr "type" "alu")
3759 (set_attr "pent_pair" "pu")
3760 (set_attr "ppro_uops" "few")])
3762 (define_expand "subsi3"
3763 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
3764 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3765 (match_operand:SI 2 "general_operand" "")))
3766 (clobber (reg:CC 17))])]
3768 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
3770 (define_insn "*subsi_1"
3771 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3772 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
3773 (match_operand:SI 2 "general_operand" "ri,rm")))
3774 (clobber (reg:CC 17))]
3775 "ix86_binary_operator_ok (MINUS, SImode, operands)"
3776 "sub{l}\\t{%2, %0|%0, %2}"
3777 [(set_attr "type" "alu")])
3779 (define_insn "*subsi_2"
3782 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
3783 (match_operand:SI 2 "general_operand" "ri,rm"))
3785 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3786 (minus:SI (match_dup 1) (match_dup 2)))]
3787 "ix86_binary_operator_ok (MINUS, SImode, operands)"
3788 "sub{l}\\t{%2, %0|%0, %2}"
3789 [(set_attr "type" "alu")])
3791 (define_insn "*subsi_3"
3794 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
3795 (match_operand:SI 2 "general_operand" "ri,rm"))
3797 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3798 (minus:SI (match_dup 1) (match_dup 2)))]
3799 "ix86_binary_operator_ok (MINUS, SImode, operands)"
3800 "sub{l}\\t{%2, %0|%0, %2}"
3801 [(set_attr "type" "alu")])
3803 (define_expand "subhi3"
3804 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
3805 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3806 (match_operand:HI 2 "general_operand" "")))
3807 (clobber (reg:CC 17))])]
3809 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
3811 (define_insn "*subhi_1"
3812 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3813 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
3814 (match_operand:HI 2 "general_operand" "ri,rm")))
3815 (clobber (reg:CC 17))]
3816 "ix86_binary_operator_ok (MINUS, HImode, operands)"
3817 "sub{w}\\t{%2, %0|%0, %2}"
3818 [(set_attr "type" "alu")])
3820 (define_insn "*subhi_2"
3823 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
3824 (match_operand:HI 2 "general_operand" "ri,rm"))
3826 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3827 (minus:HI (match_dup 1) (match_dup 2)))]
3828 "ix86_binary_operator_ok (MINUS, HImode, operands)"
3829 "sub{w}\\t{%2, %0|%0, %2}"
3830 [(set_attr "type" "alu")])
3832 (define_insn "*subhi_3"
3835 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
3836 (match_operand:HI 2 "general_operand" "ri,rm"))
3838 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3839 (minus:HI (match_dup 1) (match_dup 2)))]
3840 "ix86_binary_operator_ok (MINUS, HImode, operands)"
3841 "sub{w}\\t{%2, %0|%0, %2}"
3842 [(set_attr "type" "alu")])
3844 (define_expand "subqi3"
3845 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
3846 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
3847 (match_operand:QI 2 "general_operand" "")))
3848 (clobber (reg:CC 17))])]
3850 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
3852 (define_insn "*subqi_1"
3853 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3854 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
3855 (match_operand:QI 2 "general_operand" "qn,qmn")))
3856 (clobber (reg:CC 17))]
3857 "ix86_binary_operator_ok (MINUS, QImode, operands)"
3858 "sub{b}\\t{%2, %0|%0, %2}"
3859 [(set_attr "type" "alu")])
3861 (define_insn "*subqi_2"
3864 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
3865 (match_operand:QI 2 "general_operand" "qi,qm"))
3867 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
3868 (minus:HI (match_dup 1) (match_dup 2)))]
3869 "ix86_binary_operator_ok (MINUS, QImode, operands)"
3870 "sub{b}\\t{%2, %0|%0, %2}"
3871 [(set_attr "type" "alu")])
3873 (define_insn "*subqi_3"
3876 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
3877 (match_operand:QI 2 "general_operand" "qi,qm"))
3879 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
3880 (minus:HI (match_dup 1) (match_dup 2)))]
3881 "ix86_binary_operator_ok (MINUS, QImode, operands)"
3882 "sub{b}\\t{%2, %0|%0, %2}"
3883 [(set_attr "type" "alu")])
3885 ;; The patterns that match these are at the end of this file.
3887 (define_expand "subxf3"
3888 [(set (match_operand:XF 0 "register_operand" "")
3889 (minus:XF (match_operand:XF 1 "register_operand" "")
3890 (match_operand:XF 2 "register_operand" "")))]
3894 (define_expand "subdf3"
3895 [(set (match_operand:DF 0 "register_operand" "")
3896 (minus:DF (match_operand:DF 1 "register_operand" "")
3897 (match_operand:DF 2 "nonimmediate_operand" "")))]
3901 (define_expand "subsf3"
3902 [(set (match_operand:SF 0 "register_operand" "")
3903 (minus:SF (match_operand:SF 1 "register_operand" "")
3904 (match_operand:SF 2 "nonimmediate_operand" "")))]
3908 ;; Multiply instructions
3910 (define_expand "mulsi3"
3911 [(parallel [(set (match_operand:SI 0 "register_operand" "")
3912 (mult:SI (match_operand:SI 1 "register_operand" "")
3913 (match_operand:SI 2 "general_operand" "")))
3914 (clobber (reg:CC 17))])]
3918 (define_insn "*mulsi3_1"
3919 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
3920 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
3921 (match_operand:SI 2 "general_operand" "K,i,mr")))
3922 (clobber (reg:CC 17))]
3923 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
3924 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
3925 ; there are two ways of writing the exact same machine instruction
3926 ; in assembly language. One, for example, is:
3930 ; while the other is:
3932 ; imul $12, %eax, %eax
3934 ; The first is simply short-hand for the latter. But, some assemblers,
3935 ; like the SCO OSR5 COFF assembler, don't handle the first form.
3937 imul{l}\\t{%2, %1, %0|%0, %1, %2}
3938 imul{l}\\t{%2, %1, %0|%0, %1, %2}
3939 imul{l}\\t{%2, %0|%0, %2}"
3940 [(set_attr "type" "imul")
3941 (set_attr "length" "2,3,2")])
3943 (define_expand "mulhi3"
3944 [(parallel [(set (match_operand:HI 0 "register_operand" "")
3945 (mult:HI (match_operand:HI 1 "register_operand" "")
3946 (match_operand:HI 2 "general_operand" "")))
3947 (clobber (reg:CC 17))])]
3951 (define_insn "*mulhi3_1"
3952 [(set (match_operand:HI 0 "register_operand" "=r,r")
3953 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0")
3954 (match_operand:HI 2 "general_operand" "K,g")))
3955 (clobber (reg:CC 17))]
3956 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
3957 ; %%% There was a note about "Assembler has weird restrictions",
3958 ; concerning alternative 1 when op1 == op0. True?
3960 imul{w}\\t{%2, %1, %0|%0, %1, %2}
3961 imul{w}\\t{%2, %0|%0, %2}"
3962 [(set_attr "type" "imul")])
3964 (define_insn "umulqihi3"
3965 [(set (match_operand:HI 0 "register_operand" "=a")
3966 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3967 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
3968 (clobber (reg:CC 17))]
3971 [(set_attr "type" "imul")])
3973 (define_insn "mulqihi3"
3974 [(set (match_operand:HI 0 "register_operand" "=a")
3975 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3976 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
3977 (clobber (reg:CC 17))]
3980 [(set_attr "type" "imul")])
3982 (define_insn "umulsidi3"
3983 [(set (match_operand:DI 0 "register_operand" "=A")
3984 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3985 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
3986 (clobber (reg:CC 17))]
3989 [(set_attr "type" "imul")
3990 (set_attr "ppro_uops" "few")])
3992 (define_insn "mulsidi3"
3993 [(set (match_operand:DI 0 "register_operand" "=A")
3994 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3995 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
3996 (clobber (reg:CC 17))]
3999 [(set_attr "type" "imul")])
4001 (define_insn "umulsi3_highpart"
4002 [(set (match_operand:SI 0 "register_operand" "=d")
4005 (mult:DI (zero_extend:DI
4006 (match_operand:SI 1 "register_operand" "%a"))
4008 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4010 (clobber (match_scratch:SI 3 "=a"))
4011 (clobber (reg:CC 17))]
4014 [(set_attr "type" "imul")
4015 (set_attr "ppro_uops" "few")])
4017 (define_insn "smulsi3_highpart"
4018 [(set (match_operand:SI 0 "register_operand" "=d")
4021 (mult:DI (sign_extend:DI
4022 (match_operand:SI 1 "register_operand" "%a"))
4024 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4026 (clobber (match_scratch:SI 3 "=a"))
4027 (clobber (reg:CC 17))]
4030 [(set_attr "type" "imul")
4031 (set_attr "ppro_uops" "few")])
4033 ;; The patterns that match these are at the end of this file.
4035 (define_expand "mulxf3"
4036 [(set (match_operand:XF 0 "register_operand" "")
4037 (mult:XF (match_operand:XF 1 "register_operand" "")
4038 (match_operand:XF 2 "register_operand" "")))]
4042 (define_expand "muldf3"
4043 [(set (match_operand:DF 0 "register_operand" "")
4044 (mult:DF (match_operand:DF 1 "register_operand" "")
4045 (match_operand:DF 2 "nonimmediate_operand" "")))]
4049 (define_expand "mulsf3"
4050 [(set (match_operand:SF 0 "register_operand" "")
4051 (mult:SF (match_operand:SF 1 "register_operand" "")
4052 (match_operand:SF 2 "nonimmediate_operand" "")))]
4056 ;; Divide instructions
4058 (define_insn "divqi3"
4059 [(set (match_operand:QI 0 "register_operand" "=a")
4060 (div:QI (match_operand:HI 1 "register_operand" "0")
4061 (match_operand:QI 2 "nonimmediate_operand" "qm")))
4062 (clobber (reg:CC 17))]
4065 [(set_attr "type" "idiv")
4066 (set_attr "ppro_uops" "few")])
4068 (define_insn "udivqi3"
4069 [(set (match_operand:QI 0 "register_operand" "=a")
4070 (udiv:QI (match_operand:HI 1 "register_operand" "0")
4071 (match_operand:QI 2 "nonimmediate_operand" "qm")))
4072 (clobber (reg:CC 17))]
4075 [(set_attr "type" "idiv")
4076 (set_attr "ppro_uops" "few")])
4078 ;; The patterns that match these are at the end of this file.
4080 (define_expand "divxf3"
4081 [(set (match_operand:XF 0 "register_operand" "")
4082 (div:XF (match_operand:XF 1 "register_operand" "")
4083 (match_operand:XF 2 "register_operand" "")))]
4087 (define_expand "divdf3"
4088 [(set (match_operand:DF 0 "register_operand" "")
4089 (div:DF (match_operand:DF 1 "register_operand" "")
4090 (match_operand:DF 2 "nonimmediate_operand" "")))]
4094 (define_expand "divsf3"
4095 [(set (match_operand:SF 0 "register_operand" "")
4096 (div:SF (match_operand:SF 1 "register_operand" "")
4097 (match_operand:SF 2 "nonimmediate_operand" "")))]
4101 ;; Remainder instructions.
4102 (define_expand "divmodsi4"
4103 [(parallel [(set (match_operand:SI 0 "register_operand" "")
4104 (div:SI (match_operand:SI 1 "register_operand" "")
4105 (match_operand:SI 2 "nonimmediate_operand" "")))
4106 (set (match_operand:SI 3 "register_operand" "")
4107 (mod:SI (match_dup 1) (match_dup 2)))
4108 (clobber (reg:CC 17))])]
4112 ;; Allow to come the parameter in eax or edx to avoid extra moves.
4113 ;; Penalize eax case sligthly because it results in worse scheduling
4115 (define_insn "*divmodsi4_nocltd"
4116 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
4117 (div:SI (match_operand:SI 2 "register_operand" "1,0")
4118 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
4119 (set (match_operand:SI 1 "register_operand" "=&d,&d")
4120 (mod:SI (match_dup 2) (match_dup 3)))
4121 (clobber (reg:CC 17))]
4122 "!optimize_size && !TARGET_USE_CLTD"
4124 [(set_attr "type" "multi")])
4126 (define_insn "*divmodsi4_cltd"
4127 [(set (match_operand:SI 0 "register_operand" "=a")
4128 (div:SI (match_operand:SI 2 "register_operand" "a")
4129 (match_operand:SI 3 "nonimmediate_operand" "rm")))
4130 (set (match_operand:SI 1 "register_operand" "=&d")
4131 (mod:SI (match_dup 2) (match_dup 3)))
4132 (clobber (reg:CC 17))]
4133 "optimize_size || TARGET_USE_CLTD"
4135 [(set_attr "type" "multi")])
4137 (define_insn "*divmodsi_noext"
4138 [(set (match_operand:SI 0 "register_operand" "=a")
4139 (div:SI (match_operand:SI 1 "register_operand" "0")
4140 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4141 (set (match_operand:SI 3 "register_operand" "=d")
4142 (mod:SI (match_dup 1) (match_dup 2)))
4143 (use (match_operand:SI 4 "register_operand" "3"))
4144 (clobber (reg:CC 17))]
4147 [(set_attr "type" "idiv")
4148 (set_attr "ppro_uops" "few")])
4151 [(set (match_operand:SI 0 "register_operand" "")
4152 (div:SI (match_operand:SI 1 "register_operand" "")
4153 (match_operand:SI 2 "nonimmediate_operand" "")))
4154 (set (match_operand:SI 3 "register_operand" "")
4155 (mod:SI (match_dup 1) (match_dup 2)))
4156 (clobber (reg:CC 17))]
4158 [(parallel [(set (match_dup 3)
4159 (ashiftrt:SI (match_dup 4) (const_int 31)))
4160 (clobber (reg:CC 17))])
4161 (parallel [(set (match_dup 0)
4162 (div:SI (reg:SI 0) (match_dup 2)))
4164 (mod:SI (reg:SI 0) (match_dup 2)))
4166 (clobber (reg:CC 17))])]
4169 /* Avoid use of cltd in favour of a mov+shift. */
4170 if (!TARGET_USE_CLTD && !optimize_size)
4172 if (true_regnum (operands[1]))
4173 emit_move_insn (operands[0], operands[1]);
4175 emit_move_insn (operands[3], operands[1]);
4176 operands[4] = operands[3];
4180 if (true_regnum (operands[1]))
4182 operands[4] = operands[1];
4186 (define_insn "divmodhi4"
4187 [(set (match_operand:HI 0 "register_operand" "=a")
4188 (div:HI (match_operand:HI 1 "register_operand" "0")
4189 (match_operand:HI 2 "nonimmediate_operand" "rm")))
4190 (set (match_operand:HI 3 "register_operand" "=&d")
4191 (mod:HI (match_dup 1) (match_dup 2)))
4192 (clobber (reg:CC 17))]
4194 "cwtd\;idiv{w}\\t%2"
4195 [(set_attr "type" "multi")])
4197 (define_insn "udivmodsi4"
4198 [(set (match_operand:SI 0 "register_operand" "=a")
4199 (udiv:SI (match_operand:SI 1 "register_operand" "0")
4200 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4201 (set (match_operand:SI 3 "register_operand" "=&d")
4202 (umod:SI (match_dup 1) (match_dup 2)))
4203 (clobber (reg:CC 17))]
4205 "xor{l}\\t%3, %3\;div{l}\\t%2"
4206 [(set_attr "type" "multi")])
4208 (define_insn "*udivmodsi4_noext"
4209 [(set (match_operand:SI 0 "register_operand" "=a")
4210 (udiv:SI (match_operand:SI 1 "register_operand" "0")
4211 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4212 (set (match_operand:SI 3 "register_operand" "=d")
4213 (umod:SI (match_dup 1) (match_dup 2)))
4215 (clobber (reg:CC 17))]
4218 [(set_attr "type" "idiv")
4219 (set_attr "ppro_uops" "few")])
4222 [(set (match_operand:SI 0 "register_operand" "")
4223 (udiv:SI (match_operand:SI 1 "register_operand" "")
4224 (match_operand:SI 2 "nonimmediate_operand" "")))
4225 (set (match_operand:SI 3 "register_operand" "")
4226 (umod:SI (match_dup 1) (match_dup 2)))
4227 (clobber (reg:CC 17))]
4229 [(set (match_dup 3) (const_int 0))
4230 (parallel [(set (match_dup 0)
4231 (udiv:SI (match_dup 1) (match_dup 2)))
4233 (umod:SI (match_dup 1) (match_dup 2)))
4235 (clobber (reg:CC 17))])]
4238 (define_expand "udivmodhi4"
4239 [(set (match_dup 4) (const_int 0))
4240 (parallel [(set (match_operand:HI 0 "register_operand" "")
4241 (udiv:HI (match_operand:HI 1 "register_operand" "")
4242 (match_operand:HI 2 "nonimmediate_operand" "")))
4243 (set (match_operand:HI 3 "register_operand" "")
4244 (umod:HI (match_dup 1) (match_dup 2)))
4246 (clobber (reg:CC 17))])]
4248 "operands[4] = gen_reg_rtx (HImode);")
4250 (define_insn "*udivmodhi_noext"
4251 [(set (match_operand:HI 0 "register_operand" "=a")
4252 (udiv:HI (match_operand:HI 1 "register_operand" "0")
4253 (match_operand:HI 2 "nonimmediate_operand" "rm")))
4254 (set (match_operand:HI 3 "register_operand" "=d")
4255 (umod:HI (match_dup 1) (match_dup 2)))
4256 (use (match_operand:HI 4 "register_operand" "3"))
4257 (clobber (reg:CC 17))]
4260 [(set_attr "type" "idiv")
4261 (set_attr "ppro_uops" "few")])
4263 ;; We can not use div/idiv for double division, because it causes
4264 ;; "division by zero" on the overflow and that's not what we expect
4265 ;; from truncate. Because true (non truncating) double division is
4266 ;; never generated, we can't create this insn anyway.
4269 ; [(set (match_operand:SI 0 "register_operand" "=a")
4271 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
4273 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
4274 ; (set (match_operand:SI 3 "register_operand" "=d")
4276 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
4277 ; (clobber (reg:CC 17))]
4279 ; "div{l}\\t{%2, %0|%0, %2}"
4280 ; [(set_attr "type" "idiv")
4281 ; (set_attr "ppro_uops" "few")])
4283 ;;- Logical AND instructions
4285 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
4286 ;; Note that this excludes ah.
4288 (define_insn "testsi_1"
4290 (compare:CCNO (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
4291 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
4294 "test{l}\\t{%1, %0|%0, %1}"
4295 [(set_attr "type" "icmp")
4296 (set_attr "pent_pair" "uv,np,uv")])
4298 (define_insn "*testhi_1"
4300 (compare:CCNO (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
4301 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
4304 "test{w}\\t{%1, %0|%0, %1}"
4305 [(set_attr "type" "icmp")
4306 (set_attr "pent_pair" "uv,np,uv")])
4308 (define_insn "testqi_1"
4310 (compare:CCNO (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm")
4311 (match_operand:QI 1 "nonmemory_operand" "n,n,qn"))
4314 "test{b}\\t{%1, %0|%0, %1}"
4315 [(set_attr "type" "icmp")
4316 (set_attr "pent_pair" "uv,np,uv")])
4318 ;; ??? A bug in recog prevents it from recognizing a const_int as an
4319 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
4320 ;; for a QImode operand, which of course failed.
4322 (define_insn "testqi_ext_0"
4327 (match_operand 0 "ext_register_operand" "q")
4330 (match_operand 1 "const_int_operand" "n"))
4332 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff"
4333 "test{b}\\t{%1, %h0|%h0, %1}"
4334 [(set_attr "type" "icmp")
4335 (set_attr "pent_pair" "np")])
4337 (define_insn "*testqi_ext_1"
4342 (match_operand 0 "ext_register_operand" "q")
4346 (match_operand:QI 1 "nonimmediate_operand" "qm")))
4349 "test{b}\\t{%1, %h0|%h0, %1}"
4350 [(set_attr "type" "icmp")])
4352 (define_insn "*testqi_ext_2"
4357 (match_operand 0 "ext_register_operand" "q")
4361 (match_operand 1 "ext_register_operand" "q")
4366 "test{b}\\t{%h1, %h0|%h0, %h1}"
4367 [(set_attr "type" "icmp")])
4369 ;; Combine likes to form bit extractions for some tests. Humor it.
4370 (define_insn "*testqi_ext_3"
4372 (compare:CCNO (zero_extract:SI
4373 (match_operand 0 "nonimmediate_operand" "rm")
4374 (match_operand:SI 1 "const_int_operand" "")
4375 (match_operand:SI 2 "const_int_operand" ""))
4377 "GET_MODE (operands[0]) == SImode
4378 || GET_MODE (operands[0]) == HImode
4379 || GET_MODE (operands[0]) == QImode"
4384 (compare:CCNO (zero_extract:SI
4385 (match_operand 0 "nonimmediate_operand" "rm")
4386 (match_operand:SI 1 "const_int_operand" "")
4387 (match_operand:SI 2 "const_int_operand" ""))
4390 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
4393 HOST_WIDE_INT len = INTVAL (operands[1]);
4394 HOST_WIDE_INT pos = INTVAL (operands[2]);
4396 enum machine_mode mode;
4398 mode = GET_MODE (operands[0]);
4399 if (GET_CODE (operands[0]) == MEM)
4401 /* ??? Combine likes to put non-volatile mem extractions in QImode
4402 no matter the size of the test. So find a mode that works. */
4403 if (! MEM_VOLATILE_P (operands[0]))
4405 mode = smallest_mode_for_size (pos + len, MODE_INT);
4406 operands[0] = change_address (operands[0], mode, NULL_RTX);
4409 else if (mode == HImode && pos + len <= 8)
4411 /* Small HImode tests can be converted to QImode. */
4413 operands[0] = gen_lowpart (QImode, operands[0]);
4416 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
4417 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
4419 operands[3] = gen_rtx_AND (mode, operands[0], GEN_INT (mask));
4422 ;; %%% This used to optimize known byte-wide and operations to memory,
4423 ;; and sometimes to QImode registers. If this is considered useful,
4424 ;; it should be done with splitters.
4426 (define_expand "andsi3"
4427 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4428 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
4429 (match_operand:SI 2 "general_operand" "")))
4430 (clobber (reg:CC 17))]
4432 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
4434 (define_insn "*andsi_1"
4435 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
4436 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
4437 (match_operand:SI 2 "general_operand" "ri,rm,L")))
4438 (clobber (reg:CC 17))]
4439 "ix86_binary_operator_ok (AND, SImode, operands)"
4442 switch (get_attr_type (insn))
4446 enum machine_mode mode;
4448 if (GET_CODE (operands[2]) != CONST_INT)
4450 if (INTVAL (operands[2]) == 0xff)
4452 else if (INTVAL (operands[2]) == 0xffff)
4457 operands[1] = gen_lowpart (mode, operands[1]);
4459 return \"movz{bl|x}\\t{%1,%0|%0, %1}\";
4461 return \"movz{wl|x}\\t{%1,%0|%0, %1}\";
4465 if (! rtx_equal_p (operands[0], operands[1]))
4468 /* If operands[2] is an immediate, we may be able to use xor.
4469 Walk through the cases to figure out which subword we are
4470 supposed to clear. */
4471 if (REG_P (operands[0])
4472 && GET_CODE (operands[2]) == CONST_INT
4474 || ! TARGET_PARTIAL_REG_STALL))
4476 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffff0000
4478 return \"xor{w}\\t{%w0, %w0|%w0, %w0}\";
4479 if (QI_REG_P (operands[0]))
4481 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffff00)
4482 return \"xor{b}\\t{%b0, %b0|%b0, %b0}\";
4483 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffff00ff)
4484 return \"xor{b}\\t{%h0, %h0|%h0, %h0}\";
4487 return \"and{l}\\t{%2, %0|%0, %2}\";
4490 [(set_attr "type" "alu,alu,imovx")])
4492 (define_insn "*andsi_2"
4494 (compare:CCNO (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4495 (match_operand:SI 2 "general_operand" "rim,ri"))
4497 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4498 (and:SI (match_dup 1) (match_dup 2)))]
4499 "ix86_binary_operator_ok (AND, SImode, operands)"
4500 "and{l}\\t{%2, %0|%0, %2}"
4501 [(set_attr "type" "alu")])
4503 (define_expand "andhi3"
4504 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4505 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
4506 (match_operand:HI 2 "general_operand" "")))
4507 (clobber (reg:CC 17))]
4509 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
4511 (define_insn "*andhi_1"
4512 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
4513 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
4514 (match_operand:HI 2 "general_operand" "ri,rm,L")))
4515 (clobber (reg:CC 17))]
4516 "ix86_binary_operator_ok (AND, HImode, operands)"
4519 switch (get_attr_type (insn))
4522 if (GET_CODE (operands[2]) != CONST_INT)
4524 if (INTVAL (operands[2]) == 0xff)
4525 return \"movz{bl|x}\\t{%b1, %k0|%k0, %b1}\";
4529 if (! rtx_equal_p (operands[0], operands[1]))
4532 /* If operands[2] is an immediate, we may be able to use xor.
4533 Walk through the cases to figure out which subword we are
4534 supposed to clear. */
4535 /* %%% Do these as splits. They get length_prefix wrong. */
4536 if (GET_CODE (operands[2]) == CONST_INT
4537 && QI_REG_P (operands[0])
4539 || ! TARGET_PARTIAL_REG_STALL))
4541 if ((INTVAL (operands[2]) & 0xffff) == 0xff00)
4542 return \"xor{b}\\t{%b0, %b0|%b0, %b0}\";
4543 if ((INTVAL (operands[2]) & 0xffff) == 0x00ff)
4544 return \"xor{b}\\t{%h0, %h0|%h0, %h0}\";
4547 return \"and{w}\\t{%2, %0|%0, %2}\";
4550 [(set_attr "type" "alu,alu,imovx")])
4552 (define_insn "*andhi_2"
4554 (compare:CCNO (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4555 (match_operand:HI 2 "general_operand" "rim,ri"))
4557 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
4558 (and:HI (match_dup 1) (match_dup 2)))]
4559 "ix86_binary_operator_ok (AND, HImode, operands)"
4560 "and{w}\\t{%2, %0|%0, %2}"
4561 [(set_attr "type" "alu")])
4563 (define_expand "andqi3"
4564 [(set (match_operand:QI 0 "nonimmediate_operand" "")
4565 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
4566 (match_operand:QI 2 "general_operand" "")))
4567 (clobber (reg:CC 17))]
4569 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
4571 ;; %%% Potential partial reg stall on alternative 2. What to do?
4572 (define_insn "*andqi_1"
4573 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
4574 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
4575 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
4576 (clobber (reg:CC 17))]
4577 "ix86_binary_operator_ok (AND, QImode, operands)"
4579 and{b}\\t{%2, %0|%0, %2}
4580 and{b}\\t{%2, %0|%0, %2}
4581 and{l}\\t{%k2, %k0|%k0, %k2}"
4582 [(set_attr "type" "alu")])
4584 (define_insn "*andqi_2"
4586 (compare:CCNO (and:QI
4587 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
4588 (match_operand:QI 2 "general_operand" "qim,qi,i"))
4590 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
4591 (and:QI (match_dup 1) (match_dup 2)))]
4592 "ix86_binary_operator_ok (AND, QImode, operands)"
4594 and{b}\\t{%2, %0|%0, %2}
4595 and{b}\\t{%2, %0|%0, %2}
4596 and{l}\\t{%2, %k0|%k0, %2}"
4597 [(set_attr "type" "alu")])
4599 ;; ??? A bug in recog prevents it from recognizing a const_int as an
4600 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
4601 ;; for a QImode operand, which of course failed.
4603 (define_insn "andqi_ext_0"
4604 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4609 (match_operand 1 "ext_register_operand" "0")
4612 (match_operand 2 "const_int_operand" "n")))
4613 (clobber (reg:CC 17))]
4614 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
4615 "and{b}\\t{%2, %h0|%h0, %2}"
4616 [(set_attr "type" "alu")])
4618 ;; Generated by peephole translating test to and. This shows up
4619 ;; often in fp comparisons.
4621 (define_insn "*andqi_ext_0_cc"
4626 (match_operand 1 "ext_register_operand" "q")
4629 (match_operand 2 "const_int_operand" "n"))
4631 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4640 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
4641 "and{b}\\t{%2, %h0|%h0, %2}"
4642 [(set_attr "type" "alu")])
4644 (define_insn "*andqi_ext_1"
4645 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4650 (match_operand 1 "ext_register_operand" "0")
4654 (match_operand:QI 2 "general_operand" "qm"))))
4655 (clobber (reg:CC 17))]
4657 "and{b}\\t{%2, %h0|%h0, %2}"
4658 [(set_attr "type" "alu")])
4660 (define_insn "*andqi_ext_2"
4661 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4666 (match_operand 1 "ext_register_operand" "%0")
4670 (match_operand 2 "ext_register_operand" "q")
4673 (clobber (reg:CC 17))]
4675 "and{b}\\t{%h2, %h0|%h0, %h2}"
4676 [(set_attr "type" "alu")])
4678 ;; Logical inclusive OR instructions
4680 ;; %%% This used to optimize known byte-wide and operations to memory.
4681 ;; If this is considered useful, it should be done with splitters.
4683 (define_expand "iorsi3"
4684 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4685 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
4686 (match_operand:SI 2 "general_operand" "")))
4687 (clobber (reg:CC 17))]
4689 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
4691 (define_insn "*iorsi_1"
4692 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4693 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4694 (match_operand:SI 2 "general_operand" "ri,rmi")))
4695 (clobber (reg:CC 17))]
4696 "ix86_binary_operator_ok (IOR, SImode, operands)"
4697 "or{l}\\t{%2, %0|%0, %2}"
4698 [(set_attr "type" "alu")])
4700 (define_insn "*iorsi_2"
4702 (compare:CCNO (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4703 (match_operand:SI 2 "general_operand" "rim,ri"))
4705 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4706 (ior:SI (match_dup 1) (match_dup 2)))]
4707 "ix86_binary_operator_ok (IOR, SImode, operands)"
4708 "or{l}\\t{%2, %0|%0, %2}"
4709 [(set_attr "type" "alu")])
4711 (define_expand "iorhi3"
4712 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4713 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
4714 (match_operand:HI 2 "general_operand" "")))
4715 (clobber (reg:CC 17))]
4717 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
4719 (define_insn "*iorhi_1"
4720 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
4721 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4722 (match_operand:HI 2 "general_operand" "rmi,ri")))
4723 (clobber (reg:CC 17))]
4724 "ix86_binary_operator_ok (IOR, HImode, operands)"
4725 "or{w}\\t{%2, %0|%0, %2}"
4726 [(set_attr "type" "alu")])
4728 (define_insn "*iorhi_2"
4730 (compare:CCNO (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4731 (match_operand:HI 2 "general_operand" "rim,ri"))
4733 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
4734 (ior:HI (match_dup 1) (match_dup 2)))]
4735 "ix86_binary_operator_ok (IOR, HImode, operands)"
4736 "or{w}\\t{%2, %0|%0, %2}"
4737 [(set_attr "type" "alu")])
4739 (define_expand "iorqi3"
4740 [(set (match_operand:QI 0 "nonimmediate_operand" "")
4741 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
4742 (match_operand:QI 2 "general_operand" "")))
4743 (clobber (reg:CC 17))]
4745 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
4747 ;; %%% Potential partial reg stall on alternative 2. What to do?
4748 (define_insn "*iorqi_1"
4749 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
4750 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
4751 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
4752 (clobber (reg:CC 17))]
4753 "ix86_binary_operator_ok (IOR, QImode, operands)"
4755 or{b}\\t{%2, %0|%0, %2}
4756 or{b}\\t{%2, %0|%0, %2}
4757 or{l}\\t{%k2, %k0|%k0, %k2}"
4758 [(set_attr "type" "alu")])
4760 (define_insn "*iorqi_2"
4762 (compare:CCNO (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4763 (match_operand:QI 2 "general_operand" "qim,qi"))
4765 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
4766 (ior:QI (match_dup 1) (match_dup 2)))]
4767 "ix86_binary_operator_ok (IOR, QImode, operands)"
4768 "or{b}\\t{%2, %0|%0, %2}"
4769 [(set_attr "type" "alu")])
4771 ;; Logical XOR instructions
4773 ;; %%% This used to optimize known byte-wide and operations to memory.
4774 ;; If this is considered useful, it should be done with splitters.
4776 (define_expand "xorsi3"
4777 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4778 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
4779 (match_operand:SI 2 "general_operand" "")))
4780 (clobber (reg:CC 17))]
4782 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
4784 (define_insn "*xorsi_1"
4785 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4786 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4787 (match_operand:SI 2 "general_operand" "ri,rm")))
4788 (clobber (reg:CC 17))]
4789 "ix86_binary_operator_ok (XOR, SImode, operands)"
4790 "xor{l}\\t{%2, %0|%0, %2}"
4791 [(set_attr "type" "alu")])
4793 (define_insn "*xorsi_2"
4795 (compare:CCNO (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4796 (match_operand:SI 2 "general_operand" "rim,ri"))
4798 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4799 (xor:SI (match_dup 1) (match_dup 2)))]
4800 "ix86_binary_operator_ok (XOR, SImode, operands)"
4801 "xor{l}\\t{%2, %0|%0, %2}"
4802 [(set_attr "type" "alu")])
4804 (define_expand "xorhi3"
4805 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4806 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
4807 (match_operand:HI 2 "general_operand" "")))
4808 (clobber (reg:CC 17))]
4810 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
4812 (define_insn "*xorhi_1"
4813 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
4814 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4815 (match_operand:HI 2 "general_operand" "rmi,ri")))
4816 (clobber (reg:CC 17))]
4817 "ix86_binary_operator_ok (XOR, HImode, operands)"
4818 "xor{w}\\t{%2, %0|%0, %2}"
4819 [(set_attr "type" "alu")])
4821 (define_insn "*xorhi_2"
4823 (compare:CCNO (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4824 (match_operand:HI 2 "general_operand" "rim,ri"))
4826 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
4827 (xor:HI (match_dup 1) (match_dup 2)))]
4828 "ix86_binary_operator_ok (XOR, HImode, operands)"
4829 "xor{w}\\t{%2, %0|%0, %2}"
4830 [(set_attr "type" "alu")])
4832 (define_expand "xorqi3"
4833 [(set (match_operand:QI 0 "nonimmediate_operand" "")
4834 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
4835 (match_operand:QI 2 "general_operand" "")))
4836 (clobber (reg:CC 17))]
4838 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
4840 ;; %%% Potential partial reg stall on alternative 2. What to do?
4841 (define_insn "*xorqi_1"
4842 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
4843 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
4844 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
4845 (clobber (reg:CC 17))]
4846 "ix86_binary_operator_ok (XOR, QImode, operands)"
4848 xor{b}\\t{%2, %0|%0, %2}
4849 xor{b}\\t{%2, %0|%0, %2}
4850 xor{l}\\t{%k2, %k0|%k0, %k2}"
4851 [(set_attr "type" "alu")])
4853 (define_insn "*xorqi_cc_1"
4856 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4857 (match_operand:QI 2 "general_operand" "qim,qi"))
4859 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
4860 (xor:QI (match_dup 1) (match_dup 2)))]
4861 "ix86_binary_operator_ok (XOR, QImode, operands)"
4862 "xor{b}\\t{%2, %0|%0, %2}"
4863 [(set_attr "type" "alu")])
4865 (define_insn "xorqi_cc_ext_1"
4870 (match_operand 1 "ext_register_operand" "0")
4873 (match_operand:QI 2 "general_operand" "qmn"))
4875 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
4879 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
4882 "xor{b}\\t{%2, %h0|%h0, %2}"
4883 [(set_attr "type" "alu")])
4885 ;; Negation instructions
4887 ;; %%% define_expand from the very first?
4889 (define_expand "negdi2"
4890 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4891 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
4892 (clobber (reg:CC 17))])]
4894 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
4896 (define_insn "*negdi2_1"
4897 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
4898 (neg:DI (match_operand:DI 1 "general_operand" "0")))
4899 (clobber (reg:CC 17))]
4900 "ix86_unary_operator_ok (NEG, DImode, operands)"
4904 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4905 (neg:DI (match_operand:DI 1 "general_operand" "")))
4906 (clobber (reg:CC 17))]
4910 (compare:CCNO (neg:SI (match_dup 2)) (const_int 0)))
4911 (set (match_dup 0) (neg:SI (match_dup 2)))])
4914 (plus:SI (match_dup 3)
4915 (plus:SI (const_int 0)
4916 (ltu:SI (reg:CC 17) (const_int 0)))))
4917 (clobber (reg:CC 17))])
4920 (neg:SI (match_dup 1)))
4921 (clobber (reg:CC 17))])]
4922 "split_di (operands+1, 1, operands+2, operands+3);
4923 split_di (operands+0, 1, operands+0, operands+1);")
4925 (define_expand "negsi2"
4926 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4927 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
4928 (clobber (reg:CC 17))])]
4930 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
4932 (define_insn "*negsi2_1"
4933 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4934 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
4935 (clobber (reg:CC 17))]
4936 "ix86_unary_operator_ok (NEG, SImode, operands)"
4938 [(set_attr "type" "negnot")])
4940 (define_insn "*negsi2_cmpno"
4942 (compare:CCNO (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
4944 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4945 (neg:SI (match_dup 1)))]
4946 "ix86_unary_operator_ok (NEG, SImode, operands)"
4948 [(set_attr "type" "negnot")])
4950 (define_insn "*negsi2_cmp"
4952 (compare:CC (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
4954 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4955 (neg:SI (match_dup 1)))]
4956 "ix86_unary_operator_ok (NEG, SImode, operands)"
4958 [(set_attr "type" "negnot")])
4960 (define_expand "neghi2"
4961 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4962 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
4963 (clobber (reg:CC 17))])]
4965 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
4967 (define_insn "*neghi2_1"
4968 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4969 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
4970 (clobber (reg:CC 17))]
4971 "ix86_unary_operator_ok (NEG, HImode, operands)"
4973 [(set_attr "type" "negnot")])
4975 (define_insn "*neghi2_cmpno"
4977 (compare:CCNO (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
4979 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4980 (neg:HI (match_dup 1)))]
4981 "ix86_unary_operator_ok (NEG, HImode, operands)"
4983 [(set_attr "type" "negnot")])
4985 (define_insn "*neghi2_cmp"
4987 (compare:CC (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
4989 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4990 (neg:HI (match_dup 1)))]
4991 "ix86_unary_operator_ok (NEG, HImode, operands)"
4993 [(set_attr "type" "negnot")])
4995 (define_expand "negqi2"
4996 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
4997 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
4998 (clobber (reg:CC 17))])]
5000 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
5002 (define_insn "*negqi2_1"
5003 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5004 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
5005 (clobber (reg:CC 17))]
5006 "ix86_unary_operator_ok (NEG, QImode, operands)"
5008 [(set_attr "type" "negnot")])
5010 (define_insn "*negqi2_cmpno"
5012 (compare:CCNO (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
5014 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5015 (neg:QI (match_dup 1)))]
5016 "ix86_unary_operator_ok (NEG, QImode, operands)"
5018 [(set_attr "type" "negnot")])
5020 (define_insn "*negqi2_cmp"
5022 (compare:CC (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
5024 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5025 (neg:QI (match_dup 1)))]
5026 "ix86_unary_operator_ok (NEG, QImode, operands)"
5028 [(set_attr "type" "negnot")])
5030 ;; Changing of sign for FP values is doable using integer unit too.
5032 (define_expand "negsf2"
5033 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
5034 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
5035 (clobber (reg:CC 17))])]
5037 "ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
5039 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5040 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5042 (define_insn "*negsf2_if"
5043 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
5044 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
5045 (clobber (reg:CC 17))]
5046 "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
5050 [(set (match_operand:SF 0 "register_operand" "")
5051 (neg:SF (match_operand:SF 1 "register_operand" "")))
5052 (clobber (reg:CC 17))]
5053 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5055 (neg:SF (match_dup 1)))]
5059 [(set (match_operand:SF 0 "register_operand" "")
5060 (neg:SF (match_operand:SF 1 "register_operand" "")))
5061 (clobber (reg:CC 17))]
5062 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5063 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
5064 (clobber (reg:CC 17))])]
5065 "operands[1] = GEN_INT (0x80000000);
5066 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
5069 [(set (match_operand 0 "memory_operand" "")
5070 (neg (match_operand 1 "memory_operand" "")))
5071 (clobber (reg:CC 17))]
5072 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5073 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5074 (clobber (reg:CC 17))])]
5077 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
5079 /* XFmode's size is 12, but only 10 bytes are used. */
5082 operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
5083 operands[0] = adj_offsettable_operand (operands[0], size - 1);
5084 operands[1] = GEN_INT (0x80);
5087 (define_expand "negdf2"
5088 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
5089 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
5090 (clobber (reg:CC 17))])]
5092 "ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
5094 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5095 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5097 (define_insn "*negdf2_if"
5098 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
5099 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
5100 (clobber (reg:CC 17))]
5101 "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
5105 [(set (match_operand:DF 0 "register_operand" "")
5106 (neg:DF (match_operand:DF 1 "register_operand" "")))
5107 (clobber (reg:CC 17))]
5108 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5110 (neg:DF (match_dup 1)))]
5114 [(set (match_operand:DF 0 "register_operand" "")
5115 (neg:DF (match_operand:DF 1 "register_operand" "")))
5116 (clobber (reg:CC 17))]
5117 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5118 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
5119 (clobber (reg:CC 17))])]
5120 "operands[4] = GEN_INT (0x80000000);
5121 split_di (operands+0, 1, operands+2, operands+3);")
5123 (define_expand "negxf2"
5124 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
5125 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
5126 (clobber (reg:CC 17))])]
5128 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
5130 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5131 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5133 (define_insn "*negxf2_if"
5134 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
5135 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
5136 (clobber (reg:CC 17))]
5137 "TARGET_80387 && ix86_unary_operator_ok (NEG, XFmode, operands)"
5141 [(set (match_operand:XF 0 "register_operand" "")
5142 (neg:XF (match_operand:XF 1 "register_operand" "")))
5143 (clobber (reg:CC 17))]
5144 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5146 (neg:XF (match_dup 1)))]
5150 [(set (match_operand:XF 0 "register_operand" "")
5151 (neg:XF (match_operand:XF 1 "register_operand" "")))
5152 (clobber (reg:CC 17))]
5153 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5154 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
5155 (clobber (reg:CC 17))])]
5156 "operands[1] = GEN_INT (0x8000);
5157 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
5159 ;; Conditionize these after reload. If they matches before reload, we
5160 ;; lose the clobber and ability to use integer instructions.
5162 (define_insn "*negsf2_1"
5163 [(set (match_operand:SF 0 "register_operand" "=f")
5164 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
5165 "TARGET_80387 && reload_completed"
5167 [(set_attr "type" "fsgn")
5168 (set_attr "ppro_uops" "few")])
5170 (define_insn "*negdf2_1"
5171 [(set (match_operand:DF 0 "register_operand" "=f")
5172 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
5173 "TARGET_80387 && reload_completed"
5175 [(set_attr "type" "fsgn")
5176 (set_attr "ppro_uops" "few")])
5178 (define_insn "*negextendsfdf2"
5179 [(set (match_operand:DF 0 "register_operand" "=f")
5180 (neg:DF (float_extend:DF
5181 (match_operand:SF 1 "register_operand" "0"))))]
5184 [(set_attr "type" "fsgn")
5185 (set_attr "ppro_uops" "few")])
5187 (define_insn "*negxf2_1"
5188 [(set (match_operand:XF 0 "register_operand" "=f")
5189 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
5190 "TARGET_80387 && reload_completed"
5192 [(set_attr "type" "fsgn")
5193 (set_attr "ppro_uops" "few")])
5195 (define_insn "*negextenddfxf2"
5196 [(set (match_operand:XF 0 "register_operand" "=f")
5197 (neg:XF (float_extend:XF
5198 (match_operand:DF 1 "register_operand" "0"))))]
5201 [(set_attr "type" "fsgn")
5202 (set_attr "ppro_uops" "few")])
5204 (define_insn "*negextendsfxf2"
5205 [(set (match_operand:XF 0 "register_operand" "=f")
5206 (neg:XF (float_extend:XF
5207 (match_operand:SF 1 "register_operand" "0"))))]
5210 [(set_attr "type" "fsgn")
5211 (set_attr "ppro_uops" "few")])
5213 ;; Absolute value instructions
5215 (define_expand "abssf2"
5216 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
5217 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
5218 (clobber (reg:CC 17))])]
5220 "ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
5222 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5223 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5225 (define_insn "*abssf2_if"
5226 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
5227 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
5228 (clobber (reg:CC 17))]
5229 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
5233 [(set (match_operand:SF 0 "register_operand" "")
5234 (abs:SF (match_operand:SF 1 "register_operand" "")))
5235 (clobber (reg:CC 17))]
5236 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
5238 (abs:SF (match_dup 1)))]
5242 [(set (match_operand:SF 0 "register_operand" "")
5243 (abs:SF (match_operand:SF 1 "register_operand" "")))
5244 (clobber (reg:CC 17))]
5245 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5246 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
5247 (clobber (reg:CC 17))])]
5248 "operands[1] = GEN_INT (~0x80000000);
5249 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
5252 [(set (match_operand 0 "memory_operand" "")
5253 (abs (match_operand 1 "memory_operand" "")))
5254 (clobber (reg:CC 17))]
5255 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5256 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5257 (clobber (reg:CC 17))])]
5260 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
5262 /* XFmode's size is 12, but only 10 bytes are used. */
5265 operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
5266 operands[0] = adj_offsettable_operand (operands[0], size - 1);
5267 operands[1] = GEN_INT (~0x80);
5270 (define_expand "absdf2"
5271 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
5272 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
5273 (clobber (reg:CC 17))])]
5275 "ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
5277 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5278 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5280 (define_insn "*absdf2_if"
5281 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
5282 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
5283 (clobber (reg:CC 17))]
5284 "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
5288 [(set (match_operand:DF 0 "register_operand" "")
5289 (abs:DF (match_operand:DF 1 "register_operand" "")))
5290 (clobber (reg:CC 17))]
5291 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5293 (abs:DF (match_dup 1)))]
5297 [(set (match_operand:DF 0 "register_operand" "")
5298 (abs:DF (match_operand:DF 1 "register_operand" "")))
5299 (clobber (reg:CC 17))]
5300 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5301 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
5302 (clobber (reg:CC 17))])]
5303 "operands[4] = GEN_INT (~0x80000000);
5304 split_di (operands+0, 1, operands+2, operands+3);")
5306 (define_expand "absxf2"
5307 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
5308 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
5309 (clobber (reg:CC 17))])]
5311 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
5313 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
5314 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
5316 (define_insn "*absxf2_if"
5317 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
5318 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
5319 (clobber (reg:CC 17))]
5320 "TARGET_80387 && ix86_unary_operator_ok (ABS, XFmode, operands)"
5324 [(set (match_operand:XF 0 "register_operand" "")
5325 (abs:XF (match_operand:XF 1 "register_operand" "")))
5326 (clobber (reg:CC 17))]
5327 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
5329 (abs:XF (match_dup 1)))]
5333 [(set (match_operand:XF 0 "register_operand" "")
5334 (abs:XF (match_operand:XF 1 "register_operand" "")))
5335 (clobber (reg:CC 17))]
5336 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
5337 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
5338 (clobber (reg:CC 17))])]
5339 "operands[1] = GEN_INT (~0x8000);
5340 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
5342 (define_insn "*abssf2_1"
5343 [(set (match_operand:SF 0 "register_operand" "=f")
5344 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
5345 "TARGET_80387 && reload_completed"
5347 [(set_attr "type" "fsgn")])
5349 (define_insn "*absdf2_1"
5350 [(set (match_operand:DF 0 "register_operand" "=f")
5351 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
5352 "TARGET_80387 && reload_completed"
5354 [(set_attr "type" "fsgn")])
5356 (define_insn "*absextendsfdf2"
5357 [(set (match_operand:DF 0 "register_operand" "=f")
5358 (abs:DF (float_extend:DF
5359 (match_operand:SF 1 "register_operand" "0"))))]
5362 [(set_attr "type" "fsgn")])
5364 (define_insn "*absxf2_1"
5365 [(set (match_operand:XF 0 "register_operand" "=f")
5366 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
5367 "TARGET_80387 && reload_completed"
5369 [(set_attr "type" "fsgn")])
5371 (define_insn "*absextenddfxf2"
5372 [(set (match_operand:XF 0 "register_operand" "=f")
5373 (abs:XF (float_extend:XF
5374 (match_operand:DF 1 "register_operand" "0"))))]
5377 [(set_attr "type" "fsgn")])
5379 (define_insn "*absextendsfxf2"
5380 [(set (match_operand:XF 0 "register_operand" "=f")
5381 (abs:XF (float_extend:XF
5382 (match_operand:SF 1 "register_operand" "0"))))]
5385 [(set_attr "type" "fsgn")])
5387 ;; One complement instructions
5389 (define_expand "one_cmplsi2"
5390 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5391 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
5393 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
5395 (define_insn "*one_cmplsi2_1"
5396 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5397 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
5398 "ix86_unary_operator_ok (NOT, SImode, operands)"
5400 [(set_attr "type" "negnot")])
5402 (define_insn "*one_cmplsi2_2"
5404 (compare:CCNO (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
5406 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5407 (not:SI (match_dup 1)))]
5408 "ix86_unary_operator_ok (NOT, SImode, operands)"
5410 [(set_attr "type" "alu1")])
5414 (compare:CCNO (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
5416 (set (match_operand:SI 0 "nonimmediate_operand" "")
5417 (not:SI (match_dup 1)))]
5419 [(parallel [(set (reg:CCNO 17)
5420 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
5423 (xor:SI (match_dup 1) (const_int -1)))])]
5426 (define_expand "one_cmplhi2"
5427 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5428 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
5430 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
5432 (define_insn "*one_cmplhi2_1"
5433 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5434 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
5435 "ix86_unary_operator_ok (NOT, HImode, operands)"
5437 [(set_attr "type" "negnot")])
5439 (define_insn "*one_cmplhi2_2"
5441 (compare:CCNO (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
5443 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5444 (not:HI (match_dup 1)))]
5445 "ix86_unary_operator_ok (NEG, HImode, operands)"
5447 [(set_attr "type" "alu1")])
5451 (compare:CCNO (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
5453 (set (match_operand:HI 0 "nonimmediate_operand" "")
5454 (not:HI (match_dup 1)))]
5456 [(parallel [(set (reg:CCNO 17)
5457 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
5460 (xor:HI (match_dup 1) (const_int -1)))])]
5463 ;; %%% Potential partial reg stall on alternative 1. What to do?
5464 (define_expand "one_cmplqi2"
5465 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5466 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
5468 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
5470 (define_insn "*one_cmplqi2_1"
5471 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
5472 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
5473 "ix86_unary_operator_ok (NOT, QImode, operands)"
5477 [(set_attr "type" "negnot")])
5479 (define_insn "*one_cmplqi2_2"
5481 (compare:CCNO (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
5483 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5484 (not:QI (match_dup 1)))]
5485 "ix86_unary_operator_ok (NOT, QImode, operands)"
5487 [(set_attr "type" "alu1")])
5491 (compare:CCNO (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
5493 (set (match_operand:QI 0 "nonimmediate_operand" "")
5494 (not:QI (match_dup 1)))]
5496 [(parallel [(set (reg:CCNO 17)
5497 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
5500 (xor:QI (match_dup 1) (const_int -1)))])]
5503 ;; Arithmetic shift instructions
5505 ;; DImode shifts are implemented using the i386 "shift double" opcode,
5506 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
5507 ;; is variable, then the count is in %cl and the "imm" operand is dropped
5508 ;; from the assembler input.
5510 ;; This instruction shifts the target reg/mem as usual, but instead of
5511 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
5512 ;; is a left shift double, bits are taken from the high order bits of
5513 ;; reg, else if the insn is a shift right double, bits are taken from the
5514 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
5515 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
5517 ;; Since sh[lr]d does not change the `reg' operand, that is done
5518 ;; separately, making all shifts emit pairs of shift double and normal
5519 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
5520 ;; support a 63 bit shift, each shift where the count is in a reg expands
5521 ;; to a pair of shifts, a branch, a shift by 32 and a label.
5523 ;; If the shift count is a constant, we need never emit more than one
5524 ;; shift pair, instead using moves and sign extension for counts greater
5527 (define_expand "ashldi3"
5528 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
5529 (ashift:DI (match_operand:DI 1 "register_operand" "0")
5530 (match_operand:QI 2 "nonmemory_operand" "Jc")))
5531 (clobber (reg:CC 17))])]
5535 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
5537 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
5542 (define_insn "ashldi3_1"
5543 [(set (match_operand:DI 0 "register_operand" "=r")
5544 (ashift:DI (match_operand:DI 1 "register_operand" "0")
5545 (match_operand:QI 2 "nonmemory_operand" "Jc")))
5546 (clobber (match_scratch:SI 3 "=&r"))
5547 (clobber (reg:CC 17))]
5550 [(set_attr "type" "multi")])
5552 (define_insn "*ashldi3_2"
5553 [(set (match_operand:DI 0 "register_operand" "=r")
5554 (ashift:DI (match_operand:DI 1 "register_operand" "0")
5555 (match_operand:QI 2 "nonmemory_operand" "Jc")))
5556 (clobber (reg:CC 17))]
5559 [(set_attr "type" "multi")])
5562 [(set (match_operand:DI 0 "register_operand" "")
5563 (ashift:DI (match_operand:DI 1 "register_operand" "")
5564 (match_operand:QI 2 "nonmemory_operand" "")))
5565 (clobber (match_scratch:SI 3 ""))
5566 (clobber (reg:CC 17))]
5567 "TARGET_CMOVE && reload_completed"
5569 "ix86_split_ashldi (operands, operands[3]); DONE;")
5572 [(set (match_operand:DI 0 "register_operand" "")
5573 (ashift:DI (match_operand:DI 1 "register_operand" "")
5574 (match_operand:QI 2 "nonmemory_operand" "")))
5575 (clobber (reg:CC 17))]
5578 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
5580 (define_insn "x86_shld_1"
5581 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
5582 (ior:SI (ashift:SI (match_dup 0)
5583 (match_operand:QI 2 "nonmemory_operand" "I,c"))
5584 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
5585 (minus:QI (const_int 32) (match_dup 2)))))
5586 (clobber (reg:CC 17))]
5589 shld{l}\\t{%2, %1, %0|%0, %1, %2}
5590 shld{l}\\t{%s2%1, %0|%0, %1, %2}"
5591 [(set_attr "type" "ishift")
5592 (set_attr "length_opcode" "3")
5593 (set_attr "pent_pair" "np")
5594 (set_attr "athlon_decode" "vector")
5595 (set_attr "ppro_uops" "few")])
5597 (define_expand "x86_shift_adj_1"
5599 (compare:CCNO (and:QI (match_operand:QI 2 "register_operand" "")
5602 (set (match_operand:SI 0 "register_operand" "")
5603 (if_then_else:SI (ne (reg:CCNO 17) (const_int 0))
5604 (match_operand:SI 1 "register_operand" "")
5607 (if_then_else:SI (ne (reg:CCNO 17) (const_int 0))
5608 (match_operand:SI 3 "register_operand" "r")
5613 (define_expand "x86_shift_adj_2"
5614 [(use (match_operand:SI 0 "register_operand" ""))
5615 (use (match_operand:SI 1 "register_operand" ""))
5616 (use (match_operand:QI 2 "register_operand" ""))]
5620 rtx label = gen_label_rtx ();
5623 emit_insn (gen_testqi_1 (operands[2], GEN_INT (32)));
5625 tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
5626 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
5627 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
5628 gen_rtx_LABEL_REF (VOIDmode, label),
5630 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
5631 JUMP_LABEL (tmp) = label;
5633 emit_move_insn (operands[0], operands[1]);
5634 emit_move_insn (operands[1], const0_rtx);
5637 LABEL_NUSES (label) = 1;
5642 (define_expand "ashlsi3"
5643 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5644 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
5645 (match_operand:QI 2 "nonmemory_operand" "")))
5646 (clobber (reg:CC 17))]
5648 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
5650 (define_insn "*ashlsi3_1"
5651 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5652 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
5653 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
5654 (clobber (reg:CC 17))]
5655 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
5658 switch (get_attr_type (insn))
5661 if (operands[2] != const1_rtx)
5663 if (!rtx_equal_p (operands[0], operands[1]))
5665 return \"add{l}\\t{%0, %0|%0, %0}\";
5668 if (GET_CODE (operands[2]) != CONST_INT
5669 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
5671 operands[1] = gen_rtx_MULT (SImode, operands[1],
5672 GEN_INT (1 << INTVAL (operands[2])));
5673 return \"lea{l}\\t{%a1, %0|%0, %a1}\";
5676 if (REG_P (operands[2]))
5677 return \"sal{l}\\t{%b2, %0|%0, %b2}\";
5679 return \"sal{l}\\t{%2, %0|%0, %2}\";
5683 (cond [(eq_attr "alternative" "1")
5684 (const_string "lea")
5685 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
5687 (match_operand 0 "register_operand" ""))
5688 (match_operand 2 "const1_operand" ""))
5689 (const_string "alu")
5691 (const_string "ishift")))])
5693 ;; Convert lea to the lea pattern to avoid flags dependency.
5695 [(set (match_operand:SI 0 "register_operand" "")
5696 (ashift:SI (match_operand:SI 1 "register_operand" "")
5697 (match_operand:QI 2 "immediate_operand" "")))
5698 (clobber (reg:CC 17))]
5700 && true_regnum (operands[0]) != true_regnum (operands[1])"
5702 (mult:SI (match_dup 1)
5704 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));")
5706 ;; This pattern can't accept a variable shift count, since shifts by
5707 ;; zero don't affect the flags. We assume that shifts by constant
5708 ;; zero are optimized away.
5709 (define_insn "*ashlsi3_cmpno"
5712 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5713 (match_operand:QI 2 "immediate_operand" "I"))
5715 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5716 (ashift:SI (match_dup 1) (match_dup 2)))]
5717 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
5720 switch (get_attr_type (insn))
5723 if (operands[2] != const1_rtx)
5725 return \"add{l}\\t{%0, %0|%0, %0}\";
5728 if (REG_P (operands[2]))
5729 return \"sal{l}\\t{%b2, %0|%0, %b2}\";
5731 return \"sal{l}\\t{%2, %0|%0, %2}\";
5735 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
5737 (match_operand 0 "register_operand" ""))
5738 (match_operand 2 "const1_operand" ""))
5739 (const_string "alu")
5741 (const_string "ishift")))])
5743 (define_expand "ashlhi3"
5744 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5745 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
5746 (match_operand:QI 2 "nonmemory_operand" "")))
5747 (clobber (reg:CC 17))]
5749 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
5751 (define_insn "*ashlhi3_1"
5752 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5753 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5754 (match_operand:QI 2 "nonmemory_operand" "cI")))
5755 (clobber (reg:CC 17))]
5756 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
5759 switch (get_attr_type (insn))
5762 if (operands[2] != const1_rtx)
5764 return \"add{w}\\t{%0, %0|%0, %0}\";
5767 if (REG_P (operands[2]))
5768 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
5770 return \"sal{w}\\t{%2, %0|%0, %2}\";
5774 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
5776 (match_operand 0 "register_operand" ""))
5777 (match_operand 2 "const1_operand" ""))
5778 (const_string "alu")
5780 (const_string "ishift")))])
5782 ;; This pattern can't accept a variable shift count, since shifts by
5783 ;; zero don't affect the flags. We assume that shifts by constant
5784 ;; zero are optimized away.
5785 (define_insn "*ashlhi3_cmpno"
5788 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5789 (match_operand:QI 2 "immediate_operand" "I"))
5791 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5792 (ashift:HI (match_dup 1) (match_dup 2)))]
5793 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
5796 switch (get_attr_type (insn))
5799 if (operands[2] != const1_rtx)
5801 return \"add{w}\\t{%0, %0|%0, %0}\";
5804 if (REG_P (operands[2]))
5805 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
5807 return \"sal{w}\\t{%2, %0|%0, %2}\";
5811 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
5813 (match_operand 0 "register_operand" ""))
5814 (match_operand 2 "const1_operand" ""))
5815 (const_string "alu")
5817 (const_string "ishift")))])
5819 (define_expand "ashlqi3"
5820 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5821 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
5822 (match_operand:QI 2 "nonmemory_operand" "")))
5823 (clobber (reg:CC 17))]
5825 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
5827 ;; %%% Potential partial reg stall on alternative 2. What to do?
5828 (define_insn "*ashlqi3_1"
5829 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
5830 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
5831 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
5832 (clobber (reg:CC 17))]
5833 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
5836 switch (get_attr_type (insn))
5839 if (operands[2] != const1_rtx)
5841 if (NON_QI_REG_P (operands[1]))
5842 return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
5844 return \"add{b}\\t{%0, %0|%0, %0}\";
5847 if (REG_P (operands[2]))
5849 if (NON_QI_REG_P (operands[1]))
5850 return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
5852 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
5856 if (NON_QI_REG_P (operands[1]))
5857 return \"sal{l}\\t{%2, %k0|%k0, %2}\";
5859 return \"sal{b}\\t{%2, %0|%0, %2}\";
5864 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
5866 (match_operand 0 "register_operand" ""))
5867 (match_operand 2 "const1_operand" ""))
5868 (const_string "alu")
5870 (const_string "ishift")))])
5872 ;; This pattern can't accept a variable shift count, since shifts by
5873 ;; zero don't affect the flags. We assume that shifts by constant
5874 ;; zero are optimized away.
5875 (define_insn "*ashlqi3_cmpno"
5878 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5879 (match_operand:QI 2 "immediate_operand" "I"))
5881 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5882 (ashift:QI (match_dup 1) (match_dup 2)))]
5883 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
5886 switch (get_attr_type (insn))
5889 if (operands[2] != const1_rtx)
5891 return \"add{b}\\t{%0, %0|%0, %0}\";
5894 if (REG_P (operands[2]))
5895 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
5897 return \"sal{b}\\t{%2, %0|%0, %2}\";
5901 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
5903 (match_operand 0 "register_operand" ""))
5904 (match_operand 2 "const1_operand" ""))
5905 (const_string "alu")
5907 (const_string "ishift")))])
5909 ;; See comment above `ashldi3' about how this works.
5911 (define_expand "ashrdi3"
5912 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
5913 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
5914 (match_operand:QI 2 "nonmemory_operand" "Jc")))
5915 (clobber (reg:CC 17))])]
5919 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
5921 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
5926 (define_insn "ashrdi3_1"
5927 [(set (match_operand:DI 0 "register_operand" "=r")
5928 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
5929 (match_operand:QI 2 "nonmemory_operand" "Jc")))
5930 (clobber (match_scratch:SI 3 "=&r"))
5931 (clobber (reg:CC 17))]
5934 [(set_attr "type" "multi")])
5936 (define_insn "*ashrdi3_2"
5937 [(set (match_operand:DI 0 "register_operand" "=r")
5938 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
5939 (match_operand:QI 2 "nonmemory_operand" "Jc")))
5940 (clobber (reg:CC 17))]
5943 [(set_attr "type" "multi")])
5946 [(set (match_operand:DI 0 "register_operand" "")
5947 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5948 (match_operand:QI 2 "nonmemory_operand" "")))
5949 (clobber (match_scratch:SI 3 ""))
5950 (clobber (reg:CC 17))]
5951 "TARGET_CMOVE && reload_completed"
5953 "ix86_split_ashrdi (operands, operands[3]); DONE;")
5956 [(set (match_operand:DI 0 "register_operand" "")
5957 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5958 (match_operand:QI 2 "nonmemory_operand" "")))
5959 (clobber (reg:CC 17))]
5962 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
5964 (define_insn "x86_shrd_1"
5965 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
5966 (ior:SI (ashiftrt:SI (match_dup 0)
5967 (match_operand:QI 2 "nonmemory_operand" "I,c"))
5968 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
5969 (minus:QI (const_int 32) (match_dup 2)))))
5970 (clobber (reg:CC 17))]
5973 shrd{l}\\t{%2, %1, %0|%0, %1, %2}
5974 shrd{l}\\t{%s2%1, %0|%0, %1, %2}"
5975 [(set_attr "type" "ishift")
5976 (set_attr "length_opcode" "3")
5977 (set_attr "pent_pair" "np")
5978 (set_attr "ppro_uops" "few")])
5980 (define_expand "x86_shift_adj_3"
5981 [(use (match_operand:SI 0 "register_operand" ""))
5982 (use (match_operand:SI 1 "register_operand" ""))
5983 (use (match_operand:QI 2 "register_operand" ""))]
5987 rtx label = gen_label_rtx ();
5990 emit_insn (gen_testqi_1 (operands[2], GEN_INT (32)));
5992 tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
5993 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
5994 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
5995 gen_rtx_LABEL_REF (VOIDmode, label),
5997 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
5998 JUMP_LABEL (tmp) = label;
6000 emit_move_insn (operands[0], operands[1]);
6001 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
6004 LABEL_NUSES (label) = 1;
6009 (define_insn "ashrsi3_31"
6010 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
6011 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
6012 (match_operand:SI 2 "const_int_operand" "i,i")))
6013 (clobber (reg:CC 17))]
6014 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
6015 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6018 sar{l}\\t{%2, %0|%0, %2}"
6019 [(set_attr "type" "imovx,ishift")
6020 (set_attr "length" "1,*")])
6022 (define_expand "ashrsi3"
6023 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6024 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
6025 (match_operand:QI 2 "nonmemory_operand" "")))
6026 (clobber (reg:CC 17))]
6028 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
6030 (define_insn "*ashrsi3_1"
6031 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6032 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6033 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6034 (clobber (reg:CC 17))]
6035 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6037 sar{l}\\t{%2, %0|%0, %2}
6038 sar{l}\\t{%b2, %0|%0, %b2}"
6039 [(set_attr "type" "ishift")])
6041 ;; This pattern can't accept a variable shift count, since shifts by
6042 ;; zero don't affect the flags. We assume that shifts by constant
6043 ;; zero are optimized away.
6044 (define_insn "*ashrsi3_cmpno"
6047 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6048 (match_operand:QI 2 "immediate_operand" "I"))
6050 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6051 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
6052 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
6054 sar{l}\\t{%2, %0|%0, %2}"
6055 [(set_attr "type" "ishift")])
6057 (define_expand "ashrhi3"
6058 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6059 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
6060 (match_operand:QI 2 "nonmemory_operand" "")))
6061 (clobber (reg:CC 17))]
6063 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
6065 (define_insn "*ashrhi3_1"
6066 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
6067 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6068 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6069 (clobber (reg:CC 17))]
6070 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
6072 sar{w}\\t{%2, %0|%0, %2}
6073 sar{w}\\t{%b2, %0|%0, %b2}"
6074 [(set_attr "type" "ishift")])
6076 ;; This pattern can't accept a variable shift count, since shifts by
6077 ;; zero don't affect the flags. We assume that shifts by constant
6078 ;; zero are optimized away.
6079 (define_insn "*ashrhi3_cmpno"
6082 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6083 (match_operand:QI 2 "immediate_operand" "I"))
6085 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6086 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
6087 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
6089 sar{w}\\t{%2, %0|%0, %2}"
6090 [(set_attr "type" "ishift")])
6092 (define_expand "ashrqi3"
6093 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6094 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
6095 (match_operand:QI 2 "nonmemory_operand" "")))
6096 (clobber (reg:CC 17))]
6098 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
6100 (define_insn "*ashrqi3_1"
6101 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
6102 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6103 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6104 (clobber (reg:CC 17))]
6105 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
6107 sar{b}\\t{%2, %0|%0, %2}
6108 sar{b}\\t{%b2, %0|%0, %b2}"
6109 [(set_attr "type" "ishift")])
6111 ;; This pattern can't accept a variable shift count, since shifts by
6112 ;; zero don't affect the flags. We assume that shifts by constant
6113 ;; zero are optimized away.
6114 (define_insn "*ashrqi3_cmpno"
6117 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6118 (match_operand:QI 2 "immediate_operand" "I"))
6120 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
6121 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
6122 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
6124 sar{b}\\t{%2, %0|%0, %2}"
6125 [(set_attr "type" "ishift")])
6127 ;; Logical shift instructions
6129 ;; See comment above `ashldi3' about how this works.
6131 (define_expand "lshrdi3"
6132 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
6133 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
6134 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6135 (clobber (reg:CC 17))])]
6139 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
6141 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
6146 (define_insn "lshrdi3_1"
6147 [(set (match_operand:DI 0 "register_operand" "=r")
6148 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
6149 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6150 (clobber (match_scratch:SI 3 "=&r"))
6151 (clobber (reg:CC 17))]
6154 [(set_attr "type" "multi")])
6156 (define_insn "*lshrdi3_2"
6157 [(set (match_operand:DI 0 "register_operand" "=r")
6158 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
6159 (match_operand:QI 2 "nonmemory_operand" "Jc")))
6160 (clobber (reg:CC 17))]
6163 [(set_attr "type" "multi")])
6166 [(set (match_operand:DI 0 "register_operand" "")
6167 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6168 (match_operand:QI 2 "nonmemory_operand" "")))
6169 (clobber (match_scratch:SI 3 ""))
6170 (clobber (reg:CC 17))]
6171 "TARGET_CMOVE && reload_completed"
6173 "ix86_split_lshrdi (operands, operands[3]); DONE;")
6176 [(set (match_operand:DI 0 "register_operand" "")
6177 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6178 (match_operand:QI 2 "nonmemory_operand" "")))
6179 (clobber (reg:CC 17))]
6182 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
6184 (define_expand "lshrsi3"
6185 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6186 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
6187 (match_operand:QI 2 "nonmemory_operand" "")))
6188 (clobber (reg:CC 17))]
6190 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
6192 (define_insn "*lshrsi3_1"
6193 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6194 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6195 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6196 (clobber (reg:CC 17))]
6197 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6199 shr{l}\\t{%2, %0|%0, %2}
6200 shr{l}\\t{%b2, %0|%0, %b2}"
6201 [(set_attr "type" "ishift")])
6203 ;; This pattern can't accept a variable shift count, since shifts by
6204 ;; zero don't affect the flags. We assume that shifts by constant
6205 ;; zero are optimized away.
6206 (define_insn "*lshrsi3_cmpno"
6209 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6210 (match_operand:QI 2 "immediate_operand" "I"))
6212 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6213 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
6214 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6216 shr{l}\\t{%2, %0|%0, %2}"
6217 [(set_attr "type" "ishift")])
6219 (define_expand "lshrhi3"
6220 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6221 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
6222 (match_operand:QI 2 "nonmemory_operand" "")))
6223 (clobber (reg:CC 17))]
6225 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
6227 (define_insn "*lshrhi3_1"
6228 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
6229 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6230 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6231 (clobber (reg:CC 17))]
6232 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6234 shr{w}\\t{%2, %0|%0, %2}
6235 shr{w}\\t{%b2, %0|%0, %b2}"
6236 [(set_attr "type" "ishift")])
6238 ;; This pattern can't accept a variable shift count, since shifts by
6239 ;; zero don't affect the flags. We assume that shifts by constant
6240 ;; zero are optimized away.
6241 (define_insn "*lshrhi3_cmpno"
6244 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
6245 (match_operand:QI 2 "immediate_operand" "I"))
6247 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6248 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
6249 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
6251 shr{w}\\t{%2, %0|%0, %2}"
6252 [(set_attr "type" "ishift")])
6254 (define_expand "lshrqi3"
6255 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6256 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
6257 (match_operand:QI 2 "nonmemory_operand" "")))
6258 (clobber (reg:CC 17))]
6260 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
6262 (define_insn "*lshrqi3_1"
6263 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
6264 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6265 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6266 (clobber (reg:CC 17))]
6267 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
6269 shr{b}\\t{%2, %0|%0, %2}
6270 shr{b}\\t{%b2, %0|%0, %b2}"
6271 [(set_attr "type" "ishift")])
6273 ;; This pattern can't accept a variable shift count, since shifts by
6274 ;; zero don't affect the flags. We assume that shifts by constant
6275 ;; zero are optimized away.
6276 (define_insn "*lshrqi2_cmpno"
6279 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
6280 (match_operand:QI 2 "immediate_operand" "I"))
6282 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
6283 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
6284 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
6286 shr{b}\\t{%2, %0|%0, %2}"
6287 [(set_attr "type" "ishift")])
6289 ;; Rotate instructions
6291 (define_expand "rotlsi3"
6292 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6293 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
6294 (match_operand:QI 2 "nonmemory_operand" "")))
6295 (clobber (reg:CC 17))]
6297 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
6299 (define_insn "*rotlsi3_1"
6300 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6301 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6302 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6303 (clobber (reg:CC 17))]
6304 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
6306 rol{l}\\t{%2, %0|%0, %2}
6307 rol{l}\\t{%b2, %0|%0, %b2}"
6308 [(set_attr "type" "ishift")])
6310 (define_expand "rotlhi3"
6311 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6312 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
6313 (match_operand:QI 2 "nonmemory_operand" "")))
6314 (clobber (reg:CC 17))]
6316 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
6318 (define_insn "*rotlhi3_1"
6319 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
6320 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6321 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6322 (clobber (reg:CC 17))]
6323 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
6325 rol{w}\\t{%2, %0|%0, %2}
6326 rol{w}\\t{%b2, %0|%0, %b2}"
6327 [(set_attr "type" "ishift")])
6329 (define_expand "rotlqi3"
6330 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6331 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
6332 (match_operand:QI 2 "nonmemory_operand" "")))
6333 (clobber (reg:CC 17))]
6335 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
6337 (define_insn "*rotlqi3_1"
6338 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
6339 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6340 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6341 (clobber (reg:CC 17))]
6342 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
6344 rol{b}\\t{%2, %0|%0, %2}
6345 rol{b}\\t{%b2, %0|%0, %b2}"
6346 [(set_attr "type" "ishift")])
6348 (define_expand "rotrsi3"
6349 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6350 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
6351 (match_operand:QI 2 "nonmemory_operand" "")))
6352 (clobber (reg:CC 17))]
6354 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
6356 (define_insn "*rotrsi3_1"
6357 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6358 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6359 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6360 (clobber (reg:CC 17))]
6361 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
6363 ror{l}\\t{%2, %0|%0, %2}
6364 ror{l}\\t{%b2, %0|%0, %b2}"
6365 [(set_attr "type" "ishift")])
6367 (define_expand "rotrhi3"
6368 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6369 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
6370 (match_operand:QI 2 "nonmemory_operand" "")))
6371 (clobber (reg:CC 17))]
6373 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
6375 (define_insn "*rotrhi3"
6376 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
6377 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6378 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6379 (clobber (reg:CC 17))]
6380 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
6382 ror{w}\\t{%2, %0|%0, %2}
6383 ror{w}\\t{%b2, %0|%0, %b2}"
6384 [(set_attr "type" "ishift")])
6386 (define_expand "rotrqi3"
6387 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6388 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
6389 (match_operand:QI 2 "nonmemory_operand" "")))
6390 (clobber (reg:CC 17))]
6392 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
6394 (define_insn "*rotrqi3_1"
6395 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
6396 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6397 (match_operand:QI 2 "nonmemory_operand" "I,c")))
6398 (clobber (reg:CC 17))]
6399 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
6401 ror{b}\\t{%2, %0|%0, %2}
6402 ror{b}\\t{%b2, %0|%0, %b2}"
6403 [(set_attr "type" "ishift")])
6405 ;; Bit set / bit test instructions
6407 (define_expand "extv"
6408 [(set (match_operand:SI 0 "register_operand" "")
6409 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
6410 (match_operand:SI 2 "immediate_operand" "")
6411 (match_operand:SI 3 "immediate_operand" "")))]
6415 /* Handle extractions from %ah et al. */
6416 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
6419 /* From mips.md: extract_bit_field doesn't verify that our source
6420 matches the predicate, so check it again here. */
6421 if (! register_operand (operands[1], VOIDmode))
6425 (define_expand "extzv"
6426 [(set (match_operand:SI 0 "register_operand" "")
6427 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
6428 (match_operand:SI 2 "immediate_operand" "")
6429 (match_operand:SI 3 "immediate_operand" "")))]
6433 /* Handle extractions from %ah et al. */
6434 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
6437 /* From mips.md: extract_bit_field doesn't verify that our source
6438 matches the predicate, so check it again here. */
6439 if (! register_operand (operands[1], VOIDmode))
6443 (define_expand "insv"
6444 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
6445 (match_operand:SI 1 "immediate_operand" "")
6446 (match_operand:SI 2 "immediate_operand" ""))
6447 (match_operand:SI 3 "register_operand" ""))]
6451 /* Handle extractions from %ah et al. */
6452 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
6455 /* From mips.md: insert_bit_field doesn't verify that our source
6456 matches the predicate, so check it again here. */
6457 if (! register_operand (operands[0], VOIDmode))
6461 ;; %%% bts, btr, btc, bt.
6463 ;; Store-flag instructions.
6465 ;; For all sCOND expanders, also expand the compare or test insn that
6466 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
6468 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
6469 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
6470 ;; way, which can later delete the movzx if only QImode is needed.
6472 (define_expand "seq"
6473 [(set (match_operand:SI 0 "register_operand" "")
6474 (eq:SI (reg:CC 17) (const_int 0)))]
6476 "if (ix86_expand_setcc (EQ, 1, operands[0])) DONE; else FAIL;")
6478 (define_expand "sne"
6479 [(set (match_operand:SI 0 "register_operand" "")
6480 (ne:SI (reg:CC 17) (const_int 0)))]
6482 "if (ix86_expand_setcc (NE, 1, operands[0])) DONE; else FAIL;")
6484 (define_expand "sgt"
6485 [(set (match_operand:SI 0 "register_operand" "")
6486 (gt:SI (reg:CC 17) (const_int 0)))]
6488 "if (ix86_expand_setcc (GT, 0, operands[0])) DONE; else FAIL;")
6490 (define_expand "sgtu"
6491 [(set (match_operand:SI 0 "register_operand" "")
6492 (gtu:SI (reg:CC 17) (const_int 0)))]
6494 "if (ix86_expand_setcc (GTU, 0, operands[0])) DONE; else FAIL;")
6496 (define_expand "slt"
6497 [(set (match_operand:SI 0 "register_operand" "")
6498 (lt:SI (reg:CC 17) (const_int 0)))]
6500 "if (ix86_expand_setcc (LT, 0, operands[0])) DONE; else FAIL;")
6502 (define_expand "sltu"
6503 [(set (match_operand:SI 0 "register_operand" "")
6504 (ltu:SI (reg:CC 17) (const_int 0)))]
6506 "if (ix86_expand_setcc (LTU, 0, operands[0])) DONE; else FAIL;")
6508 (define_expand "sge"
6509 [(set (match_operand:SI 0 "register_operand" "")
6510 (ge:SI (reg:CC 17) (const_int 0)))]
6512 "if (ix86_expand_setcc (GE, 0, operands[0])) DONE; else FAIL;")
6514 (define_expand "sgeu"
6515 [(set (match_operand:SI 0 "register_operand" "")
6516 (geu:SI (reg:CC 17) (const_int 0)))]
6518 "if (ix86_expand_setcc (GEU, 0, operands[0])) DONE; else FAIL;")
6520 (define_expand "sle"
6521 [(set (match_operand:SI 0 "register_operand" "")
6522 (le:SI (reg:CC 17) (const_int 0)))]
6524 "if (ix86_expand_setcc (LE, 0, operands[0])) DONE; else FAIL;")
6526 (define_expand "sleu"
6527 [(set (match_operand:SI 0 "register_operand" "")
6528 (leu:SI (reg:CC 17) (const_int 0)))]
6530 "if (ix86_expand_setcc (LEU, 0, operands[0])) DONE; else FAIL;")
6532 (define_insn "*setcc_1"
6533 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6534 (match_operator:QI 1 "no_comparison_operator"
6535 [(reg 17) (const_int 0)]))]
6538 [(set_attr "type" "setcc")])
6540 (define_insn "*setcc_2"
6541 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
6542 (match_operator:QI 1 "no_comparison_operator"
6543 [(reg 17) (const_int 0)]))]
6546 [(set_attr "type" "setcc")])
6548 (define_insn "*setcc_3"
6549 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6550 (match_operator:QI 1 "comparison_operator"
6551 [(reg:CC 17) (const_int 0)]))]
6554 [(set_attr "type" "setcc")])
6556 (define_insn "*setcc_4"
6557 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
6558 (match_operator:QI 1 "comparison_operator"
6559 [(reg:CC 17) (const_int 0)]))]
6562 [(set_attr "type" "setcc")])
6564 ;; Basic conditional jump instructions.
6565 ;; We ignore the overflow flag for signed branch instructions.
6567 ;; For all bCOND expanders, also expand the compare or test insn that
6568 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
6570 (define_expand "beq"
6572 (if_then_else (match_dup 1)
6573 (label_ref (match_operand 0 "" ""))
6576 "ix86_expand_branch (EQ, 1, operands[0]); DONE;")
6578 (define_expand "bne"
6580 (if_then_else (match_dup 1)
6581 (label_ref (match_operand 0 "" ""))
6584 "ix86_expand_branch (NE, 1, operands[0]); DONE;")
6586 (define_expand "bgt"
6588 (if_then_else (match_dup 1)
6589 (label_ref (match_operand 0 "" ""))
6592 "ix86_expand_branch (GT, 0, operands[0]); DONE;")
6594 (define_expand "bgtu"
6596 (if_then_else (match_dup 1)
6597 (label_ref (match_operand 0 "" ""))
6600 "ix86_expand_branch (GTU, 0, operands[0]); DONE;")
6602 (define_expand "blt"
6604 (if_then_else (match_dup 1)
6605 (label_ref (match_operand 0 "" ""))
6608 "ix86_expand_branch (LT, 0, operands[0]); DONE;")
6610 (define_expand "bltu"
6612 (if_then_else (match_dup 1)
6613 (label_ref (match_operand 0 "" ""))
6616 "ix86_expand_branch (LTU, 0, operands[0]); DONE;")
6618 (define_expand "bge"
6620 (if_then_else (match_dup 1)
6621 (label_ref (match_operand 0 "" ""))
6624 "ix86_expand_branch (GE, 0, operands[0]); DONE;")
6626 (define_expand "bgeu"
6628 (if_then_else (match_dup 1)
6629 (label_ref (match_operand 0 "" ""))
6632 "ix86_expand_branch (GEU, 0, operands[0]); DONE;")
6634 (define_expand "ble"
6636 (if_then_else (match_dup 1)
6637 (label_ref (match_operand 0 "" ""))
6640 "ix86_expand_branch (LE, 0, operands[0]); DONE;")
6642 (define_expand "bleu"
6644 (if_then_else (match_dup 1)
6645 (label_ref (match_operand 0 "" ""))
6648 "ix86_expand_branch (LEU, 0, operands[0]); DONE;")
6650 (define_insn "*jcc_1"
6652 (if_then_else (match_operator 0 "no_comparison_operator"
6653 [(reg 17) (const_int 0)])
6654 (label_ref (match_operand 1 "" ""))
6658 [(set_attr "type" "ibr")
6659 (set (attr "length")
6660 (if_then_else (and (ge (minus (match_dup 1) (pc))
6662 (lt (minus (match_dup 1) (pc))
6667 (define_insn "*jcc_2"
6669 (if_then_else (match_operator 0 "no_comparison_operator"
6670 [(reg 17) (const_int 0)])
6672 (label_ref (match_operand 1 "" ""))))]
6675 [(set_attr "type" "ibr")
6676 (set (attr "length")
6677 (if_then_else (and (ge (minus (match_dup 1) (pc))
6679 (lt (minus (match_dup 1) (pc))
6684 (define_insn "*jcc_3"
6686 (if_then_else (match_operator 0 "comparison_operator"
6687 [(reg:CC 17) (const_int 0)])
6688 (label_ref (match_operand 1 "" ""))
6692 [(set_attr "type" "ibr")
6693 (set (attr "length")
6694 (if_then_else (and (ge (minus (match_dup 1) (pc))
6696 (lt (minus (match_dup 1) (pc))
6701 (define_insn "*jcc_4"
6703 (if_then_else (match_operator 0 "comparison_operator"
6704 [(reg:CC 17) (const_int 0)])
6706 (label_ref (match_operand 1 "" ""))))]
6709 [(set_attr "type" "ibr")
6710 (set (attr "length")
6711 (if_then_else (and (ge (minus (match_dup 1) (pc))
6713 (lt (minus (match_dup 1) (pc))
6718 ;; Unconditional and other jump instructions
6722 (label_ref (match_operand 0 "" "")))]
6725 [(set_attr "type" "ibr")
6726 (set (attr "length")
6727 (if_then_else (and (ge (minus (match_dup 0) (pc))
6729 (lt (minus (match_dup 0) (pc))
6734 (define_insn "indirect_jump"
6735 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
6738 [(set_attr "type" "ibr")])
6740 (define_insn "tablejump"
6741 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
6742 (use (label_ref (match_operand 1 "" "")))]
6745 [(set_attr "type" "ibr")])
6747 ;; Implement switch statements when generating PIC code. Switches are
6748 ;; implemented by `tablejump' when not using -fpic.
6750 ;; Emit code here to do the range checking and make the index zero based.
6752 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
6755 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
6757 ;; 1. An expression involving an external reference may only use the
6758 ;; addition operator, and only with an assembly-time constant.
6759 ;; The example above satisfies this because ".-.L2" is a constant.
6761 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
6762 ;; given the value of "GOT - .", where GOT is the actual address of
6763 ;; the Global Offset Table. Therefore, the .long above actually
6764 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
6765 ;; expression "GOT - .L2" by itself would generate an error from as(1).
6767 ;; The pattern below emits code that looks like this:
6770 ;; subl TABLE@GOTOFF(%ebx,index,4),reg
6773 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
6774 ;; the addr_diff_vec is known to be part of this module.
6776 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
6777 ;; evaluates to just ".L2".
6779 (define_expand "casesi"
6781 (match_operand:SI 0 "general_operand" ""))
6782 (parallel [(set (match_dup 6)
6783 (minus:SI (match_dup 5)
6784 (match_operand:SI 1 "general_operand" "")))
6785 (clobber (reg:CC 17))])
6787 (compare:CC (match_dup 6)
6788 (match_operand:SI 2 "general_operand" "")))
6790 (if_then_else (gtu (reg:CC 17)
6792 (label_ref (match_operand 4 "" ""))
6796 (minus:SI (match_dup 8)
6797 (mem:SI (plus:SI (plus:SI (mult:SI (match_dup 6) (const_int 4))
6799 (const (unspec [(label_ref (match_operand 3 "" ""))] 7))))))
6800 (clobber (reg:CC 17))])
6801 (parallel [(set (pc) (match_dup 7))
6802 (use (label_ref (match_dup 3)))])]
6806 operands[5] = gen_reg_rtx (SImode);
6807 operands[6] = gen_reg_rtx (SImode);
6808 operands[7] = gen_reg_rtx (SImode);
6809 operands[8] = pic_offset_table_rtx;
6810 current_function_uses_pic_offset_table = 1;
6813 (define_insn "*tablejump_pic"
6814 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
6815 (use (label_ref (match_operand 1 "" "")))]
6818 [(set_attr "type" "ibr")])
6822 ;; This is all complicated by the fact that since this is a jump insn
6823 ;; we must handle our own reloads.
6825 (define_expand "decrement_and_branch_on_count"
6826 [(parallel [(set (pc) (if_then_else
6827 (ne (match_operand:SI 0 "register_operand" "")
6829 (label_ref (match_operand 1 "" ""))
6832 (plus:SI (match_dup 0)
6834 (clobber (match_scratch:SI 2 ""))
6835 (clobber (reg:CC 17))])]
6839 (define_insn "*dbra_ne"
6841 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
6843 (label_ref (match_operand 0 "" ""))
6845 (set (match_operand:SI 2 "register_operand" "=1,*r,*m*r")
6846 (plus:SI (match_dup 1)
6848 (clobber (match_scratch:SI 3 "=X,X,r"))
6849 (clobber (reg:CC 17))]
6853 if (which_alternative != 0)
6855 if (get_attr_length (insn) == 2)
6856 return \"loop\\t%l0\";
6858 return \"dec{l}\\t%1\;jne\\t%l0\";
6860 [(set_attr "type" "ibr")
6861 (set_attr "ppro_uops" "many")
6862 (set (attr "length")
6863 (if_then_else (and (eq_attr "alternative" "0")
6864 (and (ge (minus (match_dup 0) (pc))
6866 (lt (minus (match_dup 0) (pc))
6871 (define_insn "*dbra_ge"
6873 (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
6875 (label_ref (match_operand 0 "" ""))
6877 (set (match_operand:SI 2 "register_operand" "=1,*r,*m*r")
6878 (plus:SI (match_dup 1)
6880 (clobber (match_scratch:SI 3 "=X,X,r"))
6881 (clobber (reg:CC 17))]
6882 "TARGET_USE_LOOP && find_reg_note (insn, REG_NONNEG, 0)"
6885 if (which_alternative != 0)
6887 if (get_attr_length (insn) == 2)
6888 return \"loop\\t%l0\";
6890 return \"dec{l}\\t%1\;jne\\t%l0\";
6892 [(set_attr "type" "ibr")
6893 (set_attr "ppro_uops" "many")
6894 (set (attr "length")
6895 (if_then_else (and (eq_attr "alternative" "0")
6896 (and (ge (minus (match_dup 0) (pc))
6898 (lt (minus (match_dup 0) (pc))
6905 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
6907 (match_operand 0 "" "")
6909 (set (match_operand:SI 2 "register_operand" "")
6910 (plus:SI (match_dup 1)
6912 (clobber (match_scratch:SI 3 ""))
6913 (clobber (reg:CC 17))]
6914 "TARGET_USE_LOOP && reload_completed
6915 && ! (REGNO (operands[1]) == 2 && rtx_equal_p (operands[1], operands[2]))"
6916 [(set (match_dup 2) (match_dup 1))
6917 (parallel [(set (reg:CCNO 17)
6918 (compare:CCNO (plus:SI (match_dup 2) (const_int -1))
6920 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
6921 (set (pc) (if_then_else (ne (reg:CCNO 17) (const_int 0))
6928 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
6930 (match_operand 0 "" "")
6932 (set (match_operand:SI 2 "memory_operand" "")
6933 (plus:SI (match_dup 1)
6935 (clobber (match_scratch:SI 3 ""))
6936 (clobber (reg:CC 17))]
6937 "TARGET_USE_LOOP && reload_completed"
6938 [(set (match_dup 3) (match_dup 1))
6939 (parallel [(set (reg:CCNO 17)
6940 (compare:CCNO (plus:SI (match_dup 3) (const_int -1))
6942 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
6943 (set (match_dup 2) (match_dup 3))
6944 (set (pc) (if_then_else (ne (reg:CCNO 17) (const_int 0))
6951 (if_then_else (ge (match_operand:SI 1 "register_operand" "")
6953 (match_operand 0 "" "")
6955 (set (match_operand:SI 2 "register_operand" "")
6956 (plus:SI (match_dup 1)
6958 (clobber (match_scratch:SI 3 ""))
6959 (clobber (reg:CC 17))]
6960 "TARGET_USE_LOOP && reload_completed
6961 && ! (REGNO (operands[1]) == 2 && rtx_equal_p (operands[1], operands[2]))"
6962 [(set (match_dup 2) (match_dup 1))
6963 (parallel [(set (reg:CCNO 17)
6964 (compare:CCNO (plus:SI (match_dup 2) (const_int -1))
6966 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
6967 (set (pc) (if_then_else (lt (reg:CCNO 17) (const_int 0))
6974 (if_then_else (ge (match_operand:SI 1 "register_operand" "")
6976 (match_operand 0 "" "")
6978 (set (match_operand:SI 2 "memory_operand" "")
6979 (plus:SI (match_dup 1)
6981 (clobber (match_scratch:SI 3 ""))
6982 (clobber (reg:CC 17))]
6983 "TARGET_USE_LOOP && reload_completed"
6984 [(set (match_dup 3) (match_dup 1))
6985 (parallel [(set (reg:CCNO 17)
6986 (compare:CCNO (plus:SI (match_dup 3) (const_int -1))
6988 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
6989 (set (match_dup 2) (match_dup 3))
6990 (set (pc) (if_then_else (lt (reg:CCNO 17) (const_int 0))
6995 ;; Call instructions.
6997 ;; If generating PIC code, the predicate indirect_operand will fail
6998 ;; for operands[0] containing symbolic references on all of the named
6999 ;; call* patterns. Each named pattern is followed by an unnamed pattern
7000 ;; that matches any call to a symbolic CONST (ie, a symbol_ref). The
7001 ;; unnamed patterns are only used while generating PIC code, because
7002 ;; otherwise the named patterns match.
7004 ;; Call subroutine returning no value.
7006 (define_expand "call_pop"
7007 [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
7008 (match_operand:SI 1 "general_operand" ""))
7011 (match_operand:SI 3 "immediate_operand" "")))])]
7017 if (operands[3] == const0_rtx)
7019 emit_insn (gen_call (operands[0], operands[1]));
7024 current_function_uses_pic_offset_table = 1;
7026 /* With half-pic, force the address into a register. */
7027 addr = XEXP (operands[0], 0);
7028 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
7029 XEXP (operands[0], 0) = force_reg (Pmode, addr);
7031 if (! expander_call_insn_operand (operands[0], QImode))
7033 = change_address (operands[0], VOIDmode,
7034 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
7037 (define_insn "*call_pop_pic"
7038 [(call (match_operand:QI 0 "call_insn_operand" "m")
7039 (match_operand:SI 1 "general_operand" "g"))
7040 (set (reg:SI 7) (plus:SI (reg:SI 7)
7041 (match_operand:SI 3 "immediate_operand" "i")))]
7045 if (constant_call_address_operand (operands[0], GET_MODE (operands[0])))
7046 return \"call\\t%P0\";
7048 operands[0] = XEXP (operands[0], 0);
7049 return \"call\\t%*%0\";
7051 [(set_attr "type" "call")])
7053 (define_insn "*call_pop_pic2"
7054 [(call (match_operand:QI 0 "constant_call_address_operand" "")
7055 (match_operand:SI 1 "general_operand" "g"))
7056 (set (reg:SI 7) (plus:SI (reg:SI 7)
7057 (match_operand:SI 3 "immediate_operand" "i")))]
7060 [(set_attr "type" "call")])
7062 (define_expand "call"
7063 [(call (match_operand:QI 0 "indirect_operand" "")
7064 (match_operand:SI 1 "general_operand" ""))]
7065 ;; Operand 1 not used on the i386.
7072 current_function_uses_pic_offset_table = 1;
7074 /* With half-pic, force the address into a register. */
7075 addr = XEXP (operands[0], 0);
7076 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
7077 XEXP (operands[0], 0) = force_reg (Pmode, addr);
7079 if (! expander_call_insn_operand (operands[0], QImode))
7081 = change_address (operands[0], VOIDmode,
7082 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
7085 (define_insn "*call_pic"
7086 [(call (match_operand:QI 0 "call_insn_operand" "m")
7087 (match_operand:SI 1 "general_operand" "g"))]
7088 ;; Operand 1 not used on the i386.
7092 if (constant_call_address_operand (operands[0], GET_MODE (operands[0])))
7093 return \"call\\t%P0\";
7095 operands[0] = XEXP (operands[0], 0);
7096 return \"call\\t%*%0\";
7098 [(set_attr "type" "call")])
7100 (define_insn "*call_pic2"
7101 [(call (match_operand:QI 0 "constant_call_address_operand" "")
7102 (match_operand:SI 1 "general_operand" "g"))]
7105 [(set_attr "type" "call")])
7107 ;; Call subroutine, returning value in operand 0
7108 ;; (which must be a hard register).
7110 (define_expand "call_value_pop"
7111 [(parallel [(set (match_operand 0 "" "")
7112 (call (match_operand:QI 1 "indirect_operand" "")
7113 (match_operand:SI 2 "general_operand" "")))
7116 (match_operand:SI 4 "immediate_operand" "")))])]
7122 if (operands[4] == const0_rtx)
7124 emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
7129 current_function_uses_pic_offset_table = 1;
7131 /* With half-pic, force the address into a register. */
7132 addr = XEXP (operands[1], 0);
7133 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
7134 XEXP (operands[1], 0) = force_reg (Pmode, addr);
7136 if (! expander_call_insn_operand (operands[1], QImode))
7138 = change_address (operands[1], VOIDmode,
7139 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
7142 (define_expand "call_value"
7143 [(set (match_operand 0 "" "")
7144 (call (match_operand:QI 1 "indirect_operand" "")
7145 (match_operand:SI 2 "general_operand" "")))]
7146 ;; Operand 2 not used on the i386.
7153 current_function_uses_pic_offset_table = 1;
7155 /* With half-pic, force the address into a register. */
7156 addr = XEXP (operands[1], 0);
7157 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
7158 XEXP (operands[1], 0) = force_reg (Pmode, addr);
7160 if (! expander_call_insn_operand (operands[1], QImode))
7162 = change_address (operands[1], VOIDmode,
7163 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
7166 ;; Call subroutine returning any type.
7168 (define_expand "untyped_call"
7169 [(parallel [(call (match_operand 0 "" "")
7171 (match_operand 1 "" "")
7172 (match_operand 2 "" "")])]
7178 /* In order to give reg-stack an easier job in validating two
7179 coprocessor registers as containing a possible return value,
7180 simply pretend the untyped call returns a complex long double
7183 emit_call_insn (TARGET_80387
7184 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
7185 operands[0], const0_rtx)
7186 : gen_call (operands[0], const0_rtx));
7188 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7190 rtx set = XVECEXP (operands[2], 0, i);
7191 emit_move_insn (SET_DEST (set), SET_SRC (set));
7194 /* The optimizer does not know that the call sets the function value
7195 registers we stored in the result block. We avoid problems by
7196 claiming that all hard registers are used and clobbered at this
7198 emit_insn (gen_blockage ());
7203 ;; Prologue and epilogue instructions
7205 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7206 ;; all of memory. This blocks insns from being moved across this point.
7208 (define_insn "blockage"
7209 [(unspec_volatile [(const_int 0)] 0)]
7212 [(set_attr "length" "0")])
7214 ;; Insn emitted into the body of a function to return from a function.
7215 ;; This is only done if the function's epilogue is known to be simple.
7216 ;; See comments for simple_386_epilogue in i386.c.
7218 (define_expand "return"
7220 "ix86_can_use_return_insn_p ()"
7223 if (current_function_pops_args)
7225 rtx popc = GEN_INT (current_function_pops_args);
7226 emit_jump_insn (gen_return_pop_internal (popc));
7231 (define_insn "return_internal"
7235 [(set_attr "length" "1")])
7237 (define_insn "return_pop_internal"
7239 (use (match_operand:SI 0 "const_int_operand" ""))]
7242 [(set_attr "length" "3")])
7248 [(set_attr "length" "1")
7249 (set_attr "ppro_uops" "one")])
7251 (define_expand "prologue"
7254 "ix86_expand_prologue (); DONE;")
7256 (define_insn "prologue_set_got"
7257 [(set (match_operand:SI 0 "register_operand" "=r")
7259 [(plus:SI (match_dup 0)
7260 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
7261 (minus:SI (pc) (match_operand 2 "" ""))))] 1))
7262 (clobber (reg:CC 17))]
7266 if (GET_CODE (operands[2]) == LABEL_REF)
7267 operands[2] = XEXP (operands[2], 0);
7268 if (TARGET_DEEP_BRANCH_PREDICTION)
7269 return \"add{l}\\t{%1, %0|%0, %1}\";
7271 return \"add{l}\\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}\";
7273 [(set_attr "type" "alu")])
7275 (define_insn "prologue_get_pc"
7276 [(set (match_operand:SI 0 "register_operand" "=r")
7277 (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
7281 if (GET_CODE (operands[1]) == LABEL_REF)
7282 operands[1] = XEXP (operands[1], 0);
7283 output_asm_insn (\"call\\t%X1\", operands);
7284 if (! TARGET_DEEP_BRANCH_PREDICTION)
7286 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
7287 CODE_LABEL_NUMBER (operands[1]));
7291 [(set_attr "type" "multi")])
7293 (define_expand "epilogue"
7296 "ix86_expand_epilogue (); DONE;")
7298 (define_insn "leave"
7299 [(set (reg:SI 7) (reg:SI 6))
7300 (set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))]
7303 [(set_attr "length" "1")
7304 (set_attr "ppro_uops" "few")])
7306 (define_expand "ffssi2"
7307 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7308 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
7312 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
7313 rtx in = operands[1];
7317 emit_move_insn (tmp, constm1_rtx);
7318 emit_insn (gen_ffssi_1 (out, in));
7319 emit_insn (gen_rtx_SET (VOIDmode, out,
7320 gen_rtx_IF_THEN_ELSE (SImode,
7321 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG),
7325 emit_insn (gen_addsi3 (out, out, const1_rtx));
7326 emit_move_insn (operands[0], out);
7329 /* Pentium bsf instruction is extremly slow. Following code is recommended by
7330 the Intel Optimizing Manual as resonable replacement:
7334 MOV DWORD PTR [TEMP+4],ECX
7337 MOV DWORD PTR [TEMP],EAX
7338 FILD QWORD PTR [TEMP]
7339 FSTP QWORD PTR [TEMP]
7340 WAIT ; WAIT only needed for compatibility with
7341 ; earlier processors
7342 MOV ECX, DWORD PTR [TEMP+4]
7345 TEST EAX,EAX ; clear zero flag
7347 Following piece of code expand ffs to similar beast.
7350 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
7352 rtx label = gen_label_rtx ();
7354 rtx mem = assign_386_stack_local (DImode, 0);
7355 rtx fptmp = gen_reg_rtx (DFmode);
7356 split_di (&mem, 1, &lo, &hi);
7358 emit_move_insn (out, const0_rtx);
7360 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label);
7362 emit_move_insn (hi, out);
7363 emit_insn (gen_subsi3 (out, out, in));
7364 emit_insn (gen_andsi3 (out, out, in));
7365 emit_move_insn (lo, out);
7366 emit_insn (gen_floatdidf2 (fptmp,mem));
7367 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
7368 emit_move_insn (out, hi);
7369 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
7370 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3fe)));
7373 LABEL_NUSES (label) = 1;
7375 emit_move_insn (operands[0], out);
7379 emit_move_insn (tmp, const0_rtx);
7380 emit_insn (gen_ffssi_1 (out, in));
7381 emit_insn (gen_rtx_SET (VOIDmode,
7382 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
7383 gen_rtx_EQ (QImode, gen_rtx_REG (CCmode, FLAGS_REG),
7385 emit_insn (gen_negsi2 (tmp, tmp));
7386 emit_insn (gen_iorsi3 (out, out, tmp));
7387 emit_insn (gen_addsi3 (out, out, const1_rtx));
7388 emit_move_insn (operands[0], out);
7393 ;; %%% The CCmode here is not strictly correct -- only Z is defined.
7394 ;; But I don't think this can be used except for from above.
7395 (define_insn "ffssi_1"
7397 (compare:CC (match_operand:SI 1 "nonimmediate_operand" "rm")
7399 (set (match_operand:SI 0 "register_operand" "=r")
7400 (unspec:SI [(match_dup 1)] 5))]
7402 "bsf{l}\\t{%1, %0|%0, %1}"
7403 [(set_attr "length_opcode" "3")
7404 (set_attr "ppro_uops" "few")])
7406 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
7407 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
7409 ;; These patterns match the binary 387 instructions for addM3, subM3,
7410 ;; mulM3 and divM3. There are three patterns for each of DFmode and
7411 ;; SFmode. The first is the normal insn, the second the same insn but
7412 ;; with one operand a conversion, and the third the same insn but with
7413 ;; the other operand a conversion. The conversion may be SFmode or
7414 ;; SImode if the target mode DFmode, but only SImode if the target mode
7417 ;; Gcc is slightly more smart about handling normal two address instructions
7418 ;; so use special patterns for add and mull.
7419 (define_insn "*fop_sf_comm"
7420 [(set (match_operand:SF 0 "register_operand" "=f")
7421 (match_operator:SF 3 "binary_fp_operator"
7422 [(match_operand:SF 1 "register_operand" "%0")
7423 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
7424 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
7425 "* return output_387_binary_op (insn, operands);"
7427 (if_then_else (match_operand:SF 3 "mult_operator" "")
7428 (const_string "fmul")
7429 (const_string "fop")))])
7431 (define_insn "*fop_df_comm"
7432 [(set (match_operand:DF 0 "register_operand" "=f")
7433 (match_operator:DF 3 "binary_fp_operator"
7434 [(match_operand:DF 1 "register_operand" "%0")
7435 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
7436 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
7437 "* return output_387_binary_op (insn, operands);"
7439 (if_then_else (match_operand:DF 3 "mult_operator" "")
7440 (const_string "fmul")
7441 (const_string "fop")))])
7443 (define_insn "*fop_xf_comm"
7444 [(set (match_operand:XF 0 "register_operand" "=f")
7445 (match_operator:XF 3 "binary_fp_operator"
7446 [(match_operand:XF 1 "register_operand" "%0")
7447 (match_operand:XF 2 "register_operand" "f")]))]
7448 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
7449 "* return output_387_binary_op (insn, operands);"
7451 (if_then_else (match_operand:XF 3 "mult_operator" "")
7452 (const_string "fmul")
7453 (const_string "fop")))])
7455 (define_insn "*fop_sf_1"
7456 [(set (match_operand:SF 0 "register_operand" "=f,f")
7457 (match_operator:SF 3 "binary_fp_operator"
7458 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
7459 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
7461 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
7462 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7463 "* return output_387_binary_op (insn, operands);"
7465 (cond [(match_operand:SF 3 "mult_operator" "")
7466 (const_string "fmul")
7467 (match_operand:SF 3 "div_operator" "")
7468 (const_string "fdiv")
7470 (const_string "fop")))])
7472 (define_insn "*fop_sf_2"
7473 [(set (match_operand:SF 0 "register_operand" "=f,f")
7474 (match_operator:SF 3 "binary_fp_operator"
7475 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
7476 (match_operand:SF 2 "register_operand" "0,0")]))]
7477 "TARGET_80387 && TARGET_USE_FIOP"
7478 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
7480 (cond [(match_operand:SF 3 "mult_operator" "")
7481 (const_string "fmul")
7482 (match_operand:SF 3 "div_operator" "")
7483 (const_string "fdiv")
7485 (const_string "fop")))
7486 (set_attr "fp_int_src" "true")
7487 (set_attr "ppro_uops" "many")])
7489 (define_insn "*fop_sf_3"
7490 [(set (match_operand:SF 0 "register_operand" "=f,f")
7491 (match_operator:SF 3 "binary_fp_operator"
7492 [(match_operand:SF 1 "register_operand" "0,0")
7493 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
7494 "TARGET_80387 && TARGET_USE_FIOP"
7495 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
7497 (cond [(match_operand:SF 3 "mult_operator" "")
7498 (const_string "fmul")
7499 (match_operand:SF 3 "div_operator" "")
7500 (const_string "fdiv")
7502 (const_string "fop")))
7503 (set_attr "fp_int_src" "true")
7504 (set_attr "ppro_uops" "many")])
7506 (define_insn "*fop_df_1"
7507 [(set (match_operand:DF 0 "register_operand" "=f,f")
7508 (match_operator:DF 3 "binary_fp_operator"
7509 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
7510 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
7512 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
7513 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7514 "* return output_387_binary_op (insn, operands);"
7516 (cond [(match_operand:DF 3 "mult_operator" "")
7517 (const_string "fmul")
7518 (match_operand:DF 3 "div_operator" "")
7519 (const_string "fdiv")
7521 (const_string "fop")))])
7523 (define_insn "*fop_df_2"
7524 [(set (match_operand:DF 0 "register_operand" "=f,f")
7525 (match_operator:DF 3 "binary_fp_operator"
7526 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
7527 (match_operand:DF 2 "register_operand" "0,0")]))]
7528 "TARGET_80387 && TARGET_USE_FIOP"
7529 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
7531 (cond [(match_operand:DF 3 "mult_operator" "")
7532 (const_string "fmul")
7533 (match_operand:DF 3 "div_operator" "")
7534 (const_string "fdiv")
7536 (const_string "fop")))
7537 (set_attr "fp_int_src" "true")
7538 (set_attr "ppro_uops" "many")])
7540 (define_insn "*fop_df_3"
7541 [(set (match_operand:DF 0 "register_operand" "=f,f")
7542 (match_operator:DF 3 "binary_fp_operator"
7543 [(match_operand:DF 1 "register_operand" "0,0")
7544 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
7545 "TARGET_80387 && TARGET_USE_FIOP"
7546 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
7548 (cond [(match_operand:DF 3 "mult_operator" "")
7549 (const_string "fmul")
7550 (match_operand:DF 3 "div_operator" "")
7551 (const_string "fdiv")
7553 (const_string "fop")))
7554 (set_attr "fp_int_src" "true")
7555 (set_attr "ppro_uops" "many")])
7557 (define_insn "*fop_df_4"
7558 [(set (match_operand:DF 0 "register_operand" "=f,f")
7559 (match_operator:DF 3 "binary_fp_operator"
7560 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7561 (match_operand:DF 2 "register_operand" "0,f")]))]
7563 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7564 "* return output_387_binary_op (insn, operands);"
7566 (cond [(match_operand:DF 3 "mult_operator" "")
7567 (const_string "fmul")
7568 (match_operand:DF 3 "div_operator" "")
7569 (const_string "fdiv")
7571 (const_string "fop")))])
7573 (define_insn "*fop_df_5"
7574 [(set (match_operand:DF 0 "register_operand" "=f,f")
7575 (match_operator:DF 3 "binary_fp_operator"
7576 [(match_operand:DF 1 "register_operand" "0,f")
7578 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7580 "* return output_387_binary_op (insn, operands);"
7582 (cond [(match_operand:DF 3 "mult_operator" "")
7583 (const_string "fmul")
7584 (match_operand:DF 3 "div_operator" "")
7585 (const_string "fdiv")
7587 (const_string "fop")))])
7589 (define_insn "*fop_xf_1"
7590 [(set (match_operand:XF 0 "register_operand" "=f,f")
7591 (match_operator:XF 3 "binary_fp_operator"
7592 [(match_operand:XF 1 "register_operand" "0,f")
7593 (match_operand:XF 2 "register_operand" "f,0")]))]
7595 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
7596 "* return output_387_binary_op (insn, operands);"
7598 (cond [(match_operand:XF 3 "mult_operator" "")
7599 (const_string "fmul")
7600 (match_operand:XF 3 "div_operator" "")
7601 (const_string "fdiv")
7603 (const_string "fop")))])
7605 (define_insn "*fop_xf_2"
7606 [(set (match_operand:XF 0 "register_operand" "=f,f")
7607 (match_operator:XF 3 "binary_fp_operator"
7608 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
7609 (match_operand:XF 2 "register_operand" "0,0")]))]
7610 "TARGET_80387 && TARGET_USE_FIOP"
7611 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
7613 (cond [(match_operand:XF 3 "mult_operator" "")
7614 (const_string "fmul")
7615 (match_operand:XF 3 "div_operator" "")
7616 (const_string "fdiv")
7618 (const_string "fop")))
7619 (set_attr "fp_int_src" "true")
7620 (set_attr "ppro_uops" "many")])
7622 (define_insn "*fop_xf_3"
7623 [(set (match_operand:XF 0 "register_operand" "=f,f")
7624 (match_operator:XF 3 "binary_fp_operator"
7625 [(match_operand:XF 1 "register_operand" "0,0")
7626 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
7627 "TARGET_80387 && TARGET_USE_FIOP"
7628 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
7630 (cond [(match_operand:XF 3 "mult_operator" "")
7631 (const_string "fmul")
7632 (match_operand:XF 3 "div_operator" "")
7633 (const_string "fdiv")
7635 (const_string "fop")))
7636 (set_attr "fp_int_src" "true")
7637 (set_attr "ppro_uops" "many")])
7639 (define_insn "*fop_xf_4"
7640 [(set (match_operand:XF 0 "register_operand" "=f,f")
7641 (match_operator:XF 3 "binary_fp_operator"
7642 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7643 (match_operand:XF 2 "register_operand" "0,f")]))]
7645 "* return output_387_binary_op (insn, operands);"
7647 (cond [(match_operand:XF 3 "mult_operator" "")
7648 (const_string "fmul")
7649 (match_operand:XF 3 "div_operator" "")
7650 (const_string "fdiv")
7652 (const_string "fop")))])
7654 (define_insn "*fop_xf_5"
7655 [(set (match_operand:XF 0 "register_operand" "=f,f")
7656 (match_operator:XF 3 "binary_fp_operator"
7657 [(match_operand:XF 1 "register_operand" "0,f")
7659 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7661 "* return output_387_binary_op (insn, operands);"
7663 (cond [(match_operand:XF 3 "mult_operator" "")
7664 (const_string "fmul")
7665 (match_operand:XF 3 "div_operator" "")
7666 (const_string "fdiv")
7668 (const_string "fop")))])
7670 (define_insn "*fop_xf_6"
7671 [(set (match_operand:XF 0 "register_operand" "=f,f")
7672 (match_operator:XF 3 "binary_fp_operator"
7673 [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
7674 (match_operand:XF 2 "register_operand" "0,f")]))]
7676 "* return output_387_binary_op (insn, operands);"
7678 (cond [(match_operand:XF 3 "mult_operator" "")
7679 (const_string "fmul")
7680 (match_operand:XF 3 "div_operator" "")
7681 (const_string "fdiv")
7683 (const_string "fop")))])
7685 (define_insn "*fop_xf_7"
7686 [(set (match_operand:XF 0 "register_operand" "=f,f")
7687 (match_operator:XF 3 "binary_fp_operator"
7688 [(match_operand:XF 1 "register_operand" "0,f")
7690 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
7692 "* return output_387_binary_op (insn, operands);"
7694 (cond [(match_operand:XF 3 "mult_operator" "")
7695 (const_string "fmul")
7696 (match_operand:XF 3 "div_operator" "")
7697 (const_string "fdiv")
7699 (const_string "fop")))])
7702 [(set (match_operand 0 "register_operand" "")
7703 (match_operator 3 "binary_fp_operator"
7704 [(float (match_operand:SI 1 "register_operand" ""))
7705 (match_operand 2 "register_operand" "")]))]
7706 "TARGET_80387 && reload_completed
7707 && FLOAT_MODE_P (GET_MODE (operands[0]))"
7708 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
7710 (match_op_dup 3 [(match_dup 4) (match_dup 2)]))
7711 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
7712 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
7713 "operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]),
7714 gen_rtx_MEM (SImode, stack_pointer_rtx));")
7717 [(set (match_operand 0 "register_operand" "")
7718 (match_operator 3 "binary_fp_operator"
7719 [(match_operand 1 "register_operand" "")
7720 (float (match_operand:SI 2 "register_operand" ""))]))]
7721 "TARGET_80387 && reload_completed
7722 && FLOAT_MODE_P (GET_MODE (operands[0]))"
7723 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 2))
7725 (match_op_dup 3 [(match_dup 1) (match_dup 4)]))
7726 (parallel [(set (match_dup 2) (mem:SI (reg:SI 7)))
7727 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
7728 "operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]),
7729 gen_rtx_MEM (SImode, stack_pointer_rtx));")
7731 ;; FPU special functions.
7733 (define_insn "sqrtsf2"
7734 [(set (match_operand:SF 0 "register_operand" "=f")
7735 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
7736 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
7738 [(set_attr "type" "fpspc")])
7740 (define_insn "sqrtdf2"
7741 [(set (match_operand:DF 0 "register_operand" "=f")
7742 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
7743 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
7744 && (TARGET_IEEE_FP || flag_fast_math) "
7746 [(set_attr "type" "fpspc")])
7748 (define_insn "*sqrtextendsfdf2"
7749 [(set (match_operand:DF 0 "register_operand" "=f")
7750 (sqrt:DF (float_extend:DF
7751 (match_operand:SF 1 "register_operand" "0"))))]
7752 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
7754 [(set_attr "type" "fpspc")])
7756 (define_insn "sqrtxf2"
7757 [(set (match_operand:XF 0 "register_operand" "=f")
7758 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
7759 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
7760 && (TARGET_IEEE_FP || flag_fast_math) "
7762 [(set_attr "type" "fpspc")])
7764 (define_insn "*sqrtextenddfxf2"
7765 [(set (match_operand:XF 0 "register_operand" "=f")
7766 (sqrt:XF (float_extend:XF
7767 (match_operand:DF 1 "register_operand" "0"))))]
7768 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
7770 [(set_attr "type" "fpspc")])
7772 (define_insn "*sqrtextendsfxf2"
7773 [(set (match_operand:XF 0 "register_operand" "=f")
7774 (sqrt:XF (float_extend:XF
7775 (match_operand:SF 1 "register_operand" "0"))))]
7776 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
7778 [(set_attr "type" "fpspc")])
7780 (define_insn "sindf2"
7781 [(set (match_operand:DF 0 "register_operand" "=f")
7782 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
7783 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
7785 [(set_attr "type" "fpspc")])
7787 (define_insn "sinsf2"
7788 [(set (match_operand:SF 0 "register_operand" "=f")
7789 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
7790 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
7792 [(set_attr "type" "fpspc")])
7794 (define_insn "*sinextendsfdf2"
7795 [(set (match_operand:DF 0 "register_operand" "=f")
7796 (unspec:DF [(float_extend:DF
7797 (match_operand:SF 1 "register_operand" "0"))] 1))]
7798 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
7800 [(set_attr "type" "fpspc")])
7802 (define_insn "sinxf2"
7803 [(set (match_operand:XF 0 "register_operand" "=f")
7804 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
7805 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
7807 [(set_attr "type" "fpspc")])
7809 (define_insn "cosdf2"
7810 [(set (match_operand:DF 0 "register_operand" "=f")
7811 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
7812 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
7814 [(set_attr "type" "fpspc")])
7816 (define_insn "cossf2"
7817 [(set (match_operand:SF 0 "register_operand" "=f")
7818 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
7819 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
7821 [(set_attr "type" "fpspc")])
7823 (define_insn "*cosextendsfdf2"
7824 [(set (match_operand:DF 0 "register_operand" "=f")
7825 (unspec:DF [(float_extend:DF
7826 (match_operand:SF 1 "register_operand" "0"))] 2))]
7827 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
7829 [(set_attr "type" "fpspc")])
7831 (define_insn "cosxf2"
7832 [(set (match_operand:XF 0 "register_operand" "=f")
7833 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
7834 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
7836 [(set_attr "type" "fpspc")])
7838 ;; Block operation instructions
7841 [(set (reg:SI 19) (const_int 0))]
7844 [(set_attr "type" "cld")])
7846 (define_expand "movstrsi"
7847 [(use (match_operand:BLK 0 "memory_operand" ""))
7848 (use (match_operand:BLK 1 "memory_operand" ""))
7849 (use (match_operand:SI 2 "nonmemory_operand" ""))
7850 (use (match_operand:SI 3 "const_int_operand" ""))]
7854 rtx srcreg, destreg, countreg;
7858 if (GET_CODE (operands[3]) == CONST_INT)
7859 align = INTVAL (operands[3]);
7861 /* This simple hack avoids all inlining code and simplifies code bellow. */
7862 if (!TARGET_ALIGN_STRINGOPS)
7865 if (GET_CODE (operands[2]) == CONST_INT)
7866 count = INTVAL (operands[2]);
7868 destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7869 srcreg = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
7871 emit_insn (gen_cld());
7873 /* When optimizing for size emit simple rep ; movsb instruction for
7874 counts not divisible by 4. */
7876 if ((!optimize || optimize_size)
7877 && (count < 0 || (count & 0x03)))
7879 countreg = copy_to_mode_reg (SImode, operands[2]);
7880 emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
7881 destreg, srcreg, countreg));
7884 /* For constant aligned (or small unaligned) copies use rep movsl
7885 followed by code copying the rest. For PentiumPro ensure 8 byte
7886 alignment to allow rep movsl acceleration. */
7890 || (!TARGET_PENTIUMPRO && align >= 4)
7891 || optimize_size || count < 64))
7895 countreg = copy_to_mode_reg (SImode,
7896 GEN_INT ((count >> 2)
7898 emit_insn (gen_rep_movsi (destreg, srcreg, countreg,
7899 destreg, srcreg, countreg));
7902 emit_insn (gen_strmovhi (destreg, srcreg));
7904 emit_insn (gen_strmovqi (destreg, srcreg));
7906 /* The generic code based on the glibc implementation:
7907 - align destination to 4 bytes (8 byte alignment is used for PentiumPro
7908 allowing accelerated copying there)
7909 - copy the data using rep movsl
7916 /* In case we don't know anything about the alignment, default to
7917 library version, since it is usually equally fast and result in
7919 if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
7922 if (TARGET_SINGLE_STRINGOP)
7923 emit_insn (gen_cld());
7925 countreg2 = gen_reg_rtx (SImode);
7926 countreg = copy_to_mode_reg (SImode, operands[2]);
7928 /* We don't use loops to align destination and to copy parts smaller
7929 than 4 bytes, because gcc is able to optimize such code better (in
7930 the case the destination or the count really is aligned, gcc is often
7931 able to predict the branches) and also it is friendlier to the
7932 hardware branch prediction.
7934 Using loops is benefical for generic case, because we can
7935 handle small counts using the loops. Many CPUs (such as Athlon)
7936 have large REP prefix setup costs.
7938 This is quite costy. Maybe we can revisit this decision later or
7939 add some customizability to this code. */
7942 && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
7944 label = gen_label_rtx ();
7945 emit_cmp_and_jump_insns (countreg, GEN_INT (3),
7946 LEU, 0, SImode, 1, 0, label);
7950 rtx label = gen_label_rtx ();
7951 rtx tmpcount = gen_reg_rtx (SImode);
7952 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
7953 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
7954 SImode, 1, 0, label);
7955 emit_insn (gen_strmovqi (destreg, srcreg));
7956 emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
7958 LABEL_NUSES (label) = 1;
7962 rtx label = gen_label_rtx ();
7963 rtx tmpcount = gen_reg_rtx (SImode);
7964 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
7965 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
7966 SImode, 1, 0, label);
7967 emit_insn (gen_strmovhi (destreg, srcreg));
7968 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
7970 LABEL_NUSES (label) = 1;
7972 if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
7974 rtx label = gen_label_rtx ();
7975 rtx tmpcount = gen_reg_rtx (SImode);
7976 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
7977 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
7978 SImode, 1, 0, label);
7979 emit_insn (gen_strmovsi (destreg, srcreg));
7980 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
7982 LABEL_NUSES (label) = 1;
7985 if (!TARGET_SINGLE_STRINGOP)
7986 emit_insn (gen_cld());
7987 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
7988 emit_insn (gen_rep_movsi (destreg, srcreg, countreg2,
7989 destreg, srcreg, countreg2));
7994 LABEL_NUSES (label) = 1;
7996 if (align > 2 && count > 0 && (count & 2))
7997 emit_insn (gen_strmovhi (destreg, srcreg));
7998 if (align <= 2 || count < 0)
8000 rtx label = gen_label_rtx ();
8001 rtx tmpcount = gen_reg_rtx (SImode);
8002 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
8003 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8004 SImode, 1, 0, label);
8005 emit_insn (gen_strmovhi (destreg, srcreg));
8007 LABEL_NUSES (label) = 1;
8009 if (align > 1 && count > 0 && (count & 1))
8010 emit_insn (gen_strmovsi (destreg, srcreg));
8011 if (align <= 1 || count < 0)
8013 rtx label = gen_label_rtx ();
8014 rtx tmpcount = gen_reg_rtx (SImode);
8015 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
8016 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8017 SImode, 1, 0, label);
8018 emit_insn (gen_strmovqi (destreg, srcreg));
8020 LABEL_NUSES (label) = 1;
8026 ;; Most CPUs don't like single string operations
8027 ;; Handle this case here to simplify previous expander.
8029 (define_expand "strmovsi"
8031 (mem:SI (match_operand:SI 1 "register_operand" "")))
8032 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
8034 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
8035 (clobber (reg:CC 17))])
8036 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
8037 (clobber (reg:CC 17))])]
8041 if (TARGET_SINGLE_STRINGOP || optimize_size)
8043 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
8048 operands[2] = gen_reg_rtx (SImode);
8051 (define_expand "strmovhi"
8053 (mem:HI (match_operand:SI 1 "register_operand" "")))
8054 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
8056 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
8057 (clobber (reg:CC 17))])
8058 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
8059 (clobber (reg:CC 17))])]
8063 if (TARGET_SINGLE_STRINGOP || optimize_size)
8065 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
8070 operands[2] = gen_reg_rtx (HImode);
8073 (define_expand "strmovqi"
8075 (mem:QI (match_operand:SI 1 "register_operand" "")))
8076 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
8078 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
8079 (clobber (reg:CC 17))])
8080 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
8081 (clobber (reg:CC 17))])]
8085 if (TARGET_SINGLE_STRINGOP || optimize_size)
8087 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
8092 operands[2] = gen_reg_rtx (QImode);
8095 (define_insn "strmovsi_1"
8096 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
8097 (mem:SI (match_operand:SI 3 "register_operand" "1")))
8098 (set (match_operand:SI 0 "register_operand" "=D")
8099 (plus:SI (match_dup 0)
8101 (set (match_operand:SI 1 "register_operand" "=S")
8102 (plus:SI (match_dup 1)
8105 "TARGET_SINGLE_STRINGOP || optimize_size"
8107 [(set_attr "type" "str")
8108 (set_attr "memory" "both")])
8110 (define_insn "strmovhi_1"
8111 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
8112 (mem:HI (match_operand:SI 3 "register_operand" "1")))
8113 (set (match_operand:SI 0 "register_operand" "=D")
8114 (plus:SI (match_dup 0)
8116 (set (match_operand:SI 1 "register_operand" "=S")
8117 (plus:SI (match_dup 1)
8120 "TARGET_SINGLE_STRINGOP || optimize_size"
8122 [(set_attr "type" "str")
8123 (set_attr "memory" "both")
8124 (set_attr "length_prefix" "1")])
8126 (define_insn "strmovqi_1"
8127 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
8128 (mem:QI (match_operand:SI 3 "register_operand" "1")))
8129 (set (match_operand:SI 0 "register_operand" "=D")
8130 (plus:SI (match_dup 0)
8132 (set (match_operand:SI 1 "register_operand" "=S")
8133 (plus:SI (match_dup 1)
8136 "TARGET_SINGLE_STRINGOP || optimize_size"
8138 [(set_attr "type" "str")
8139 (set_attr "memory" "both")])
8141 ;; It might seem that operands 3 & 4 could use predicate register_operand.
8142 ;; But strength reduction might offset the MEM expression. So we let
8143 ;; reload put the address into %edi & %esi.
8145 (define_insn "rep_movsi"
8146 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
8147 (use (match_operand:SI 5 "register_operand" "2"))
8148 (set (match_operand:SI 0 "register_operand" "=D")
8149 (plus:SI (match_operand:SI 3 "address_operand" "0")
8150 (ashift:SI (match_dup 5) (const_int 2))))
8151 (set (match_operand:SI 1 "register_operand" "=S")
8152 (plus:SI (match_operand:SI 4 "address_operand" "1")
8153 (ashift:SI (match_dup 5) (const_int 2))))
8154 (set (mem:BLK (match_dup 3))
8155 (mem:BLK (match_dup 4)))
8158 "rep\;movsl|rep movsd"
8159 [(set_attr "type" "str")
8160 (set_attr "length_prefix" "1")
8161 (set_attr "memory" "both")])
8163 (define_insn "rep_movqi"
8164 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
8165 (use (match_operand:SI 5 "register_operand" "2"))
8166 (set (match_operand:SI 0 "register_operand" "=D")
8167 (plus:SI (match_operand:SI 3 "address_operand" "0") (match_dup 5)))
8168 (set (match_operand:SI 1 "register_operand" "=S")
8169 (plus:SI (match_operand:SI 4 "address_operand" "1") (match_dup 5)))
8170 (set (mem:BLK (match_dup 3))
8171 (mem:BLK (match_dup 4)))
8174 "rep\;movsb|rep movsb"
8175 [(set_attr "type" "str")
8176 (set_attr "length_prefix" "1")
8177 (set_attr "memory" "both")])
8179 (define_expand "clrstrsi"
8180 [(use (match_operand:BLK 0 "memory_operand" ""))
8181 (use (match_operand:SI 1 "nonmemory_operand" ""))
8182 (use (match_operand:SI 2 "const_int_operand" ""))]
8186 /* See comments in movstr expanders. The code is mostly identical. */
8188 rtx destreg, zeroreg, countreg;
8192 if (GET_CODE (operands[2]) == CONST_INT)
8193 align = INTVAL (operands[2]);
8195 /* This simple hack avoids all inlining code and simplifies code bellow. */
8196 if (!TARGET_ALIGN_STRINGOPS)
8199 if (GET_CODE (operands[1]) == CONST_INT)
8200 count = INTVAL (operands[1]);
8202 destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
8204 emit_insn (gen_cld());
8206 /* When optimizing for size emit simple rep ; movsb instruction for
8207 counts not divisible by 4. */
8209 if ((!optimize || optimize_size)
8210 && (count < 0 || (count & 0x03)))
8212 countreg = copy_to_mode_reg (SImode, operands[1]);
8213 zeroreg = copy_to_mode_reg (QImode, const0_rtx);
8214 emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg,
8215 destreg, countreg));
8219 || (!TARGET_PENTIUMPRO && align >= 4)
8220 || optimize_size || count < 64))
8222 zeroreg = copy_to_mode_reg (SImode, const0_rtx);
8223 if (INTVAL (operands[1]) & ~0x03)
8225 countreg = copy_to_mode_reg (SImode,
8226 GEN_INT ((INTVAL (operands[1]) >> 2)
8228 emit_insn (gen_rep_stossi (destreg, countreg, zeroreg,
8229 destreg, countreg));
8231 if (INTVAL (operands[1]) & 0x02)
8232 emit_insn (gen_strsethi (destreg,
8233 gen_rtx_SUBREG (HImode, zeroreg, 0)));
8234 if (INTVAL (operands[1]) & 0x01)
8235 emit_insn (gen_strsetqi (destreg,
8236 gen_rtx_SUBREG (QImode, zeroreg, 0)));
8243 /* In case we don't know anything about the alignment, default to
8244 library version, since it is usually equally fast and result in
8246 if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
8249 if (TARGET_SINGLE_STRINGOP)
8250 emit_insn (gen_cld());
8252 countreg2 = gen_reg_rtx (SImode);
8253 countreg = copy_to_mode_reg (SImode, operands[1]);
8254 zeroreg = copy_to_mode_reg (SImode, const0_rtx);
8257 && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
8259 label = gen_label_rtx ();
8260 emit_cmp_and_jump_insns (countreg, GEN_INT (3),
8261 LEU, 0, SImode, 1, 0, label);
8265 rtx label = gen_label_rtx ();
8266 rtx tmpcount = gen_reg_rtx (SImode);
8267 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
8268 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8269 SImode, 1, 0, label);
8270 emit_insn (gen_strsetqi (destreg,
8271 gen_rtx_SUBREG (QImode, zeroreg, 0)));
8272 emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
8274 LABEL_NUSES (label) = 1;
8278 rtx label = gen_label_rtx ();
8279 rtx tmpcount = gen_reg_rtx (SImode);
8280 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
8281 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8282 SImode, 1, 0, label);
8283 emit_insn (gen_strsethi (destreg,
8284 gen_rtx_SUBREG (HImode, zeroreg, 0)));
8285 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
8287 LABEL_NUSES (label) = 1;
8289 if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
8291 rtx label = gen_label_rtx ();
8292 rtx tmpcount = gen_reg_rtx (SImode);
8293 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
8294 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8295 SImode, 1, 0, label);
8296 emit_insn (gen_strsethi (destreg, zeroreg));
8297 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
8299 LABEL_NUSES (label) = 1;
8302 if (!TARGET_SINGLE_STRINGOP)
8303 emit_insn (gen_cld());
8304 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
8305 emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg,
8306 destreg, countreg2));
8311 LABEL_NUSES (label) = 1;
8313 if (align > 2 && count > 0 && (count & 2))
8314 emit_insn (gen_strsethi (destreg,
8315 gen_rtx_SUBREG (HImode, zeroreg, 0)));
8316 if (align <= 2 || count < 0)
8318 rtx label = gen_label_rtx ();
8319 rtx tmpcount = gen_reg_rtx (SImode);
8320 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
8321 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8322 SImode, 1, 0, label);
8323 emit_insn (gen_strsethi (destreg,
8324 gen_rtx_SUBREG (HImode, zeroreg, 0)));
8326 LABEL_NUSES (label) = 1;
8328 if (align > 1 && count > 0 && (count & 1))
8329 emit_insn (gen_strsetqi (destreg,
8330 gen_rtx_SUBREG (QImode, zeroreg, 0)));
8331 if (align <= 1 || count < 0)
8333 rtx label = gen_label_rtx ();
8334 rtx tmpcount = gen_reg_rtx (SImode);
8335 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
8336 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
8337 SImode, 1, 0, label);
8338 emit_insn (gen_strsetqi (destreg,
8339 gen_rtx_SUBREG (QImode, zeroreg, 0)));
8341 LABEL_NUSES (label) = 1;
8347 ;; Most CPUs don't like single string operations
8348 ;; Handle this case here to simplify previous expander.
8350 (define_expand "strsetsi"
8351 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
8352 (match_operand:SI 1 "register_operand" ""))
8353 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
8354 (clobber (reg:CC 17))])]
8358 if (TARGET_SINGLE_STRINGOP || optimize_size)
8360 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
8365 (define_expand "strsethi"
8366 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
8367 (match_operand:HI 1 "register_operand" ""))
8368 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
8369 (clobber (reg:CC 17))])]
8373 if (TARGET_SINGLE_STRINGOP || optimize_size)
8375 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
8380 (define_expand "strsetqi"
8381 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
8382 (match_operand:QI 1 "register_operand" ""))
8383 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
8384 (clobber (reg:CC 17))])]
8388 if (TARGET_SINGLE_STRINGOP || optimize_size)
8390 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
8395 (define_insn "strsetsi_1"
8396 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
8397 (match_operand:SI 2 "register_operand" "a"))
8398 (set (match_operand:SI 0 "register_operand" "=D")
8399 (plus:SI (match_dup 0)
8402 "TARGET_SINGLE_STRINGOP || optimize_size"
8404 [(set_attr "type" "str")
8405 (set_attr "memory" "store")])
8407 (define_insn "strsethi_1"
8408 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
8409 (match_operand:HI 2 "register_operand" "a"))
8410 (set (match_operand:SI 0 "register_operand" "=D")
8411 (plus:SI (match_dup 0)
8414 "TARGET_SINGLE_STRINGOP || optimize_size"
8416 [(set_attr "type" "str")
8417 (set_attr "memory" "store")
8418 (set_attr "length_prefix" "1")])
8420 (define_insn "strsetqi_1"
8421 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
8422 (match_operand:QI 2 "register_operand" "a"))
8423 (set (match_operand:SI 0 "register_operand" "=D")
8424 (plus:SI (match_dup 0)
8427 "TARGET_SINGLE_STRINGOP || optimize_size"
8429 [(set_attr "type" "str")
8430 (set_attr "memory" "store")])
8432 ;; It might seem that operand 0 could use predicate register_operand.
8433 ;; But strength reduction might offset the MEM expression. So we let
8434 ;; reload put the address into %edi.
8436 (define_insn "rep_stossi"
8437 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
8438 (use (match_operand:SI 2 "register_operand" "a"))
8439 (use (match_operand:SI 4 "register_operand" "1"))
8440 (set (match_operand:SI 0 "register_operand" "=D")
8441 (plus:SI (match_operand:SI 3 "address_operand" "0")
8442 (ashift:SI (match_dup 3) (const_int 2))))
8443 (set (mem:BLK (match_dup 3))
8447 "rep\;stosl|rep stosd"
8448 [(set_attr "type" "str")
8449 (set_attr "length_prefix" "1")
8450 (set_attr "memory" "store")])
8452 (define_insn "rep_stosqi"
8453 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
8454 (use (match_operand:QI 2 "register_operand" "a"))
8455 (use (match_operand:SI 4 "register_operand" "1"))
8456 (set (match_operand:SI 0 "register_operand" "=D")
8457 (plus:SI (match_operand:SI 3 "address_operand" "0") (match_dup 3)))
8458 (set (mem:BLK (match_dup 3))
8462 "rep\;stosb|rep stosb"
8463 [(set_attr "type" "str")
8464 (set_attr "length_prefix" "1")
8465 (set_attr "memory" "store")])
8467 (define_expand "cmpstrsi"
8468 [(set (match_operand:SI 0 "register_operand" "")
8469 (compare:SI (match_operand:BLK 1 "general_operand" "")
8470 (match_operand:BLK 2 "general_operand" "")))
8471 (use (match_operand:SI 3 "general_operand" ""))
8472 (use (match_operand:SI 4 "immediate_operand" ""))]
8476 rtx addr1, addr2, out, outlow, count, countreg, align;
8479 if (GET_CODE (out) != REG)
8480 out = gen_reg_rtx (SImode);
8482 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
8483 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
8485 count = operands[3];
8486 countreg = copy_to_mode_reg (SImode, count);
8488 /* %%% Iff we are testing strict equality, we can use known alignment
8489 to good advantage. This may be possible with combine, particularly
8490 once cc0 is dead. */
8491 align = operands[4];
8493 emit_insn (gen_cld ());
8494 if (GET_CODE (count) == CONST_INT)
8496 if (INTVAL (count) == 0)
8498 emit_move_insn (operands[0], const0_rtx);
8501 emit_insn (gen_cmpstrsi_nz_1 (addr1, addr2, countreg, align));
8505 emit_insn (gen_cmpsi_1 (countreg, countreg));
8506 emit_insn (gen_cmpstrsi_1 (addr1, addr2, countreg, align));
8509 outlow = gen_lowpart (QImode, out);
8510 emit_insn (gen_cmpintqi (outlow));
8511 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
8513 if (operands[0] != out)
8514 emit_move_insn (operands[0], out);
8519 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
8521 (define_expand "cmpintqi"
8523 (gtu:QI (reg:CC 17) (const_int 0)))
8525 (ltu:QI (reg:CC 17) (const_int 0)))
8526 (parallel [(set (match_operand:QI 0 "register_operand" "")
8527 (minus:QI (match_dup 1)
8529 (clobber (reg:CC 17))])]
8531 "operands[1] = gen_reg_rtx (QImode);
8532 operands[2] = gen_reg_rtx (QImode);")
8534 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
8535 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
8537 ;; It might seem that operands 0 & 1 could use predicate register_operand.
8538 ;; But strength reduction might offset the MEM expression. So we let
8539 ;; reload put the address into %edi & %esi.
8541 (define_insn "cmpstrsi_nz_1"
8543 (compare:CC (mem:BLK (match_operand:SI 0 "address_operand" "S"))
8544 (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
8545 (use (match_operand:SI 2 "register_operand" "c"))
8546 (use (match_operand:SI 3 "immediate_operand" "i"))
8548 (clobber (match_dup 0))
8549 (clobber (match_dup 1))
8550 (clobber (match_dup 2))]
8553 [(set_attr "type" "str")
8554 (set_attr "length_prefix" "1")])
8556 ;; The same, but the count is not known to not be zero.
8558 (define_insn "cmpstrsi_1"
8560 (if_then_else:CC (ne (match_operand:SI 2 "register_operand" "c")
8562 (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
8563 (mem:BLK (match_operand:SI 1 "address_operand" "D")))
8565 (use (match_operand:SI 3 "immediate_operand" "i"))
8568 (clobber (match_dup 0))
8569 (clobber (match_dup 1))
8570 (clobber (match_dup 2))]
8573 [(set_attr "type" "str")
8574 (set_attr "length_prefix" "1")])
8576 (define_expand "strlensi"
8577 [(set (match_operand:SI 0 "register_operand" "")
8578 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
8579 (match_operand:QI 2 "immediate_operand" "")
8580 (match_operand:SI 3 "immediate_operand" "")] 0))]
8584 rtx out, addr, eoschar, align, scratch1, scratch2, scratch3;
8586 /* The generic case of strlen expander is long. Avoid it's
8587 expanding unless TARGET_INLINE_ALL_STRINGOPS. */
8589 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
8591 && (GET_CODE (align) != CONST_INT || INTVAL (align) < 4))
8595 addr = force_reg (Pmode, XEXP (operands[1], 0));
8596 eoschar = operands[2];
8597 align = operands[3];
8598 scratch1 = gen_reg_rtx (SImode);
8600 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
8603 /* Well it seems that some optimizer does not combine a call like
8604 foo(strlen(bar), strlen(bar));
8605 when the move and the subtraction is done here. It does calculate
8606 the length just once when these instructions are done inside of
8607 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
8608 often used and I use one fewer register for the lifetime of
8609 output_strlen_unroll() this is better. */
8611 if (GET_CODE (align) != CONST_INT || INTVAL (align) < 4)
8612 emit_move_insn (scratch1, addr);
8614 emit_move_insn (out, addr);
8616 ix86_expand_strlensi_unroll_1 (out, align, scratch1);
8618 /* strlensi_unroll_1 returns the address of the zero at the end of
8619 the string, like memchr(), so compute the length by subtracting
8620 the start address. */
8621 emit_insn (gen_subsi3 (out, out, addr));
8625 scratch2 = gen_reg_rtx (SImode);
8626 scratch3 = gen_reg_rtx (SImode);
8628 emit_move_insn (scratch3, addr);
8630 emit_insn (gen_cld ());
8631 emit_insn (gen_strlensi_1 (scratch1, scratch3, eoschar,
8632 align, constm1_rtx));
8633 emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
8634 emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
8639 ;; It might seem that operands 0 & 1 could use predicate register_operand.
8640 ;; But strength reduction might offset the MEM expression. So we let
8641 ;; reload put the address into %edi.
8643 (define_insn "strlensi_1"
8644 [(set (match_operand:SI 0 "register_operand" "=&c")
8645 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
8646 (match_operand:QI 2 "general_operand" "a")
8647 (match_operand:SI 3 "immediate_operand" "i")
8648 (match_operand:SI 4 "immediate_operand" "0")] 0))
8650 (clobber (match_dup 1))
8651 (clobber (reg:CC 17))]
8654 [(set_attr "type" "str")
8655 (set_attr "length_prefix" "1")])
8657 ;; Conditional move instructions.
8659 (define_expand "movsicc"
8660 [(set (match_operand:SI 0 "register_operand" "")
8661 (if_then_else:SI (match_operand 1 "comparison_operator" "")
8662 (match_operand:SI 2 "general_operand" "")
8663 (match_operand:SI 3 "general_operand" "")))]
8665 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
8667 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
8668 ;; the register first winds up with `sbbl $0,reg', which is also weird.
8669 ;; So just document what we're doing explicitly.
8671 (define_insn "x86_movsicc_0_m1"
8672 [(set (match_operand:SI 0 "register_operand" "=r")
8673 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
8676 (clobber (reg:CC 17))]
8679 ; Since we don't have the proper number of operands for an alu insn,
8680 ; fill in all the blanks.
8681 [(set_attr "type" "alu")
8682 (set_attr "memory" "none")
8683 (set_attr "imm_disp" "false")
8684 (set_attr "length" "2")])
8686 (define_insn "*movsicc_noc"
8687 [(set (match_operand:SI 0 "register_operand" "=r,r")
8688 (if_then_else:SI (match_operator 1 "no_comparison_operator"
8689 [(reg 17) (const_int 0)])
8690 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
8691 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
8693 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
8695 cmov%C1\\t{%2, %0|%0, %2}
8696 cmov%c1\\t{%3, %0|%0, %3}"
8697 [(set_attr "type" "icmov")])
8699 (define_insn "*movsicc_c"
8700 [(set (match_operand:SI 0 "register_operand" "=r,r")
8701 (if_then_else:SI (match_operator 1 "comparison_operator"
8702 [(reg:CC 17) (const_int 0)])
8703 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
8704 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
8706 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
8708 cmov%C1\\t{%2, %0|%0, %2}
8709 cmov%c1\\t{%3, %0|%0, %3}"
8710 [(set_attr "type" "icmov")])
8712 (define_expand "movhicc"
8713 [(set (match_operand:HI 0 "register_operand" "")
8714 (if_then_else:HI (match_operand 1 "comparison_operator" "")
8715 (match_operand:HI 2 "nonimmediate_operand" "")
8716 (match_operand:HI 3 "nonimmediate_operand" "")))]
8718 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
8720 (define_insn "*movhicc_noc"
8721 [(set (match_operand:HI 0 "register_operand" "=r,r")
8722 (if_then_else:HI (match_operator 1 "no_comparison_operator"
8723 [(reg 17) (const_int 0)])
8724 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
8725 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
8727 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
8729 cmov%C1\\t{%2, %0|%0, %2}
8730 cmov%c1\\t{%3, %0|%0, %3}"
8731 [(set_attr "type" "icmov")])
8733 (define_insn "*movhicc_c"
8734 [(set (match_operand:HI 0 "register_operand" "=r,r")
8735 (if_then_else:HI (match_operator 1 "comparison_operator"
8736 [(reg:CC 17) (const_int 0)])
8737 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
8738 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
8740 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
8742 cmov%C1\\t{%2, %0|%0, %2}
8743 cmov%c1\\t{%3, %0|%0, %3}"
8744 [(set_attr "type" "icmov")])
8746 (define_expand "movsfcc"
8747 [(set (match_operand:SF 0 "register_operand" "")
8748 (if_then_else:SF (match_operand 1 "comparison_operator" "")
8749 (match_operand:SF 2 "register_operand" "")
8750 (match_operand:SF 3 "register_operand" "")))]
8752 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
8754 (define_insn "*movsfcc_1"
8755 [(set (match_operand:SF 0 "register_operand" "=f,f")
8756 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
8757 [(reg 17) (const_int 0)])
8758 (match_operand:SF 2 "register_operand" "f,0")
8759 (match_operand:SF 3 "register_operand" "0,f")))]
8762 fcmov%F1\\t{%2, %0|%0, %2}
8763 fcmov%f1\\t{%3, %0|%0, %3}"
8764 [(set_attr "type" "fcmov")])
8766 (define_expand "movdfcc"
8767 [(set (match_operand:DF 0 "register_operand" "")
8768 (if_then_else:DF (match_operand 1 "comparison_operator" "")
8769 (match_operand:DF 2 "register_operand" "")
8770 (match_operand:DF 3 "register_operand" "")))]
8772 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
8774 (define_insn "*movdfcc_1"
8775 [(set (match_operand:DF 0 "register_operand" "=f,f")
8776 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
8777 [(reg 17) (const_int 0)])
8778 (match_operand:DF 2 "register_operand" "f,0")
8779 (match_operand:DF 3 "register_operand" "0,f")))]
8782 fcmov%F1\\t{%2, %0|%0, %2}
8783 fcmov%f1\\t{%3, %0|%0, %3}"
8784 [(set_attr "type" "fcmov")])
8786 (define_expand "movxfcc"
8787 [(set (match_operand:XF 0 "register_operand" "")
8788 (if_then_else:XF (match_operand 1 "comparison_operator" "")
8789 (match_operand:XF 2 "register_operand" "")
8790 (match_operand:XF 3 "register_operand" "")))]
8792 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
8794 (define_insn "*movxfcc_1"
8795 [(set (match_operand:XF 0 "register_operand" "=f,f")
8796 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
8797 [(reg 17) (const_int 0)])
8798 (match_operand:XF 2 "register_operand" "f,0")
8799 (match_operand:XF 3 "register_operand" "0,f")))]
8802 fcmov%F1\\t{%2, %0|%0, %2}
8803 fcmov%f1\\t{%3, %0|%0, %3}"
8804 [(set_attr "type" "fcmov")])
8806 ;; Misc patterns (?)
8808 ;; This pattern exists to put a dependancy on all ebp-based memory accesses.
8809 ;; Otherwise there will be nothing to keep
8811 ;; [(set (reg ebp) (reg esp))]
8812 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
8813 ;; (clobber (eflags)]
8814 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
8816 ;; in proper program order.
8818 (define_insn "pro_epilogue_adjust_stack"
8819 [(set (match_operand:SI 0 "register_operand" "=r,r")
8820 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
8821 (match_operand:SI 2 "immediate_operand" "i,i")))
8822 (set (match_operand:SI 3 "register_operand" "+r,r")
8824 (clobber (reg:CC 17))]
8828 switch (get_attr_type (insn))
8831 return \"mov{l}\\t{%1, %0|%0, %1}\";
8834 if (GET_CODE (operands[2]) == CONST_INT
8835 && (INTVAL (operands[2]) == 128
8836 || (INTVAL (operands[2]) < 0
8837 && INTVAL (operands[2]) != -128)))
8839 operands[2] = GEN_INT (-INTVAL (operands[2]));
8840 return \"sub{l}\\t{%2, %0|%0, %2}\";
8842 return \"add{l}\\t{%2, %0|%0, %2}\";
8845 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
8846 return \"lea{l}\\t{%a2, %0|%0, %a2}\";
8853 (cond [(eq_attr "alternative" "0")
8854 (const_string "alu")
8855 (match_operand:SI 2 "const0_operand" "")
8856 (const_string "imov")
8858 (const_string "lea")))])
8860 (define_insn "allocate_stack_worker"
8861 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
8862 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
8863 (clobber (match_dup 0))
8864 (clobber (reg:CC 17))]
8865 "TARGET_STACK_PROBE"
8867 [(set_attr "type" "multi")
8868 (set_attr "length" "5")])
8870 (define_expand "allocate_stack"
8871 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
8872 (minus:SI (reg:SI 7)
8873 (match_operand:SI 1 "general_operand" "")))
8874 (clobber (reg:CC 17))])
8875 (parallel [(set (reg:SI 7)
8876 (minus:SI (reg:SI 7) (match_dup 1)))
8877 (clobber (reg:CC 17))])]
8878 "TARGET_STACK_PROBE"
8881 #ifdef CHECK_STACK_LIMIT
8882 if (GET_CODE (operands[1]) == CONST_INT
8883 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
8884 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
8888 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
8891 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
8895 (define_expand "exception_receiver"
8900 load_pic_register ();
8904 (define_expand "builtin_setjmp_receiver"
8905 [(label_ref (match_operand 0 "" ""))]
8909 load_pic_register ();
8913 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
8916 [(set (match_operand 0 "register_operand" "")
8917 (match_operator 3 "promotable_binary_operator"
8918 [(match_operand 1 "register_operand" "")
8919 (match_operand 2 "aligned_operand" "")]))
8920 (clobber (reg:CC 17))]
8921 "! TARGET_PARTIAL_REG_STALL && reload_completed
8922 && ((GET_MODE (operands[0]) == HImode
8923 && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
8924 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
8925 || (GET_MODE (operands[0]) == QImode
8926 && (TARGET_PROMOTE_QImode || optimize_size)))"
8927 [(parallel [(set (match_dup 0)
8928 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8929 (clobber (reg:CC 17))])]
8930 "operands[0] = gen_lowpart (SImode, operands[0]);
8931 operands[1] = gen_lowpart (SImode, operands[1]);
8932 if (GET_CODE (operands[3]) != ASHIFT)
8933 operands[2] = gen_lowpart (SImode, operands[2]);
8934 GET_MODE (operands[3]) = SImode;")
8938 (compare:CCNO (and (match_operand 1 "aligned_operand" "")
8939 (match_operand 2 "const_int_operand" ""))
8941 (set (match_operand 0 "register_operand" "")
8942 (and (match_dup 1) (match_dup 2)))]
8943 "! TARGET_PARTIAL_REG_STALL && reload_completed
8944 && (GET_MODE (operands[0]) == HImode
8945 || (GET_MODE (operands[0]) == QImode
8946 && (TARGET_PROMOTE_QImode || optimize_size)))"
8947 [(parallel [(set (reg:CCNO 17)
8948 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
8951 (and:SI (match_dup 1) (match_dup 2)))])]
8953 = GEN_INT (INTVAL (operands[2]) & GET_MODE_MASK (GET_MODE (operands[0])));
8954 operands[0] = gen_lowpart (SImode, operands[0]);
8955 operands[1] = gen_lowpart (SImode, operands[1]);")
8959 (compare:CCNO (and (match_operand 0 "aligned_operand" "")
8960 (match_operand 1 "const_int_operand" ""))
8962 "! TARGET_PARTIAL_REG_STALL && reload_completed
8963 && (GET_MODE (operands[0]) == HImode
8964 || (GET_MODE (operands[0]) == QImode
8965 && (TARGET_PROMOTE_QImode || optimize_size)))"
8967 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
8970 = GEN_INT (INTVAL (operands[1]) & GET_MODE_MASK (GET_MODE (operands[0])));
8971 operands[0] = gen_lowpart (SImode, operands[0]);")
8974 [(set (match_operand 0 "register_operand" "")
8975 (neg (match_operand 1 "register_operand" "")))
8976 (clobber (reg:CC 17))]
8977 "! TARGET_PARTIAL_REG_STALL && reload_completed
8978 && (GET_MODE (operands[0]) == HImode
8979 || (GET_MODE (operands[0]) == QImode
8980 && (TARGET_PROMOTE_QImode || optimize_size)))"
8981 [(parallel [(set (match_dup 0)
8982 (neg:SI (match_dup 1)))
8983 (clobber (reg:CC 17))])]
8984 "operands[0] = gen_lowpart (SImode, operands[0]);
8985 operands[1] = gen_lowpart (SImode, operands[1]);")
8988 [(set (match_operand 0 "register_operand" "")
8989 (not (match_operand 1 "register_operand" "")))]
8990 "! TARGET_PARTIAL_REG_STALL && reload_completed
8991 && (GET_MODE (operands[0]) == HImode
8992 || (GET_MODE (operands[0]) == QImode
8993 && (TARGET_PROMOTE_QImode || optimize_size)))"
8995 (not:SI (match_dup 1)))]
8996 "operands[0] = gen_lowpart (SImode, operands[0]);
8997 operands[1] = gen_lowpart (SImode, operands[1]);")
9000 [(set (match_operand 0 "register_operand" "")
9001 (if_then_else (match_operator 1 "comparison_operator"
9002 [(reg 17) (const_int 0)])
9003 (match_operand 2 "register_operand" "")
9004 (match_operand 3 "register_operand" "")))]
9005 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
9006 && (GET_MODE (operands[0]) == HImode
9007 || (GET_MODE (operands[0]) == QImode
9008 && (TARGET_PROMOTE_QImode || optimize_size)))"
9010 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
9011 "operands[0] = gen_lowpart (SImode, operands[0]);
9012 operands[2] = gen_lowpart (SImode, operands[2]);
9013 operands[3] = gen_lowpart (SImode, operands[3]);")
9016 ;; RTL Peephole optimizations, run before sched2. These primarily look to
9017 ;; transform a complex memory operation into two memory to register operations.
9019 ;; Don't push memory operands
9021 [(set (match_operand:SI 0 "push_operand" "")
9022 (match_operand:SI 1 "memory_operand" ""))
9023 (match_scratch:SI 2 "r")]
9024 "! optimize_size && ! TARGET_PUSH_MEMORY"
9025 [(set (match_dup 2) (match_dup 1))
9026 (set (match_dup 0) (match_dup 2))]
9029 ;; We need to handle SFmode only, because DFmode and XFmode is split to
9032 [(set (match_operand:SF 0 "push_operand" "")
9033 (match_operand:SF 1 "memory_operand" ""))
9034 (match_scratch:SF 2 "r")]
9035 "! optimize_size && ! TARGET_PUSH_MEMORY"
9036 [(set (match_dup 2) (match_dup 1))
9037 (set (match_dup 0) (match_dup 2))]
9041 [(set (match_operand:HI 0 "push_operand" "")
9042 (match_operand:HI 1 "memory_operand" ""))
9043 (match_scratch:HI 2 "r")]
9044 "! optimize_size && ! TARGET_PUSH_MEMORY"
9045 [(set (match_dup 2) (match_dup 1))
9046 (set (match_dup 0) (match_dup 2))]
9050 [(set (match_operand:QI 0 "push_operand" "")
9051 (match_operand:QI 1 "memory_operand" ""))
9052 (match_scratch:QI 2 "q")]
9053 "! optimize_size && ! TARGET_PUSH_MEMORY"
9054 [(set (match_dup 2) (match_dup 1))
9055 (set (match_dup 0) (match_dup 2))]
9058 ;; Don't move an immediate directly to memory when the instruction
9061 [(match_scratch:SI 1 "r")
9062 (set (match_operand:SI 0 "memory_operand" "")
9064 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
9065 && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))
9066 && ! TARGET_USE_MOV0
9067 && TARGET_SPLIT_LONG_MOVES"
9068 [(parallel [(set (match_dup 1) (const_int 0))
9069 (clobber (reg:CC 17))])
9070 (set (match_dup 0) (match_dup 1))]
9074 [(match_scratch:HI 1 "r")
9075 (set (match_operand:HI 0 "memory_operand" "")
9077 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
9078 && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))
9079 && ! TARGET_USE_MOV0
9080 && TARGET_SPLIT_LONG_MOVES"
9081 [(parallel [(set (match_dup 2) (const_int 0))
9082 (clobber (reg:CC 17))])
9083 (set (match_dup 0) (match_dup 1))]
9084 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
9087 [(match_scratch:QI 1 "q")
9088 (set (match_operand:QI 0 "memory_operand" "")
9090 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
9091 && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))
9092 && ! TARGET_USE_MOV0
9093 && TARGET_SPLIT_LONG_MOVES"
9094 [(parallel [(set (match_dup 2) (const_int 0))
9095 (clobber (reg:CC 17))])
9096 (set (match_dup 0) (match_dup 1))]
9097 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
9100 [(match_scratch:SI 2 "r")
9101 (set (match_operand:SI 0 "memory_operand" "")
9102 (match_operand:SI 1 "immediate_operand" ""))]
9103 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
9104 && TARGET_SPLIT_LONG_MOVES"
9105 [(set (match_dup 2) (match_dup 1))
9106 (set (match_dup 0) (match_dup 2))]
9110 [(match_scratch:HI 2 "r")
9111 (set (match_operand:HI 0 "memory_operand" "")
9112 (match_operand:HI 1 "immediate_operand" ""))]
9113 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
9114 && TARGET_SPLIT_LONG_MOVES"
9115 [(set (match_dup 2) (match_dup 1))
9116 (set (match_dup 0) (match_dup 2))]
9120 [(match_scratch:QI 2 "q")
9121 (set (match_operand:QI 0 "memory_operand" "")
9122 (match_operand:QI 1 "immediate_operand" ""))]
9123 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
9124 && TARGET_SPLIT_LONG_MOVES"
9125 [(set (match_dup 2) (match_dup 1))
9126 (set (match_dup 0) (match_dup 2))]
9129 ;; Don't compare memory with zero, load and use a test instead.
9132 (compare:CCNO (match_operand:SI 0 "memory_operand" "")
9134 (match_scratch:SI 3 "r")]
9136 [(set (match_dup 3) (match_dup 0))
9137 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
9140 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
9141 ;; Don't split NOTs with a displacement operand, because resulting XOR
9142 ;; will not be pariable anyway.
9144 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
9145 ;; represented using a modRM byte. The XOR replacement is long decoded,
9146 ;; so this split helps here as well.
9148 ;; Note: Can't do this as a regular split because reg_dead_p assumes
9149 ;; resource info is live.
9152 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9153 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9155 && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))
9157 && (GET_CODE (operands[0]) != MEM
9158 || !memory_displacement_operand (operands[0], SImode)))
9159 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
9160 [(parallel [(set (match_dup 0)
9161 (xor:SI (match_dup 1) (const_int -1)))
9162 (clobber (reg:CC 17))])]
9166 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9167 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9169 && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))
9171 && (GET_CODE (operands[0]) != MEM
9172 || !memory_displacement_operand (operands[0], HImode)))
9173 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
9174 [(parallel [(set (match_dup 0)
9175 (xor:HI (match_dup 1) (const_int -1)))
9176 (clobber (reg:CC 17))])]
9180 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
9181 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
9183 && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))
9185 && (GET_CODE (operands[0]) != MEM
9186 || !memory_displacement_operand (operands[0], QImode)))
9187 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
9188 [(parallel [(set (match_dup 0)
9189 (xor:QI (match_dup 1) (const_int -1)))
9190 (clobber (reg:CC 17))])]
9193 ;; Non pairable "test imm, reg" instructions can be translated to
9194 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
9195 ;; byte opcode instead of two, have a short form for byte operands),
9196 ;; so do it for other CPUs as well. Given that the value was dead,
9197 ;; this should not create any new dependancies. Pass on the sub-word
9198 ;; versions if we're concerned about partial register stalls.
9202 (compare:CCNO (and:SI (match_operand:SI 0 "register_operand" "")
9203 (match_operand:SI 1 "immediate_operand" ""))
9205 "(true_regnum (operands[0]) != 0
9206 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
9207 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
9210 (compare:CCNO (and:SI (match_dup 0)
9214 (and:SI (match_dup 0) (match_dup 1)))])]
9217 ;; We don't need to handle HImode case, because it will be promoted to SImode
9218 ;; on ! TARGET_PARTIAL_REG_STALL
9222 (compare:CCNO (and:QI (match_operand:QI 0 "register_operand" "")
9223 (match_operand:QI 1 "immediate_operand" ""))
9225 "! TARGET_PARTIAL_REG_STALL
9226 && true_regnum (operands[0]) != 0
9227 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
9230 (compare:CCNO (and:QI (match_dup 0)
9234 (and:QI (match_dup 0) (match_dup 1)))])]
9242 (match_operand 0 "ext_register_operand" "q")
9245 (match_operand 1 "const_int_operand" "n"))
9247 "! TARGET_PARTIAL_REG_STALL
9248 && true_regnum (operands[0]) != 0
9249 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
9250 [(parallel [(set (reg:CCNO 17)
9259 (set (zero_extract:SI (match_dup 0)
9270 ;; Don't do logical operations with memory inputs.
9272 [(match_scratch:SI 2 "r")
9273 (parallel [(set (match_operand:SI 0 "register_operand" "")
9274 (match_operator:SI 3 "arith_or_logical_operator"
9276 (match_operand:SI 1 "memory_operand" "")]))
9277 (clobber (reg:CC 17))])]
9278 "! optimize_size && ! TARGET_READ_MODIFY"
9279 [(set (match_dup 2) (match_dup 1))
9280 (parallel [(set (match_dup 0)
9281 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
9282 (clobber (reg:CC 17))])]
9286 [(match_scratch:SI 2 "r")
9287 (parallel [(set (match_operand:SI 0 "register_operand" "")
9288 (match_operator:SI 3 "arith_or_logical_operator"
9289 [(match_operand:SI 1 "memory_operand" "")
9291 (clobber (reg:CC 17))])]
9292 "! optimize_size && ! TARGET_READ_MODIFY"
9293 [(set (match_dup 2) (match_dup 1))
9294 (parallel [(set (match_dup 0)
9295 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
9296 (clobber (reg:CC 17))])]
9299 ; Don't do logical operations with memory outputs
9301 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
9302 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
9303 ; the same decoder scheduling characteristics as the original.
9306 [(match_scratch:SI 2 "r")
9307 (parallel [(set (match_operand:SI 0 "memory_operand" "")
9308 (match_operator:SI 3 "arith_or_logical_operator"
9310 (match_operand:SI 1 "nonmemory_operand" "")]))
9311 (clobber (reg:CC 17))])]
9312 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
9313 [(set (match_dup 2) (match_dup 0))
9314 (parallel [(set (match_dup 2)
9315 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
9316 (clobber (reg:CC 17))])
9317 (set (match_dup 0) (match_dup 2))]
9321 [(match_scratch:SI 2 "r")
9322 (parallel [(set (match_operand:SI 0 "memory_operand" "")
9323 (match_operator:SI 3 "arith_or_logical_operator"
9324 [(match_operand:SI 1 "nonmemory_operand" "")
9326 (clobber (reg:CC 17))])]
9327 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
9328 [(set (match_dup 2) (match_dup 0))
9329 (parallel [(set (match_dup 2)
9330 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9331 (clobber (reg:CC 17))])
9332 (set (match_dup 0) (match_dup 2))]
9335 ;; Attempt to always use XOR for zeroing registers.
9337 [(set (match_operand 0 "register_operand" "")
9339 "(GET_MODE (operands[0]) == QImode
9340 || GET_MODE (operands[0]) == HImode
9341 || GET_MODE (operands[0]) == SImode)
9342 && (! TARGET_USE_MOV0 || optimize_size)
9343 && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
9344 [(parallel [(set (match_dup 0) (const_int 0))
9345 (clobber (reg:CC 17))])]
9346 "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
9348 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
9350 [(set (match_operand 0 "register_operand" "")
9352 "(GET_MODE (operands[0]) == HImode
9353 || GET_MODE (operands[0]) == SImode)
9354 && (optimize_size || TARGET_PENTIUM)
9355 && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
9356 [(parallel [(set (match_dup 0) (const_int -1))
9357 (clobber (reg:CC 17))])]
9358 "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
9360 ;; Attempt to convert simple leas to adds. These can be created by
9363 [(set (match_operand:SI 0 "register_operand" "")
9364 (plus:SI (match_dup 0)
9365 (match_operand:SI 1 "nonmemory_operand" "")))]
9366 "reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
9367 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
9368 (clobber (reg:CC 17))])]
9372 [(set (match_operand:SI 0 "register_operand" "")
9373 (mult:SI (match_dup 0)
9374 (match_operand:SI 1 "immediate_operand" "")))]
9375 "reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
9376 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
9377 (clobber (reg:CC 17))])]
9378 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
9380 ;; Merge two successive stack adjusts. The combiner doesn't know how
9381 ;; to do this, and doesn't see all of them.
9382 ;; (reg:SI 7) is %esp.
9386 (plus:SI (reg:SI 7) (match_operand:SI 0 "const_int_operand" "")))
9387 (clobber (reg:CC 17))])
9390 (plus:SI (reg:SI 7) (match_operand:SI 1 "const_int_operand" "")))
9391 (clobber (reg:CC 17))])]
9395 (plus:SI (reg:SI 7) (match_dup 2)))
9396 (clobber (reg:CC 17))])]
9397 "operands[2] = GEN_INT (INTVAL (operands[0]) + INTVAL (operands[1]));")
9399 ;; Call-value patterns last so that the wildcard operand does not
9400 ;; disrupt insn-recog's switch tables.
9402 (define_insn "*call_value_pop_1"
9403 [(set (match_operand 0 "" "")
9404 (call (match_operand:QI 1 "call_insn_operand" "m")
9405 (match_operand:SI 2 "general_operand" "g")))
9406 (set (reg:SI 7) (plus:SI (reg:SI 7)
9407 (match_operand:SI 4 "immediate_operand" "i")))]
9411 if (constant_call_address_operand (operands[1], GET_MODE (operands[1])))
9412 return \"call\\t%P1\";
9414 operands[1] = XEXP (operands[1], 0);
9415 return \"call\\t%*%1\";
9417 [(set_attr "type" "callv")])
9419 (define_insn "*call_value_pop_2"
9420 [(set (match_operand 0 "" "")
9421 (call (match_operand:QI 1 "constant_call_address_operand" "")
9422 (match_operand:SI 2 "general_operand" "g")))
9423 (set (reg:SI 7) (plus:SI (reg:SI 7)
9424 (match_operand:SI 4 "immediate_operand" "i")))]
9427 [(set_attr "type" "callv")])
9429 (define_insn "*call_value_1"
9430 [(set (match_operand 0 "" "")
9431 (call (match_operand:QI 1 "call_insn_operand" "m")
9432 (match_operand:SI 2 "general_operand" "g")))]
9433 ;; Operand 2 not used on the i386.
9437 if (constant_call_address_operand (operands[1], GET_MODE (operands[1])))
9438 return \"call\\t%P1\";
9440 operands[1] = XEXP (operands[1], 0);
9441 return \"call\\t%*%1\";
9443 [(set_attr "type" "callv")])
9445 (define_insn "*call_value_2"
9446 [(set (match_operand 0 "" "")
9447 (call (match_operand:QI 1 "constant_call_address_operand" "")
9448 (match_operand:SI 2 "general_operand" "g")))]
9451 [(set_attr "type" "callv")])