1 ; GCC machine description for Intel X86.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000 Free Software
4 ;; Mostly by William Schelter.
6 ;; This file is part of GNU CC.
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA. */
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
29 ;; updates for most instructions.
31 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
32 ;; constraint letters.
34 ;; the special asm out single letter directives following a '%' are:
35 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
37 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
38 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
39 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
40 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
41 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
42 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
43 ;; 'J' Print the appropriate jump operand.
45 ;; 'b' Print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; 'w' Likewise, print the HImode name of the register.
48 ;; 'k' Likewise, print the SImode name of the register.
49 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
50 ;; 'y' Print "st(0)" instead of "st" as a register.
53 ;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode.
54 ;; operand 0 is the memory address to scan.
55 ;; operand 1 is a register containing the value to scan for. The mode
56 ;; of the scas opcode will be the same as the mode of this operand.
57 ;; operand 2 is the known alignment of operand 0.
58 ;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT.
59 ;; operand 0 is the argument for `sin'.
60 ;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT.
61 ;; operand 0 is the argument for `cos'.
62 ;; 3 This is part of a `stack probe' operation. The mode of the UNSPEC is
63 ;; always SImode. operand 0 is the size of the stack allocation.
64 ;; 4 This is the source of a fake SET of the frame pointer which is used to
65 ;; prevent insns referencing it being scheduled across the initial
66 ;; decrement of the stack pointer.
67 ;; 5 This is a `bsf' operation.
68 ;; 6 This is the @GOT offset of a PIC address.
69 ;; 7 This is the @GOTOFF offset of a PIC address.
70 ;; 8 This is a reference to a symbol's @PLT address.
72 ;; This shadows the processor_type enumeration, so changes must be made
73 ;; to i386.h at the same time.
75 ;; $FreeBSD: src/contrib/gcc/config/i386/i386.md,v 1.7.2.2 2001/04/10 19:23:24 obrien Exp $
78 "integer,binary,memory,test,compare,fcompare,idiv,imul,lea,fld,fpop,fpdiv,fpmul"
79 (const_string "integer"))
81 (define_attr "memory" "none,load,store"
82 (cond [(eq_attr "type" "idiv,lea")
85 (eq_attr "type" "fld")
88 (eq_attr "type" "test")
89 (if_then_else (match_operand 0 "memory_operand" "")
91 (const_string "none"))
93 (eq_attr "type" "compare,fcompare")
94 (if_then_else (ior (match_operand 0 "memory_operand" "")
95 (match_operand 1 "memory_operand" ""))
97 (const_string "none"))
99 (and (eq_attr "type" "integer,memory,fpop")
100 (match_operand 0 "memory_operand" ""))
101 (const_string "store")
103 (and (eq_attr "type" "integer,memory,fpop")
104 (match_operand 1 "memory_operand" ""))
105 (const_string "load")
107 (and (eq_attr "type" "binary,imul,fpmul,fpdiv")
108 (ior (match_operand 1 "memory_operand" "")
109 (match_operand 2 "memory_operand" "")))
110 (const_string "load")]
112 (const_string "none")))
116 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
117 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
119 ; pentiumpro has a reservation station with 5 ports
120 ; port 0 has integer, float add, integer divide, float divide, float
121 ; multiply, and shifter units.
122 ; port 1 has integer, and jump units.
123 ; port 2 has the load address generation unit
124 ; ports 3 and 4 have the store address generation units
126 ; pentium has two integer pipelines, the main u pipe and the secondary v pipe.
127 ; and a float pipeline
131 (define_function_unit "fp" 1 0
132 (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "i386,i486"))
135 (define_function_unit "fp" 1 0
136 (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "pentium,pentiumpro"))
139 (define_function_unit "fp" 1 0
140 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentium"))
143 (define_function_unit "fp" 1 0
144 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentiumpro"))
147 (define_function_unit "fp" 1 0
148 (and (eq_attr "type" "idiv") (eq_attr "cpu" "pentiumpro"))
151 (define_function_unit "fp" 1 0
152 (and (eq_attr "type" "imul") (eq_attr "cpu" "pentiumpro"))
155 (define_function_unit "fp" 1 0
156 (eq_attr "type" "fpdiv")
159 (define_function_unit "fp" 1 0
160 (and (eq_attr "type" "fld") (eq_attr "cpu" "!pentiumpro,k6"))
163 ;; K6 FPU is not pipelined.
164 (define_function_unit "fp" 1 0
165 (and (eq_attr "type" "fpop,fpmul,fcompare") (eq_attr "cpu" "k6"))
168 ;; i386 and i486 have one integer unit, which need not be modeled
170 (define_function_unit "integer" 2 0
171 (and (eq_attr "type" "integer,binary,test,compare,lea") (eq_attr "cpu" "pentium,pentiumpro"))
174 (define_function_unit "integer" 2 0
175 (and (eq_attr "cpu" "k6")
176 (and (eq_attr "type" "integer,binary,test,compare")
177 (eq_attr "memory" "!load")))
180 ;; Internally, K6 converts REG OP MEM instructions into a load (2 cycles)
181 ;; and a register operation (1 cycle).
182 (define_function_unit "integer" 2 0
183 (and (eq_attr "cpu" "k6")
184 (and (eq_attr "type" "integer,binary,test,compare")
185 (eq_attr "memory" "load")))
188 ;; Multiplies use one of the integer units
189 (define_function_unit "integer" 2 0
190 (and (eq_attr "cpu" "pentium") (eq_attr "type" "imul"))
193 (define_function_unit "integer" 2 0
194 (and (eq_attr "cpu" "k6") (eq_attr "type" "imul"))
197 (define_function_unit "integer" 2 0
198 (and (eq_attr "cpu" "pentium") (eq_attr "type" "idiv"))
201 (define_function_unit "integer" 2 0
202 (and (eq_attr "cpu" "k6") (eq_attr "type" "idiv"))
205 ;; Pentium Pro and K6 have a separate load unit.
206 (define_function_unit "load" 1 0
207 (and (eq_attr "cpu" "pentiumpro") (eq_attr "memory" "load"))
210 (define_function_unit "load" 1 0
211 (and (eq_attr "cpu" "k6") (eq_attr "memory" "load"))
214 ;; Pentium Pro and K6 have a separate store unit.
215 (define_function_unit "store" 1 0
216 (and (eq_attr "cpu" "pentiumpro,k6") (eq_attr "memory" "store"))
219 ;; lea executes in the K6 store unit with 1 cycle latency
220 (define_function_unit "store" 1 0
221 (and (eq_attr "cpu" "k6") (eq_attr "type" "lea"))
225 ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
226 ;; But restricting MEM here would mean that gcc could not remove a redundant
227 ;; test in cases like "incl MEM / je TARGET".
229 ;; We don't want to allow a constant operand for test insns because
230 ;; (set (cc0) (const_int foo)) has no mode information. Such insns will
231 ;; be folded while optimizing anyway.
233 ;; All test insns have expanders that save the operands away without
234 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
235 ;; after the tstM or cmp) will actually emit the tstM or cmpM.
237 ;; Processor type -- this attribute must exactly match the processor_type
238 ;; enumeration in i386.h.
240 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6"
241 (const (symbol_ref "ix86_cpu")))
243 (define_insn "tstsi_1"
245 (match_operand:SI 0 "nonimmediate_operand" "rm"))]
249 if (REG_P (operands[0]))
250 return AS2 (test%L0,%0,%0);
252 operands[1] = const0_rtx;
253 return AS2 (cmp%L0,%1,%0);
255 [(set_attr "type" "test")])
257 (define_expand "tstsi"
259 (match_operand:SI 0 "nonimmediate_operand" ""))]
263 i386_compare_gen = gen_tstsi_1;
264 i386_compare_op0 = operands[0];
265 i386_compare_op1 = const0_rtx;
269 (define_insn "tsthi_1"
271 (match_operand:HI 0 "nonimmediate_operand" "rm"))]
275 if (REG_P (operands[0]))
276 return AS2 (test%W0,%0,%0);
278 operands[1] = const0_rtx;
279 return AS2 (cmp%W0,%1,%0);
281 [(set_attr "type" "test")])
283 (define_expand "tsthi"
285 (match_operand:HI 0 "nonimmediate_operand" ""))]
289 i386_compare_gen = gen_tsthi_1;
290 i386_compare_op0 = operands[0];
291 i386_compare_op1 = const0_rtx;
295 (define_insn "tstqi_1"
297 (match_operand:QI 0 "nonimmediate_operand" "qm"))]
301 if (REG_P (operands[0]))
302 return AS2 (test%B0,%0,%0);
304 operands[1] = const0_rtx;
305 return AS2 (cmp%B0,%1,%0);
307 [(set_attr "type" "test")])
309 (define_expand "tstqi"
311 (match_operand:QI 0 "nonimmediate_operand" ""))]
315 i386_compare_gen = gen_tstqi_1;
316 i386_compare_op0 = operands[0];
317 i386_compare_op1 = const0_rtx;
321 (define_insn "tstsf_cc"
323 (match_operand:SF 0 "register_operand" "f"))
324 (clobber (match_scratch:HI 1 "=a"))]
325 "TARGET_80387 && ! TARGET_IEEE_FP"
328 if (! STACK_TOP_P (operands[0]))
331 output_asm_insn (\"ftst\", operands);
333 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
334 output_asm_insn (AS1 (fstp,%y0), operands);
336 return output_fp_cc0_set (insn);
338 [(set_attr "type" "test")])
340 ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
341 ;; isn't IEEE compliant.
343 (define_expand "tstsf"
344 [(parallel [(set (cc0)
345 (match_operand:SF 0 "register_operand" ""))
346 (clobber (match_scratch:HI 1 ""))])]
347 "TARGET_80387 && ! TARGET_IEEE_FP"
350 i386_compare_gen = gen_tstsf_cc;
351 i386_compare_op0 = operands[0];
352 i386_compare_op1 = const0_rtx;
356 (define_insn "tstdf_cc"
358 (match_operand:DF 0 "register_operand" "f"))
359 (clobber (match_scratch:HI 1 "=a"))]
360 "TARGET_80387 && ! TARGET_IEEE_FP"
363 if (! STACK_TOP_P (operands[0]))
366 output_asm_insn (\"ftst\", operands);
368 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
369 output_asm_insn (AS1 (fstp,%y0), operands);
371 return output_fp_cc0_set (insn);
373 [(set_attr "type" "test")])
375 ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
376 ;; isn't IEEE compliant.
378 (define_expand "tstdf"
379 [(parallel [(set (cc0)
380 (match_operand:DF 0 "register_operand" ""))
381 (clobber (match_scratch:HI 1 ""))])]
382 "TARGET_80387 && ! TARGET_IEEE_FP"
385 i386_compare_gen = gen_tstdf_cc;
386 i386_compare_op0 = operands[0];
387 i386_compare_op1 = const0_rtx;
391 (define_insn "tstxf_cc"
393 (match_operand:XF 0 "register_operand" "f"))
394 (clobber (match_scratch:HI 1 "=a"))]
395 "TARGET_80387 && ! TARGET_IEEE_FP"
398 if (! STACK_TOP_P (operands[0]))
401 output_asm_insn (\"ftst\", operands);
403 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
404 output_asm_insn (AS1 (fstp,%y0), operands);
406 return output_fp_cc0_set (insn);
408 [(set_attr "type" "test")])
410 ;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode
411 ;; isn't IEEE compliant.
413 (define_expand "tstxf"
414 [(parallel [(set (cc0)
415 (match_operand:XF 0 "register_operand" ""))
416 (clobber (match_scratch:HI 1 ""))])]
417 "TARGET_80387 && ! TARGET_IEEE_FP"
420 i386_compare_gen = gen_tstxf_cc;
421 i386_compare_op0 = operands[0];
422 i386_compare_op1 = const0_rtx;
426 ;;- compare instructions. See comments above tstM patterns about
427 ;; expansion of these insns.
429 (define_insn "cmpsi_1"
431 (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
432 (match_operand:SI 1 "general_operand" "ri,mr")))]
433 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
434 "* return AS2 (cmp%L0,%1,%0);"
435 [(set_attr "type" "compare")])
437 (define_expand "cmpsi"
439 (compare (match_operand:SI 0 "nonimmediate_operand" "")
440 (match_operand:SI 1 "general_operand" "")))]
444 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
445 operands[0] = force_reg (SImode, operands[0]);
447 i386_compare_gen = gen_cmpsi_1;
448 i386_compare_op0 = operands[0];
449 i386_compare_op1 = operands[1];
453 (define_insn "cmphi_1"
455 (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
456 (match_operand:HI 1 "general_operand" "ri,mr")))]
457 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
458 "* return AS2 (cmp%W0,%1,%0);"
459 [(set_attr "type" "compare")])
461 (define_expand "cmphi"
463 (compare (match_operand:HI 0 "nonimmediate_operand" "")
464 (match_operand:HI 1 "general_operand" "")))]
468 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
469 operands[0] = force_reg (HImode, operands[0]);
471 i386_compare_gen = gen_cmphi_1;
472 i386_compare_op0 = operands[0];
473 i386_compare_op1 = operands[1];
477 (define_insn "cmpqi_1"
479 (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
480 (match_operand:QI 1 "general_operand" "qm,nq")))]
481 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
482 "* return AS2 (cmp%B0,%1,%0);"
483 [(set_attr "type" "compare")])
485 (define_expand "cmpqi"
487 (compare (match_operand:QI 0 "nonimmediate_operand" "")
488 (match_operand:QI 1 "general_operand" "")))]
492 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
493 operands[0] = force_reg (QImode, operands[0]);
495 i386_compare_gen = gen_cmpqi_1;
496 i386_compare_op0 = operands[0];
497 i386_compare_op1 = operands[1];
501 ;; These implement float point compares. For each of DFmode and
502 ;; SFmode, there is the normal insn, and an insn where the second operand
503 ;; is converted to the desired mode.
507 (match_operator 2 "VOIDmode_compare_op"
508 [(match_operand:XF 0 "register_operand" "f")
509 (match_operand:XF 1 "register_operand" "f")]))
510 (clobber (match_scratch:HI 3 "=a"))]
512 "* return output_float_compare (insn, operands);"
513 [(set_attr "type" "fcompare")])
517 (match_operator 2 "VOIDmode_compare_op"
518 [(match_operand:XF 0 "register_operand" "f")
520 (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
521 (clobber (match_scratch:HI 3 "=a"))]
523 "* return output_float_compare (insn, operands);"
524 [(set_attr "type" "fcompare")])
528 (match_operator 2 "VOIDmode_compare_op"
530 (match_operand:DF 0 "nonimmediate_operand" "fm"))
531 (match_operand:XF 1 "register_operand" "f")]))
532 (clobber (match_scratch:HI 3 "=a"))]
534 "* return output_float_compare (insn, operands);"
535 [(set_attr "type" "fcompare")])
539 (match_operator 2 "VOIDmode_compare_op"
540 [(match_operand:XF 0 "register_operand" "f")
542 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
543 (clobber (match_scratch:HI 3 "=a"))]
545 "* return output_float_compare (insn, operands);"
546 [(set_attr "type" "fcompare")])
550 (match_operator 2 "VOIDmode_compare_op"
552 (match_operand:SF 0 "nonimmediate_operand" "fm"))
553 (match_operand:XF 1 "register_operand" "f")]))
554 (clobber (match_scratch:HI 3 "=a"))]
556 "* return output_float_compare (insn, operands);"
557 [(set_attr "type" "fcompare")])
561 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
562 (match_operand:XF 1 "register_operand" "f")))
563 (clobber (match_scratch:HI 2 "=a"))]
565 "* return output_float_compare (insn, operands);"
566 [(set_attr "type" "fcompare")])
570 (match_operator 2 "VOIDmode_compare_op"
571 [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
572 (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
573 (clobber (match_scratch:HI 3 "=a,a"))]
575 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
576 "* return output_float_compare (insn, operands);"
577 [(set_attr "type" "fcompare")])
581 (match_operator 2 "VOIDmode_compare_op"
582 [(match_operand:DF 0 "register_operand" "f")
584 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
585 (clobber (match_scratch:HI 3 "=a"))]
587 "* return output_float_compare (insn, operands);"
588 [(set_attr "type" "fcompare")])
592 (match_operator 2 "VOIDmode_compare_op"
594 (match_operand:SF 0 "nonimmediate_operand" "fm"))
595 (match_operand:DF 1 "register_operand" "f")]))
596 (clobber (match_scratch:HI 3 "=a"))]
598 "* return output_float_compare (insn, operands);"
599 [(set_attr "type" "fcompare")])
603 (match_operator 2 "VOIDmode_compare_op"
605 (match_operand:SF 0 "register_operand" "f"))
606 (match_operand:DF 1 "nonimmediate_operand" "fm")]))
607 (clobber (match_scratch:HI 3 "=a"))]
609 "* return output_float_compare (insn, operands);"
610 [(set_attr "type" "fcompare")])
614 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
615 (match_operand:DF 1 "register_operand" "f")))
616 (clobber (match_scratch:HI 2 "=a"))]
618 "* return output_float_compare (insn, operands);"
619 [(set_attr "type" "fcompare")])
621 ;; These two insns will never be generated by combine due to the mode of
625 ; (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
627 ; (match_operand:SF 1 "register_operand" "f"))))
628 ; (clobber (match_scratch:HI 2 "=a"))]
630 ; "* return output_float_compare (insn, operands);")
634 ; (compare:CCFPEQ (float_extend:DF
635 ; (match_operand:SF 0 "register_operand" "f"))
636 ; (match_operand:DF 1 "register_operand" "f")))
637 ; (clobber (match_scratch:HI 2 "=a"))]
639 ; "* return output_float_compare (insn, operands);")
641 (define_insn "*cmpsf_cc_1"
643 (match_operator 2 "VOIDmode_compare_op"
644 [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
645 (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
646 (clobber (match_scratch:HI 3 "=a,a"))]
648 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
649 "* return output_float_compare (insn, operands);"
650 [(set_attr "type" "fcompare")])
654 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
655 (match_operand:SF 1 "register_operand" "f")))
656 (clobber (match_scratch:HI 2 "=a"))]
658 "* return output_float_compare (insn, operands);"
659 [(set_attr "type" "fcompare")])
661 (define_expand "cmpxf"
663 (compare (match_operand:XF 0 "register_operand" "")
664 (match_operand:XF 1 "register_operand" "")))]
668 i386_compare_gen = gen_cmpxf_cc;
669 i386_compare_gen_eq = gen_cmpxf_ccfpeq;
670 i386_compare_op0 = operands[0];
671 i386_compare_op1 = operands[1];
675 (define_expand "cmpdf"
677 (compare (match_operand:DF 0 "register_operand" "")
678 (match_operand:DF 1 "general_operand" "")))]
682 i386_compare_gen = gen_cmpdf_cc;
683 i386_compare_gen_eq = gen_cmpdf_ccfpeq;
684 i386_compare_op0 = operands[0];
685 i386_compare_op1 = (immediate_operand (operands[1], DFmode))
686 ? copy_to_mode_reg (DFmode, operands[1]) : operands[1];
690 (define_expand "cmpsf"
692 (compare (match_operand:SF 0 "register_operand" "")
693 (match_operand:SF 1 "general_operand" "")))]
697 i386_compare_gen = gen_cmpsf_cc;
698 i386_compare_gen_eq = gen_cmpsf_ccfpeq;
699 i386_compare_op0 = operands[0];
700 i386_compare_op1 = (immediate_operand (operands[1], SFmode))
701 ? copy_to_mode_reg (SFmode, operands[1]) : operands[1];
705 (define_expand "cmpxf_cc"
706 [(parallel [(set (cc0)
707 (compare (match_operand:XF 0 "register_operand" "")
708 (match_operand:XF 1 "register_operand" "")))
709 (clobber (match_scratch:HI 2 ""))])]
713 (define_expand "cmpxf_ccfpeq"
714 [(parallel [(set (cc0)
715 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
716 (match_operand:XF 1 "register_operand" "")))
717 (clobber (match_scratch:HI 2 ""))])]
721 (define_expand "cmpdf_cc"
722 [(parallel [(set (cc0)
723 (compare (match_operand:DF 0 "register_operand" "")
724 (match_operand:DF 1 "register_operand" "")))
725 (clobber (match_scratch:HI 2 ""))])]
729 (define_expand "cmpdf_ccfpeq"
730 [(parallel [(set (cc0)
731 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
732 (match_operand:DF 1 "register_operand" "")))
733 (clobber (match_scratch:HI 2 ""))])]
737 if (! register_operand (operands[1], DFmode))
738 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
741 (define_expand "cmpsf_cc"
742 [(parallel [(set (cc0)
743 (compare (match_operand:SF 0 "register_operand" "")
744 (match_operand:SF 1 "register_operand" "")))
745 (clobber (match_scratch:HI 2 ""))])]
749 (define_expand "cmpsf_ccfpeq"
750 [(parallel [(set (cc0)
751 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
752 (match_operand:SF 1 "register_operand" "")))
753 (clobber (match_scratch:HI 2 ""))])]
757 if (! register_operand (operands[1], SFmode))
758 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
765 (and:SI (match_operand:SI 0 "general_operand" "%ro")
766 (match_operand:SI 1 "nonmemory_operand" "ri")))]
770 /* For small integers, we may actually use testb. */
771 if (GET_CODE (operands[1]) == CONST_INT
772 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
773 && (! REG_P (operands[0]) || QI_REG_P (operands[0]))
774 /* A Pentium test is pairable only with eax. Not with ah or al. */
775 && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
778 /* We may set the sign bit spuriously. */
780 if ((INTVAL (operands[1]) & ~0xff) == 0)
782 cc_status.flags |= CC_NOT_NEGATIVE;
783 return AS2 (test%B0,%1,%b0);
786 if ((INTVAL (operands[1]) & ~0xff00) == 0)
788 cc_status.flags |= CC_NOT_NEGATIVE;
789 operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
791 if (QI_REG_P (operands[0]))
792 return AS2 (test%B0,%1,%h0);
795 operands[0] = adj_offsettable_operand (operands[0], 1);
796 return AS2 (test%B0,%1,%b0);
800 if (GET_CODE (operands[0]) == MEM
801 && (INTVAL (operands[1]) & ~0xff0000) == 0)
803 cc_status.flags |= CC_NOT_NEGATIVE;
804 operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
805 operands[0] = adj_offsettable_operand (operands[0], 2);
806 return AS2 (test%B0,%1,%b0);
809 if (GET_CODE (operands[0]) == MEM
810 && (INTVAL (operands[1]) & ~0xff000000) == 0)
812 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
813 operands[0] = adj_offsettable_operand (operands[0], 3);
814 return AS2 (test%B0,%1,%b0);
818 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
819 return AS2 (test%L0,%1,%0);
821 return AS2 (test%L1,%0,%1);
823 [(set_attr "type" "compare")])
827 (and:HI (match_operand:HI 0 "general_operand" "%ro")
828 (match_operand:HI 1 "nonmemory_operand" "ri")))]
832 if (GET_CODE (operands[1]) == CONST_INT
833 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
834 && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
836 if ((INTVAL (operands[1]) & 0xff00) == 0)
838 /* ??? This might not be necessary. */
839 if (INTVAL (operands[1]) & 0xffff0000)
840 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
842 /* We may set the sign bit spuriously. */
843 cc_status.flags |= CC_NOT_NEGATIVE;
844 return AS2 (test%B0,%1,%b0);
847 if ((INTVAL (operands[1]) & 0xff) == 0)
849 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
851 if (QI_REG_P (operands[0]))
852 return AS2 (test%B0,%1,%h0);
855 operands[0] = adj_offsettable_operand (operands[0], 1);
856 return AS2 (test%B0,%1,%b0);
861 /* use 32-bit test instruction if there are no sign issues */
862 if (GET_CODE (operands[1]) == CONST_INT
863 && !(INTVAL (operands[1]) & ~0x7fff)
864 && i386_aligned_p (operands[0]))
865 return AS2 (test%L0,%1,%k0);
867 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
868 return AS2 (test%W0,%1,%0);
870 return AS2 (test%W1,%0,%1);
872 [(set_attr "type" "compare")])
876 (and:QI (match_operand:QI 0 "nonimmediate_operand" "%qm")
877 (match_operand:QI 1 "nonmemory_operand" "qi")))]
881 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
882 return AS2 (test%B0,%1,%0);
884 return AS2 (test%B1,%0,%1);
886 [(set_attr "type" "compare")])
888 ;; move instructions.
889 ;; There is one for each machine mode,
890 ;; and each is preceded by a corresponding push-insn pattern
891 ;; (since pushes are not general_operands on the 386).
894 [(set (match_operand:SI 0 "push_operand" "=<")
895 (match_operand:SI 1 "nonmemory_operand" "rn"))]
897 "* return AS1 (push%L0,%1);"
898 [(set_attr "memory" "store")])
901 [(set (match_operand:SI 0 "push_operand" "=<")
902 (match_operand:SI 1 "nonmemory_operand" "ri"))]
904 "* return AS1 (push%L0,%1);"
905 [(set_attr "memory" "store")])
907 ;; On a 386, it is faster to push MEM directly.
910 [(set (match_operand:SI 0 "push_operand" "=<")
911 (match_operand:SI 1 "memory_operand" "m"))]
913 "* return AS1 (push%L0,%1);"
914 [(set_attr "type" "memory")
915 (set_attr "memory" "load")])
917 ;; General case of fullword move.
919 ;; If generating PIC code and operands[1] is a symbolic CONST, emit a
920 ;; move to get the address of the symbolic object from the GOT.
922 (define_expand "movsi"
923 [(set (match_operand:SI 0 "general_operand" "")
924 (match_operand:SI 1 "general_operand" ""))]
930 if (flag_pic && SYMBOLIC_CONST (operands[1]))
931 emit_pic_move (operands, SImode);
933 /* Don't generate memory->memory moves, go through a register */
935 && no_new_pseudos == 0
936 && GET_CODE (operands[0]) == MEM
937 && GET_CODE (operands[1]) == MEM)
939 operands[1] = force_reg (SImode, operands[1]);
943 ;; On i486, incl reg is faster than movl $1,reg.
946 [(set (match_operand:SI 0 "general_operand" "=g,r,r")
947 (match_operand:SI 1 "general_operand" "rn,i,m"))]
948 "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
949 || (GET_CODE (operands[1]) != MEM))
955 /* K6: mov reg,0 is slightly faster than xor reg,reg but is 3 bytes
957 if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
958 && operands[1] == const0_rtx && REG_P (operands[0]))
959 return AS2 (xor%L0,%0,%0);
961 if (operands[1] == const1_rtx
962 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
963 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
964 && (link = find_reg_note (insn, REG_WAS_0, 0))
965 /* Make sure the insn that stored the 0 is still present. */
966 && ! INSN_DELETED_P (XEXP (link, 0))
967 && GET_CODE (XEXP (link, 0)) != NOTE
968 /* Make sure cross jumping didn't happen here. */
969 && no_labels_between_p (XEXP (link, 0), insn)
970 /* Make sure the reg hasn't been clobbered. */
971 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
972 /* Fastest way to change a 0 to a 1. */
973 return AS1 (inc%L0,%0);
975 if (SYMBOLIC_CONST (operands[1]))
976 return AS2 (lea%L0,%a1,%0);
978 return AS2 (mov%L0,%1,%0);
980 [(set_attr "type" "integer,integer,memory")
981 (set_attr "memory" "*,*,load")])
984 [(set (match_operand:SI 0 "general_operand" "=g,r")
985 (match_operand:SI 1 "general_operand" "ri,m"))]
986 "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
987 || (GET_CODE (operands[1]) != MEM))
993 /* Use of xor was disabled for AMD K6 as recommended by the Optimization
994 Manual. My test shows, that this generally hurts the performance, because
995 mov is longer and takes longer to decode and decoding is the main
996 bottleneck of K6 when executing GCC code. */
998 if (operands[1] == const0_rtx && REG_P (operands[0]))
999 return AS2 (xor%L0,%0,%0);
1001 if (operands[1] == const1_rtx
1002 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
1003 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1004 && (link = find_reg_note (insn, REG_WAS_0, 0))
1005 /* Make sure the insn that stored the 0 is still present. */
1006 && ! INSN_DELETED_P (XEXP (link, 0))
1007 && GET_CODE (XEXP (link, 0)) != NOTE
1008 /* Make sure cross jumping didn't happen here. */
1009 && no_labels_between_p (XEXP (link, 0), insn)
1010 /* Make sure the reg hasn't been clobbered. */
1011 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1012 /* Fastest way to change a 0 to a 1. */
1013 return AS1 (inc%L0,%0);
1015 return AS2 (mov%L0,%1,%0);
1017 [(set_attr "type" "integer,memory")
1018 (set_attr "memory" "*,load")])
1021 [(set (match_operand:HI 0 "push_operand" "=<")
1022 (match_operand:HI 1 "nonmemory_operand" "ri"))]
1024 "* return AS1 (push%W0,%1);"
1025 [(set_attr "type" "memory")
1026 (set_attr "memory" "store")])
1029 [(set (match_operand:HI 0 "push_operand" "=<")
1030 (match_operand:HI 1 "memory_operand" "m"))]
1031 "TARGET_PUSH_MEMORY"
1032 "* return AS1 (push%W0,%1);"
1033 [(set_attr "type" "memory")
1034 (set_attr "memory" "load")])
1036 ;; On i486, an incl and movl are both faster than incw and movw.
1038 (define_expand "movhi"
1039 [(set (match_operand:HI 0 "general_operand" "")
1040 (match_operand:HI 1 "general_operand" ""))]
1044 /* Don't generate memory->memory moves, go through a register */
1046 && no_new_pseudos == 0
1047 && GET_CODE (operands[0]) == MEM
1048 && GET_CODE (operands[1]) == MEM)
1050 operands[1] = force_reg (HImode, operands[1]);
1055 [(set (match_operand:HI 0 "general_operand" "=g,r")
1056 (match_operand:HI 1 "general_operand" "ri,m"))]
1057 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1061 if (REG_P (operands[0]) && operands[1] == const0_rtx)
1062 return AS2 (xor%L0,%k0,%k0);
1064 if (REG_P (operands[0]) && operands[1] == const1_rtx
1065 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
1066 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1067 && (link = find_reg_note (insn, REG_WAS_0, 0))
1068 /* Make sure the insn that stored the 0 is still present. */
1069 && ! INSN_DELETED_P (XEXP (link, 0))
1070 && GET_CODE (XEXP (link, 0)) != NOTE
1071 /* Make sure cross jumping didn't happen here. */
1072 && no_labels_between_p (XEXP (link, 0), insn)
1073 /* Make sure the reg hasn't been clobbered. */
1074 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1075 /* Fastest way to change a 0 to a 1. */
1076 return AS1 (inc%L0,%k0);
1078 if (REG_P (operands[0]))
1080 if (i386_aligned_p (operands[1]))
1082 operands[1] = i386_sext16_if_const (operands[1]);
1083 return AS2 (mov%L0,%k1,%k0);
1085 if (! TARGET_ZERO_EXTEND_WITH_AND)
1087 /* movzwl is faster than movw on the Pentium Pro,
1088 * although not as fast as an aligned movl. */
1090 return AS2 (movzx,%1,%k0);
1092 return AS2 (movz%W0%L0,%1,%k0);
1097 return AS2 (mov%W0,%1,%0);
1099 [(set_attr "type" "integer,memory")
1100 (set_attr "memory" "*,load")])
1102 (define_expand "movstricthi"
1103 [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
1104 (match_operand:HI 1 "general_operand" ""))]
1108 /* Don't generate memory->memory moves, go through a register */
1110 && no_new_pseudos == 0
1111 && GET_CODE (operands[0]) == MEM
1112 && GET_CODE (operands[1]) == MEM)
1114 operands[1] = force_reg (HImode, operands[1]);
1119 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
1120 (match_operand:HI 1 "general_operand" "ri,m"))]
1121 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1126 /* Use of xor was disabled for AMD K6 as recommended by the Optimization
1127 Manual. My test shows, that this generally hurts the performance, because
1128 mov is longer and takes longer to decode and decoding is the main
1129 bottleneck of K6 when executing GCC code. */
1131 if (operands[1] == const0_rtx && REG_P (operands[0]))
1132 return AS2 (xor%W0,%0,%0);
1134 if (operands[1] == const1_rtx
1135 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
1136 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1137 && (link = find_reg_note (insn, REG_WAS_0, 0))
1138 /* Make sure the insn that stored the 0 is still present. */
1139 && ! INSN_DELETED_P (XEXP (link, 0))
1140 && GET_CODE (XEXP (link, 0)) != NOTE
1141 /* Make sure cross jumping didn't happen here. */
1142 && no_labels_between_p (XEXP (link, 0), insn)
1143 /* Make sure the reg hasn't been clobbered. */
1144 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1145 /* Fastest way to change a 0 to a 1. */
1146 return AS1 (inc%W0,%0);
1148 return AS2 (mov%W0,%1,%0);
1150 [(set_attr "type" "integer,memory")])
1152 ;; emit_push_insn when it calls move_by_pieces
1153 ;; requires an insn to "push a byte".
1154 ;; But actually we use pushw, which has the effect of rounding
1155 ;; the amount pushed up to a halfword.
1157 [(set (match_operand:QI 0 "push_operand" "=<")
1158 (match_operand:QI 1 "const_int_operand" "n"))]
1160 "* return AS1(push%W0,%1);")
1163 [(set (match_operand:QI 0 "push_operand" "=<")
1164 (match_operand:QI 1 "register_operand" "q"))]
1168 operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]));
1169 return AS1 (push%W0,%1);
1172 ;; On i486, incb reg is faster than movb $1,reg.
1174 ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
1175 ;; or writes %ah, %bh, %ch, %dh.
1177 (define_expand "movqi"
1178 [(set (match_operand:QI 0 "general_operand" "")
1179 (match_operand:QI 1 "general_operand" ""))]
1183 /* Don't generate memory->memory moves, go through a register */
1185 && no_new_pseudos == 0
1186 && GET_CODE (operands[0]) == MEM
1187 && GET_CODE (operands[1]) == MEM)
1189 operands[1] = force_reg (QImode, operands[1]);
1194 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,*r,qm")
1195 (match_operand:QI 1 "general_operand" "*g,*rn,qn"))]
1196 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1201 /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8.
1202 It is at least as fast as xor on any processor except a Pentium. */
1204 if (operands[1] == const1_rtx
1206 && (link = find_reg_note (insn, REG_WAS_0, 0))
1207 /* Make sure the insn that stored the 0 is still present. */
1208 && ! INSN_DELETED_P (XEXP (link, 0))
1209 && GET_CODE (XEXP (link, 0)) != NOTE
1210 /* Make sure cross jumping didn't happen here. */
1211 && no_labels_between_p (XEXP (link, 0), insn)
1212 /* Make sure the reg hasn't been clobbered. */
1213 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1215 /* Fastest way to change a 0 to a 1.
1216 If inc%B0 isn't allowed, use inc%L0. */
1217 if (NON_QI_REG_P (operands[0]))
1218 return AS1 (inc%L0,%k0);
1220 return AS1 (inc%B0,%0);
1223 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1224 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1225 return (AS2 (mov%L0,%k1,%k0));
1227 return (AS2 (mov%B0,%1,%0));
1230 ;; If it becomes necessary to support movstrictqi into %esi or %edi,
1231 ;; use the insn sequence:
1233 ;; shrdl $8,srcreg,dstreg
1236 ;; If operands[1] is a constant, then an andl/orl sequence would be
1239 (define_expand "movstrictqi"
1240 [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
1241 (match_operand:QI 1 "general_operand" ""))]
1245 /* Don't generate memory->memory moves, go through a register */
1247 && no_new_pseudos == 0
1248 && GET_CODE (operands[0]) == MEM
1249 && GET_CODE (operands[1]) == MEM)
1251 operands[1] = force_reg (QImode, operands[1]);
1256 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1257 (match_operand:QI 1 "general_operand" "*qn,m"))]
1258 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1263 /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. */
1265 if (operands[1] == const1_rtx
1267 && ! NON_QI_REG_P (operands[0])
1268 && (link = find_reg_note (insn, REG_WAS_0, 0))
1269 /* Make sure the insn that stored the 0 is still present. */
1270 && ! INSN_DELETED_P (XEXP (link, 0))
1271 && GET_CODE (XEXP (link, 0)) != NOTE
1272 /* Make sure cross jumping didn't happen here. */
1273 && no_labels_between_p (XEXP (link, 0), insn)
1274 /* Make sure the reg hasn't been clobbered. */
1275 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1276 /* Fastest way to change a 0 to a 1. */
1277 return AS1 (inc%B0,%0);
1279 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1280 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1283 return (AS2 (mov%L0,%k1,%k0));
1286 return AS2 (mov%B0,%1,%0);
1289 (define_insn "movsf_push"
1290 [(set (match_operand:SF 0 "push_operand" "=<,<")
1291 (match_operand:SF 1 "general_operand" "*rfF,m"))]
1292 "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM
1293 || reload_in_progress || reload_completed"
1296 if (STACK_REG_P (operands[1]))
1300 if (! STACK_TOP_P (operands[1]))
1303 xops[0] = AT_SP (SFmode);
1304 xops[1] = GEN_INT (4);
1305 xops[2] = stack_pointer_rtx;
1307 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1309 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1310 output_asm_insn (AS1 (fstp%S0,%0), xops);
1312 output_asm_insn (AS1 (fst%S0,%0), xops);
1317 return AS1 (push%L0,%1);
1321 [(set (match_operand:SF 0 "push_operand" "")
1322 (match_operand:SF 1 "general_operand" ""))]
1323 "reload_completed && STACK_REG_P (operands[1])"
1325 (minus:SI (reg:SI 7) (const_int 4)))
1326 (set (mem:SF (reg:SI 7))
1330 (define_expand "movsf"
1331 [(set (match_operand:SF 0 "general_operand" "")
1332 (match_operand:SF 1 "general_operand" ""))]
1336 /* Don't generate memory->memory moves, go through a register */
1338 && no_new_pseudos == 0
1339 && GET_CODE (operands[0]) == MEM
1340 && GET_CODE (operands[1]) == MEM)
1342 operands[1] = force_reg (SFmode, operands[1]);
1345 /* If we are loading a floating point constant that isn't 0 or 1
1346 into a register, force the value to memory now, since we'll
1347 get better code out the back end. */
1348 else if ((reload_in_progress | reload_completed) == 0
1349 && GET_CODE (operands[0]) != MEM
1350 && GET_CODE (operands[1]) == CONST_DOUBLE
1351 && !standard_80387_constant_p (operands[1]))
1353 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
1357 ;; For the purposes of regclass, prefer FLOAT_REGS.
1359 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r,!m")
1360 (match_operand:SF 1 "general_operand" "fmG,f,*rmF,*rF"))]
1361 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1364 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1366 /* First handle a `pop' insn or a `fld %st(0)' */
1368 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1371 return AS1 (fstp,%y0);
1373 return AS1 (fld,%y0);
1376 /* Handle other kinds of writes from the 387 */
1378 if (STACK_TOP_P (operands[1]))
1381 return AS1 (fstp%z0,%y0);
1383 return AS1 (fst%z0,%y0);
1386 /* Handle other kinds of reads to the 387 */
1388 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1389 return output_move_const_single (operands);
1391 if (STACK_TOP_P (operands[0]))
1392 return AS1 (fld%z1,%y1);
1394 /* Handle all SFmode moves not involving the 387 */
1396 return singlemove_string (operands);
1398 [(set_attr "type" "fld")])
1401 (define_insn "swapsf"
1402 [(set (match_operand:SF 0 "register_operand" "f")
1403 (match_operand:SF 1 "register_operand" "f"))
1409 if (STACK_TOP_P (operands[0]))
1410 return AS1 (fxch,%1);
1412 return AS1 (fxch,%0);
1416 (define_insn "movdf_push"
1417 [(set (match_operand:DF 0 "push_operand" "=<,<")
1418 (match_operand:DF 1 "general_operand" "*rfF,o"))]
1419 "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM
1420 || reload_in_progress || reload_completed"
1423 if (STACK_REG_P (operands[1]))
1427 xops[0] = AT_SP (DFmode);
1428 xops[1] = GEN_INT (8);
1429 xops[2] = stack_pointer_rtx;
1431 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1433 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1434 output_asm_insn (AS1 (fstp%Q0,%0), xops);
1436 output_asm_insn (AS1 (fst%Q0,%0), xops);
1441 if (which_alternative == 1)
1442 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 0, 0);
1444 return output_move_double (operands);
1448 [(set (match_operand:DF 0 "push_operand" "")
1449 (match_operand:DF 1 "register_operand" ""))]
1450 "reload_completed && STACK_REG_P (operands[1])"
1452 (minus:SI (reg:SI 7) (const_int 8)))
1453 (set (mem:DF (reg:SI 7))
1457 (define_expand "movdf"
1458 [(set (match_operand:DF 0 "general_operand" "")
1459 (match_operand:DF 1 "general_operand" ""))]
1463 /* Don't generate memory->memory moves, go through a register */
1465 && no_new_pseudos == 0
1466 && GET_CODE (operands[0]) == MEM
1467 && GET_CODE (operands[1]) == MEM)
1469 operands[1] = force_reg (DFmode, operands[1]);
1472 /* If we are loading a floating point constant that isn't 0 or 1 into a
1473 register, indicate we need the pic register loaded. This could be
1474 optimized into stores of constants if the target eventually moves to
1475 memory, but better safe than sorry. */
1476 else if ((reload_in_progress | reload_completed) == 0
1477 && GET_CODE (operands[0]) != MEM
1478 && GET_CODE (operands[1]) == CONST_DOUBLE
1479 && !standard_80387_constant_p (operands[1]))
1481 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
1485 ;; For the purposes of regclass, prefer FLOAT_REGS.
1487 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r,!o")
1488 (match_operand:DF 1 "general_operand" "fmG,f,*roF,*rF"))]
1489 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1490 || (GET_CODE (operands[1]) != MEM)"
1493 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1495 /* First handle a `pop' insn or a `fld %st(0)' */
1497 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1500 return AS1 (fstp,%y0);
1502 return AS1 (fld,%y0);
1505 /* Handle other kinds of writes from the 387 */
1507 if (STACK_TOP_P (operands[1]))
1510 return AS1 (fstp%z0,%y0);
1512 return AS1 (fst%z0,%y0);
1515 /* Handle other kinds of reads to the 387 */
1517 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1518 return output_move_const_single (operands);
1520 if (STACK_TOP_P (operands[0]))
1521 return AS1 (fld%z1,%y1);
1523 /* Handle all DFmode moves not involving the 387 */
1525 return output_move_double (operands);
1527 [(set_attr "type" "fld")])
1531 (define_insn "swapdf"
1532 [(set (match_operand:DF 0 "register_operand" "f")
1533 (match_operand:DF 1 "register_operand" "f"))
1539 if (STACK_TOP_P (operands[0]))
1540 return AS1 (fxch,%1);
1542 return AS1 (fxch,%0);
1545 (define_insn "movxf_push"
1546 [(set (match_operand:XF 0 "push_operand" "=<,<")
1547 (match_operand:XF 1 "general_operand" "*rfF,o"))]
1548 "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM
1549 || reload_in_progress || reload_completed"
1552 if (STACK_REG_P (operands[1]))
1556 xops[0] = AT_SP (XFmode);
1557 xops[1] = GEN_INT (12);
1558 xops[2] = stack_pointer_rtx;
1560 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1562 output_asm_insn (AS1 (fstp%T0,%0), xops);
1563 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1564 output_asm_insn (AS1 (fld%T0,%0), xops);
1569 if (which_alternative == 1)
1570 return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 0, 0);
1572 return output_move_double (operands);
1576 [(set (match_operand:XF 0 "push_operand" "")
1577 (match_operand:XF 1 "register_operand" ""))]
1578 "reload_completed && STACK_REG_P (operands[1])"
1580 (minus:SI (reg:SI 7) (const_int 12)))
1581 (set (mem:XF (reg:SI 7))
1585 (define_expand "movxf"
1586 [(set (match_operand:XF 0 "general_operand" "")
1587 (match_operand:XF 1 "general_operand" ""))]
1591 /* Don't generate memory->memory moves, go through a register */
1593 && no_new_pseudos == 0
1594 && GET_CODE (operands[0]) == MEM
1595 && GET_CODE (operands[1]) == MEM)
1597 operands[1] = force_reg (XFmode, operands[1]);
1600 /* If we are loading a floating point constant that isn't 0 or 1
1601 into a register, indicate we need the pic register loaded. This could
1602 be optimized into stores of constants if the target eventually moves
1603 to memory, but better safe than sorry. */
1604 else if ((reload_in_progress | reload_completed) == 0
1605 && GET_CODE (operands[0]) != MEM
1606 && GET_CODE (operands[1]) == CONST_DOUBLE
1607 && !standard_80387_constant_p (operands[1]))
1609 operands[1] = validize_mem (force_const_mem (XFmode, operands[1]));
1615 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!*r,!o")
1616 (match_operand:XF 1 "general_operand" "fmG,f,*roF,*rF"))]
1617 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1618 || (GET_CODE (operands[1]) != MEM)"
1621 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1623 /* First handle a `pop' insn or a `fld %st(0)' */
1625 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1628 return AS1 (fstp,%y0);
1630 return AS1 (fld,%y0);
1633 /* Handle other kinds of writes from the 387 */
1635 if (STACK_TOP_P (operands[1]))
1637 output_asm_insn (AS1 (fstp%z0,%y0), operands);
1638 if (! stack_top_dies)
1639 return AS1 (fld%z0,%y0);
1644 /* Handle other kinds of reads to the 387 */
1646 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1647 return output_move_const_single (operands);
1649 if (STACK_TOP_P (operands[0]))
1650 return AS1 (fld%z1,%y1);
1652 /* Handle all XFmode moves not involving the 387 */
1654 return output_move_double (operands);
1657 (define_insn "swapxf"
1658 [(set (match_operand:XF 0 "register_operand" "f")
1659 (match_operand:XF 1 "register_operand" "f"))
1665 if (STACK_TOP_P (operands[0]))
1666 return AS1 (fxch,%1);
1668 return AS1 (fxch,%0);
1672 [(set (match_operand:DI 0 "push_operand" "=<")
1673 (match_operand:DI 1 "general_operand" "riF"))]
1675 "* return output_move_double (operands);")
1678 [(set (match_operand:DI 0 "push_operand" "=<")
1679 (match_operand:DI 1 "memory_operand" "o"))]
1680 "TARGET_PUSH_MEMORY"
1681 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode),0,0);")
1683 (define_expand "movdi"
1684 [(set (match_operand:DI 0 "general_operand" "")
1685 (match_operand:DI 1 "general_operand" ""))]
1689 /* Don't generate memory->memory moves, go through a register */
1691 && no_new_pseudos == 0
1692 && GET_CODE (operands[0]) == MEM
1693 && GET_CODE (operands[1]) == MEM)
1695 operands[1] = force_reg (DImode, operands[1]);
1700 [(set (match_operand:DI 0 "general_operand" "=g,r")
1701 (match_operand:DI 1 "general_operand" "riF,m"))]
1702 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1703 || (GET_CODE (operands[1]) != MEM)"
1704 "* return output_move_double (operands);"
1705 [(set_attr "type" "integer,memory")
1706 (set_attr "memory" "*,load")])
1709 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1710 (match_operand:DI 1 "general_operand" ""))]
1712 && (offsettable_memref_p (operands[0])
1713 || nonmemory_operand (operands[0], DImode))
1714 && (offsettable_memref_p (operands[1])
1715 || nonmemory_operand (operands[1], DImode))
1716 && (! reg_overlap_mentioned_p (gen_lowpart (SImode, operands[0]),
1718 || ! reg_overlap_mentioned_p (gen_highpart (SImode, operands[0]),
1726 split_di (&operands[0], 1, &operands[2], &operands[3]);
1727 split_di (&operands[1], 1, &operands[4], &operands[5]);
1729 if (reg_overlap_mentioned_p (operands[2], operands[1]))
1734 operands[2] = operands[3];
1738 operands[4] = operands[5];
1743 ;;- conversion instructions
1746 ;;- zero extension instructions
1747 ;; See comments by `andsi' for when andl is faster than movzx.
1749 (define_expand "zero_extendhisi2"
1750 [(set (match_operand:SI 0 "register_operand" "")
1751 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1755 ;; When optimizing for the PPro/PII or code size, always use movzwl.
1756 ;; We want to use a different pattern so we can use different constraints
1757 ;; than the generic pattern.
1759 [(set (match_operand:SI 0 "register_operand" "=r")
1760 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
1761 "(optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1762 "* return AS2 (movz%W0%L0,%1,%0);")
1765 [(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
1766 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
1767 "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1772 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1773 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1775 xops[0] = operands[0];
1776 xops[1] = GEN_INT (0xffff);
1777 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1780 if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1]))
1782 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1783 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1787 if (TARGET_ZERO_EXTEND_WITH_AND)
1789 xops[0] = operands[0];
1790 xops[1] = GEN_INT (0xffff);
1791 if (i386_aligned_p (operands[1]))
1792 output_asm_insn (AS2 (mov%L0,%k1,%k0),operands);
1794 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1795 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1800 return AS2 (movzx,%1,%0);
1802 return AS2 (movz%W0%L0,%1,%0);
1807 [(set (match_operand:SI 0 "register_operand" "")
1808 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1809 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])"
1812 (set (strict_low_part (match_dup 2))
1814 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1818 [(set (match_operand:SI 0 "register_operand" "")
1819 (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))]
1820 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])"
1821 [(set (strict_low_part (match_dup 2))
1824 (and:SI (match_dup 0)
1825 (const_int 65535)))]
1826 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1828 (define_expand "zero_extendqihi2"
1829 [(set (match_operand:HI 0 "register_operand" "")
1830 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1835 [(set (match_operand:HI 0 "register_operand" "=r")
1836 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1837 "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
1839 "* return AS2 (movz%B0%W0,%1,%0);")
1842 [(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
1843 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1844 "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1849 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1850 && REG_P (operands[1])
1851 && REGNO (operands[0]) == REGNO (operands[1]))
1853 xops[0] = operands[0];
1854 xops[1] = GEN_INT (0xff);
1855 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1858 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1860 if(!reg_overlap_mentioned_p(operands[0],operands[1]))
1862 output_asm_insn (AS2 (xor%L0,%k0,%k0), operands);
1863 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1867 xops[0] = operands[0];
1868 xops[1] = GEN_INT (0xff);
1869 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1870 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1876 return AS2 (movzx,%1,%0);
1878 return AS2 (movz%B0%W0,%1,%0);
1883 [(set (match_operand:HI 0 "register_operand" "")
1884 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1885 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1886 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1889 (set (strict_low_part (match_dup 2))
1891 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1895 [(set (match_operand:HI 0 "register_operand" "")
1896 (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))]
1897 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1898 && reg_overlap_mentioned_p (operands[0], operands[1])"
1899 [(set (strict_low_part (match_dup 2))
1902 (and:HI (match_dup 0)
1904 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1907 [(set (match_operand:HI 0 "register_operand" "")
1908 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1909 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND"
1913 (and:HI (match_dup 0)
1915 "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0)
1916 operands[1] = SUBREG_REG (operands[1]);
1917 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG
1918 || REGNO (operands[0]) == REGNO (operands[1]))
1920 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));")
1922 (define_expand "zero_extendqisi2"
1923 [(set (match_operand:SI 0 "register_operand" "")
1924 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1929 [(set (match_operand:SI 0 "register_operand" "=r")
1930 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1931 "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
1932 "* return AS2 (movz%B0%L0,%1,%0);")
1935 [(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
1936 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1937 "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1942 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1943 && REG_P (operands[1])
1944 && REGNO (operands[0]) == REGNO (operands[1]))
1946 xops[0] = operands[0];
1947 xops[1] = GEN_INT (0xff);
1948 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1951 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1953 if(!reg_overlap_mentioned_p (operands[0], operands[1]))
1955 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1956 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1960 xops[0] = operands[0];
1961 xops[1] = GEN_INT (0xff);
1962 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1963 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1968 if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG)
1970 xops[0] = operands[0];
1971 xops[1] = GEN_INT (0xff);
1972 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
1973 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
1974 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1979 return AS2 (movzx,%1,%0);
1981 return AS2 (movz%B0%L0,%1,%0);
1986 [(set (match_operand:SI 0 "register_operand" "")
1987 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1988 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1989 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1992 (set (strict_low_part (match_dup 2))
1994 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1998 [(set (match_operand:SI 0 "register_operand" "")
1999 (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))]
2000 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
2001 && reg_overlap_mentioned_p (operands[0], operands[1])"
2002 [(set (strict_low_part (match_dup 2))
2005 (and:SI (match_dup 0)
2007 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2010 [(set (match_operand:SI 0 "register_operand" "")
2011 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2012 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
2013 && ! reg_overlap_mentioned_p (operands[0], operands[1])"
2017 (and:SI (match_dup 0)
2019 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
2021 (define_insn "zero_extendsidi2"
2022 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
2023 (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))]
2028 [(set (match_operand:DI 0 "register_operand" "")
2029 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2030 "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
2031 [(set (match_dup 4) (const_int 0))]
2032 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2035 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2036 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
2038 [(set (match_dup 3) (match_dup 1))
2039 (set (match_dup 4) (const_int 0))]
2040 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2042 ;;- sign extension instructions
2044 (define_insn "extendsidi2"
2045 [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*o")
2046 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,*r")))
2047 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
2051 ;; Extend to memory case when source register does die.
2053 [(set (match_operand:DI 0 "memory_operand" "")
2054 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2055 (clobber (match_operand:SI 2 "register_operand" ""))]
2057 && dead_or_set_p (insn, operands[1])
2058 && !reg_mentioned_p (operands[1], operands[0]))"
2059 [(set (match_dup 3) (match_dup 1))
2060 (set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
2061 (set (match_dup 4) (match_dup 1))]
2062 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2064 ;; Extend to memory case when source register does not die.
2066 [(set (match_operand:DI 0 "memory_operand" "")
2067 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2068 (clobber (match_operand:SI 2 "register_operand" ""))]
2073 split_di (&operands[0], 1, &operands[3], &operands[4]);
2075 emit_move_insn (operands[3], operands[1]);
2077 /* Generate a cltd if possible and doing so it profitable. */
2078 if (true_regnum (operands[1]) == 0
2079 && true_regnum (operands[2]) == 1
2080 && (optimize_size || !TARGET_PENTIUM))
2082 emit_insn (gen_ashrsi3_31 (operands[2], operands[1]));
2086 emit_move_insn (operands[2], operands[1]);
2087 emit_insn (gen_ashrsi3_31 (operands[2], operands[2]));
2089 emit_move_insn (operands[4], operands[2]);
2093 ;; Extend to register case. Optimize case where source and destination
2094 ;; registers match and cases where we can use cltd.
2096 [(set (match_operand:DI 0 "register_operand" "")
2097 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2098 (clobber (match_scratch:SI 2 ""))]
2103 split_di (&operands[0], 1, &operands[3], &operands[4]);
2105 if (true_regnum (operands[3]) != true_regnum (operands[1]))
2106 emit_move_insn (operands[3], operands[1]);
2108 /* Generate a cltd if possible and doing so it profitable. */
2109 if (true_regnum (operands[3]) == 0
2110 && (optimize_size || !TARGET_PENTIUM))
2112 emit_insn (gen_ashrsi3_31 (operands[4], operands[3]));
2116 if (true_regnum (operands[4]) != true_regnum (operands[1]))
2117 emit_move_insn (operands[4], operands[1]);
2119 emit_insn (gen_ashrsi3_31 (operands[4], operands[4]));
2123 ;; Note that the i386 programmers' manual says that the opcodes
2124 ;; are named movsx..., but the assembler on Unix does not accept that.
2125 ;; We use what the Unix assembler expects.
2127 (define_insn "extendhisi2"
2128 [(set (match_operand:SI 0 "register_operand" "=r")
2129 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2133 if (REGNO (operands[0]) == 0
2134 && REG_P (operands[1]) && REGNO (operands[1]) == 0
2135 && (optimize_size || ix86_cpu != PROCESSOR_K6))
2143 return AS2 (movsx,%1,%0);
2145 return AS2 (movs%W0%L0,%1,%0);
2149 (define_insn "extendqihi2"
2150 [(set (match_operand:HI 0 "register_operand" "=r")
2151 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2155 if (REGNO (operands[0]) == 0
2156 && REG_P (operands[1]) && REGNO (operands[1]) == 0
2157 && (optimize_size || ix86_cpu != PROCESSOR_K6))
2161 return AS2 (movsx,%1,%0);
2163 return AS2 (movs%B0%W0,%1,%0);
2167 (define_insn "extendqisi2"
2168 [(set (match_operand:SI 0 "register_operand" "=r")
2169 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2174 return AS2 (movsx,%1,%0);
2176 return AS2 (movs%B0%L0,%1,%0);
2181 ;; Truncation of long long -> 32 bit
2183 (define_expand "truncdisi2"
2184 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2185 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2189 /* Don't generate memory->memory moves, go through a register */
2191 && (reload_in_progress | reload_completed) == 0
2192 && GET_CODE (operands[0]) == MEM
2193 && GET_CODE (operands[1]) == MEM)
2195 rtx target = gen_reg_rtx (SImode);
2196 emit_insn (gen_truncdisi2 (target, operands[1]));
2197 emit_move_insn (operands[0], target);
2203 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2204 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2205 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2208 rtx low[2], high[2], xops[2];
2210 split_di (&operands[1], 1, low, high);
2211 xops[0] = operands[0];
2213 if (!rtx_equal_p (xops[0], xops[1]))
2214 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2220 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2221 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
2223 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2226 rtx low[2], high[2], xops[2];
2228 split_di (&operands[1], 1, low, high);
2229 xops[0] = operands[0];
2231 if (!rtx_equal_p (xops[0], xops[1]))
2232 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2239 ;; Conversions between float and double.
2241 (define_expand "extendsfdf2"
2242 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2244 (match_operand:SF 1 "nonimmediate_operand" "")))
2245 (clobber (match_dup 2))
2246 (clobber (match_dup 3))])]
2250 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2251 operands[1] = force_reg (SFmode, operands[1]);
2253 operands[2] = assign_386_stack_local (SFmode, 0);
2254 operands[3] = assign_386_stack_local (DFmode, 0);
2258 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!f,!*r")
2260 (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f")))
2261 (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m"))
2262 (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))]
2263 "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2264 || GET_CODE (operands[1]) != MEM)"
2267 output_float_extend (insn, operands);
2270 [(set_attr "type" "fld,fpop,fld,fpop")])
2273 [(set (match_operand:DF 0 "register_operand" "")
2274 (float_extend:DF (match_operand:SF 1 "register_operand" "")))
2275 (clobber (match_operand:SF 2 "memory_operand" ""))
2276 (clobber (match_operand:DF 3 "memory_operand" ""))]
2277 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
2281 (float_extend:DF (match_dup 2)))]
2285 [(set (match_operand:DF 0 "register_operand" "")
2286 (float_extend:DF (match_operand:SF 1 "register_operand" "")))
2287 (clobber (match_operand:SF 2 "memory_operand" ""))
2288 (clobber (match_operand:DF 3 "memory_operand" ""))]
2289 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
2291 (float_extend:DF (match_dup 1)))
2297 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2298 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))
2299 (clobber (match_operand:SF 2 "memory_operand" ""))
2300 (clobber (match_operand:DF 3 "memory_operand" ""))]
2301 "TARGET_80387 && reload_completed"
2303 (float_extend:DF (match_dup 1)))]
2307 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
2308 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2309 "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2310 || GET_CODE (operands[1]) != MEM)"
2313 output_float_extend (insn, operands);
2316 [(set_attr "type" "fld,fpop")])
2318 (define_expand "extenddfxf2"
2319 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
2321 (match_operand:DF 1 "nonimmediate_operand" "")))
2322 (clobber (match_dup 2))
2323 (clobber (match_dup 3))])]
2327 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2328 operands[1] = force_reg (DFmode, operands[1]);
2330 operands[2] = assign_386_stack_local (DFmode, 0);
2331 operands[3] = assign_386_stack_local (XFmode, 0);
2335 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r")
2337 (match_operand:DF 1 "nonimmediate_operand" "fm,f,*r,f")))
2338 (clobber (match_operand:DF 2 "memory_operand" "m,m,o,m"))
2339 (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
2340 "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2341 || GET_CODE (operands[1]) != MEM)"
2344 output_float_extend (insn, operands);
2347 [(set_attr "type" "fld,fpop,fld,fpop")])
2350 [(set (match_operand:XF 0 "register_operand" "")
2351 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
2352 (clobber (match_operand:DF 2 "memory_operand" ""))
2353 (clobber (match_operand:XF 3 "memory_operand" ""))]
2354 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
2358 (float_extend:XF (match_dup 2)))]
2362 [(set (match_operand:XF 0 "register_operand" "")
2363 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
2364 (clobber (match_operand:DF 2 "memory_operand" ""))
2365 (clobber (match_operand:XF 3 "memory_operand" ""))]
2366 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
2368 (float_extend:XF (match_dup 1)))
2374 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2375 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))
2376 (clobber (match_operand:DF 2 "memory_operand" ""))
2377 (clobber (match_operand:XF 3 "memory_operand" ""))]
2378 "TARGET_80387 && reload_completed"
2380 (float_extend:XF (match_dup 1)))]
2384 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
2385 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
2386 "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2387 || GET_CODE (operands[1]) != MEM)"
2390 output_float_extend (insn, operands);
2393 [(set_attr "type" "fld,fpop")])
2395 (define_expand "extendsfxf2"
2396 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
2398 (match_operand:SF 1 "nonimmediate_operand" "")))
2399 (clobber (match_dup 2))
2400 (clobber (match_dup 3))])]
2404 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2405 operands[1] = force_reg (SFmode, operands[1]);
2407 operands[2] = assign_386_stack_local (SFmode, 0);
2408 operands[3] = assign_386_stack_local (XFmode, 0);
2412 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r")
2414 (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f")))
2415 (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m"))
2416 (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
2417 "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2418 || GET_CODE (operands[1]) != MEM)"
2421 output_float_extend (insn, operands);
2424 [(set_attr "type" "fld,fpop,fld,fpop")])
2427 [(set (match_operand:XF 0 "register_operand" "")
2428 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
2429 (clobber (match_operand:SF 2 "memory_operand" ""))
2430 (clobber (match_operand:XF 3 "memory_operand" ""))]
2431 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
2435 (float_extend:XF (match_dup 2)))]
2439 [(set (match_operand:XF 0 "register_operand" "")
2440 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
2441 (clobber (match_operand:SF 2 "memory_operand" ""))
2442 (clobber (match_operand:XF 3 "memory_operand" ""))]
2443 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
2445 (float_extend:XF (match_dup 1)))
2451 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2452 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))
2453 (clobber (match_operand:SF 2 "memory_operand" ""))
2454 (clobber (match_operand:XF 3 "memory_operand" ""))]
2455 "TARGET_80387 && reload_completed"
2457 (float_extend:XF (match_dup 1)))]
2461 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
2463 (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2464 "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2465 || GET_CODE (operands[1]) != MEM)"
2468 output_float_extend (insn, operands);
2471 [(set_attr "type" "fld,fpop")])
2473 (define_expand "truncdfsf2"
2474 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2476 (match_operand:DF 1 "register_operand" "")))
2477 (clobber (match_dup 2))])]
2481 operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2485 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r")
2487 (match_operand:DF 1 "register_operand" "0,f,f")))
2488 (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))]
2492 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2495 xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
2497 if (stack_top_dies || STACK_REG_P (operands[0]))
2498 output_asm_insn (AS1 (fstp%z0,%0), xops);
2500 output_asm_insn (AS1 (fst%z0,%0), xops);
2502 if (STACK_REG_P (operands[0]))
2503 return AS1 (fld%z2,%2);
2504 else if (NON_STACK_REG_P (operands[0]))
2505 return AS2 (mov%L0,%2,%0);
2509 [(set_attr "type" "fpop")])
2512 [(set (match_operand:SF 0 "register_operand" "")
2513 (float_truncate:SF (match_operand:DF 1 "register_operand" "")))
2514 (clobber (match_operand:SF 2 "memory_operand" ""))]
2515 "TARGET_80387 && reload_completed"
2517 (float_truncate:SF (match_dup 1)))
2523 [(set (match_operand:SF 0 "memory_operand" "")
2524 (float_truncate:SF (match_operand:DF 1 "register_operand" "")))
2525 (clobber (match_operand:SF 2 "memory_operand" ""))]
2526 "TARGET_80387 && reload_completed"
2528 (float_truncate:SF (match_dup 1)))]
2531 ;; This cannot output into an f-reg because there is no way to be sure
2532 ;; of truncating in that case.
2535 [(set (match_operand:SF 0 "memory_operand" "=m")
2536 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2540 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2543 return AS1 (fstp%z0,%0);
2545 return AS1 (fst%z0,%0);
2547 [(set_attr "type" "fpop")])
2549 (define_expand "truncxfsf2"
2550 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2552 (match_operand:XF 1 "register_operand" "")))
2553 (clobber (match_dup 2))])]
2557 operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2561 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r")
2563 (match_operand:XF 1 "register_operand" "0,f,f")))
2564 (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))]
2568 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2571 xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
2573 if (stack_top_dies || STACK_REG_P (operands[0]))
2574 output_asm_insn (AS1 (fstp%z0,%0), xops);
2576 output_asm_insn (AS1 (fst%z0,%0), xops);
2578 if (STACK_REG_P (operands[0]))
2579 return AS1 (fld%z2,%2);
2580 else if (NON_STACK_REG_P (operands[0]))
2581 return AS2 (mov%L0,%2,%0);
2585 [(set_attr "type" "fpop")])
2588 [(set (match_operand:SF 0 "register_operand" "")
2589 (float_truncate:SF (match_operand:XF 1 "register_operand" "")))
2590 (clobber (match_operand:SF 2 "memory_operand" ""))]
2591 "TARGET_80387 && reload_completed"
2593 (float_truncate:SF (match_dup 1)))
2599 [(set (match_operand:SF 0 "memory_operand" "")
2600 (float_truncate:SF (match_operand:XF 1 "register_operand" "")))
2601 (clobber (match_operand:SF 2 "memory_operand" ""))]
2602 "TARGET_80387 && reload_completed"
2604 (float_truncate:SF (match_dup 1)))]
2608 [(set (match_operand:SF 0 "memory_operand" "=m")
2609 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
2613 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2616 return AS1 (fstp%z0,%0);
2618 return AS1 (fst%z0,%0);
2620 [(set_attr "type" "fpop")])
2622 (define_expand "truncxfdf2"
2623 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2625 (match_operand:XF 1 "register_operand" "")))
2626 (clobber (match_dup 2))])]
2630 operands[2] = (rtx) assign_386_stack_local (DFmode, 0);
2634 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r")
2636 (match_operand:XF 1 "register_operand" "0,f,f")))
2637 (clobber (match_operand:DF 2 "memory_operand" "m,m,o"))]
2641 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2644 xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
2646 if (stack_top_dies || STACK_REG_P (operands[0]))
2647 output_asm_insn (AS1 (fstp%z0,%0), xops);
2649 output_asm_insn (AS1 (fst%z0,%0), xops);
2651 if (STACK_REG_P (operands[0]))
2652 return AS1 (fld%z2,%2);
2653 else if (NON_STACK_REG_P (operands[0]))
2655 xops[0] = operands[0];
2656 xops[1] = operands[2];
2657 output_asm_insn (output_move_double (xops), xops);
2662 [(set_attr "type" "fpop")])
2665 [(set (match_operand:DF 0 "register_operand" "")
2666 (float_truncate:DF (match_operand:XF 1 "register_operand" "")))
2667 (clobber (match_operand:DF 2 "memory_operand" ""))]
2668 "TARGET_80387 && reload_completed"
2670 (float_truncate:DF (match_dup 1)))
2676 [(set (match_operand:DF 0 "memory_operand" "")
2677 (float_truncate:DF (match_operand:XF 1 "register_operand" "")))
2678 (clobber (match_operand:DF 2 "memory_operand" ""))]
2679 "TARGET_80387 && reload_completed"
2681 (float_truncate:DF (match_dup 1)))]
2685 [(set (match_operand:DF 0 "memory_operand" "=m")
2686 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
2690 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2693 return AS1 (fstp%z0,%0);
2695 return AS1 (fst%z0,%0);
2697 [(set_attr "type" "fpop")])
2699 ;; Conversions between floating point and fix point.
2701 (define_expand "fix_truncsfsi2"
2702 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2703 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))
2704 (clobber (match_dup 2))
2705 (clobber (match_dup 3))
2706 (clobber (match_dup 4))
2707 (clobber (match_scratch:HI 5 ""))])]
2711 operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2712 operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2713 operands[4] = (rtx) assign_386_stack_local (SImode, 0);
2717 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r")
2718 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
2719 (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2720 (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2721 (clobber (match_operand:SI 4 "memory_operand" "m,m"))
2722 (clobber (match_scratch:HI 5 "=&r,&r"))]
2724 "* return output_fix_trunc (insn, operands);"
2725 [(set_attr "type" "fpop")])
2727 (define_expand "fix_truncsfdi2"
2728 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2729 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
2730 (clobber (match_dup 1))
2731 (clobber (match_dup 2))
2732 (clobber (match_dup 3))
2733 (clobber (match_dup 4))
2734 (clobber (match_scratch:HI 5 ""))])]
2738 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
2739 operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2740 operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2741 operands[4] = (rtx) assign_386_stack_local (DImode, 0);
2745 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r")
2746 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
2747 (clobber (match_dup 1))
2748 (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2749 (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2750 (clobber (match_operand:DI 4 "memory_operand" "m,o"))
2751 (clobber (match_scratch:HI 5 "=&r,&r"))]
2753 "* return output_fix_trunc (insn, operands);"
2754 [(set_attr "type" "fpop")])
2756 (define_expand "fix_truncdfsi2"
2757 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2758 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" ""))))
2759 (clobber (match_dup 2))
2760 (clobber (match_dup 3))
2761 (clobber (match_dup 4))
2762 (clobber (match_scratch:HI 5 ""))])]
2766 operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2767 operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2768 operands[4] = (rtx) assign_386_stack_local (SImode, 0);
2772 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r")
2773 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
2774 (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2775 (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2776 (clobber (match_operand:SI 4 "memory_operand" "m,m"))
2777 (clobber (match_scratch:HI 5 "=&r,&r"))]
2779 "* return output_fix_trunc (insn, operands);"
2780 [(set_attr "type" "fpop")])
2782 (define_expand "fix_truncdfdi2"
2783 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2784 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
2785 (clobber (match_dup 1))
2786 (clobber (match_dup 2))
2787 (clobber (match_dup 3))
2788 (clobber (match_dup 4))
2789 (clobber (match_scratch:HI 5 ""))])]
2793 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
2794 operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2795 operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2796 operands[4] = (rtx) assign_386_stack_local (DImode, 0);
2800 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r")
2801 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
2802 (clobber (match_dup 1))
2803 (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2804 (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2805 (clobber (match_operand:DI 4 "memory_operand" "m,o"))
2806 (clobber (match_scratch:HI 5 "=&r,&r"))]
2808 "* return output_fix_trunc (insn, operands);"
2809 [(set_attr "type" "fpop")])
2811 (define_expand "fix_truncxfsi2"
2812 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2813 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" ""))))
2814 (clobber (match_dup 2))
2815 (clobber (match_dup 3))
2816 (clobber (match_dup 4))
2817 (clobber (match_scratch:HI 5 ""))])]
2821 operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2822 operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2823 operands[4] = (rtx) assign_386_stack_local (SImode, 0);
2827 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r")
2828 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
2829 (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2830 (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2831 (clobber (match_operand:SI 4 "memory_operand" "m,m"))
2832 (clobber (match_scratch:HI 5 "=&r,&r"))]
2834 "* return output_fix_trunc (insn, operands);"
2835 [(set_attr "type" "fpop")])
2837 (define_expand "fix_truncxfdi2"
2838 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2839 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" ""))))
2840 (clobber (match_dup 1))
2841 (clobber (match_dup 2))
2842 (clobber (match_dup 3))
2843 (clobber (match_dup 4))
2844 (clobber (match_scratch:HI 5 ""))])]
2848 operands[1] = copy_to_mode_reg (XFmode, operands[1]);
2849 operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2850 operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2851 operands[4] = (rtx) assign_386_stack_local (DImode, 0);
2855 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r")
2856 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
2857 (clobber (match_dup 1))
2858 (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2859 (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2860 (clobber (match_operand:DI 4 "memory_operand" "m,o"))
2861 (clobber (match_scratch:HI 5 "=&r,&r"))]
2863 "* return output_fix_trunc (insn, operands);"
2864 [(set_attr "type" "fpop")])
2866 ;; Conversion between fixed point and floating point.
2868 ;; ??? Possibly represent floatunssidf2 here in gcc2.
2870 (define_expand "floatsisf2"
2871 [(parallel [(set (match_operand:SF 0 "register_operand" "")
2872 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))
2873 (clobber (match_dup 2))])]
2875 "operands[2] = assign_386_stack_local (SImode, 0);")
2878 [(set (match_operand:SF 0 "register_operand" "=f,f")
2879 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
2880 (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
2885 [(set (match_operand:SF 0 "register_operand" "")
2886 (float:SF (match_operand:SI 1 "memory_operand" "")))
2887 (clobber (match_operand:SI 2 "memory_operand" ""))]
2888 "TARGET_80387 && reload_completed"
2890 (float:SF (match_dup 1)))]
2894 [(set (match_operand:SF 0 "register_operand" "")
2895 (float:SF (match_operand:SI 1 "register_operand" "")))
2896 (clobber (match_operand:SI 2 "memory_operand" ""))]
2897 "TARGET_80387 && reload_completed"
2901 (float:SF (match_dup 2)))]
2905 [(set (match_operand:SF 0 "register_operand" "=f")
2906 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
2908 "* return AS1 (fild%z1,%1);"
2909 [(set_attr "type" "fpop")])
2911 (define_expand "floathisf2"
2912 [(parallel [(set (match_operand:SF 0 "register_operand" "")
2913 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))
2914 (clobber (match_dup 2))])]
2916 "operands[2] = assign_386_stack_local (HImode, 0);")
2919 [(set (match_operand:SF 0 "register_operand" "=f,f")
2920 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
2921 (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
2926 [(set (match_operand:SF 0 "register_operand" "")
2927 (float:SF (match_operand:HI 1 "memory_operand" "")))
2928 (clobber (match_operand:HI 2 "memory_operand" ""))]
2929 "TARGET_80387 && reload_completed"
2931 (float:SF (match_dup 1)))]
2935 [(set (match_operand:SF 0 "register_operand" "")
2936 (float:SF (match_operand:HI 1 "register_operand" "")))
2937 (clobber (match_operand:HI 2 "memory_operand" ""))]
2938 "TARGET_80387 && reload_completed"
2942 (float:SF (match_dup 2)))]
2946 [(set (match_operand:SF 0 "register_operand" "=f")
2947 (float:SF (match_operand:HI 1 "memory_operand" "m")))]
2949 "* return AS1 (fild%z1,%1);"
2950 [(set_attr "type" "fpop")])
2952 (define_expand "floatdisf2"
2953 [(parallel [(set (match_operand:SF 0 "register_operand" "")
2954 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))
2955 (clobber (match_dup 2))])]
2957 "operands[2] = assign_386_stack_local (DImode, 0);")
2960 [(set (match_operand:SF 0 "register_operand" "=f,f")
2961 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
2962 (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
2967 [(set (match_operand:SF 0 "register_operand" "")
2968 (float:SF (match_operand:DI 1 "memory_operand" "")))
2969 (clobber (match_operand:DI 2 "memory_operand" ""))]
2970 "TARGET_80387 && reload_completed"
2972 (float:SF (match_dup 1)))]
2976 [(set (match_operand:SF 0 "register_operand" "")
2977 (float:SF (match_operand:DI 1 "register_operand" "")))
2978 (clobber (match_operand:DI 2 "memory_operand" ""))]
2979 "TARGET_80387 && reload_completed"
2983 (float:SF (match_dup 2)))]
2987 [(set (match_operand:SF 0 "register_operand" "=f")
2988 (float:SF (match_operand:DI 1 "memory_operand" "m")))]
2990 "* return AS1 (fild%z1,%1);"
2991 [(set_attr "type" "fpop")])
2993 (define_expand "floatsidf2"
2994 [(parallel [(set (match_operand:DF 0 "register_operand" "")
2995 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
2996 (clobber (match_dup 2))])]
2998 "operands[2] = assign_386_stack_local (SImode, 0);")
3001 [(set (match_operand:DF 0 "register_operand" "=f,f")
3002 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
3003 (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
3008 [(set (match_operand:DF 0 "register_operand" "")
3009 (float:DF (match_operand:SI 1 "memory_operand" "")))
3010 (clobber (match_operand:SI 2 "memory_operand" ""))]
3011 "TARGET_80387 && reload_completed"
3013 (float:DF (match_dup 1)))]
3017 [(set (match_operand:DF 0 "register_operand" "")
3018 (float:DF (match_operand:SI 1 "register_operand" "")))
3019 (clobber (match_operand:SI 2 "memory_operand" ""))]
3020 "TARGET_80387 && reload_completed"
3024 (float:DF (match_dup 2)))]
3028 [(set (match_operand:DF 0 "register_operand" "=f")
3029 (float:DF (match_operand:SI 1 "memory_operand" "m")))]
3031 "* return AS1 (fild%z1,%1);"
3032 [(set_attr "type" "fpop")])
3034 (define_expand "floathidf2"
3035 [(parallel [(set (match_operand:DF 0 "register_operand" "")
3036 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))
3037 (clobber (match_dup 2))])]
3039 "operands[2] = assign_386_stack_local (HImode, 0);")
3042 [(set (match_operand:DF 0 "register_operand" "=f,f")
3043 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
3044 (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
3049 [(set (match_operand:DF 0 "register_operand" "")
3050 (float:DF (match_operand:HI 1 "memory_operand" "")))
3051 (clobber (match_operand:HI 2 "memory_operand" ""))]
3052 "TARGET_80387 && reload_completed"
3054 (float:DF (match_dup 1)))]
3058 [(set (match_operand:DF 0 "register_operand" "")
3059 (float:DF (match_operand:HI 1 "register_operand" "")))
3060 (clobber (match_operand:HI 2 "memory_operand" ""))]
3061 "TARGET_80387 && reload_completed"
3065 (float:DF (match_dup 2)))]
3069 [(set (match_operand:DF 0 "register_operand" "=f")
3070 (float:DF (match_operand:HI 1 "memory_operand" "m")))]
3072 "* return AS1 (fild%z1,%1);"
3073 [(set_attr "type" "fpop")])
3075 (define_expand "floatdidf2"
3076 [(parallel [(set (match_operand:DF 0 "register_operand" "")
3077 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))
3078 (clobber (match_dup 2))])]
3080 "operands[2] = assign_386_stack_local (DImode, 0);")
3083 [(set (match_operand:DF 0 "register_operand" "=f,f")
3084 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
3085 (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
3090 [(set (match_operand:DF 0 "register_operand" "")
3091 (float:DF (match_operand:DI 1 "memory_operand" "")))
3092 (clobber (match_operand:DI 2 "memory_operand" ""))]
3093 "TARGET_80387 && reload_completed"
3095 (float:DF (match_dup 1)))]
3099 [(set (match_operand:DF 0 "register_operand" "")
3100 (float:DF (match_operand:DI 1 "register_operand" "")))
3101 (clobber (match_operand:DI 2 "memory_operand" ""))]
3102 "TARGET_80387 && reload_completed"
3106 (float:DF (match_dup 2)))]
3110 [(set (match_operand:DF 0 "register_operand" "=f")
3111 (float:DF (match_operand:DI 1 "memory_operand" "m")))]
3113 "* return AS1 (fild%z1,%1);"
3114 [(set_attr "type" "fpop")])
3116 (define_expand "floatsixf2"
3117 [(parallel [(set (match_operand:XF 0 "register_operand" "")
3118 (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))
3119 (clobber (match_dup 2))])]
3121 "operands[2] = assign_386_stack_local (SImode, 0);")
3124 [(set (match_operand:XF 0 "register_operand" "=f,f")
3125 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
3126 (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
3131 [(set (match_operand:XF 0 "register_operand" "")
3132 (float:XF (match_operand:SI 1 "memory_operand" "")))
3133 (clobber (match_operand:SI 2 "memory_operand" ""))]
3134 "TARGET_80387 && reload_completed"
3136 (float:XF (match_dup 1)))]
3140 [(set (match_operand:XF 0 "register_operand" "")
3141 (float:XF (match_operand:SI 1 "register_operand" "")))
3142 (clobber (match_operand:SI 2 "memory_operand" ""))]
3143 "TARGET_80387 && reload_completed"
3147 (float:XF (match_dup 2)))]
3151 [(set (match_operand:XF 0 "register_operand" "=f")
3152 (float:XF (match_operand:SI 1 "memory_operand" "m")))]
3154 "* return AS1 (fild%z1,%1);"
3155 [(set_attr "type" "fpop")])
3157 (define_expand "floathixf2"
3158 [(parallel [(set (match_operand:XF 0 "register_operand" "")
3159 (float:XF (match_operand:HI 1 "nonimmediate_operand" "")))
3160 (clobber (match_dup 2))])]
3162 "operands[2] = assign_386_stack_local (HImode, 0);")
3165 [(set (match_operand:XF 0 "register_operand" "=f,f")
3166 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
3167 (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
3172 [(set (match_operand:XF 0 "register_operand" "")
3173 (float:XF (match_operand:HI 1 "memory_operand" "")))
3174 (clobber (match_operand:HI 2 "memory_operand" ""))]
3175 "TARGET_80387 && reload_completed"
3177 (float:XF (match_dup 1)))]
3181 [(set (match_operand:XF 0 "register_operand" "")
3182 (float:XF (match_operand:HI 1 "register_operand" "")))
3183 (clobber (match_operand:HI 2 "memory_operand" ""))]
3184 "TARGET_80387 && reload_completed"
3188 (float:XF (match_dup 2)))]
3192 [(set (match_operand:XF 0 "register_operand" "=f")
3193 (float:XF (match_operand:HI 1 "memory_operand" "m")))]
3195 "* return AS1 (fild%z1,%1);"
3196 [(set_attr "type" "fpop")])
3198 (define_expand "floatdixf2"
3199 [(parallel [(set (match_operand:XF 0 "register_operand" "")
3200 (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))
3201 (clobber (match_dup 2))])]
3203 "operands[2] = assign_386_stack_local (DImode, 0);")
3206 [(set (match_operand:XF 0 "register_operand" "=f,f")
3207 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
3208 (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
3213 [(set (match_operand:XF 0 "register_operand" "")
3214 (float:XF (match_operand:DI 1 "memory_operand" "")))
3215 (clobber (match_operand:DI 2 "memory_operand" ""))]
3216 "TARGET_80387 && reload_completed"
3218 (float:XF (match_dup 1)))]
3222 [(set (match_operand:XF 0 "register_operand" "")
3223 (float:XF (match_operand:DI 1 "register_operand" "")))
3224 (clobber (match_operand:DI 2 "memory_operand" ""))]
3225 "TARGET_80387 && reload_completed"
3229 (float:XF (match_dup 2)))]
3233 [(set (match_operand:XF 0 "register_operand" "=f")
3234 (float:XF (match_operand:DI 1 "memory_operand" "m")))]
3236 "* return AS1 (fild%z1,%1);"
3237 [(set_attr "type" "fpop")])
3239 ;;- add instructions
3241 (define_insn "*addsidi3_1"
3242 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o")
3243 (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o")
3244 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri"))))
3245 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))]
3249 rtx low[3], high[3], xops[7];
3253 split_di (operands, 2, low, high);
3254 high[2] = const0_rtx;
3255 low[2] = operands[2];
3257 if (!rtx_equal_p (operands[0], operands[1]))
3264 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3266 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3267 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3273 xops[6] = operands[3];
3274 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3275 output_asm_insn (AS2 (add%L6,%5,%6), xops);
3276 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3277 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3278 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3279 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3284 output_asm_insn (AS2 (add%L0,%2,%0), low);
3285 output_asm_insn (AS2 (adc%L0,%2,%0), high);
3286 cc_status.value1 = high[0];
3287 cc_status.flags = CC_NO_OVERFLOW;
3290 [(set_attr "type" "binary")])
3292 (define_insn "addsidi3_2"
3293 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o")
3294 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r"))
3295 (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o")))
3296 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))]
3300 rtx low[3], high[3], xops[7];
3304 split_di (operands, 2, low, high);
3305 high[2] = const0_rtx;
3306 low[2] = operands[2];
3308 if (!rtx_equal_p (operands[0], operands[1]))
3315 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3317 if (rtx_equal_p (low[0], operands[2]))
3319 output_asm_insn (AS2 (mov%L0,%2,%0), high);
3320 output_asm_insn (AS2 (add%L0,%1,%0), low);
3321 output_asm_insn (AS2 (adc%L0,%1,%0), high);
3324 if (rtx_equal_p (high[0], operands[2]))
3326 if (GET_CODE (operands[0]) != MEM)
3328 output_asm_insn (AS2 (mov%L0,%2,%0), low);
3329 output_asm_insn (AS2 (mov%L0,%2,%0), high);
3330 output_asm_insn (AS2 (add%L0,%1,%0), low);
3331 output_asm_insn (AS2 (adc%L0,%1,%0), high);
3335 /* It's too late to ask for a scratch now - but this
3336 will probably not happen too often. */
3337 output_asm_insn (AS2 (add%L1,%2,%1), low);
3338 output_asm_insn (AS2 (mov%L0,%1,%0), low);
3339 output_asm_insn (AS2 (mov%L1,%2,%1), low);
3340 output_asm_insn (AS2 (mov%L0,%2,%0), high);
3341 output_asm_insn (AS2 (adc%L0,%1,%0), high);
3342 output_asm_insn (AS2 (sub%L1,%0,%1), low);
3343 output_asm_insn (AS1 (neg%L1,%1), low);
3347 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3348 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3354 xops[6] = operands[3];
3355 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3356 output_asm_insn (AS2 (add%L6,%5,%6), xops);
3357 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3358 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3359 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3360 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3365 output_asm_insn (AS2 (add%L0,%2,%0), low);
3366 output_asm_insn (AS2 (adc%L0,%2,%0), high);
3367 cc_status.value1 = high[0];
3368 cc_status.flags = CC_NO_OVERFLOW;
3371 [(set_attr "type" "binary")])
3373 (define_insn "adddi3"
3374 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
3375 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
3376 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
3377 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
3381 rtx low[3], high[3], xops[7], temp;
3385 if (rtx_equal_p (operands[0], operands[2]))
3388 operands[1] = operands[2];
3392 split_di (operands, 3, low, high);
3393 if (!rtx_equal_p (operands[0], operands[1]))
3400 if (GET_CODE (operands[0]) != MEM)
3402 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3403 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3409 xops[6] = operands[3];
3410 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3411 output_asm_insn (AS2 (add%L6,%5,%6), xops);
3412 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3413 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3414 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3415 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3420 cc_status.value1 = high[0];
3421 cc_status.flags = CC_NO_OVERFLOW;
3423 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
3429 xops[4] = operands[3];
3431 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3432 output_asm_insn (AS2 (add%L1,%4,%1), xops);
3433 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3434 output_asm_insn (AS2 (adc%L0,%4,%0), xops);
3437 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
3439 output_asm_insn (AS2 (add%L0,%2,%0), low);
3440 output_asm_insn (AS2 (adc%L0,%2,%0), high);
3444 output_asm_insn (AS2 (add%L0,%2,%0), high);
3448 [(set_attr "type" "binary")])
3450 ;; On a 486, it is faster to do movl/addl than to do a single leal if
3451 ;; operands[1] and operands[2] are both registers.
3453 (define_expand "addsi3"
3454 [(set (match_operand:SI 0 "nonimmediate_operand" "")
3455 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3456 (match_operand:SI 2 "general_operand" "")))]
3458 "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);")
3461 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
3462 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
3463 (match_operand:SI 2 "general_operand" "rmi,ri,ri")))]
3464 "ix86_binary_operator_ok (PLUS, SImode, operands)"
3467 if (REG_P (operands[0]) && REG_P (operands[1])
3468 && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
3469 && REGNO (operands[0]) != REGNO (operands[1]))
3471 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3472 return AS2 (add%L0,%1,%0);
3474 if (operands[2] == stack_pointer_rtx)
3479 operands[1] = operands[2];
3483 if (operands[2] != stack_pointer_rtx)
3486 operands[1] = SET_SRC (PATTERN (insn));
3487 return AS2 (lea%L0,%a1,%0);
3491 if (!rtx_equal_p (operands[0], operands[1]))
3492 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
3494 if (operands[2] == const1_rtx)
3495 return AS1 (inc%L0,%0);
3497 if (operands[2] == constm1_rtx)
3498 return AS1 (dec%L0,%0);
3500 /* subl $-128,%ebx is smaller than addl $128,%ebx. */
3501 if (GET_CODE (operands[2]) == CONST_INT
3502 && INTVAL (operands[2]) == 128)
3504 /* This doesn't compute the carry bit in the same way
3505 * as add%L0, but we use inc and dec above and they
3506 * don't set the carry bit at all. If inc/dec don't need
3507 * a CC_STATUS_INIT, this doesn't either... */
3508 operands[2] = GEN_INT (-128);
3509 return AS2 (sub%L0,%2,%0);
3512 return AS2 (add%L0,%2,%0);
3514 [(set_attr "type" "binary")])
3516 ;; addsi3 is faster, so put this after.
3518 (define_insn "movsi_lea"
3519 [(set (match_operand:SI 0 "register_operand" "=r")
3520 (match_operand:QI 1 "address_operand" "p"))]
3524 /* Adding a constant to a register is faster with an add. */
3525 /* ??? can this ever happen? */
3526 if (GET_CODE (operands[1]) == PLUS
3527 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
3528 && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
3530 operands[1] = XEXP (operands[1], 1);
3532 if (operands[1] == const1_rtx)
3533 return AS1 (inc%L0,%0);
3535 if (operands[1] == constm1_rtx)
3536 return AS1 (dec%L0,%0);
3538 return AS2 (add%L0,%1,%0);
3542 return AS2 (lea%L0,%a1,%0);
3544 [(set_attr "type" "lea")])
3546 ;; ??? `lea' here, for three operand add? If leaw is used, only %bx,
3547 ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
3548 ;; able to handle the operand. But leal always works?
3550 (define_expand "addhi3"
3551 [(set (match_operand:HI 0 "general_operand" "")
3552 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3553 (match_operand:HI 2 "general_operand" "")))]
3555 "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);")
3558 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,?r")
3559 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
3560 (match_operand:HI 2 "general_operand" "ri,rm,ri")))]
3561 "ix86_binary_operator_ok (PLUS, HImode, operands)"
3564 if (REG_P (operands[0]) && REG_P (operands[1])
3565 && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
3566 && REGNO (operands[0]) != REGNO (operands[1]))
3568 if (operands[2] == stack_pointer_rtx)
3573 = gen_rtx_PLUS (SImode,
3574 gen_rtx_REG (SImode, REGNO (operands[1])),
3575 (! REG_P (operands[2])
3577 : gen_rtx_REG (SImode, REGNO (operands[2]))));
3578 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
3579 return AS2 (lea%L0,%a1,%0);
3582 /* ??? what about offsettable memory references? */
3583 if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */
3584 && QI_REG_P (operands[0])
3585 && GET_CODE (operands[2]) == CONST_INT
3586 && (INTVAL (operands[2]) & 0xff) == 0
3587 && i386_cc_probably_useless_p (insn))
3589 int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
3593 return AS1 (inc%B0,%h0);
3594 else if (byteval == 255)
3595 return AS1 (dec%B0,%h0);
3597 operands[2] = GEN_INT (byteval);
3598 return AS2 (add%B0,%2,%h0);
3601 /* Use a 32-bit operation when possible, to avoid the prefix penalty. */
3602 if (REG_P (operands[0])
3603 && i386_aligned_p (operands[2])
3604 && i386_cc_probably_useless_p (insn))
3608 if (GET_CODE (operands[2]) == CONST_INT)
3610 HOST_WIDE_INT intval = 0xffff & INTVAL (operands[2]);
3613 return AS1 (inc%L0,%k0);
3615 if (intval == 0xffff)
3616 return AS1 (dec%L0,%k0);
3618 operands[2] = i386_sext16_if_const (operands[2]);
3620 return AS2 (add%L0,%k2,%k0);
3623 if (operands[2] == const1_rtx)
3624 return AS1 (inc%W0,%0);
3626 if (operands[2] == constm1_rtx
3627 || (GET_CODE (operands[2]) == CONST_INT
3628 && INTVAL (operands[2]) == 65535))
3629 return AS1 (dec%W0,%0);
3631 return AS2 (add%W0,%2,%0);
3633 [(set_attr "type" "binary")])
3635 (define_expand "addqi3"
3636 [(set (match_operand:QI 0 "general_operand" "")
3637 (plus:QI (match_operand:QI 1 "general_operand" "")
3638 (match_operand:QI 2 "general_operand" "")))]
3640 "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);")
3643 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,?q")
3644 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q")
3645 (match_operand:QI 2 "general_operand" "qn,qmn,qn")))]
3646 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3649 if (REG_P (operands[0]) && REG_P (operands[1])
3650 && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
3651 && (REGNO (operands[0]) != REGNO (operands[1])
3652 || NON_QI_REG_P (operands[1])
3653 || (REG_P (operands[2]) && NON_QI_REG_P (operands[2]))))
3655 if (operands[2] == stack_pointer_rtx)
3660 = gen_rtx_PLUS (SImode,
3661 gen_rtx_REG (SImode, REGNO (operands[1])),
3662 (! REG_P (operands[2])
3664 : gen_rtx_REG (SImode, REGNO (operands[2]))));
3665 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
3666 return AS2 (lea%L0,%a1,%0);
3668 if (operands[2] == const1_rtx)
3669 return AS1 (inc%B0,%0);
3671 if (operands[2] == constm1_rtx
3672 || (GET_CODE (operands[2]) == CONST_INT
3673 && INTVAL (operands[2]) == 255))
3674 return AS1 (dec%B0,%0);
3676 return AS2 (add%B0,%2,%0);
3678 [(set_attr "type" "binary")])
3680 ;Lennart Augustsson <augustss@cs.chalmers.se>
3681 ;says this pattern just makes slower code:
3685 ; leal -80(%ebp),%eax
3689 ; [(set (match_operand:SI 0 "push_operand" "=<")
3690 ; (plus:SI (match_operand:SI 1 "register_operand" "%r")
3691 ; (match_operand:SI 2 "nonmemory_operand" "ri")))]
3696 ; xops[0] = operands[0];
3697 ; xops[1] = operands[1];
3698 ; xops[2] = operands[2];
3699 ; xops[3] = gen_rtx_MEM (SImode, stack_pointer_rtx);
3700 ; output_asm_insn (\"push%z1 %1\", xops);
3701 ; output_asm_insn (AS2 (add%z3,%2,%3), xops);
3705 ;; The patterns that match these are at the end of this file.
3707 (define_expand "addxf3"
3708 [(set (match_operand:XF 0 "register_operand" "")
3709 (plus:XF (match_operand:XF 1 "register_operand" "")
3710 (match_operand:XF 2 "register_operand" "")))]
3714 (define_expand "adddf3"
3715 [(set (match_operand:DF 0 "register_operand" "")
3716 (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3717 (match_operand:DF 2 "nonimmediate_operand" "")))]
3721 (define_expand "addsf3"
3722 [(set (match_operand:SF 0 "register_operand" "")
3723 (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3724 (match_operand:SF 2 "nonimmediate_operand" "")))]
3728 ;;- subtract instructions
3730 (define_insn "subsidi3"
3731 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o")
3732 (minus:DI (match_operand:DI 1 "general_operand" "0iF,0,roiF,roiF,riF,o,o")
3733 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,ri,i,r"))))
3734 (clobber (match_scratch:SI 3 "=X,X,X,X,X,&r,&r"))]
3738 rtx low[3], high[3], xops[7];
3742 split_di (operands, 2, low, high);
3743 high[2] = const0_rtx;
3744 low[2] = operands[2];
3746 if (!rtx_equal_p (operands[0], operands[1]))
3753 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3755 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3756 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3762 xops[6] = operands[3];
3763 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3764 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3765 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3766 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3767 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3768 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3773 output_asm_insn (AS2 (sub%L0,%2,%0), low);
3774 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3775 cc_status.value1 = high[0];
3776 cc_status.flags = CC_NO_OVERFLOW;
3780 [(set_attr "type" "binary")])
3782 (define_insn "subdi3"
3783 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
3784 (minus:DI (match_operand:DI 1 "general_operand" "0,0,0iF,or,roiF,roiF")
3785 (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
3786 (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
3790 rtx low[3], high[3], xops[7];
3794 split_di (operands, 3, low, high);
3796 if (!rtx_equal_p (operands[0], operands[1]))
3803 if (GET_CODE (operands[0]) != MEM)
3805 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3806 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3812 xops[6] = operands[3];
3813 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3814 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3815 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3816 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3817 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3818 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3823 cc_status.value1 = high[0];
3824 cc_status.flags = CC_NO_OVERFLOW;
3826 if (GET_CODE (operands[3]) == REG)
3832 xops[4] = operands[3];
3834 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3835 output_asm_insn (AS2 (sub%L1,%4,%1), xops);
3836 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3837 output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
3840 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
3842 output_asm_insn (AS2 (sub%L0,%2,%0), low);
3843 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3847 output_asm_insn (AS2 (sub%L0,%2,%0), high);
3852 [(set_attr "type" "binary")])
3854 (define_expand "subsi3"
3855 [(set (match_operand:SI 0 "nonimmediate_operand" "")
3856 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3857 (match_operand:SI 2 "general_operand" "")))]
3859 "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);")
3862 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3863 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
3864 (match_operand:SI 2 "general_operand" "ri,rm")))]
3865 "ix86_binary_operator_ok (MINUS, SImode, operands)"
3866 "* return AS2 (sub%L0,%2,%0);"
3867 [(set_attr "type" "binary")])
3869 (define_expand "subhi3"
3870 [(set (match_operand:HI 0 "general_operand" "")
3871 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3872 (match_operand:HI 2 "general_operand" "")))]
3874 "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);")
3877 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3878 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
3879 (match_operand:HI 2 "general_operand" "ri,rm")))]
3880 "ix86_binary_operator_ok (MINUS, HImode, operands)"
3883 if (REG_P (operands[0])
3884 && i386_aligned_p (operands[2])
3885 && i386_cc_probably_useless_p (insn))
3888 operands[2] = i386_sext16_if_const (operands[2]);
3889 return AS2 (sub%L0,%k2,%k0);
3891 return AS2 (sub%W0,%2,%0);
3893 [(set_attr "type" "binary")])
3895 (define_expand "subqi3"
3896 [(set (match_operand:QI 0 "general_operand" "")
3897 (minus:QI (match_operand:QI 1 "general_operand" "")
3898 (match_operand:QI 2 "general_operand" "")))]
3900 "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);")
3903 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3904 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
3905 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3906 "ix86_binary_operator_ok (MINUS, QImode, operands)"
3907 "* return AS2 (sub%B0,%2,%0);"
3908 [(set_attr "type" "binary")])
3910 ;; The patterns that match these are at the end of this file.
3912 (define_expand "subxf3"
3913 [(set (match_operand:XF 0 "register_operand" "")
3914 (minus:XF (match_operand:XF 1 "register_operand" "")
3915 (match_operand:XF 2 "register_operand" "")))]
3919 (define_expand "subdf3"
3920 [(set (match_operand:DF 0 "register_operand" "")
3921 (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3922 (match_operand:DF 2 "nonimmediate_operand" "")))]
3926 (define_expand "subsf3"
3927 [(set (match_operand:SF 0 "register_operand" "")
3928 (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3929 (match_operand:SF 2 "nonimmediate_operand" "")))]
3933 ;;- multiply instructions
3935 ;(define_insn "mulqi3"
3936 ; [(set (match_operand:QI 0 "register_operand" "=a")
3937 ; (mult:QI (match_operand:QI 1 "register_operand" "%0")
3938 ; (match_operand:QI 2 "nonimmediate_operand" "qm")))]
3942 (define_insn "mulhi3"
3943 [(set (match_operand:HI 0 "register_operand" "=r,r")
3944 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%0,rm")
3945 (match_operand:HI 2 "general_operand" "g,i")))]
3949 if (GET_CODE (operands[1]) == REG
3950 && REGNO (operands[1]) == REGNO (operands[0])
3951 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3952 /* Assembler has weird restrictions. */
3953 return AS2 (imul%W0,%2,%0);
3954 return AS3 (imul%W0,%2,%1,%0);
3956 [(set_attr "type" "imul")])
3958 (define_insn "mulsi3"
3959 [(set (match_operand:SI 0 "register_operand" "=r,r")
3960 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
3961 (match_operand:SI 2 "general_operand" "g,i")))]
3965 if (GET_CODE (operands[1]) == REG
3966 && REGNO (operands[1]) == REGNO (operands[0])
3967 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3968 /* Assembler has weird restrictions. */
3969 return AS2 (imul%L0,%2,%0);
3970 return AS3 (imul%L0,%2,%1,%0);
3972 [(set_attr "type" "imul")])
3974 (define_insn "umulqihi3"
3975 [(set (match_operand:HI 0 "register_operand" "=a")
3976 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3977 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3980 [(set_attr "type" "imul")])
3982 (define_insn "mulqihi3"
3983 [(set (match_operand:HI 0 "register_operand" "=a")
3984 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3985 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3988 [(set_attr "type" "imul")])
3990 (define_insn "umulsidi3"
3991 [(set (match_operand:DI 0 "register_operand" "=A")
3992 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3993 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
3994 "TARGET_WIDE_MULTIPLY"
3996 [(set_attr "type" "imul")])
3998 (define_insn "mulsidi3"
3999 [(set (match_operand:DI 0 "register_operand" "=A")
4000 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
4001 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
4002 "TARGET_WIDE_MULTIPLY"
4004 [(set_attr "type" "imul")])
4006 (define_insn "umulsi3_highpart"
4007 [(set (match_operand:SI 0 "register_operand" "=d")
4008 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
4009 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
4011 (clobber (match_scratch:SI 3 "=a"))]
4012 "TARGET_WIDE_MULTIPLY"
4014 [(set_attr "type" "imul")])
4016 (define_insn "smulsi3_highpart"
4017 [(set (match_operand:SI 0 "register_operand" "=d")
4018 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
4019 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
4021 (clobber (match_scratch:SI 3 "=a"))]
4022 "TARGET_WIDE_MULTIPLY"
4024 [(set_attr "type" "imul")])
4026 ;; The patterns that match these are at the end of this file.
4028 (define_expand "mulxf3"
4029 [(set (match_operand:XF 0 "register_operand" "")
4030 (mult:XF (match_operand:XF 1 "register_operand" "")
4031 (match_operand:XF 2 "register_operand" "")))]
4035 (define_expand "muldf3"
4036 [(set (match_operand:DF 0 "register_operand" "")
4037 (mult:DF (match_operand:DF 1 "register_operand" "")
4038 (match_operand:DF 2 "nonimmediate_operand" "")))]
4042 (define_expand "mulsf3"
4043 [(set (match_operand:SF 0 "register_operand" "")
4044 (mult:SF (match_operand:SF 1 "register_operand" "")
4045 (match_operand:SF 2 "nonimmediate_operand" "")))]
4049 ;;- divide instructions
4051 (define_insn "divqi3"
4052 [(set (match_operand:QI 0 "register_operand" "=a")
4053 (div:QI (match_operand:HI 1 "register_operand" "0")
4054 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
4058 (define_insn "udivqi3"
4059 [(set (match_operand:QI 0 "register_operand" "=a")
4060 (udiv:QI (match_operand:HI 1 "register_operand" "0")
4061 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
4064 [(set_attr "type" "idiv")])
4066 ;; The patterns that match these are at the end of this file.
4068 (define_expand "divxf3"
4069 [(set (match_operand:XF 0 "register_operand" "")
4070 (div:XF (match_operand:XF 1 "register_operand" "")
4071 (match_operand:XF 2 "register_operand" "")))]
4075 (define_expand "divdf3"
4076 [(set (match_operand:DF 0 "register_operand" "")
4077 (div:DF (match_operand:DF 1 "register_operand" "")
4078 (match_operand:DF 2 "nonimmediate_operand" "")))]
4082 (define_expand "divsf3"
4083 [(set (match_operand:SF 0 "register_operand" "")
4084 (div:SF (match_operand:SF 1 "register_operand" "")
4085 (match_operand:SF 2 "nonimmediate_operand" "")))]
4089 ;; Remainder instructions.
4091 (define_insn "divmodsi4"
4092 [(set (match_operand:SI 0 "register_operand" "=a")
4093 (div:SI (match_operand:SI 1 "register_operand" "0")
4094 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4095 (set (match_operand:SI 3 "register_operand" "=&d")
4096 (mod:SI (match_dup 1) (match_dup 2)))]
4101 output_asm_insn (\"cdq\", operands);
4103 output_asm_insn (\"cltd\", operands);
4105 return AS1 (idiv%L0,%2);
4107 [(set_attr "type" "idiv")])
4109 (define_insn "divmodhi4"
4110 [(set (match_operand:HI 0 "register_operand" "=a")
4111 (div:HI (match_operand:HI 1 "register_operand" "0")
4112 (match_operand:HI 2 "nonimmediate_operand" "rm")))
4113 (set (match_operand:HI 3 "register_operand" "=&d")
4114 (mod:HI (match_dup 1) (match_dup 2)))]
4117 [(set_attr "type" "idiv")])
4119 ;; ??? Can we make gcc zero extend operand[0]?
4120 (define_insn "udivmodsi4"
4121 [(set (match_operand:SI 0 "register_operand" "=a")
4122 (udiv:SI (match_operand:SI 1 "register_operand" "0")
4123 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4124 (set (match_operand:SI 3 "register_operand" "=&d")
4125 (umod:SI (match_dup 1) (match_dup 2)))]
4129 output_asm_insn (AS2 (xor%L3,%3,%3), operands);
4130 return AS1 (div%L0,%2);
4132 [(set_attr "type" "idiv")])
4134 ;; ??? Can we make gcc zero extend operand[0]?
4135 (define_insn "udivmodhi4"
4136 [(set (match_operand:HI 0 "register_operand" "=a")
4137 (udiv:HI (match_operand:HI 1 "register_operand" "0")
4138 (match_operand:HI 2 "nonimmediate_operand" "rm")))
4139 (set (match_operand:HI 3 "register_operand" "=&d")
4140 (umod:HI (match_dup 1) (match_dup 2)))]
4144 output_asm_insn (AS2 (xor%W0,%3,%3), operands);
4145 return AS1 (div%W0,%2);
4147 [(set_attr "type" "idiv")])
4150 ;;this should be a valid double division which we may want to add
4153 [(set (match_operand:SI 0 "register_operand" "=a")
4154 (udiv:DI (match_operand:DI 1 "register_operand" "a")
4155 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4156 (set (match_operand:SI 3 "register_operand" "=d")
4157 (umod:SI (match_dup 1) (match_dup 2)))]
4160 [(set_attr "type" "idiv")])
4163 ;;- and instructions
4170 ;; but if the reg is %eax, then the "andl" is faster.
4172 ;; On i486, the "andl" is always faster than the "movzbl".
4174 ;; On both i386 and i486, a three operand AND is as fast with movzbl or
4175 ;; movzwl as with andl, if operands[0] != operands[1].
4177 ;; The `r' in `rm' for operand 3 looks redundant, but it causes
4178 ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
4180 (define_insn "andsi3"
4181 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4182 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4183 (match_operand:SI 2 "general_operand" "ri,rm")))]
4187 HOST_WIDE_INT intval;
4188 if (!rtx_equal_p (operands[0], operands[1])
4189 && rtx_equal_p (operands[0], operands[2]))
4193 operands[1] = operands[2];
4196 switch (GET_CODE (operands[2]))
4199 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4201 intval = INTVAL (operands[2]);
4202 /* zero-extend 16->32? */
4203 if (intval == 0xffff && REG_P (operands[0])
4204 && (! REG_P (operands[1])
4205 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
4206 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
4208 /* ??? tege: Should forget CC_STATUS only if we clobber a
4209 remembered operand. Fix that later. */
4212 return AS2 (movzx,%w1,%0);
4214 return AS2 (movz%W0%L0,%w1,%0);
4218 /* zero extend 8->32? */
4219 if (intval == 0xff && REG_P (operands[0])
4220 && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
4221 && (! REG_P (operands[1])
4222 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
4223 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
4225 /* ??? tege: Should forget CC_STATUS only if we clobber a
4226 remembered operand. Fix that later. */
4229 return AS2 (movzx,%b1,%0);
4231 return AS2 (movz%B0%L0,%b1,%0);
4235 /* Check partial bytes.. non-QI-regs are not available */
4236 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4239 /* only low byte has zero bits? */
4240 if (~(intval | 0xff) == 0)
4243 if (REG_P (operands[0]))
4248 return AS2 (xor%B0,%b0,%b0);
4251 /* we're better off with the 32-bit version if reg != EAX */
4252 /* the value is sign-extended in 8 bits */
4253 if (REGNO (operands[0]) != 0 && (intval & 0x80))
4259 operands[2] = GEN_INT (intval);
4262 return AS2 (mov%B0,%2,%b0);
4264 return AS2 (and%B0,%2,%b0);
4267 /* only second byte has zero? */
4268 if (~(intval | 0xff00) == 0)
4272 intval = (intval >> 8) & 0xff;
4273 operands[2] = GEN_INT (intval);
4276 if (REG_P (operands[0]))
4277 return AS2 (xor%B0,%h0,%h0);
4278 operands[0] = adj_offsettable_operand (operands[0], 1);
4279 return AS2 (mov%B0,%2,%b0);
4282 if (REG_P (operands[0]))
4283 return AS2 (and%B0,%2,%h0);
4285 operands[0] = adj_offsettable_operand (operands[0], 1);
4286 return AS2 (and%B0,%2,%b0);
4289 if (REG_P (operands[0]))
4292 /* third byte has zero bits? */
4293 if (~(intval | 0xff0000) == 0)
4295 intval = (intval >> 16) & 0xff;
4296 operands[0] = adj_offsettable_operand (operands[0], 2);
4299 operands[2] = GEN_INT (intval);
4301 return AS2 (mov%B0,%2,%b0);
4302 return AS2 (and%B0,%2,%b0);
4305 /* fourth byte has zero bits? */
4306 if (~(intval | 0xff000000) == 0)
4308 intval = (intval >> 24) & 0xff;
4309 operands[0] = adj_offsettable_operand (operands[0], 3);
4310 goto byte_and_operation;
4313 /* Low word is zero? */
4314 if (intval == 0xffff0000)
4316 word_zero_and_operation:
4318 operands[2] = const0_rtx;
4319 return AS2 (mov%W0,%2,%w0);
4322 /* High word is zero? */
4323 if (intval == 0x0000ffff)
4325 operands[0] = adj_offsettable_operand (operands[0], 2);
4326 goto word_zero_and_operation;
4333 return AS2 (and%L0,%2,%0);
4335 [(set_attr "type" "binary")])
4337 (define_insn "andhi3"
4338 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4339 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4340 (match_operand:HI 2 "general_operand" "ri,rm")))]
4344 if (GET_CODE (operands[2]) == CONST_INT
4345 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
4347 /* Can we ignore the upper byte? */
4348 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
4349 && (INTVAL (operands[2]) & 0xff00) == 0xff00)
4353 if ((INTVAL (operands[2]) & 0xff) == 0)
4355 operands[2] = const0_rtx;
4356 return AS2 (mov%B0,%2,%b0);
4359 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
4360 return AS2 (and%B0,%2,%b0);
4363 /* Can we ignore the lower byte? */
4364 /* ??? what about offsettable memory references? */
4365 if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
4369 if ((INTVAL (operands[2]) & 0xff00) == 0)
4371 operands[2] = const0_rtx;
4372 return AS2 (mov%B0,%2,%h0);
4375 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
4376 return AS2 (and%B0,%2,%h0);
4379 /* use 32-bit ops on registers when there are no sign issues.. */
4380 if (REG_P (operands[0]))
4382 if (!(INTVAL (operands[2]) & ~0x7fff))
4383 return AS2 (and%L0,%2,%k0);
4387 if (REG_P (operands[0])
4388 && i386_aligned_p (operands[2]))
4391 /* If op[2] is constant, we should zero-extend it and */
4392 /* make a note that op[0] has been zero-extended, so */
4393 /* that we could use 32-bit ops on it forthwith, but */
4394 /* there is no such reg-note available. Instead we do */
4395 /* a sign extension as that can result in shorter asm */
4396 operands[2] = i386_sext16_if_const (operands[2]);
4397 return AS2 (and%L0,%k2,%k0);
4400 /* Use a 32-bit word with the upper bits set, invalidate CC */
4401 if (GET_CODE (operands[2]) == CONST_INT
4402 && i386_aligned_p (operands[0]))
4404 HOST_WIDE_INT val = INTVAL (operands[2]);
4407 if (val != INTVAL (operands[2]))
4408 operands[2] = GEN_INT (val);
4409 return AS2 (and%L0,%k2,%k0);
4412 return AS2 (and%W0,%2,%0);
4414 [(set_attr "type" "binary")])
4416 (define_insn "andqi3"
4417 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4418 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4419 (match_operand:QI 2 "general_operand" "qn,qmn")))]
4421 "* return AS2 (and%B0,%2,%0);"
4422 [(set_attr "type" "binary")])
4424 /* I am nervous about these two.. add them later..
4425 ;I presume this means that we have something in say op0= eax which is small
4426 ;and we want to and it with memory so we can do this by just an
4427 ;andb m,%al and have success.
4429 [(set (match_operand:SI 0 "general_operand" "=r")
4430 (and:SI (zero_extend:SI
4431 (match_operand:HI 1 "nonimmediate_operand" "rm"))
4432 (match_operand:SI 2 "general_operand" "0")))]
4433 "GET_CODE (operands[2]) == CONST_INT
4434 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
4438 [(set (match_operand:SI 0 "register_operand" "=q")
4440 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
4441 (match_operand:SI 2 "register_operand" "0")))]
4442 "GET_CODE (operands[2]) == CONST_INT
4443 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
4448 ;;- Bit set (inclusive or) instructions
4450 ;; This optimizes known byte-wide operations to memory, and in some cases
4451 ;; to QI registers.. Note that we don't want to use the QI registers too
4452 ;; aggressively, because often the 32-bit register instruction is the same
4453 ;; size, and likely to be faster on PentiumPro.
4454 (define_insn "iorsi3"
4455 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4456 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4457 (match_operand:SI 2 "general_operand" "ri,rm")))]
4461 HOST_WIDE_INT intval;
4462 switch (GET_CODE (operands[2]))
4466 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4469 /* don't try to optimize volatile accesses */
4470 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4473 intval = INTVAL (operands[2]);
4474 if ((intval & ~0xff) == 0)
4476 if (REG_P (operands[0]))
4478 /* Do low byte access only for %eax or when high bit is set */
4479 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4486 if (intval != INTVAL (operands[2]))
4487 operands[2] = GEN_INT (intval);
4490 return AS2 (mov%B0,%2,%b0);
4492 return AS2 (or%B0,%2,%b0);
4496 if ((intval & ~0xff00) == 0)
4500 if (REG_P (operands[0]))
4503 operands[2] = GEN_INT (intval);
4505 return AS2 (mov%B0,%2,%h0);
4507 return AS2 (or%B0,%2,%h0);
4510 operands[0] = adj_offsettable_operand (operands[0], 1);
4511 goto byte_or_operation;
4514 if (REG_P (operands[0]))
4518 if ((intval & ~0xff0000) == 0)
4521 operands[0] = adj_offsettable_operand (operands[0], 2);
4522 goto byte_or_operation;
4526 if ((intval & ~0xff000000) == 0)
4528 intval = (intval >> 24) & 0xff;
4529 operands[0] = adj_offsettable_operand (operands[0], 3);
4530 goto byte_or_operation;
4537 return AS2 (or%L0,%2,%0);
4539 [(set_attr "type" "binary")])
4541 (define_insn "iorhi3"
4542 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4543 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4544 (match_operand:HI 2 "general_operand" "ri,rm")))]
4548 HOST_WIDE_INT intval;
4549 switch (GET_CODE (operands[2]))
4553 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4556 /* don't try to optimize volatile accesses */
4557 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4560 intval = 0xffff & INTVAL (operands[2]);
4562 if ((intval & 0xff00) == 0)
4564 if (REG_P (operands[0]))
4566 /* Do low byte access only for %eax or when high bit is set */
4567 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4575 return AS2 (mov%B0,%2,%b0);
4577 return AS2 (or%B0,%2,%b0);
4581 if ((intval & 0xff) == 0)
4584 operands[2] = GEN_INT (intval);
4586 if (REG_P (operands[0]))
4590 return AS2 (mov%B0,%2,%h0);
4592 return AS2 (or%B0,%2,%h0);
4595 operands[0] = adj_offsettable_operand (operands[0], 1);
4597 goto byte_or_operation;
4604 if (REG_P (operands[0])
4605 && i386_aligned_p (operands[2]))
4608 operands[2] = i386_sext16_if_const (operands[2]);
4609 return AS2 (or%L0,%k2,%k0);
4612 if (GET_CODE (operands[2]) == CONST_INT
4613 && i386_aligned_p (operands[0]))
4616 intval = 0xffff & INTVAL (operands[2]);
4617 if (intval != INTVAL (operands[2]))
4618 operands[2] = GEN_INT (intval);
4619 return AS2 (or%L0,%2,%k0);
4622 return AS2 (or%W0,%2,%0);
4624 [(set_attr "type" "binary")])
4626 (define_insn "iorqi3"
4627 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4628 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4629 (match_operand:QI 2 "general_operand" "qn,qmn")))]
4631 "* return AS2 (or%B0,%2,%0);"
4632 [(set_attr "type" "binary")])
4634 ;;- xor instructions
4636 (define_insn "xorsi3"
4637 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4638 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4639 (match_operand:SI 2 "general_operand" "ri,rm")))]
4643 HOST_WIDE_INT intval;
4644 switch (GET_CODE (operands[2]))
4648 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4651 /* don't try to optimize volatile accesses */
4652 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4655 intval = INTVAL (operands[2]);
4656 if ((intval & ~0xff) == 0)
4658 if (REG_P (operands[0]))
4660 /* Do low byte access only for %eax or when high bit is set */
4661 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4669 && (!TARGET_PENTIUM || optimize_size
4670 || (GET_CODE (operands[0]) == MEM
4671 && memory_address_info (XEXP (operands[0], 0), 1))))
4672 return AS1 (not%B0,%b0);
4674 if (intval != INTVAL (operands[2]))
4675 operands[2] = GEN_INT (intval);
4676 return AS2 (xor%B0,%2,%b0);
4680 if ((intval & ~0xff00) == 0)
4684 if (REG_P (operands[0]))
4688 && (!TARGET_PENTIUM || optimize_size
4689 || (GET_CODE (operands[0]) == MEM
4690 && memory_address_info (XEXP (operands[0], 0), 1))))
4691 return AS1 (not%B0,%h0);
4693 operands[2] = GEN_INT (intval);
4694 return AS2 (xor%B0,%2,%h0);
4697 operands[0] = adj_offsettable_operand (operands[0], 1);
4699 goto byte_xor_operation;
4702 if (REG_P (operands[0]))
4706 if ((intval & ~0xff0000) == 0)
4709 operands[0] = adj_offsettable_operand (operands[0], 2);
4710 goto byte_xor_operation;
4714 if ((intval & ~0xff000000) == 0)
4716 intval = (intval >> 24) & 0xff;
4717 operands[0] = adj_offsettable_operand (operands[0], 3);
4718 goto byte_xor_operation;
4725 return AS2 (xor%L0,%2,%0);
4727 [(set_attr "type" "binary")])
4729 (define_insn "xorhi3"
4730 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4731 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4732 (match_operand:HI 2 "general_operand" "ri,rm")))]
4736 if (GET_CODE (operands[2]) == CONST_INT
4737 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
4739 /* Can we ignore the upper byte? */
4740 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
4741 && (INTVAL (operands[2]) & 0xff00) == 0)
4744 if (INTVAL (operands[2]) & 0xffff0000)
4745 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
4747 if (INTVAL (operands[2]) == 0xff
4748 && (!TARGET_PENTIUM || optimize_size
4749 || (GET_CODE (operands[0]) == MEM
4750 && memory_address_info (XEXP (operands[0], 0), 1))))
4751 return AS1 (not%B0,%b0);
4753 return AS2 (xor%B0,%2,%b0);
4756 /* Can we ignore the lower byte? */
4757 /* ??? what about offsettable memory references? */
4758 if (QI_REG_P (operands[0])
4759 && (INTVAL (operands[2]) & 0xff) == 0)
4762 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
4764 if (INTVAL (operands[2]) == 0xff
4765 && (!TARGET_PENTIUM || optimize_size
4766 || (GET_CODE (operands[0]) == MEM
4767 && memory_address_info (XEXP (operands[0], 0), 1))))
4768 return AS1 (not%B0,%h0);
4770 return AS2 (xor%B0,%2,%h0);
4774 if (REG_P (operands[0])
4775 && i386_aligned_p (operands[2]))
4778 operands[2] = i386_sext16_if_const (operands[2]);
4779 return AS2 (xor%L0,%k2,%k0);
4782 if (GET_CODE (operands[2]) == CONST_INT
4783 && i386_aligned_p (operands[0]))
4785 HOST_WIDE_INT intval;
4787 intval = 0xffff & INTVAL (operands[2]);
4788 if (intval != INTVAL (operands[2]))
4789 operands[2] = GEN_INT (intval);
4790 return AS2 (xor%L0,%2,%k0);
4793 return AS2 (xor%W0,%2,%0);
4795 [(set_attr "type" "binary")])
4797 (define_insn "xorqi3"
4798 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4799 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4800 (match_operand:QI 2 "general_operand" "qn,qm")))]
4802 "* return AS2 (xor%B0,%2,%0);"
4803 [(set_attr "type" "binary")])
4805 ;; logical operations for DImode
4807 (define_insn "anddi3"
4808 [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4809 (and:DI (match_operand:DI 1 "general_operand" "%0,0")
4810 (match_operand:DI 2 "general_operand" "oriF,riF")))]
4813 [(set_attr "type" "binary")])
4816 (define_insn "iordi3"
4817 [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4818 (ior:DI (match_operand:DI 1 "general_operand" "%0,0")
4819 (match_operand:DI 2 "general_operand" "oriF,riF")))]
4822 [(set_attr "type" "binary")])
4824 (define_insn "xordi3"
4825 [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4826 (xor:DI (match_operand:DI 1 "general_operand" "%0,0")
4827 (match_operand:DI 2 "general_operand" "oriF,riF")))]
4830 [(set_attr "type" "binary")])
4833 [(set (match_operand:DI 0 "general_operand" "")
4834 (match_operator:DI 3 "ix86_logical_operator"
4835 [(match_operand:DI 1 "general_operand" "")
4836 (match_operand:DI 2 "general_operand" "")]))]
4838 [(set (match_dup 4) (match_op_dup:SI 3 [(match_dup 6) (match_dup 8)]))
4839 (set (match_dup 5) (match_op_dup:SI 3 [(match_dup 7) (match_dup 9)]))]
4840 "split_di (&operands[0], 1, &operands[4], &operands[5]);
4841 split_di (&operands[1], 1, &operands[6], &operands[7]);
4842 split_di (&operands[2], 1, &operands[8], &operands[9]);")
4844 ;;- negation instructions
4846 (define_insn "negdi2"
4847 [(set (match_operand:DI 0 "general_operand" "=&ro")
4848 (neg:DI (match_operand:DI 1 "general_operand" "0")))]
4852 rtx xops[2], low[1], high[1];
4856 split_di (operands, 1, low, high);
4857 xops[0] = const0_rtx;
4860 output_asm_insn (AS1 (neg%L0,%0), low);
4861 output_asm_insn (AS2 (adc%L1,%0,%1), xops);
4862 output_asm_insn (AS1 (neg%L0,%0), high);
4866 (define_insn "negsi2"
4867 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4868 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
4872 (define_insn "neghi2"
4873 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4874 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
4877 if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn))
4880 return AS1(neg%L0,%k0);
4882 return AS1(neg%W0,%0);")
4884 (define_insn "negqi2"
4885 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4886 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
4890 (define_insn "negsf2"
4891 [(set (match_operand:SF 0 "register_operand" "=f")
4892 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
4895 [(set_attr "type" "fpop")])
4897 (define_insn "negdf2"
4898 [(set (match_operand:DF 0 "register_operand" "=f")
4899 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
4902 [(set_attr "type" "fpop")])
4905 [(set (match_operand:DF 0 "register_operand" "=f")
4906 (neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
4909 [(set_attr "type" "fpop")])
4911 (define_insn "negxf2"
4912 [(set (match_operand:XF 0 "register_operand" "=f")
4913 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
4916 [(set_attr "type" "fpop")])
4919 [(set (match_operand:XF 0 "register_operand" "=f")
4920 (neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4923 [(set_attr "type" "fpop")])
4925 ;; Absolute value instructions
4927 (define_insn "abssf2"
4928 [(set (match_operand:SF 0 "register_operand" "=f")
4929 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
4932 [(set_attr "type" "fpop")])
4934 (define_insn "absdf2"
4935 [(set (match_operand:DF 0 "register_operand" "=f")
4936 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
4939 [(set_attr "type" "fpop")])
4942 [(set (match_operand:DF 0 "register_operand" "=f")
4943 (abs:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
4946 [(set_attr "type" "fpop")])
4948 (define_insn "absxf2"
4949 [(set (match_operand:XF 0 "register_operand" "=f")
4950 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
4953 [(set_attr "type" "fpop")])
4956 [(set (match_operand:XF 0 "register_operand" "=f")
4957 (abs:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4960 [(set_attr "type" "fpop")])
4962 (define_insn "sqrtsf2"
4963 [(set (match_operand:SF 0 "register_operand" "=f")
4964 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
4965 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4968 (define_insn "sqrtdf2"
4969 [(set (match_operand:DF 0 "register_operand" "=f")
4970 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
4971 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4972 && (TARGET_IEEE_FP || flag_fast_math) "
4976 [(set (match_operand:DF 0 "register_operand" "=f")
4977 (sqrt:DF (float_extend:DF
4978 (match_operand:SF 1 "register_operand" "0"))))]
4979 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4982 (define_insn "sqrtxf2"
4983 [(set (match_operand:XF 0 "register_operand" "=f")
4984 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
4985 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4986 && (TARGET_IEEE_FP || flag_fast_math) "
4990 [(set (match_operand:XF 0 "register_operand" "=f")
4991 (sqrt:XF (float_extend:XF
4992 (match_operand:DF 1 "register_operand" "0"))))]
4993 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4997 [(set (match_operand:XF 0 "register_operand" "=f")
4998 (sqrt:XF (float_extend:XF
4999 (match_operand:SF 1 "register_operand" "0"))))]
5000 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
5003 (define_insn "sindf2"
5004 [(set (match_operand:DF 0 "register_operand" "=f")
5005 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
5006 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5009 (define_insn "sinsf2"
5010 [(set (match_operand:SF 0 "register_operand" "=f")
5011 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
5012 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5016 [(set (match_operand:DF 0 "register_operand" "=f")
5017 (unspec:DF [(float_extend:DF
5018 (match_operand:SF 1 "register_operand" "0"))] 1))]
5019 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5022 (define_insn "sinxf2"
5023 [(set (match_operand:XF 0 "register_operand" "=f")
5024 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
5025 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5028 (define_insn "cosdf2"
5029 [(set (match_operand:DF 0 "register_operand" "=f")
5030 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
5031 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5034 (define_insn "cossf2"
5035 [(set (match_operand:SF 0 "register_operand" "=f")
5036 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
5037 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5041 [(set (match_operand:DF 0 "register_operand" "=f")
5042 (unspec:DF [(float_extend:DF
5043 (match_operand:SF 1 "register_operand" "0"))] 2))]
5044 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5047 (define_insn "cosxf2"
5048 [(set (match_operand:XF 0 "register_operand" "=f")
5049 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
5050 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5053 ;;- one complement instructions
5055 (define_insn "one_cmplsi2"
5056 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5057 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
5061 /* A Pentium NOT is not pariable. Output it only in case of complex
5062 memory address, because XOR will be inpariable anyway because
5063 of immediate/displacement rule. */
5065 if (TARGET_PENTIUM && !optimize_size
5066 && (GET_CODE (operands[0]) != MEM
5067 || memory_address_info (XEXP (operands[0], 0), 1) == 0))
5070 xops[0] = operands[0];
5071 xops[1] = GEN_INT (0xffffffff);
5072 output_asm_insn (AS2 (xor%L0,%1,%0), xops);
5076 return AS1 (not%L0,%0);
5079 (define_insn "one_cmplhi2"
5080 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5081 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
5085 /* A Pentium NOT is not pariable. Output it only in case of complex
5086 memory address, because XOR will be inpariable anyway because
5087 of immediate/displacement rule. */
5089 if (TARGET_PENTIUM && !optimize_size
5090 && (GET_CODE (operands[0]) != MEM
5091 || memory_address_info (XEXP (operands[0], 0), 1) == 0))
5094 xops[0] = operands[0];
5095 xops[1] = GEN_INT (0xffff);
5096 if (REG_P (operands[0])
5097 && i386_cc_probably_useless_p (insn))
5100 output_asm_insn (AS2 (xor%L0,%1,%k0), xops);
5103 output_asm_insn (AS2 (xor%W0,%1,%0), xops);
5108 if (REG_P (operands[0])
5109 && i386_cc_probably_useless_p (insn))
5112 return AS1 (not%L0,%k0);
5114 return AS1 (not%W0,%0);
5118 (define_insn "one_cmplqi2"
5119 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5120 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
5124 /* A Pentium NOT is not pariable. Output it only in case of complex
5125 memory address, because XOR will be inpariable anyway because
5126 of immediate/displacement rule. */
5128 if (TARGET_PENTIUM && !optimize_size
5129 && (GET_CODE (operands[0]) != MEM
5130 || memory_address_info (XEXP (operands[0], 0), 1) == 0))
5133 xops[0] = operands[0];
5134 xops[1] = GEN_INT (0xff);
5135 output_asm_insn (AS2 (xor%B0,%1,%0), xops);
5139 return AS1 (not%B0,%0);
5142 ;;- arithmetic shift instructions
5144 ;; DImode shifts are implemented using the i386 "shift double" opcode,
5145 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
5146 ;; is variable, then the count is in %cl and the "imm" operand is dropped
5147 ;; from the assembler input.
5149 ;; This instruction shifts the target reg/mem as usual, but instead of
5150 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
5151 ;; is a left shift double, bits are taken from the high order bits of
5152 ;; reg, else if the insn is a shift right double, bits are taken from the
5153 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
5154 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
5156 ;; Since sh[lr]d does not change the `reg' operand, that is done
5157 ;; separately, making all shifts emit pairs of shift double and normal
5158 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
5159 ;; support a 63 bit shift, each shift where the count is in a reg expands
5160 ;; to a pair of shifts, a branch, a shift by 32 and a label.
5162 ;; If the shift count is a constant, we need never emit more than one
5163 ;; shift pair, instead using moves and sign extension for counts greater
5166 (define_expand "ashldi3"
5167 [(set (match_operand:DI 0 "register_operand" "")
5168 (ashift:DI (match_operand:DI 1 "register_operand" "")
5169 (match_operand:QI 2 "nonmemory_operand" "")))]
5173 if (GET_CODE (operands[2]) != CONST_INT
5174 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
5176 operands[2] = copy_to_mode_reg (QImode, operands[2]);
5177 emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
5181 emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
5186 (define_insn "ashldi3_const_int"
5187 [(set (match_operand:DI 0 "register_operand" "=&r")
5188 (ashift:DI (match_operand:DI 1 "register_operand" "0")
5189 (match_operand:QI 2 "const_int_operand" "J")))]
5190 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
5193 rtx xops[4], low[1], high[1];
5197 split_di (operands, 1, low, high);
5198 xops[0] = operands[2];
5199 xops[1] = const1_rtx;
5203 if (INTVAL (xops[0]) > 31)
5205 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
5206 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5208 if (INTVAL (xops[0]) > 32)
5210 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
5211 output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
5216 output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
5217 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
5222 (define_insn "ashldi3_non_const_int"
5223 [(set (match_operand:DI 0 "register_operand" "=&r")
5224 (ashift:DI (match_operand:DI 1 "register_operand" "0")
5225 (match_operand:QI 2 "register_operand" "c")))]
5229 rtx xops[5], low[1], high[1];
5233 split_di (operands, 1, low, high);
5234 xops[0] = operands[2];
5235 xops[1] = GEN_INT (32);
5238 xops[4] = gen_label_rtx ();
5240 output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
5241 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
5242 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5243 output_asm_insn (AS1 (je,%X4), xops);
5244 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
5245 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5246 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5247 CODE_LABEL_NUMBER (xops[4]));
5251 (define_expand "ashlsi3"
5252 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5253 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
5254 (match_operand:SI 2 "nonmemory_operand" "")))]
5258 (define_expand "ashlhi3"
5259 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5260 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
5261 (match_operand:HI 2 "nonmemory_operand" "")))]
5265 (define_expand "ashlqi3"
5266 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5267 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
5268 (match_operand:QI 2 "nonmemory_operand" "")))]
5272 ;; Pattern for shifts which can be encoded into an lea instruction.
5273 ;; This is kept as a separate pattern so that regmove can optimize cases
5274 ;; where we know the source and destination must match.
5276 ;; Do not expose this pattern when optimizing for size since we never want
5277 ;; to use lea when optimizing for size since mov+sal is smaller than lea.
5280 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
5281 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
5282 (match_operand:SI 2 "small_shift_operand" "M,M")))]
5284 "* return output_ashl (insn, operands);")
5286 ;; Generic left shift pattern to catch all cases not handled by the
5287 ;; shift pattern above.
5289 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5290 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5291 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5293 "* return output_ashl (insn, operands);")
5296 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r")
5297 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
5298 (match_operand:HI 2 "small_shift_operand" "M,M")))]
5300 "* return output_ashl (insn, operands);")
5303 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5304 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5305 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5307 "* return output_ashl (insn, operands);")
5310 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q")
5311 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,q")
5312 (match_operand:QI 2 "small_shift_operand" "M,M")))]
5314 "* return output_ashl (insn, operands);")
5316 ;; Generic left shift pattern to catch all cases not handled by the
5317 ;; shift pattern above.
5319 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5320 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5321 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5323 "* return output_ashl (insn, operands);")
5325 ;; See comment above `ashldi3' about how this works.
5327 (define_expand "ashrdi3"
5328 [(set (match_operand:DI 0 "register_operand" "")
5329 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5330 (match_operand:QI 2 "nonmemory_operand" "")))]
5334 if (GET_CODE (operands[2]) != CONST_INT
5335 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
5337 operands[2] = copy_to_mode_reg (QImode, operands[2]);
5338 emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1],
5342 emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2]));
5347 (define_insn "ashldi3_32"
5348 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
5349 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
5354 rtx low[2], high[2], xops[4];
5356 split_di (operands, 2, low, high);
5360 xops[3] = const0_rtx;
5361 if (!rtx_equal_p (xops[0], xops[1]))
5362 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
5364 if (GET_CODE (low[0]) == MEM)
5365 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5367 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5372 (define_insn "ashrdi3_const_int"
5373 [(set (match_operand:DI 0 "register_operand" "=&r")
5374 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
5375 (match_operand:QI 2 "const_int_operand" "J")))]
5376 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
5379 rtx xops[4], low[1], high[1];
5383 split_di (operands, 1, low, high);
5384 xops[0] = operands[2];
5385 xops[1] = const1_rtx;
5389 if (INTVAL (xops[0]) > 31)
5391 xops[1] = GEN_INT (31);
5392 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5393 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */
5395 if (INTVAL (xops[0]) > 32)
5397 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
5398 output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */
5403 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
5404 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
5410 (define_insn "ashrdi3_non_const_int"
5411 [(set (match_operand:DI 0 "register_operand" "=&r")
5412 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
5413 (match_operand:QI 2 "register_operand" "c")))]
5417 rtx xops[5], low[1], high[1];
5421 split_di (operands, 1, low, high);
5422 xops[0] = operands[2];
5423 xops[1] = GEN_INT (32);
5426 xops[4] = gen_label_rtx ();
5428 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
5429 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
5430 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5431 output_asm_insn (AS1 (je,%X4), xops);
5432 xops[1] = GEN_INT (31);
5433 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5434 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */
5435 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5436 CODE_LABEL_NUMBER (xops[4]));
5440 (define_insn "ashrsi3_31"
5441 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d")
5442 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a")
5444 "!TARGET_PENTIUM || optimize_size"
5449 (define_insn "ashrsi3"
5450 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5451 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5452 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5456 if (REG_P (operands[2]))
5457 return AS2 (sar%L0,%b2,%0);
5459 return AS2 (sar%L0,%2,%0);
5462 (define_insn "ashrhi3"
5463 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5464 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5465 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5469 if (REG_P (operands[2]))
5470 return AS2 (sar%W0,%b2,%0);
5472 return AS2 (sar%W0,%2,%0);
5475 (define_insn "ashrqi3"
5476 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5477 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5478 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5482 if (REG_P (operands[2]))
5483 return AS2 (sar%B0,%b2,%0);
5485 return AS2 (sar%B0,%2,%0);
5488 ;;- logical shift instructions
5490 ;; See comment above `ashldi3' about how this works.
5492 (define_expand "lshrdi3"
5493 [(set (match_operand:DI 0 "register_operand" "")
5494 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5495 (match_operand:QI 2 "nonmemory_operand" "")))]
5499 if (GET_CODE (operands[2]) != CONST_INT
5500 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
5502 operands[2] = copy_to_mode_reg (QImode, operands[2]);
5503 emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
5507 emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
5512 (define_insn "lshrdi3_32"
5513 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
5514 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
5519 rtx low[2], high[2], xops[4];
5521 split_di (operands, 2, low, high);
5525 xops[3] = const0_rtx;
5526 if (!rtx_equal_p (xops[0], xops[1]))
5527 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
5529 if (GET_CODE (low[0]) == MEM)
5530 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5532 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5537 (define_insn "lshrdi3_const_int"
5538 [(set (match_operand:DI 0 "register_operand" "=&r")
5539 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5540 (match_operand:QI 2 "const_int_operand" "J")))]
5541 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
5544 rtx xops[4], low[1], high[1];
5548 split_di (operands, 1, low, high);
5549 xops[0] = operands[2];
5550 xops[1] = const1_rtx;
5554 if (INTVAL (xops[0]) > 31)
5556 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
5557 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
5559 if (INTVAL (xops[0]) > 32)
5561 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
5562 output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
5567 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
5568 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
5574 (define_insn "lshrdi3_non_const_int"
5575 [(set (match_operand:DI 0 "register_operand" "=&r")
5576 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5577 (match_operand:QI 2 "register_operand" "c")))]
5581 rtx xops[5], low[1], high[1];
5585 split_di (operands, 1, low, high);
5586 xops[0] = operands[2];
5587 xops[1] = GEN_INT (32);
5590 xops[4] = gen_label_rtx ();
5592 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
5593 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
5594 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5595 output_asm_insn (AS1 (je,%X4), xops);
5596 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
5597 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
5598 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5599 CODE_LABEL_NUMBER (xops[4]));
5603 (define_insn "lshrsi3"
5604 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5605 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5606 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5610 if (REG_P (operands[2]))
5611 return AS2 (shr%L0,%b2,%0);
5613 return AS2 (shr%L0,%2,%1);
5616 (define_insn "lshrhi3"
5617 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5618 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5619 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5623 if (REG_P (operands[2]))
5624 return AS2 (shr%W0,%b2,%0);
5626 return AS2 (shr%W0,%2,%0);
5629 (define_insn "lshrqi3"
5630 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5631 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5632 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5636 if (REG_P (operands[2]))
5637 return AS2 (shr%B0,%b2,%0);
5639 return AS2 (shr%B0,%2,%0);
5642 ;;- rotate instructions
5644 (define_insn "rotlsi3"
5645 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5646 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5647 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5651 if (REG_P (operands[2]))
5652 return AS2 (rol%L0,%b2,%0);
5654 return AS2 (rol%L0,%2,%0);
5657 (define_insn "rotlhi3"
5658 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5659 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5660 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5664 if (REG_P (operands[2]))
5665 return AS2 (rol%W0,%b2,%0);
5667 return AS2 (rol%W0,%2,%0);
5670 (define_insn "rotlqi3"
5671 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5672 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5673 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5677 if (REG_P (operands[2]))
5678 return AS2 (rol%B0,%b2,%0);
5680 return AS2 (rol%B0,%2,%0);
5683 (define_insn "rotrsi3"
5684 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5685 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5686 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5690 if (REG_P (operands[2]))
5691 return AS2 (ror%L0,%b2,%0);
5693 return AS2 (ror%L0,%2,%0);
5696 (define_insn "rotrhi3"
5697 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5698 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5699 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5703 if (REG_P (operands[2]))
5704 return AS2 (ror%W0,%b2,%0);
5706 return AS2 (ror%W0,%2,%0);
5709 (define_insn "rotrqi3"
5710 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5711 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5712 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5716 if (REG_P (operands[2]))
5717 return AS2 (ror%B0,%b2,%0);
5719 return AS2 (ror%B0,%2,%0);
5723 ;; This usually looses. But try a define_expand to recognize a few case
5724 ;; we can do efficiently, such as accessing the "high" QImode registers,
5725 ;; %ah, %bh, %ch, %dh.
5726 ;; ??? Note this has a botch on the mode of operand 0, which needs to be
5727 ;; fixed if this is ever enabled.
5729 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
5730 (match_operand:SI 1 "immediate_operand" "i")
5731 (match_operand:SI 2 "immediate_operand" "i"))
5732 (match_operand:SI 3 "nonmemory_operand" "ri"))]
5736 if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
5738 if (GET_CODE (operands[3]) == CONST_INT)
5740 unsigned int mask = (1 << INTVAL (operands[1])) - 1;
5741 operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
5742 output_asm_insn (AS2 (and%L0,%1,%0), operands);
5743 operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
5744 output_asm_insn (AS2 (or%L0,%3,%0), operands);
5748 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
5749 if (INTVAL (operands[2]))
5750 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5751 output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
5752 operands[2] = GEN_INT (BITS_PER_WORD
5753 - INTVAL (operands[1]) - INTVAL (operands[2]));
5754 if (INTVAL (operands[2]))
5755 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5761 ;; ??? There are problems with the mode of operand[3]. The point of this
5762 ;; is to represent an HImode move to a "high byte" register.
5764 (define_expand "insv"
5765 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
5766 (match_operand:SI 1 "immediate_operand" "")
5767 (match_operand:SI 2 "immediate_operand" ""))
5768 (match_operand:QI 3 "nonmemory_operand" "ri"))]
5772 if (GET_CODE (operands[1]) != CONST_INT
5773 || GET_CODE (operands[2]) != CONST_INT)
5776 if (! (INTVAL (operands[1]) == 8
5777 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
5778 && ! INTVAL (operands[1]) == 1)
5783 ;; On i386, the register count for a bit operation is *not* truncated,
5784 ;; so SHIFT_COUNT_TRUNCATED must not be defined.
5786 ;; On i486, the shift & or/and code is faster than bts or btr. If
5787 ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
5789 ;; On i386, bts is a little faster if operands[0] is a reg, and a
5790 ;; little slower if operands[0] is a MEM, than the shift & or/and code.
5791 ;; Use bts & btr, since they reload better.
5793 ;; General bit set and clear.
5795 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm")
5797 (match_operand:SI 2 "register_operand" "r"))
5798 (match_operand:SI 3 "const_int_operand" "n"))]
5799 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5804 if (INTVAL (operands[3]) == 1)
5805 return AS2 (bts%L0,%2,%0);
5807 return AS2 (btr%L0,%2,%0);
5810 ;; Bit complement. See comments on previous pattern.
5811 ;; ??? Is this really worthwhile?
5813 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5814 (xor:SI (ashift:SI (const_int 1)
5815 (match_operand:SI 1 "register_operand" "r"))
5816 (match_operand:SI 2 "nonimmediate_operand" "0")))]
5817 "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT"
5822 return AS2 (btc%L0,%1,%0);
5826 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5827 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5828 (ashift:SI (const_int 1)
5829 (match_operand:SI 2 "register_operand" "r"))))]
5830 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5835 return AS2 (btc%L0,%2,%0);
5838 ;; Recognizers for bit-test instructions.
5840 ;; The bt opcode allows a MEM in operands[0]. But on both i386 and
5841 ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
5842 ;; bt on the MEM directly.
5844 ;; ??? The first argument of a zero_extract must not be reloaded, so
5845 ;; don't allow a MEM in the operand predicate without allowing it in the
5849 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5851 (match_operand:SI 1 "register_operand" "r")))]
5852 "GET_CODE (operands[1]) != CONST_INT"
5855 cc_status.flags |= CC_Z_IN_NOT_C;
5856 return AS2 (bt%L0,%1,%0);
5860 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5861 (match_operand:SI 1 "const_int_operand" "n")
5862 (match_operand:SI 2 "const_int_operand" "n")))]
5868 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5869 operands[1] = GEN_INT (mask);
5871 if (QI_REG_P (operands[0])
5872 /* A Pentium test is pairable only with eax. Not with ah or al. */
5873 && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
5876 if ((mask & ~0xff) == 0)
5878 cc_status.flags |= CC_NOT_NEGATIVE;
5879 return AS2 (test%B0,%1,%b0);
5882 if ((mask & ~0xff00) == 0)
5884 cc_status.flags |= CC_NOT_NEGATIVE;
5885 operands[1] = GEN_INT (mask >> 8);
5886 return AS2 (test%B0,%1,%h0);
5890 return AS2 (test%L0,%1,%0);
5893 ;; ??? All bets are off if operand 0 is a volatile MEM reference.
5894 ;; The CPU may access unspecified bytes around the actual target byte.
5897 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
5898 (match_operand:SI 1 "const_int_operand" "n")
5899 (match_operand:SI 2 "const_int_operand" "n")))]
5900 "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
5905 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5906 operands[1] = GEN_INT (mask);
5908 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
5909 /* A Pentium test is pairable only with eax. Not with ah or al. */
5910 && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
5913 if ((mask & ~0xff) == 0)
5915 cc_status.flags |= CC_NOT_NEGATIVE;
5916 return AS2 (test%B0,%1,%b0);
5919 if ((mask & ~0xff00) == 0)
5921 cc_status.flags |= CC_NOT_NEGATIVE;
5922 operands[1] = GEN_INT (mask >> 8);
5924 if (QI_REG_P (operands[0]))
5925 return AS2 (test%B0,%1,%h0);
5928 operands[0] = adj_offsettable_operand (operands[0], 1);
5929 return AS2 (test%B0,%1,%b0);
5933 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
5935 cc_status.flags |= CC_NOT_NEGATIVE;
5936 operands[1] = GEN_INT (mask >> 16);
5937 operands[0] = adj_offsettable_operand (operands[0], 2);
5938 return AS2 (test%B0,%1,%b0);
5941 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
5943 cc_status.flags |= CC_NOT_NEGATIVE;
5944 operands[1] = GEN_INT (mask >> 24);
5945 operands[0] = adj_offsettable_operand (operands[0], 3);
5946 return AS2 (test%B0,%1,%b0);
5950 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
5951 return AS2 (test%L0,%1,%0);
5953 return AS2 (test%L1,%0,%1);
5956 ;; Store-flag instructions.
5958 ;; For all sCOND expanders, also expand the compare or test insn that
5959 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
5961 (define_expand "seq"
5963 (set (match_operand:QI 0 "register_operand" "")
5964 (eq:QI (cc0) (const_int 0)))]
5969 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5970 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5972 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5975 (define_expand "sne"
5977 (set (match_operand:QI 0 "register_operand" "")
5978 (ne:QI (cc0) (const_int 0)))]
5983 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5984 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5986 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5989 (define_expand "sgt"
5991 (set (match_operand:QI 0 "register_operand" "")
5992 (gt:QI (cc0) (const_int 0)))]
5994 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5996 (define_expand "sgtu"
5998 (set (match_operand:QI 0 "register_operand" "")
5999 (gtu:QI (cc0) (const_int 0)))]
6001 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6003 (define_expand "slt"
6005 (set (match_operand:QI 0 "register_operand" "")
6006 (lt:QI (cc0) (const_int 0)))]
6008 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6010 (define_expand "sltu"
6012 (set (match_operand:QI 0 "register_operand" "")
6013 (ltu:QI (cc0) (const_int 0)))]
6015 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6017 (define_expand "sge"
6019 (set (match_operand:QI 0 "register_operand" "")
6020 (ge:QI (cc0) (const_int 0)))]
6022 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6024 (define_expand "sgeu"
6026 (set (match_operand:QI 0 "register_operand" "")
6027 (geu:QI (cc0) (const_int 0)))]
6029 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6031 (define_expand "sle"
6033 (set (match_operand:QI 0 "register_operand" "")
6034 (le:QI (cc0) (const_int 0)))]
6036 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6038 (define_expand "sleu"
6040 (set (match_operand:QI 0 "register_operand" "")
6041 (leu:QI (cc0) (const_int 0)))]
6043 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6045 ;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may
6046 ;; not have any input reloads. A MEM write might need an input reload
6047 ;; for the address of the MEM. So don't allow MEM as the SET_DEST.
6049 (define_insn "*setcc"
6050 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6051 (match_operator:QI 1 "comparison_operator" [(cc0) (const_int 0)]))]
6052 "reload_completed || register_operand (operands[0], QImode)"
6055 enum rtx_code code = GET_CODE (operands[1]);
6056 if (cc_prev_status.flags & CC_TEST_AX)
6060 operands[2] = gen_rtx_REG (SImode, 0);
6090 if (!TARGET_PENTIUM || optimize_size)
6092 operands[3] = GEN_INT (c >> 8);
6093 output_asm_insn (AS2 (test%B0,%3,%h2), operands);
6097 operands[3] = GEN_INT (c);
6098 output_asm_insn (AS2 (test%L0,%3,%2), operands);
6100 return eq ? AS1 (sete,%0) : AS1 (setne, %0);
6103 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
6105 return AS1(set%D1,%0);
6109 ;; Basic conditional jump instructions.
6110 ;; We ignore the overflow flag for signed branch instructions.
6112 ;; For all bCOND expanders, also expand the compare or test insn that
6113 ;; generates cc0. Generate an equality comparison if `beq' or `bne'.
6115 (define_expand "beq"
6118 (if_then_else (eq (cc0)
6120 (label_ref (match_operand 0 "" ""))
6126 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
6127 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
6129 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
6132 (define_expand "bne"
6135 (if_then_else (ne (cc0)
6137 (label_ref (match_operand 0 "" ""))
6143 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
6144 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
6146 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
6150 (define_expand "bgt"
6153 (if_then_else (gt (cc0)
6155 (label_ref (match_operand 0 "" ""))
6158 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6160 (define_expand "bgtu"
6163 (if_then_else (gtu (cc0)
6165 (label_ref (match_operand 0 "" ""))
6168 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6170 (define_expand "blt"
6173 (if_then_else (lt (cc0)
6175 (label_ref (match_operand 0 "" ""))
6178 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6181 (define_expand "bltu"
6184 (if_then_else (ltu (cc0)
6186 (label_ref (match_operand 0 "" ""))
6189 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6191 (define_expand "bge"
6194 (if_then_else (ge (cc0)
6196 (label_ref (match_operand 0 "" ""))
6199 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6201 (define_expand "bgeu"
6204 (if_then_else (geu (cc0)
6206 (label_ref (match_operand 0 "" ""))
6209 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6211 (define_expand "ble"
6214 (if_then_else (le (cc0)
6216 (label_ref (match_operand 0 "" ""))
6219 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6221 (define_expand "bleu"
6224 (if_then_else (leu (cc0)
6226 (label_ref (match_operand 0 "" ""))
6229 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6233 (if_then_else (match_operator 0 "comparison_operator"
6234 [(cc0) (const_int 0)])
6235 (label_ref (match_operand 1 "" ""))
6240 enum rtx_code code = GET_CODE (operands[0]);
6241 if (cc_prev_status.flags & CC_TEST_AX)
6245 operands[2] = gen_rtx_REG (SImode, 0);
6275 if (!TARGET_PENTIUM || optimize_size)
6277 operands[3] = GEN_INT (c >> 8);
6278 output_asm_insn (AS2 (test%B0,%3,%h2), operands);
6282 operands[3] = GEN_INT (c);
6283 output_asm_insn (AS2 (test%L0,%3,%2), operands);
6285 return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
6287 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
6290 return AS1(j%D0,%l1);
6295 (if_then_else (match_operator 0 "comparison_operator"
6296 [(cc0) (const_int 0)])
6298 (label_ref (match_operand 1 "" ""))))]
6302 enum rtx_code code = GET_CODE (operands[0]);
6303 if (cc_prev_status.flags & CC_TEST_AX)
6307 operands[2] = gen_rtx_REG (SImode, 0);
6337 if (!TARGET_PENTIUM || optimize_size)
6339 operands[3] = GEN_INT (c >> 8);
6340 output_asm_insn (AS2 (test%B0,%3,%h2), operands);
6344 operands[3] = GEN_INT (c);
6345 output_asm_insn (AS2 (test%L0,%3,%2), operands);
6347 return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
6349 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
6352 return AS1(j%d0,%l1);
6355 ;; Unconditional and other jump instructions
6359 (label_ref (match_operand 0 "" "")))]
6362 [(set_attr "memory" "none")])
6364 (define_insn "indirect_jump"
6365 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
6371 return AS1 (jmp,%*%0);
6373 [(set_attr "memory" "none")])
6375 ;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
6376 ;; if S does not change i
6378 (define_expand "decrement_and_branch_until_zero"
6379 [(parallel [(set (pc)
6380 (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "")
6383 (label_ref (match_operand 1 "" ""))
6386 (plus:SI (match_dup 0)
6393 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
6394 [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+c*r,m")
6395 (match_operand:SI 2 "general_operand" "rmi,ri"))
6397 (label_ref (match_operand 3 "" ""))
6400 (plus:SI (match_dup 1)
6407 if (GET_CODE (operands[1]) == REG && REGNO (operands[2]) == 2 &&
6408 operands[2] == constm1_rtx && ix86_cpu == PROCESSOR_K6)
6409 return \"loop %l3\";
6411 if (operands[2] == constm1_rtx)
6412 output_asm_insn (AS1 (dec%L1,%1), operands);
6414 else if (operands[2] == const1_rtx)
6415 output_asm_insn (AS1 (inc%L1,%1), operands);
6418 output_asm_insn (AS2 (add%L1,%2,%1), operands);
6420 return AS1 (%J0,%l3);
6425 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
6426 [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
6427 (match_operand:SI 2 "general_operand" "rmi,ri"))
6429 (label_ref (match_operand 3 "" ""))
6432 (minus:SI (match_dup 1)
6438 if (operands[2] == const1_rtx)
6439 output_asm_insn (AS1 (dec%L1,%1), operands);
6441 else if (operands[1] == constm1_rtx)
6442 output_asm_insn (AS1 (inc%L1,%1), operands);
6445 output_asm_insn (AS2 (sub%L1,%2,%1), operands);
6447 return AS1 (%J0,%l3);
6452 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6454 (label_ref (match_operand 1 "" ""))
6457 (plus:SI (match_dup 0)
6463 operands[2] = const1_rtx;
6464 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6470 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6472 (label_ref (match_operand 1 "" ""))
6475 (plus:SI (match_dup 0)
6481 operands[2] = const1_rtx;
6482 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6488 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6490 (label_ref (match_operand 1 "" ""))
6493 (plus:SI (match_dup 0)
6499 output_asm_insn (AS1 (dec%L0,%0), operands);
6505 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6507 (label_ref (match_operand 1 "" ""))
6510 (plus:SI (match_dup 0)
6516 output_asm_insn (AS1 (dec%L0,%0), operands);
6522 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6524 (label_ref (match_operand 1 "" ""))
6527 (plus:SI (match_dup 0)
6533 output_asm_insn (AS1 (inc%L0,%0), operands);
6539 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6541 (label_ref (match_operand 1 "" ""))
6544 (plus:SI (match_dup 0)
6550 output_asm_insn (AS1 (inc%L0,%0), operands);
6554 ;; Implement switch statements when generating PIC code. Switches are
6555 ;; implemented by `tablejump' when not using -fpic.
6557 ;; Emit code here to do the range checking and make the index zero based.
6559 (define_expand "casesi"
6561 (match_operand:SI 0 "general_operand" ""))
6563 (minus:SI (match_dup 5)
6564 (match_operand:SI 1 "general_operand" "")))
6566 (compare:CC (match_dup 6)
6567 (match_operand:SI 2 "general_operand" "")))
6569 (if_then_else (gtu (cc0)
6571 (label_ref (match_operand 4 "" ""))
6575 (minus:SI (reg:SI 3)
6576 (mem:SI (plus:SI (mult:SI (match_dup 6)
6578 (label_ref (match_operand 3 "" ""))))))
6579 (clobber (match_scratch:SI 7 ""))])]
6583 operands[5] = gen_reg_rtx (SImode);
6584 operands[6] = gen_reg_rtx (SImode);
6585 current_function_uses_pic_offset_table = 1;
6588 ;; Implement a casesi insn.
6590 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
6593 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
6595 ;; 1. An expression involving an external reference may only use the
6596 ;; addition operator, and only with an assembly-time constant.
6597 ;; The example above satisfies this because ".-.L2" is a constant.
6599 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
6600 ;; given the value of "GOT - .", where GOT is the actual address of
6601 ;; the Global Offset Table. Therefore, the .long above actually
6602 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
6603 ;; expression "GOT - .L2" by itself would generate an error from as(1).
6605 ;; The pattern below emits code that looks like this:
6608 ;; subl TABLE@GOTOFF(%ebx,index,4),reg
6611 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
6612 ;; the addr_diff_vec is known to be part of this module.
6614 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
6615 ;; evaluates to just ".L2".
6619 (minus:SI (reg:SI 3)
6621 (mult:SI (match_operand:SI 0 "register_operand" "r")
6623 (label_ref (match_operand 1 "" ""))))))
6624 (clobber (match_scratch:SI 2 "=&r"))]
6630 xops[0] = operands[0];
6631 xops[1] = operands[1];
6632 xops[2] = operands[2];
6633 xops[3] = pic_offset_table_rtx;
6635 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
6636 output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
6637 output_asm_insn (AS1 (jmp,%*%2), xops);
6638 ASM_OUTPUT_ALIGN (asm_out_file, i386_align_jumps);
6642 (define_insn "tablejump"
6643 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
6644 (use (label_ref (match_operand 1 "" "")))]
6650 return AS1 (jmp,%*%0);
6655 ;; If generating PIC code, the predicate indirect_operand will fail
6656 ;; for operands[0] containing symbolic references on all of the named
6657 ;; call* patterns. Each named pattern is followed by an unnamed pattern
6658 ;; that matches any call to a symbolic CONST (ie, a symbol_ref). The
6659 ;; unnamed patterns are only used while generating PIC code, because
6660 ;; otherwise the named patterns match.
6662 ;; Call subroutine returning no value.
6664 (define_expand "call_pop"
6665 [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
6666 (match_operand:SI 1 "general_operand" ""))
6669 (match_operand:SI 3 "immediate_operand" "")))])]
6675 if (operands[3] == const0_rtx)
6677 emit_insn (gen_call (operands[0], operands[1]));
6682 current_function_uses_pic_offset_table = 1;
6684 /* With half-pic, force the address into a register. */
6685 addr = XEXP (operands[0], 0);
6686 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6687 XEXP (operands[0], 0) = force_reg (Pmode, addr);
6689 if (! expander_call_insn_operand (operands[0], QImode))
6691 = change_address (operands[0], VOIDmode,
6692 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
6696 [(call (match_operand:QI 0 "call_insn_operand" "m")
6697 (match_operand:SI 1 "general_operand" "g"))
6698 (set (reg:SI 7) (plus:SI (reg:SI 7)
6699 (match_operand:SI 3 "immediate_operand" "i")))]
6703 if (GET_CODE (operands[0]) == MEM
6704 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6706 operands[0] = XEXP (operands[0], 0);
6707 return AS1 (call,%*%0);
6710 return AS1 (call,%P0);
6714 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6715 (match_operand:SI 1 "general_operand" "g"))
6716 (set (reg:SI 7) (plus:SI (reg:SI 7)
6717 (match_operand:SI 3 "immediate_operand" "i")))]
6721 (define_expand "call"
6722 [(call (match_operand:QI 0 "indirect_operand" "")
6723 (match_operand:SI 1 "general_operand" ""))]
6724 ;; Operand 1 not used on the i386.
6731 current_function_uses_pic_offset_table = 1;
6733 /* With half-pic, force the address into a register. */
6734 addr = XEXP (operands[0], 0);
6735 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6736 XEXP (operands[0], 0) = force_reg (Pmode, addr);
6738 if (! expander_call_insn_operand (operands[0], QImode))
6740 = change_address (operands[0], VOIDmode,
6741 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
6745 [(call (match_operand:QI 0 "call_insn_operand" "m")
6746 (match_operand:SI 1 "general_operand" "g"))]
6747 ;; Operand 1 not used on the i386.
6751 if (GET_CODE (operands[0]) == MEM
6752 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6754 operands[0] = XEXP (operands[0], 0);
6755 return AS1 (call,%*%0);
6758 return AS1 (call,%P0);
6762 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6763 (match_operand:SI 1 "general_operand" "g"))]
6764 ;; Operand 1 not used on the i386.
6768 ;; Call subroutine, returning value in operand 0
6769 ;; (which must be a hard register).
6771 (define_expand "call_value_pop"
6772 [(parallel [(set (match_operand 0 "" "")
6773 (call (match_operand:QI 1 "indirect_operand" "")
6774 (match_operand:SI 2 "general_operand" "")))
6777 (match_operand:SI 4 "immediate_operand" "")))])]
6783 if (operands[4] == const0_rtx)
6785 emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
6790 current_function_uses_pic_offset_table = 1;
6792 /* With half-pic, force the address into a register. */
6793 addr = XEXP (operands[1], 0);
6794 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6795 XEXP (operands[1], 0) = force_reg (Pmode, addr);
6797 if (! expander_call_insn_operand (operands[1], QImode))
6799 = change_address (operands[1], VOIDmode,
6800 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
6804 [(set (match_operand 0 "" "=rf")
6805 (call (match_operand:QI 1 "call_insn_operand" "m")
6806 (match_operand:SI 2 "general_operand" "g")))
6807 (set (reg:SI 7) (plus:SI (reg:SI 7)
6808 (match_operand:SI 4 "immediate_operand" "i")))]
6812 if (GET_CODE (operands[1]) == MEM
6813 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6815 operands[1] = XEXP (operands[1], 0);
6816 output_asm_insn (AS1 (call,%*%1), operands);
6819 output_asm_insn (AS1 (call,%P1), operands);
6825 [(set (match_operand 0 "" "=rf")
6826 (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6827 (match_operand:SI 2 "general_operand" "g")))
6828 (set (reg:SI 7) (plus:SI (reg:SI 7)
6829 (match_operand:SI 4 "immediate_operand" "i")))]
6833 (define_expand "call_value"
6834 [(set (match_operand 0 "" "")
6835 (call (match_operand:QI 1 "indirect_operand" "")
6836 (match_operand:SI 2 "general_operand" "")))]
6837 ;; Operand 2 not used on the i386.
6844 current_function_uses_pic_offset_table = 1;
6846 /* With half-pic, force the address into a register. */
6847 addr = XEXP (operands[1], 0);
6848 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6849 XEXP (operands[1], 0) = force_reg (Pmode, addr);
6851 if (! expander_call_insn_operand (operands[1], QImode))
6853 = change_address (operands[1], VOIDmode,
6854 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
6858 [(set (match_operand 0 "" "=rf")
6859 (call (match_operand:QI 1 "call_insn_operand" "m")
6860 (match_operand:SI 2 "general_operand" "g")))]
6861 ;; Operand 2 not used on the i386.
6865 if (GET_CODE (operands[1]) == MEM
6866 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6868 operands[1] = XEXP (operands[1], 0);
6869 output_asm_insn (AS1 (call,%*%1), operands);
6872 output_asm_insn (AS1 (call,%P1), operands);
6878 [(set (match_operand 0 "" "=rf")
6879 (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6880 (match_operand:SI 2 "general_operand" "g")))]
6881 ;; Operand 2 not used on the i386.
6885 ;; Call subroutine returning any type.
6887 (define_expand "untyped_call"
6888 [(parallel [(call (match_operand 0 "" "")
6890 (match_operand 1 "" "")
6891 (match_operand 2 "" "")])]
6897 /* In order to give reg-stack an easier job in validating two
6898 coprocessor registers as containing a possible return value,
6899 simply pretend the untyped call returns a complex long double
6902 emit_call_insn (TARGET_80387
6903 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
6904 operands[0], const0_rtx)
6905 : gen_call (operands[0], const0_rtx));
6907 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6909 rtx set = XVECEXP (operands[2], 0, i);
6910 emit_move_insn (SET_DEST (set), SET_SRC (set));
6913 /* The optimizer does not know that the call sets the function value
6914 registers we stored in the result block. We avoid problems by
6915 claiming that all hard registers are used and clobbered at this
6917 emit_insn (gen_blockage ());
6922 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6923 ;; all of memory. This blocks insns from being moved across this point.
6925 (define_insn "blockage"
6926 [(unspec_volatile [(const_int 0)] 0)]
6929 [(set_attr "memory" "none")])
6931 ;; Insn emitted into the body of a function to return from a function.
6932 ;; This is only done if the function's epilogue is known to be simple.
6933 ;; See comments for simple_386_epilogue in i386.c.
6935 (define_expand "return"
6937 "ix86_can_use_return_insn_p ()"
6940 (define_insn "return_internal"
6944 [(set_attr "memory" "none")])
6946 (define_insn "return_pop_internal"
6948 (use (match_operand:SI 0 "const_int_operand" ""))]
6951 [(set_attr "memory" "none")])
6957 [(set_attr "memory" "none")])
6959 (define_expand "prologue"
6964 ix86_expand_prologue ();
6968 ;; The use of UNSPEC here is currently not necessary - a simple SET of ebp
6969 ;; to itself would be enough. But this way we are safe even if some optimizer
6970 ;; becomes too clever in the future.
6971 (define_insn "prologue_set_stack_ptr"
6973 (minus:SI (reg:SI 7) (match_operand:SI 0 "immediate_operand" "i")))
6974 (set (reg:SI 6) (unspec:SI [(reg:SI 6)] 4))]
6980 xops[0] = operands[0];
6981 xops[1] = stack_pointer_rtx;
6982 output_asm_insn (AS2 (sub%L1,%0,%1), xops);
6985 [(set_attr "memory" "none")])
6987 (define_insn "prologue_set_got"
6988 [(set (match_operand:SI 0 "" "")
6990 [(plus:SI (match_dup 0)
6991 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
6992 (minus:SI (pc) (match_operand 2 "" ""))))] 1))]
6998 if (TARGET_DEEP_BRANCH_PREDICTION)
7000 sprintf (buffer, \"addl %s,%%0\", XSTR (operands[1], 0));
7001 output_asm_insn (buffer, operands);
7005 sprintf (buffer, \"addl %s+[.-%%X2],%%0\", XSTR (operands[1], 0));
7006 output_asm_insn (buffer, operands);
7011 (define_insn "prologue_get_pc"
7012 [(set (match_operand:SI 0 "" "")
7013 (unspec_volatile [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
7017 output_asm_insn (AS1 (call,%X1), operands);
7018 if (! TARGET_DEEP_BRANCH_PREDICTION)
7020 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1]));
7024 [(set_attr "memory" "none")])
7026 (define_insn "prologue_get_pc_and_set_got"
7027 [(unspec_volatile [(match_operand:SI 0 "" "")] 3)]
7031 operands[1] = gen_label_rtx ();
7032 output_asm_insn (AS1 (call,%X1), operands);
7033 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
7034 CODE_LABEL_NUMBER (operands[1]));
7035 output_asm_insn (AS1 (pop%L0,%0), operands);
7036 output_asm_insn (\"addl $%__GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands);
7039 [(set_attr "memory" "none")])
7041 (define_expand "epilogue"
7046 ix86_expand_epilogue ();
7050 (define_insn "epilogue_set_stack_ptr"
7051 [(set (reg:SI 7) (reg:SI 6))
7052 (clobber (reg:SI 6))]
7058 xops[0] = frame_pointer_rtx;
7059 xops[1] = stack_pointer_rtx;
7060 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
7063 [(set_attr "memory" "none")])
7065 (define_insn "leave"
7067 (clobber (reg:SI 6))
7068 (clobber (reg:SI 7))]
7071 [(set_attr "memory" "none")])
7074 [(set (match_operand:SI 0 "register_operand" "r")
7075 (mem:SI (reg:SI 7)))
7076 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))]
7080 output_asm_insn (AS1 (pop%L0,%P0), operands);
7083 [(set_attr "memory" "load")])
7085 (define_expand "movstrsi"
7086 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
7087 (match_operand:BLK 1 "memory_operand" ""))
7088 (use (match_operand:SI 2 "const_int_operand" ""))
7089 (use (match_operand:SI 3 "const_int_operand" ""))
7090 (clobber (match_scratch:SI 4 ""))
7091 (clobber (match_dup 5))
7092 (clobber (match_dup 6))])]
7098 if (GET_CODE (operands[2]) != CONST_INT)
7101 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7102 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
7104 operands[5] = addr0;
7105 operands[6] = addr1;
7107 operands[0] = change_address (operands[0], VOIDmode, addr0);
7108 operands[1] = change_address (operands[1], VOIDmode, addr1);
7111 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7112 ;; But strength reduction might offset the MEM expression. So we let
7113 ;; reload put the address into %edi & %esi.
7116 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
7117 (mem:BLK (match_operand:SI 1 "address_operand" "S")))
7118 (use (match_operand:SI 2 "const_int_operand" "n"))
7119 (use (match_operand:SI 3 "immediate_operand" "i"))
7120 (clobber (match_scratch:SI 4 "=&c"))
7121 (clobber (match_dup 0))
7122 (clobber (match_dup 1))]
7128 output_asm_insn (\"cld\", operands);
7129 if (GET_CODE (operands[2]) == CONST_INT)
7131 if (INTVAL (operands[2]) & ~0x03)
7133 xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
7134 xops[1] = operands[4];
7136 output_asm_insn (AS2 (mov%L1,%0,%1), xops);
7138 output_asm_insn (\"rep movsd\", xops);
7140 output_asm_insn (\"rep\;movsl\", xops);
7143 if (INTVAL (operands[2]) & 0x02)
7144 output_asm_insn (\"movsw\", operands);
7145 if (INTVAL (operands[2]) & 0x01)
7146 output_asm_insn (\"movsb\", operands);
7153 (define_expand "clrstrsi"
7154 [(set (match_dup 3) (const_int 0))
7155 (parallel [(set (match_operand:BLK 0 "memory_operand" "")
7157 (use (match_operand:SI 1 "const_int_operand" ""))
7158 (use (match_operand:SI 2 "const_int_operand" ""))
7160 (clobber (match_scratch:SI 4 ""))
7161 (clobber (match_dup 5))])]
7167 if (GET_CODE (operands[1]) != CONST_INT)
7170 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7172 operands[3] = gen_reg_rtx (SImode);
7173 operands[5] = addr0;
7175 operands[0] = gen_rtx_MEM (BLKmode, addr0);
7178 ;; It might seem that operand 0 could use predicate register_operand.
7179 ;; But strength reduction might offset the MEM expression. So we let
7180 ;; reload put the address into %edi.
7182 (define_insn "*bzero"
7183 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
7185 (use (match_operand:SI 1 "const_int_operand" "n"))
7186 (use (match_operand:SI 2 "immediate_operand" "i"))
7187 (use (match_operand:SI 3 "register_operand" "a"))
7188 (clobber (match_scratch:SI 4 "=&c"))
7189 (clobber (match_dup 0))]
7195 output_asm_insn (\"cld\", operands);
7196 if (GET_CODE (operands[1]) == CONST_INT)
7198 unsigned int count = INTVAL (operands[1]) & 0xffffffff;
7201 xops[0] = GEN_INT (count / 4);
7202 xops[1] = operands[4];
7204 /* K6: stos takes 1 cycle, rep stos takes 8 + %ecx cycles.
7205 80386: 4/5+5n (+2 for set of ecx)
7206 80486: 5/7+5n (+1 for set of ecx)
7208 if (count / 4 < ((int) ix86_cpu < (int)PROCESSOR_PENTIUM ? 4 : 6))
7212 output_asm_insn (\"stosd\", xops);
7214 output_asm_insn (\"stosl\", xops);
7216 while ((count -= 4) > 3);
7220 output_asm_insn (AS2 (mov%L1,%0,%1), xops);
7222 output_asm_insn (\"rep stosd\", xops);
7224 output_asm_insn (\"rep\;stosl\", xops);
7228 if (INTVAL (operands[1]) & 0x02)
7229 output_asm_insn (\"stosw\", operands);
7230 if (INTVAL (operands[1]) & 0x01)
7231 output_asm_insn (\"stosb\", operands);
7238 (define_expand "cmpstrsi"
7239 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7240 (compare:SI (match_operand:BLK 1 "general_operand" "")
7241 (match_operand:BLK 2 "general_operand" "")))
7242 (use (match_operand:SI 3 "general_operand" ""))
7243 (use (match_operand:SI 4 "immediate_operand" ""))
7244 (clobber (match_dup 5))
7245 (clobber (match_dup 6))
7246 (clobber (match_dup 3))])]
7252 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
7253 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
7254 operands[3] = copy_to_mode_reg (SImode, operands[3]);
7256 operands[5] = addr1;
7257 operands[6] = addr2;
7259 operands[1] = gen_rtx_MEM (BLKmode, addr1);
7260 operands[2] = gen_rtx_MEM (BLKmode, addr2);
7264 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
7265 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
7267 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7268 ;; But strength reduction might offset the MEM expression. So we let
7269 ;; reload put the address into %edi & %esi.
7271 ;; ??? Most comparisons have a constant length, and it's therefore
7272 ;; possible to know that the length is non-zero, and to avoid the extra
7273 ;; code to handle zero-length compares.
7276 [(set (match_operand:SI 0 "register_operand" "=&r")
7277 (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
7278 (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
7279 (use (match_operand:SI 3 "register_operand" "c"))
7280 (use (match_operand:SI 4 "immediate_operand" "i"))
7281 (clobber (match_dup 1))
7282 (clobber (match_dup 2))
7283 (clobber (match_dup 3))]
7289 label = gen_label_rtx ();
7291 output_asm_insn (\"cld\", operands);
7292 output_asm_insn (AS2 (xor%L0,%0,%0), operands);
7293 output_asm_insn (\"repz\;cmps%B2\", operands);
7294 output_asm_insn (\"je %l0\", &label);
7296 xops[0] = operands[0];
7297 xops[1] = const1_rtx;
7298 output_asm_insn (AS2 (sbb%L0,%0,%0), xops);
7299 if (QI_REG_P (xops[0]))
7300 output_asm_insn (AS2 (or%B0,%1,%b0), xops);
7302 output_asm_insn (AS2 (or%L0,%1,%0), xops);
7304 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
7310 (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
7311 (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
7312 (use (match_operand:SI 2 "register_operand" "c"))
7313 (use (match_operand:SI 3 "immediate_operand" "i"))
7314 (clobber (match_dup 0))
7315 (clobber (match_dup 1))
7316 (clobber (match_dup 2))]
7322 cc_status.flags |= CC_NOT_SIGNED;
7324 xops[0] = gen_rtx_REG (QImode, 0);
7325 xops[1] = CONST0_RTX (QImode);
7327 output_asm_insn (\"cld\", operands);
7328 output_asm_insn (AS2 (test%B0,%1,%0), xops);
7329 return \"repz\;cmps%B2\";
7333 ;; Note, you cannot optimize away the branch following the bsfl by assuming
7334 ;; that the destination is not modified if the input is 0, since not all
7335 ;; x86 implementations do this.
7337 (define_expand "ffssi2"
7338 [(set (match_operand:SI 0 "general_operand" "")
7339 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
7343 rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode);
7345 emit_insn (gen_ffssi_1 (temp, operands[1]));
7346 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0);
7347 emit_jump_insn (gen_bne (label));
7348 emit_move_insn (temp, constm1_rtx);
7350 temp = expand_binop (SImode, add_optab, temp, const1_rtx,
7351 operands[0], 0, OPTAB_WIDEN);
7353 if (temp != operands[0])
7354 emit_move_insn (operands[0], temp);
7358 (define_insn "ffssi_1"
7359 [(set (match_operand:SI 0 "register_operand" "=r")
7360 (unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
7362 "* return AS2 (bsf%L0,%1,%0);")
7364 (define_expand "ffshi2"
7365 [(set (match_operand:SI 0 "general_operand" "")
7366 (ffs:HI (match_operand:HI 1 "general_operand" "")))]
7370 rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode);
7372 emit_insn (gen_ffshi_1 (temp, operands[1]));
7373 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0);
7374 emit_jump_insn (gen_bne (label));
7375 emit_move_insn (temp, constm1_rtx);
7377 temp = expand_binop (HImode, add_optab, temp, const1_rtx,
7378 operands[0], 0, OPTAB_WIDEN);
7380 if (temp != operands[0])
7381 emit_move_insn (operands[0], temp);
7385 (define_insn "ffshi_1"
7386 [(set (match_operand:HI 0 "register_operand" "=r")
7387 (unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
7389 "* return AS2 (bsf%W0,%1,%0);")
7391 ;; These patterns match the binary 387 instructions for addM3, subM3,
7392 ;; mulM3 and divM3. There are three patterns for each of DFmode and
7393 ;; SFmode. The first is the normal insn, the second the same insn but
7394 ;; with one operand a conversion, and the third the same insn but with
7395 ;; the other operand a conversion.
7398 [(set (match_operand:DF 0 "register_operand" "=f,f")
7399 (match_operator:DF 3 "binary_387_op"
7400 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
7401 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
7403 "* return output_387_binary_op (insn, operands);"
7405 (cond [(match_operand:DF 3 "is_mul" "")
7406 (const_string "fpmul")
7407 (match_operand:DF 3 "is_div" "")
7408 (const_string "fpdiv")
7410 (const_string "fpop")
7415 [(set (match_operand:XF 0 "register_operand" "=f,f")
7416 (match_operator:XF 3 "binary_387_op"
7417 [(match_operand:XF 1 "register_operand" "0,f")
7418 (match_operand:XF 2 "register_operand" "f,0")]))]
7420 "* return output_387_binary_op (insn, operands);"
7422 (cond [(match_operand:DF 3 "is_mul" "")
7423 (const_string "fpmul")
7424 (match_operand:DF 3 "is_div" "")
7425 (const_string "fpdiv")
7427 (const_string "fpop")
7432 [(set (match_operand:XF 0 "register_operand" "=f,f")
7433 (match_operator:XF 3 "binary_387_op"
7434 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7435 (match_operand:XF 2 "register_operand" "0,f")]))]
7437 "* return output_387_binary_op (insn, operands);"
7439 (cond [(match_operand:DF 3 "is_mul" "")
7440 (const_string "fpmul")
7441 (match_operand:DF 3 "is_div" "")
7442 (const_string "fpdiv")
7444 (const_string "fpop")
7449 [(set (match_operand:XF 0 "register_operand" "=f,f")
7450 (match_operator:XF 3 "binary_387_op"
7451 [(match_operand:XF 1 "register_operand" "0,f")
7453 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7455 "* return output_387_binary_op (insn, operands);"
7457 (cond [(match_operand:DF 3 "is_mul" "")
7458 (const_string "fpmul")
7459 (match_operand:DF 3 "is_div" "")
7460 (const_string "fpdiv")
7462 (const_string "fpop")
7467 [(set (match_operand:DF 0 "register_operand" "=f,f")
7468 (match_operator:DF 3 "binary_387_op"
7469 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7470 (match_operand:DF 2 "register_operand" "0,f")]))]
7472 "* return output_387_binary_op (insn, operands);"
7474 (cond [(match_operand:DF 3 "is_mul" "")
7475 (const_string "fpmul")
7476 (match_operand:DF 3 "is_div" "")
7477 (const_string "fpdiv")
7479 (const_string "fpop")
7484 [(set (match_operand:DF 0 "register_operand" "=f,f")
7485 (match_operator:DF 3 "binary_387_op"
7486 [(match_operand:DF 1 "register_operand" "0,f")
7488 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7490 "* return output_387_binary_op (insn, operands);"
7492 (cond [(match_operand:DF 3 "is_mul" "")
7493 (const_string "fpmul")
7494 (match_operand:DF 3 "is_div" "")
7495 (const_string "fpdiv")
7497 (const_string "fpop")
7502 [(set (match_operand:SF 0 "register_operand" "=f,f")
7503 (match_operator:SF 3 "binary_387_op"
7504 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
7505 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
7507 "* return output_387_binary_op (insn, operands);"
7509 (cond [(match_operand:DF 3 "is_mul" "")
7510 (const_string "fpmul")
7511 (match_operand:DF 3 "is_div" "")
7512 (const_string "fpdiv")
7514 (const_string "fpop")
7518 (define_expand "strlensi"
7519 [(parallel [(set (match_dup 4)
7520 (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
7521 (match_operand:QI 2 "immediate_operand" "")
7522 (match_operand:SI 3 "immediate_operand" "")] 0))
7523 (clobber (match_dup 1))])
7525 (not:SI (match_dup 4)))
7526 (set (match_operand:SI 0 "register_operand" "")
7527 (plus:SI (match_dup 5)
7532 if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1)
7537 /* well it seems that some optimizer does not combine a call like
7538 foo(strlen(bar), strlen(bar));
7539 when the move and the subtraction is done here. It does calculate
7540 the length just once when these instructions are done inside of
7541 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
7542 often used and I use one fewer register for the lifetime of
7543 output_strlen_unroll() this is better. */
7544 scratch = gen_reg_rtx (SImode);
7545 address = force_reg (SImode, XEXP (operands[1], 0));
7547 /* move address to scratch-register
7548 this is done here because the i586 can do the following and
7549 in the same cycle with the following move. */
7550 if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4)
7551 emit_insn (gen_movsi (scratch, address));
7553 emit_insn (gen_movsi (operands[0], address));
7555 if(TARGET_USE_Q_REG)
7556 emit_insn (gen_strlensi_unroll5 (operands[0],
7561 emit_insn (gen_strlensi_unroll4 (operands[0],
7566 /* gen_strlensi_unroll[45] returns the address of the zero
7567 at the end of the string, like memchr(), so compute the
7568 length by subtracting the startaddress. */
7569 emit_insn (gen_subsi3 (operands[0], operands[0], address));
7573 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7574 operands[4] = gen_reg_rtx (SImode);
7575 operands[5] = gen_reg_rtx (SImode);
7578 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7579 ;; But strength reduction might offset the MEM expression. So we let
7580 ;; reload put the address into %edi.
7583 [(set (match_operand:SI 0 "register_operand" "=&c")
7584 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
7585 (match_operand:QI 2 "immediate_operand" "a")
7586 (match_operand:SI 3 "immediate_operand" "i")] 0))
7587 (clobber (match_dup 1))]
7593 xops[0] = operands[0];
7594 xops[1] = constm1_rtx;
7595 output_asm_insn (\"cld\", operands);
7596 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
7597 return \"repnz\;scas%B2\";
7600 /* Conditional move define_insns. */
7602 (define_expand "movsicc"
7603 [(set (match_operand:SI 0 "register_operand" "")
7604 (if_then_else:SI (match_operand 1 "comparison_operator" "")
7605 (match_operand:SI 2 "nonimmediate_operand" "")
7606 (match_operand:SI 3 "nonimmediate_operand" "")))]
7610 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7613 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7614 GET_MODE (i386_compare_op0),
7615 i386_compare_op0, i386_compare_op1);
7619 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
7620 (if_then_else:SI (match_operator 1 "comparison_operator"
7621 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7622 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7623 (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0")
7624 (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7629 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
7630 (if_then_else:SI (match_operator 1 "comparison_operator"
7631 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7632 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7633 (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0")
7634 (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7635 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7639 [(set (match_operand:SI 0 "register_operand" "")
7640 (if_then_else:SI (match_operator 1 "comparison_operator"
7641 [(match_operand 2 "nonimmediate_operand" "")
7643 (match_operand:SI 3 "nonimmediate_operand" "")
7644 (match_operand:SI 4 "nonimmediate_operand" "")))]
7645 "TARGET_CMOVE && reload_completed"
7649 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7650 (match_dup 3) (match_dup 4)))]
7654 [(set (match_operand:SI 0 "register_operand" "")
7655 (if_then_else:SI (match_operator 1 "comparison_operator"
7656 [(match_operand 2 "nonimmediate_operand" "")
7657 (match_operand 3 "general_operand" "")])
7658 (match_operand:SI 4 "nonimmediate_operand" "")
7659 (match_operand:SI 5 "nonimmediate_operand" "")))]
7660 "TARGET_CMOVE && reload_completed"
7661 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7663 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7664 (match_dup 4) (match_dup 5)))]
7668 [(set (match_operand:SI 0 "register_operand" "=r,r")
7669 (if_then_else:SI (match_operator 1 "comparison_operator"
7670 [(cc0) (const_int 0)])
7671 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
7672 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
7673 "TARGET_CMOVE && reload_completed"
7674 "* return output_int_conditional_move (which_alternative, operands);")
7676 (define_expand "movhicc"
7677 [(set (match_operand:HI 0 "register_operand" "")
7678 (if_then_else:HI (match_operand 1 "comparison_operator" "")
7679 (match_operand:HI 2 "nonimmediate_operand" "")
7680 (match_operand:HI 3 "nonimmediate_operand" "")))]
7684 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7687 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7688 GET_MODE (i386_compare_op0),
7689 i386_compare_op0, i386_compare_op1);
7693 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
7694 (if_then_else:HI (match_operator 1 "comparison_operator"
7695 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7696 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7697 (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0")
7698 (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7703 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
7704 (if_then_else:HI (match_operator 1 "comparison_operator"
7705 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7706 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7707 (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0")
7708 (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7709 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7713 [(set (match_operand:HI 0 "register_operand" "")
7714 (if_then_else:HI (match_operator 1 "comparison_operator"
7715 [(match_operand 2 "nonimmediate_operand" "")
7717 (match_operand:HI 3 "nonimmediate_operand" "")
7718 (match_operand:HI 4 "nonimmediate_operand" "")))]
7719 "TARGET_CMOVE && reload_completed"
7723 (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7724 (match_dup 3) (match_dup 4)))]
7728 [(set (match_operand:HI 0 "register_operand" "")
7729 (if_then_else:HI (match_operator 1 "comparison_operator"
7730 [(match_operand 2 "nonimmediate_operand" "")
7731 (match_operand 3 "general_operand" "")])
7732 (match_operand:HI 4 "nonimmediate_operand" "")
7733 (match_operand:HI 5 "nonimmediate_operand" "")))]
7734 "TARGET_CMOVE && reload_completed"
7736 (compare (match_dup 2) (match_dup 3)))
7738 (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7739 (match_dup 4) (match_dup 5)))]
7743 [(set (match_operand:HI 0 "register_operand" "=r,r")
7744 (if_then_else:HI (match_operator 1 "comparison_operator"
7745 [(cc0) (const_int 0)])
7746 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
7747 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
7748 "TARGET_CMOVE && reload_completed"
7749 "* return output_int_conditional_move (which_alternative, operands);")
7751 (define_expand "movsfcc"
7752 [(set (match_operand:SF 0 "register_operand" "")
7753 (if_then_else:SF (match_operand 1 "comparison_operator" "")
7754 (match_operand:SF 2 "register_operand" "")
7755 (match_operand:SF 3 "register_operand" "")))]
7761 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7764 /* The floating point conditional move instructions don't directly
7765 support conditions resulting from a signed integer comparison. */
7767 switch (GET_CODE (operands[1]))
7773 temp = emit_store_flag (gen_reg_rtx (QImode),
7774 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7780 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7784 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7785 GET_MODE (i386_compare_op0),
7786 i386_compare_op0, i386_compare_op1);
7792 [(set (match_operand:SF 0 "register_operand" "=f,f,f,f")
7793 (if_then_else:SF (match_operator 1 "comparison_operator"
7794 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7795 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7796 (match_operand:SF 4 "register_operand" "f,f,0,0")
7797 (match_operand:SF 5 "register_operand" "0,0,f,f")))]
7799 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7800 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7804 [(set (match_operand:SF 0 "register_operand" "=f,f,f,f")
7805 (if_then_else:SF (match_operator 1 "comparison_operator"
7806 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7807 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7808 (match_operand:SF 4 "register_operand" "f,f,0,0")
7809 (match_operand:SF 5 "register_operand" "0,0,f,f")))]
7810 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7811 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7812 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7816 [(set (match_operand:SF 0 "register_operand" "")
7817 (if_then_else:SF (match_operator 1 "comparison_operator"
7818 [(match_operand 2 "nonimmediate_operand" "")
7820 (match_operand:SF 3 "register_operand" "")
7821 (match_operand:SF 4 "register_operand" "")))]
7822 "TARGET_CMOVE && reload_completed"
7826 (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7827 (match_dup 3) (match_dup 4)))]
7831 [(set (match_operand:SF 0 "register_operand" "")
7832 (if_then_else:SF (match_operator 1 "comparison_operator"
7833 [(match_operand 2 "nonimmediate_operand" "")
7834 (match_operand 3 "general_operand" "")])
7835 (match_operand:SF 4 "register_operand" "")
7836 (match_operand:SF 5 "register_operand" "")))]
7837 "TARGET_CMOVE && reload_completed"
7838 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7840 (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7841 (match_dup 4) (match_dup 5)))]
7845 [(set (match_operand:SF 0 "register_operand" "=f,f")
7846 (if_then_else:SF (match_operator 1 "comparison_operator"
7847 [(cc0) (const_int 0)])
7848 (match_operand:SF 2 "register_operand" "f,0")
7849 (match_operand:SF 3 "register_operand" "0,f")))]
7850 "TARGET_CMOVE && reload_completed"
7851 "* return output_fp_conditional_move (which_alternative, operands);")
7853 (define_expand "movdfcc"
7854 [(set (match_operand:DF 0 "register_operand" "")
7855 (if_then_else:DF (match_operand 1 "comparison_operator" "")
7856 (match_operand:DF 2 "register_operand" "")
7857 (match_operand:DF 3 "register_operand" "")))]
7863 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7866 /* The floating point conditional move instructions don't directly
7867 support conditions resulting from a signed integer comparison. */
7869 switch (GET_CODE (operands[1]))
7875 temp = emit_store_flag (gen_reg_rtx (QImode),
7876 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7882 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7886 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7887 GET_MODE (i386_compare_op0),
7888 i386_compare_op0, i386_compare_op1);
7894 [(set (match_operand:DF 0 "register_operand" "=f,f,f,f")
7895 (if_then_else:DF (match_operator 1 "comparison_operator"
7896 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7897 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7898 (match_operand:DF 4 "register_operand" "f,f,0,0")
7899 (match_operand:DF 5 "register_operand" "0,0,f,f")))]
7901 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7902 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7906 [(set (match_operand:DF 0 "register_operand" "=f,f,f,f")
7907 (if_then_else:DF (match_operator 1 "comparison_operator"
7908 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7909 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7910 (match_operand:DF 4 "register_operand" "f,f,0,0")
7911 (match_operand:DF 5 "register_operand" "0,0,f,f")))]
7912 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7913 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7914 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7918 [(set (match_operand:DF 0 "register_operand" "")
7919 (if_then_else:DF (match_operator 1 "comparison_operator"
7920 [(match_operand 2 "nonimmediate_operand" "")
7922 (match_operand:DF 3 "register_operand" "")
7923 (match_operand:DF 4 "register_operand" "")))]
7924 "TARGET_CMOVE && reload_completed"
7928 (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7929 (match_dup 3) (match_dup 4)))]
7933 [(set (match_operand:DF 0 "register_operand" "")
7934 (if_then_else:DF (match_operator 1 "comparison_operator"
7935 [(match_operand 2 "nonimmediate_operand" "")
7936 (match_operand 3 "general_operand" "")])
7937 (match_operand:DF 4 "register_operand" "")
7938 (match_operand:DF 5 "register_operand" "")))]
7939 "TARGET_CMOVE && reload_completed"
7940 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7942 (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7943 (match_dup 4) (match_dup 5)))]
7947 [(set (match_operand:DF 0 "register_operand" "=f,f")
7948 (if_then_else:DF (match_operator 1 "comparison_operator"
7949 [(cc0) (const_int 0)])
7950 (match_operand:DF 2 "register_operand" "f,0")
7951 (match_operand:DF 3 "register_operand" "0,f")))]
7952 "TARGET_CMOVE && reload_completed"
7953 "* return output_fp_conditional_move (which_alternative, operands);")
7955 (define_expand "movxfcc"
7956 [(set (match_operand:XF 0 "register_operand" "")
7957 (if_then_else:XF (match_operand 1 "comparison_operator" "")
7958 (match_operand:XF 2 "register_operand" "")
7959 (match_operand:XF 3 "register_operand" "")))]
7965 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7968 /* The floating point conditional move instructions don't directly
7969 support conditions resulting from a signed integer comparison. */
7971 switch (GET_CODE (operands[1]))
7977 temp = emit_store_flag (gen_reg_rtx (QImode),
7978 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7984 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7988 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7989 GET_MODE (i386_compare_op0),
7990 i386_compare_op0, i386_compare_op1);
7996 [(set (match_operand:XF 0 "register_operand" "=f,f,f,f")
7997 (if_then_else:XF (match_operator 1 "comparison_operator"
7998 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7999 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
8000 (match_operand:XF 4 "register_operand" "f,f,0,0")
8001 (match_operand:XF 5 "register_operand" "0,0,f,f")))]
8003 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
8004 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
8008 [(set (match_operand:XF 0 "register_operand" "=f,f,f,f")
8009 (if_then_else:XF (match_operator 1 "comparison_operator"
8010 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
8011 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
8012 (match_operand:XF 4 "register_operand" "f,f,0,0")
8013 (match_operand:XF 5 "register_operand" "0,0,f,f")))]
8014 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
8015 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
8016 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
8020 [(set (match_operand:XF 0 "register_operand" "")
8021 (if_then_else:XF (match_operator 1 "comparison_operator"
8022 [(match_operand 2 "nonimmediate_operand" "")
8024 (match_operand:XF 3 "register_operand" "")
8025 (match_operand:XF 4 "register_operand" "")))]
8026 "TARGET_CMOVE && reload_completed"
8030 (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
8031 (match_dup 3) (match_dup 4)))]
8035 [(set (match_operand:XF 0 "register_operand" "")
8036 (if_then_else:XF (match_operator 1 "comparison_operator"
8037 [(match_operand 2 "nonimmediate_operand" "")
8038 (match_operand 3 "general_operand" "")])
8039 (match_operand:XF 4 "register_operand" "")
8040 (match_operand:XF 5 "register_operand" "")))]
8041 "TARGET_CMOVE && reload_completed"
8042 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
8044 (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
8045 (match_dup 4) (match_dup 5)))]
8049 [(set (match_operand:XF 0 "register_operand" "=f,f")
8050 (if_then_else:XF (match_operator 1 "comparison_operator"
8051 [(cc0) (const_int 0)])
8052 (match_operand:XF 2 "register_operand" "f,0")
8053 (match_operand:XF 3 "register_operand" "0,f")))]
8054 "TARGET_CMOVE && reload_completed"
8055 "* return output_fp_conditional_move (which_alternative, operands);")
8057 (define_expand "movdicc"
8058 [(set (match_operand:DI 0 "register_operand" "")
8059 (if_then_else:DI (match_operand 1 "comparison_operator" "")
8060 (match_operand:DI 2 "nonimmediate_operand" "")
8061 (match_operand:DI 3 "nonimmediate_operand" "")))]
8065 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
8068 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
8069 GET_MODE (i386_compare_op0),
8070 i386_compare_op0, i386_compare_op1);
8074 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r")
8075 (if_then_else:DI (match_operator 1 "comparison_operator"
8076 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
8077 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
8078 (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0")
8079 (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))]
8084 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r")
8085 (if_then_else:DI (match_operator 1 "comparison_operator"
8086 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
8087 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
8088 (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0")
8089 (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))]
8090 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
8094 [(set (match_operand:DI 0 "register_operand" "")
8095 (if_then_else:DI (match_operator 1 "comparison_operator"
8096 [(match_operand 2 "nonimmediate_operand" "")
8098 (match_operand:DI 3 "nonimmediate_operand" "")
8099 (match_operand:DI 4 "nonimmediate_operand" "")))]
8100 "TARGET_CMOVE && reload_completed"
8104 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8105 (match_dup 7) (match_dup 9)))
8107 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8108 (match_dup 8) (match_dup 10)))]
8109 "split_di (&operands[0], 1, &operands[5], &operands[6]);
8110 split_di (&operands[3], 1, &operands[7], &operands[8]);
8111 split_di (&operands[4], 1, &operands[9], &operands[10]);")
8114 [(set (match_operand:DI 0 "register_operand" "")
8115 (if_then_else:DI (match_operator 1 "comparison_operator"
8116 [(match_operand 2 "nonimmediate_operand" "")
8117 (match_operand 3 "general_operand" "")])
8118 (match_operand:DI 4 "nonimmediate_operand" "")
8119 (match_operand:DI 5 "nonimmediate_operand" "")))]
8120 "TARGET_CMOVE && reload_completed"
8121 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
8123 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8124 (match_dup 8) (match_dup 10)))
8126 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8127 (match_dup 9) (match_dup 11)))]
8128 "split_di (&operands[0], 1, &operands[6], &operands[7]);
8129 split_di (&operands[4], 1, &operands[8], &operands[9]);
8130 split_di (&operands[5], 1, &operands[10], &operands[11]);")
8132 (define_insn "strlensi_unroll"
8133 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
8134 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r"))
8135 (match_operand:SI 2 "immediate_operand" "i,i")] 0))
8136 (clobber (match_scratch:SI 3 "=&q,&r"))]
8138 "* return output_strlen_unroll (operands);")
8140 ;; the only difference between the following patterns is the register preference
8141 ;; on a pentium using a q-register saves one clock cycle per 4 characters
8143 (define_insn "strlensi_unroll4"
8144 [(set (match_operand:SI 0 "register_operand" "=r,r")
8145 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0"))
8146 (match_operand:SI 1 "immediate_operand" "i,i")
8147 (match_operand:SI 2 "register_operand" "+q,!r")] 0))
8148 (clobber (match_dup 2))]
8149 "(TARGET_USE_ANY_REG && optimize > 1)"
8150 "* return output_strlen_unroll (operands);")
8152 (define_insn "strlensi_unroll5"
8153 [(set (match_operand:SI 0 "register_operand" "=r")
8154 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0"))
8155 (match_operand:SI 1 "immediate_operand" "i")
8156 (match_operand:SI 2 "register_operand" "+q")] 0))
8157 (clobber (match_dup 2))]
8158 "(TARGET_USE_Q_REG && optimize > 1)"
8159 "* return output_strlen_unroll (operands);"
8162 (define_insn "allocate_stack_worker"
8163 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
8164 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
8165 (clobber (match_dup 0))]
8166 "TARGET_STACK_PROBE"
8167 "* return AS1(call,__alloca);"
8168 [(set_attr "memory" "none")])
8170 (define_expand "allocate_stack"
8171 [(set (match_operand:SI 0 "register_operand" "=r")
8172 (minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" "")))
8173 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))]
8174 "TARGET_STACK_PROBE"
8177 #ifdef CHECK_STACK_LIMIT
8178 if (GET_CODE (operands[1]) == CONST_INT
8179 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
8180 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
8184 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
8187 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
8191 (define_expand "exception_receiver"
8196 load_pic_register (1);
8200 (define_expand "builtin_setjmp_receiver"
8201 [(label_ref (match_operand 0 "" ""))]
8205 load_pic_register (1);