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 $
76 ;; $DragonFly: src/contrib/gcc/config/i386/Attic/i386.md,v 1.2 2003/06/17 04:24:02 dillon Exp $
79 "integer,binary,memory,test,compare,fcompare,idiv,imul,lea,fld,fpop,fpdiv,fpmul"
80 (const_string "integer"))
82 (define_attr "memory" "none,load,store"
83 (cond [(eq_attr "type" "idiv,lea")
86 (eq_attr "type" "fld")
89 (eq_attr "type" "test")
90 (if_then_else (match_operand 0 "memory_operand" "")
92 (const_string "none"))
94 (eq_attr "type" "compare,fcompare")
95 (if_then_else (ior (match_operand 0 "memory_operand" "")
96 (match_operand 1 "memory_operand" ""))
98 (const_string "none"))
100 (and (eq_attr "type" "integer,memory,fpop")
101 (match_operand 0 "memory_operand" ""))
102 (const_string "store")
104 (and (eq_attr "type" "integer,memory,fpop")
105 (match_operand 1 "memory_operand" ""))
106 (const_string "load")
108 (and (eq_attr "type" "binary,imul,fpmul,fpdiv")
109 (ior (match_operand 1 "memory_operand" "")
110 (match_operand 2 "memory_operand" "")))
111 (const_string "load")]
113 (const_string "none")))
117 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
118 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
120 ; pentiumpro has a reservation station with 5 ports
121 ; port 0 has integer, float add, integer divide, float divide, float
122 ; multiply, and shifter units.
123 ; port 1 has integer, and jump units.
124 ; port 2 has the load address generation unit
125 ; ports 3 and 4 have the store address generation units
127 ; pentium has two integer pipelines, the main u pipe and the secondary v pipe.
128 ; and a float pipeline
132 (define_function_unit "fp" 1 0
133 (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "i386,i486"))
136 (define_function_unit "fp" 1 0
137 (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "pentium,pentiumpro"))
140 (define_function_unit "fp" 1 0
141 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentium"))
144 (define_function_unit "fp" 1 0
145 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentiumpro"))
148 (define_function_unit "fp" 1 0
149 (and (eq_attr "type" "idiv") (eq_attr "cpu" "pentiumpro"))
152 (define_function_unit "fp" 1 0
153 (and (eq_attr "type" "imul") (eq_attr "cpu" "pentiumpro"))
156 (define_function_unit "fp" 1 0
157 (eq_attr "type" "fpdiv")
160 (define_function_unit "fp" 1 0
161 (and (eq_attr "type" "fld") (eq_attr "cpu" "!pentiumpro,k6"))
164 ;; K6 FPU is not pipelined.
165 (define_function_unit "fp" 1 0
166 (and (eq_attr "type" "fpop,fpmul,fcompare") (eq_attr "cpu" "k6"))
169 ;; i386 and i486 have one integer unit, which need not be modeled
171 (define_function_unit "integer" 2 0
172 (and (eq_attr "type" "integer,binary,test,compare,lea") (eq_attr "cpu" "pentium,pentiumpro"))
175 (define_function_unit "integer" 2 0
176 (and (eq_attr "cpu" "k6")
177 (and (eq_attr "type" "integer,binary,test,compare")
178 (eq_attr "memory" "!load")))
181 ;; Internally, K6 converts REG OP MEM instructions into a load (2 cycles)
182 ;; and a register operation (1 cycle).
183 (define_function_unit "integer" 2 0
184 (and (eq_attr "cpu" "k6")
185 (and (eq_attr "type" "integer,binary,test,compare")
186 (eq_attr "memory" "load")))
189 ;; Multiplies use one of the integer units
190 (define_function_unit "integer" 2 0
191 (and (eq_attr "cpu" "pentium") (eq_attr "type" "imul"))
194 (define_function_unit "integer" 2 0
195 (and (eq_attr "cpu" "k6") (eq_attr "type" "imul"))
198 (define_function_unit "integer" 2 0
199 (and (eq_attr "cpu" "pentium") (eq_attr "type" "idiv"))
202 (define_function_unit "integer" 2 0
203 (and (eq_attr "cpu" "k6") (eq_attr "type" "idiv"))
206 ;; Pentium Pro and K6 have a separate load unit.
207 (define_function_unit "load" 1 0
208 (and (eq_attr "cpu" "pentiumpro") (eq_attr "memory" "load"))
211 (define_function_unit "load" 1 0
212 (and (eq_attr "cpu" "k6") (eq_attr "memory" "load"))
215 ;; Pentium Pro and K6 have a separate store unit.
216 (define_function_unit "store" 1 0
217 (and (eq_attr "cpu" "pentiumpro,k6") (eq_attr "memory" "store"))
220 ;; lea executes in the K6 store unit with 1 cycle latency
221 (define_function_unit "store" 1 0
222 (and (eq_attr "cpu" "k6") (eq_attr "type" "lea"))
226 ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
227 ;; But restricting MEM here would mean that gcc could not remove a redundant
228 ;; test in cases like "incl MEM / je TARGET".
230 ;; We don't want to allow a constant operand for test insns because
231 ;; (set (cc0) (const_int foo)) has no mode information. Such insns will
232 ;; be folded while optimizing anyway.
234 ;; All test insns have expanders that save the operands away without
235 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
236 ;; after the tstM or cmp) will actually emit the tstM or cmpM.
238 ;; Processor type -- this attribute must exactly match the processor_type
239 ;; enumeration in i386.h.
241 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6"
242 (const (symbol_ref "ix86_cpu")))
244 (define_insn "tstsi_1"
246 (match_operand:SI 0 "nonimmediate_operand" "rm"))]
250 if (REG_P (operands[0]))
251 return AS2 (test%L0,%0,%0);
253 operands[1] = const0_rtx;
254 return AS2 (cmp%L0,%1,%0);
256 [(set_attr "type" "test")])
258 (define_expand "tstsi"
260 (match_operand:SI 0 "nonimmediate_operand" ""))]
264 i386_compare_gen = gen_tstsi_1;
265 i386_compare_op0 = operands[0];
266 i386_compare_op1 = const0_rtx;
270 (define_insn "tsthi_1"
272 (match_operand:HI 0 "nonimmediate_operand" "rm"))]
276 if (REG_P (operands[0]))
277 return AS2 (test%W0,%0,%0);
279 operands[1] = const0_rtx;
280 return AS2 (cmp%W0,%1,%0);
282 [(set_attr "type" "test")])
284 (define_expand "tsthi"
286 (match_operand:HI 0 "nonimmediate_operand" ""))]
290 i386_compare_gen = gen_tsthi_1;
291 i386_compare_op0 = operands[0];
292 i386_compare_op1 = const0_rtx;
296 (define_insn "tstqi_1"
298 (match_operand:QI 0 "nonimmediate_operand" "qm"))]
302 if (REG_P (operands[0]))
303 return AS2 (test%B0,%0,%0);
305 operands[1] = const0_rtx;
306 return AS2 (cmp%B0,%1,%0);
308 [(set_attr "type" "test")])
310 (define_expand "tstqi"
312 (match_operand:QI 0 "nonimmediate_operand" ""))]
316 i386_compare_gen = gen_tstqi_1;
317 i386_compare_op0 = operands[0];
318 i386_compare_op1 = const0_rtx;
322 (define_insn "tstsf_cc"
324 (match_operand:SF 0 "register_operand" "f"))
325 (clobber (match_scratch:HI 1 "=a"))]
326 "TARGET_80387 && ! TARGET_IEEE_FP"
329 if (! STACK_TOP_P (operands[0]))
332 output_asm_insn (\"ftst\", operands);
334 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
335 output_asm_insn (AS1 (fstp,%y0), operands);
337 return output_fp_cc0_set (insn);
339 [(set_attr "type" "test")])
341 ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
342 ;; isn't IEEE compliant.
344 (define_expand "tstsf"
345 [(parallel [(set (cc0)
346 (match_operand:SF 0 "register_operand" ""))
347 (clobber (match_scratch:HI 1 ""))])]
348 "TARGET_80387 && ! TARGET_IEEE_FP"
351 i386_compare_gen = gen_tstsf_cc;
352 i386_compare_op0 = operands[0];
353 i386_compare_op1 = const0_rtx;
357 (define_insn "tstdf_cc"
359 (match_operand:DF 0 "register_operand" "f"))
360 (clobber (match_scratch:HI 1 "=a"))]
361 "TARGET_80387 && ! TARGET_IEEE_FP"
364 if (! STACK_TOP_P (operands[0]))
367 output_asm_insn (\"ftst\", operands);
369 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
370 output_asm_insn (AS1 (fstp,%y0), operands);
372 return output_fp_cc0_set (insn);
374 [(set_attr "type" "test")])
376 ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
377 ;; isn't IEEE compliant.
379 (define_expand "tstdf"
380 [(parallel [(set (cc0)
381 (match_operand:DF 0 "register_operand" ""))
382 (clobber (match_scratch:HI 1 ""))])]
383 "TARGET_80387 && ! TARGET_IEEE_FP"
386 i386_compare_gen = gen_tstdf_cc;
387 i386_compare_op0 = operands[0];
388 i386_compare_op1 = const0_rtx;
392 (define_insn "tstxf_cc"
394 (match_operand:XF 0 "register_operand" "f"))
395 (clobber (match_scratch:HI 1 "=a"))]
396 "TARGET_80387 && ! TARGET_IEEE_FP"
399 if (! STACK_TOP_P (operands[0]))
402 output_asm_insn (\"ftst\", operands);
404 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
405 output_asm_insn (AS1 (fstp,%y0), operands);
407 return output_fp_cc0_set (insn);
409 [(set_attr "type" "test")])
411 ;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode
412 ;; isn't IEEE compliant.
414 (define_expand "tstxf"
415 [(parallel [(set (cc0)
416 (match_operand:XF 0 "register_operand" ""))
417 (clobber (match_scratch:HI 1 ""))])]
418 "TARGET_80387 && ! TARGET_IEEE_FP"
421 i386_compare_gen = gen_tstxf_cc;
422 i386_compare_op0 = operands[0];
423 i386_compare_op1 = const0_rtx;
427 ;;- compare instructions. See comments above tstM patterns about
428 ;; expansion of these insns.
430 (define_insn "cmpsi_1"
432 (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
433 (match_operand:SI 1 "general_operand" "ri,mr")))]
434 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
435 "* return AS2 (cmp%L0,%1,%0);"
436 [(set_attr "type" "compare")])
438 (define_expand "cmpsi"
440 (compare (match_operand:SI 0 "nonimmediate_operand" "")
441 (match_operand:SI 1 "general_operand" "")))]
445 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
446 operands[0] = force_reg (SImode, operands[0]);
448 i386_compare_gen = gen_cmpsi_1;
449 i386_compare_op0 = operands[0];
450 i386_compare_op1 = operands[1];
454 (define_insn "cmphi_1"
456 (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
457 (match_operand:HI 1 "general_operand" "ri,mr")))]
458 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
459 "* return AS2 (cmp%W0,%1,%0);"
460 [(set_attr "type" "compare")])
462 (define_expand "cmphi"
464 (compare (match_operand:HI 0 "nonimmediate_operand" "")
465 (match_operand:HI 1 "general_operand" "")))]
469 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
470 operands[0] = force_reg (HImode, operands[0]);
472 i386_compare_gen = gen_cmphi_1;
473 i386_compare_op0 = operands[0];
474 i386_compare_op1 = operands[1];
478 (define_insn "cmpqi_1"
480 (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
481 (match_operand:QI 1 "general_operand" "qm,nq")))]
482 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
483 "* return AS2 (cmp%B0,%1,%0);"
484 [(set_attr "type" "compare")])
486 (define_expand "cmpqi"
488 (compare (match_operand:QI 0 "nonimmediate_operand" "")
489 (match_operand:QI 1 "general_operand" "")))]
493 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494 operands[0] = force_reg (QImode, operands[0]);
496 i386_compare_gen = gen_cmpqi_1;
497 i386_compare_op0 = operands[0];
498 i386_compare_op1 = operands[1];
502 ;; These implement float point compares. For each of DFmode and
503 ;; SFmode, there is the normal insn, and an insn where the second operand
504 ;; is converted to the desired mode.
508 (match_operator 2 "VOIDmode_compare_op"
509 [(match_operand:XF 0 "register_operand" "f")
510 (match_operand:XF 1 "register_operand" "f")]))
511 (clobber (match_scratch:HI 3 "=a"))]
513 "* return output_float_compare (insn, operands);"
514 [(set_attr "type" "fcompare")])
518 (match_operator 2 "VOIDmode_compare_op"
519 [(match_operand:XF 0 "register_operand" "f")
521 (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
522 (clobber (match_scratch:HI 3 "=a"))]
524 "* return output_float_compare (insn, operands);"
525 [(set_attr "type" "fcompare")])
529 (match_operator 2 "VOIDmode_compare_op"
531 (match_operand:DF 0 "nonimmediate_operand" "fm"))
532 (match_operand:XF 1 "register_operand" "f")]))
533 (clobber (match_scratch:HI 3 "=a"))]
535 "* return output_float_compare (insn, operands);"
536 [(set_attr "type" "fcompare")])
540 (match_operator 2 "VOIDmode_compare_op"
541 [(match_operand:XF 0 "register_operand" "f")
543 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
544 (clobber (match_scratch:HI 3 "=a"))]
546 "* return output_float_compare (insn, operands);"
547 [(set_attr "type" "fcompare")])
551 (match_operator 2 "VOIDmode_compare_op"
553 (match_operand:SF 0 "nonimmediate_operand" "fm"))
554 (match_operand:XF 1 "register_operand" "f")]))
555 (clobber (match_scratch:HI 3 "=a"))]
557 "* return output_float_compare (insn, operands);"
558 [(set_attr "type" "fcompare")])
562 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
563 (match_operand:XF 1 "register_operand" "f")))
564 (clobber (match_scratch:HI 2 "=a"))]
566 "* return output_float_compare (insn, operands);"
567 [(set_attr "type" "fcompare")])
571 (match_operator 2 "VOIDmode_compare_op"
572 [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
573 (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
574 (clobber (match_scratch:HI 3 "=a,a"))]
576 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
577 "* return output_float_compare (insn, operands);"
578 [(set_attr "type" "fcompare")])
582 (match_operator 2 "VOIDmode_compare_op"
583 [(match_operand:DF 0 "register_operand" "f")
585 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
586 (clobber (match_scratch:HI 3 "=a"))]
588 "* return output_float_compare (insn, operands);"
589 [(set_attr "type" "fcompare")])
593 (match_operator 2 "VOIDmode_compare_op"
595 (match_operand:SF 0 "nonimmediate_operand" "fm"))
596 (match_operand:DF 1 "register_operand" "f")]))
597 (clobber (match_scratch:HI 3 "=a"))]
599 "* return output_float_compare (insn, operands);"
600 [(set_attr "type" "fcompare")])
604 (match_operator 2 "VOIDmode_compare_op"
606 (match_operand:SF 0 "register_operand" "f"))
607 (match_operand:DF 1 "nonimmediate_operand" "fm")]))
608 (clobber (match_scratch:HI 3 "=a"))]
610 "* return output_float_compare (insn, operands);"
611 [(set_attr "type" "fcompare")])
615 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
616 (match_operand:DF 1 "register_operand" "f")))
617 (clobber (match_scratch:HI 2 "=a"))]
619 "* return output_float_compare (insn, operands);"
620 [(set_attr "type" "fcompare")])
622 ;; These two insns will never be generated by combine due to the mode of
626 ; (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
628 ; (match_operand:SF 1 "register_operand" "f"))))
629 ; (clobber (match_scratch:HI 2 "=a"))]
631 ; "* return output_float_compare (insn, operands);")
635 ; (compare:CCFPEQ (float_extend:DF
636 ; (match_operand:SF 0 "register_operand" "f"))
637 ; (match_operand:DF 1 "register_operand" "f")))
638 ; (clobber (match_scratch:HI 2 "=a"))]
640 ; "* return output_float_compare (insn, operands);")
642 (define_insn "*cmpsf_cc_1"
644 (match_operator 2 "VOIDmode_compare_op"
645 [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
646 (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
647 (clobber (match_scratch:HI 3 "=a,a"))]
649 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
650 "* return output_float_compare (insn, operands);"
651 [(set_attr "type" "fcompare")])
655 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
656 (match_operand:SF 1 "register_operand" "f")))
657 (clobber (match_scratch:HI 2 "=a"))]
659 "* return output_float_compare (insn, operands);"
660 [(set_attr "type" "fcompare")])
662 (define_expand "cmpxf"
664 (compare (match_operand:XF 0 "register_operand" "")
665 (match_operand:XF 1 "register_operand" "")))]
669 i386_compare_gen = gen_cmpxf_cc;
670 i386_compare_gen_eq = gen_cmpxf_ccfpeq;
671 i386_compare_op0 = operands[0];
672 i386_compare_op1 = operands[1];
676 (define_expand "cmpdf"
678 (compare (match_operand:DF 0 "register_operand" "")
679 (match_operand:DF 1 "general_operand" "")))]
683 i386_compare_gen = gen_cmpdf_cc;
684 i386_compare_gen_eq = gen_cmpdf_ccfpeq;
685 i386_compare_op0 = operands[0];
686 i386_compare_op1 = (immediate_operand (operands[1], DFmode))
687 ? copy_to_mode_reg (DFmode, operands[1]) : operands[1];
691 (define_expand "cmpsf"
693 (compare (match_operand:SF 0 "register_operand" "")
694 (match_operand:SF 1 "general_operand" "")))]
698 i386_compare_gen = gen_cmpsf_cc;
699 i386_compare_gen_eq = gen_cmpsf_ccfpeq;
700 i386_compare_op0 = operands[0];
701 i386_compare_op1 = (immediate_operand (operands[1], SFmode))
702 ? copy_to_mode_reg (SFmode, operands[1]) : operands[1];
706 (define_expand "cmpxf_cc"
707 [(parallel [(set (cc0)
708 (compare (match_operand:XF 0 "register_operand" "")
709 (match_operand:XF 1 "register_operand" "")))
710 (clobber (match_scratch:HI 2 ""))])]
714 (define_expand "cmpxf_ccfpeq"
715 [(parallel [(set (cc0)
716 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
717 (match_operand:XF 1 "register_operand" "")))
718 (clobber (match_scratch:HI 2 ""))])]
722 (define_expand "cmpdf_cc"
723 [(parallel [(set (cc0)
724 (compare (match_operand:DF 0 "register_operand" "")
725 (match_operand:DF 1 "register_operand" "")))
726 (clobber (match_scratch:HI 2 ""))])]
730 (define_expand "cmpdf_ccfpeq"
731 [(parallel [(set (cc0)
732 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
733 (match_operand:DF 1 "register_operand" "")))
734 (clobber (match_scratch:HI 2 ""))])]
738 if (! register_operand (operands[1], DFmode))
739 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
742 (define_expand "cmpsf_cc"
743 [(parallel [(set (cc0)
744 (compare (match_operand:SF 0 "register_operand" "")
745 (match_operand:SF 1 "register_operand" "")))
746 (clobber (match_scratch:HI 2 ""))])]
750 (define_expand "cmpsf_ccfpeq"
751 [(parallel [(set (cc0)
752 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
753 (match_operand:SF 1 "register_operand" "")))
754 (clobber (match_scratch:HI 2 ""))])]
758 if (! register_operand (operands[1], SFmode))
759 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
766 (and:SI (match_operand:SI 0 "general_operand" "%ro")
767 (match_operand:SI 1 "nonmemory_operand" "ri")))]
771 /* For small integers, we may actually use testb. */
772 if (GET_CODE (operands[1]) == CONST_INT
773 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
774 && (! REG_P (operands[0]) || QI_REG_P (operands[0]))
775 /* A Pentium test is pairable only with eax. Not with ah or al. */
776 && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
779 /* We may set the sign bit spuriously. */
781 if ((INTVAL (operands[1]) & ~0xff) == 0)
783 cc_status.flags |= CC_NOT_NEGATIVE;
784 return AS2 (test%B0,%1,%b0);
787 if ((INTVAL (operands[1]) & ~0xff00) == 0)
789 cc_status.flags |= CC_NOT_NEGATIVE;
790 operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
792 if (QI_REG_P (operands[0]))
793 return AS2 (test%B0,%1,%h0);
796 operands[0] = adj_offsettable_operand (operands[0], 1);
797 return AS2 (test%B0,%1,%b0);
801 if (GET_CODE (operands[0]) == MEM
802 && (INTVAL (operands[1]) & ~0xff0000) == 0)
804 cc_status.flags |= CC_NOT_NEGATIVE;
805 operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
806 operands[0] = adj_offsettable_operand (operands[0], 2);
807 return AS2 (test%B0,%1,%b0);
810 if (GET_CODE (operands[0]) == MEM
811 && (INTVAL (operands[1]) & ~0xff000000) == 0)
813 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
814 operands[0] = adj_offsettable_operand (operands[0], 3);
815 return AS2 (test%B0,%1,%b0);
819 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
820 return AS2 (test%L0,%1,%0);
822 return AS2 (test%L1,%0,%1);
824 [(set_attr "type" "compare")])
828 (and:HI (match_operand:HI 0 "general_operand" "%ro")
829 (match_operand:HI 1 "nonmemory_operand" "ri")))]
833 if (GET_CODE (operands[1]) == CONST_INT
834 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
835 && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
837 if ((INTVAL (operands[1]) & 0xff00) == 0)
839 /* ??? This might not be necessary. */
840 if (INTVAL (operands[1]) & 0xffff0000)
841 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
843 /* We may set the sign bit spuriously. */
844 cc_status.flags |= CC_NOT_NEGATIVE;
845 return AS2 (test%B0,%1,%b0);
848 if ((INTVAL (operands[1]) & 0xff) == 0)
850 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
852 if (QI_REG_P (operands[0]))
853 return AS2 (test%B0,%1,%h0);
856 operands[0] = adj_offsettable_operand (operands[0], 1);
857 return AS2 (test%B0,%1,%b0);
862 /* use 32-bit test instruction if there are no sign issues */
863 if (GET_CODE (operands[1]) == CONST_INT
864 && !(INTVAL (operands[1]) & ~0x7fff)
865 && i386_aligned_p (operands[0]))
866 return AS2 (test%L0,%1,%k0);
868 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
869 return AS2 (test%W0,%1,%0);
871 return AS2 (test%W1,%0,%1);
873 [(set_attr "type" "compare")])
877 (and:QI (match_operand:QI 0 "nonimmediate_operand" "%qm")
878 (match_operand:QI 1 "nonmemory_operand" "qi")))]
882 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
883 return AS2 (test%B0,%1,%0);
885 return AS2 (test%B1,%0,%1);
887 [(set_attr "type" "compare")])
889 ;; move instructions.
890 ;; There is one for each machine mode,
891 ;; and each is preceded by a corresponding push-insn pattern
892 ;; (since pushes are not general_operands on the 386).
895 [(set (match_operand:SI 0 "push_operand" "=<")
896 (match_operand:SI 1 "nonmemory_operand" "rn"))]
898 "* return AS1 (push%L0,%1);"
899 [(set_attr "memory" "store")])
902 [(set (match_operand:SI 0 "push_operand" "=<")
903 (match_operand:SI 1 "nonmemory_operand" "ri"))]
905 "* return AS1 (push%L0,%1);"
906 [(set_attr "memory" "store")])
908 ;; On a 386, it is faster to push MEM directly.
911 [(set (match_operand:SI 0 "push_operand" "=<")
912 (match_operand:SI 1 "memory_operand" "m"))]
914 "* return AS1 (push%L0,%1);"
915 [(set_attr "type" "memory")
916 (set_attr "memory" "load")])
918 ;; General case of fullword move.
920 ;; If generating PIC code and operands[1] is a symbolic CONST, emit a
921 ;; move to get the address of the symbolic object from the GOT.
923 (define_expand "movsi"
924 [(set (match_operand:SI 0 "general_operand" "")
925 (match_operand:SI 1 "general_operand" ""))]
931 if (flag_pic && SYMBOLIC_CONST (operands[1]))
932 emit_pic_move (operands, SImode);
934 /* Don't generate memory->memory moves, go through a register */
936 && no_new_pseudos == 0
937 && GET_CODE (operands[0]) == MEM
938 && GET_CODE (operands[1]) == MEM)
940 operands[1] = force_reg (SImode, operands[1]);
944 ;; On i486, incl reg is faster than movl $1,reg.
947 [(set (match_operand:SI 0 "general_operand" "=g,r,r")
948 (match_operand:SI 1 "general_operand" "rn,i,m"))]
949 "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
950 || (GET_CODE (operands[1]) != MEM))
956 /* K6: mov reg,0 is slightly faster than xor reg,reg but is 3 bytes
958 if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
959 && operands[1] == const0_rtx && REG_P (operands[0]))
960 return AS2 (xor%L0,%0,%0);
962 if (operands[1] == const1_rtx
963 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
964 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
965 && (link = find_reg_note (insn, REG_WAS_0, 0))
966 /* Make sure the insn that stored the 0 is still present. */
967 && ! INSN_DELETED_P (XEXP (link, 0))
968 && GET_CODE (XEXP (link, 0)) != NOTE
969 /* Make sure cross jumping didn't happen here. */
970 && no_labels_between_p (XEXP (link, 0), insn)
971 /* Make sure the reg hasn't been clobbered. */
972 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
973 /* Fastest way to change a 0 to a 1. */
974 return AS1 (inc%L0,%0);
976 if (SYMBOLIC_CONST (operands[1]))
977 return AS2 (lea%L0,%a1,%0);
979 return AS2 (mov%L0,%1,%0);
981 [(set_attr "type" "integer,integer,memory")
982 (set_attr "memory" "*,*,load")])
985 [(set (match_operand:SI 0 "general_operand" "=g,r")
986 (match_operand:SI 1 "general_operand" "ri,m"))]
987 "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
988 || (GET_CODE (operands[1]) != MEM))
994 /* Use of xor was disabled for AMD K6 as recommended by the Optimization
995 Manual. My test shows, that this generally hurts the performance, because
996 mov is longer and takes longer to decode and decoding is the main
997 bottleneck of K6 when executing GCC code. */
999 if (operands[1] == const0_rtx && REG_P (operands[0]))
1000 return AS2 (xor%L0,%0,%0);
1002 if (operands[1] == const1_rtx
1003 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
1004 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1005 && (link = find_reg_note (insn, REG_WAS_0, 0))
1006 /* Make sure the insn that stored the 0 is still present. */
1007 && ! INSN_DELETED_P (XEXP (link, 0))
1008 && GET_CODE (XEXP (link, 0)) != NOTE
1009 /* Make sure cross jumping didn't happen here. */
1010 && no_labels_between_p (XEXP (link, 0), insn)
1011 /* Make sure the reg hasn't been clobbered. */
1012 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1013 /* Fastest way to change a 0 to a 1. */
1014 return AS1 (inc%L0,%0);
1016 return AS2 (mov%L0,%1,%0);
1018 [(set_attr "type" "integer,memory")
1019 (set_attr "memory" "*,load")])
1022 [(set (match_operand:HI 0 "push_operand" "=<")
1023 (match_operand:HI 1 "nonmemory_operand" "ri"))]
1025 "* return AS1 (push%W0,%1);"
1026 [(set_attr "type" "memory")
1027 (set_attr "memory" "store")])
1030 [(set (match_operand:HI 0 "push_operand" "=<")
1031 (match_operand:HI 1 "memory_operand" "m"))]
1032 "TARGET_PUSH_MEMORY"
1033 "* return AS1 (push%W0,%1);"
1034 [(set_attr "type" "memory")
1035 (set_attr "memory" "load")])
1037 ;; On i486, an incl and movl are both faster than incw and movw.
1039 (define_expand "movhi"
1040 [(set (match_operand:HI 0 "general_operand" "")
1041 (match_operand:HI 1 "general_operand" ""))]
1045 /* Don't generate memory->memory moves, go through a register */
1047 && no_new_pseudos == 0
1048 && GET_CODE (operands[0]) == MEM
1049 && GET_CODE (operands[1]) == MEM)
1051 operands[1] = force_reg (HImode, operands[1]);
1056 [(set (match_operand:HI 0 "general_operand" "=g,r")
1057 (match_operand:HI 1 "general_operand" "ri,m"))]
1058 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1062 if (REG_P (operands[0]) && operands[1] == const0_rtx)
1063 return AS2 (xor%L0,%k0,%k0);
1065 if (REG_P (operands[0]) && operands[1] == const1_rtx
1066 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
1067 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1068 && (link = find_reg_note (insn, REG_WAS_0, 0))
1069 /* Make sure the insn that stored the 0 is still present. */
1070 && ! INSN_DELETED_P (XEXP (link, 0))
1071 && GET_CODE (XEXP (link, 0)) != NOTE
1072 /* Make sure cross jumping didn't happen here. */
1073 && no_labels_between_p (XEXP (link, 0), insn)
1074 /* Make sure the reg hasn't been clobbered. */
1075 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1076 /* Fastest way to change a 0 to a 1. */
1077 return AS1 (inc%L0,%k0);
1079 if (REG_P (operands[0]))
1081 if (i386_aligned_p (operands[1]))
1083 operands[1] = i386_sext16_if_const (operands[1]);
1084 return AS2 (mov%L0,%k1,%k0);
1086 if (! TARGET_ZERO_EXTEND_WITH_AND)
1088 /* movzwl is faster than movw on the Pentium Pro,
1089 * although not as fast as an aligned movl. */
1091 return AS2 (movzx,%1,%k0);
1093 return AS2 (movz%W0%L0,%1,%k0);
1098 return AS2 (mov%W0,%1,%0);
1100 [(set_attr "type" "integer,memory")
1101 (set_attr "memory" "*,load")])
1103 (define_expand "movstricthi"
1104 [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
1105 (match_operand:HI 1 "general_operand" ""))]
1109 /* Don't generate memory->memory moves, go through a register */
1111 && no_new_pseudos == 0
1112 && GET_CODE (operands[0]) == MEM
1113 && GET_CODE (operands[1]) == MEM)
1115 operands[1] = force_reg (HImode, operands[1]);
1120 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
1121 (match_operand:HI 1 "general_operand" "ri,m"))]
1122 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1127 /* Use of xor was disabled for AMD K6 as recommended by the Optimization
1128 Manual. My test shows, that this generally hurts the performance, because
1129 mov is longer and takes longer to decode and decoding is the main
1130 bottleneck of K6 when executing GCC code. */
1132 if (operands[1] == const0_rtx && REG_P (operands[0]))
1133 return AS2 (xor%W0,%0,%0);
1135 if (operands[1] == const1_rtx
1136 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
1137 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1138 && (link = find_reg_note (insn, REG_WAS_0, 0))
1139 /* Make sure the insn that stored the 0 is still present. */
1140 && ! INSN_DELETED_P (XEXP (link, 0))
1141 && GET_CODE (XEXP (link, 0)) != NOTE
1142 /* Make sure cross jumping didn't happen here. */
1143 && no_labels_between_p (XEXP (link, 0), insn)
1144 /* Make sure the reg hasn't been clobbered. */
1145 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1146 /* Fastest way to change a 0 to a 1. */
1147 return AS1 (inc%W0,%0);
1149 return AS2 (mov%W0,%1,%0);
1151 [(set_attr "type" "integer,memory")])
1153 ;; emit_push_insn when it calls move_by_pieces
1154 ;; requires an insn to "push a byte".
1155 ;; But actually we use pushw, which has the effect of rounding
1156 ;; the amount pushed up to a halfword.
1158 [(set (match_operand:QI 0 "push_operand" "=<")
1159 (match_operand:QI 1 "const_int_operand" "n"))]
1161 "* return AS1(push%W0,%1);")
1164 [(set (match_operand:QI 0 "push_operand" "=<")
1165 (match_operand:QI 1 "register_operand" "q"))]
1169 operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]));
1170 return AS1 (push%W0,%1);
1173 ;; On i486, incb reg is faster than movb $1,reg.
1175 ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
1176 ;; or writes %ah, %bh, %ch, %dh.
1178 (define_expand "movqi"
1179 [(set (match_operand:QI 0 "general_operand" "")
1180 (match_operand:QI 1 "general_operand" ""))]
1184 /* Don't generate memory->memory moves, go through a register */
1186 && no_new_pseudos == 0
1187 && GET_CODE (operands[0]) == MEM
1188 && GET_CODE (operands[1]) == MEM)
1190 operands[1] = force_reg (QImode, operands[1]);
1195 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,*r,qm")
1196 (match_operand:QI 1 "general_operand" "*g,*rn,qn"))]
1197 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1202 /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8.
1203 It is at least as fast as xor on any processor except a Pentium. */
1205 if (operands[1] == const1_rtx
1207 && (link = find_reg_note (insn, REG_WAS_0, 0))
1208 /* Make sure the insn that stored the 0 is still present. */
1209 && ! INSN_DELETED_P (XEXP (link, 0))
1210 && GET_CODE (XEXP (link, 0)) != NOTE
1211 /* Make sure cross jumping didn't happen here. */
1212 && no_labels_between_p (XEXP (link, 0), insn)
1213 /* Make sure the reg hasn't been clobbered. */
1214 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1216 /* Fastest way to change a 0 to a 1.
1217 If inc%B0 isn't allowed, use inc%L0. */
1218 if (NON_QI_REG_P (operands[0]))
1219 return AS1 (inc%L0,%k0);
1221 return AS1 (inc%B0,%0);
1224 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1225 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1226 return (AS2 (mov%L0,%k1,%k0));
1228 return (AS2 (mov%B0,%1,%0));
1231 ;; If it becomes necessary to support movstrictqi into %esi or %edi,
1232 ;; use the insn sequence:
1234 ;; shrdl $8,srcreg,dstreg
1237 ;; If operands[1] is a constant, then an andl/orl sequence would be
1240 (define_expand "movstrictqi"
1241 [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
1242 (match_operand:QI 1 "general_operand" ""))]
1246 /* Don't generate memory->memory moves, go through a register */
1248 && no_new_pseudos == 0
1249 && GET_CODE (operands[0]) == MEM
1250 && GET_CODE (operands[1]) == MEM)
1252 operands[1] = force_reg (QImode, operands[1]);
1257 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1258 (match_operand:QI 1 "general_operand" "*qn,m"))]
1259 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1264 /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. */
1266 if (operands[1] == const1_rtx
1268 && ! NON_QI_REG_P (operands[0])
1269 && (link = find_reg_note (insn, REG_WAS_0, 0))
1270 /* Make sure the insn that stored the 0 is still present. */
1271 && ! INSN_DELETED_P (XEXP (link, 0))
1272 && GET_CODE (XEXP (link, 0)) != NOTE
1273 /* Make sure cross jumping didn't happen here. */
1274 && no_labels_between_p (XEXP (link, 0), insn)
1275 /* Make sure the reg hasn't been clobbered. */
1276 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1277 /* Fastest way to change a 0 to a 1. */
1278 return AS1 (inc%B0,%0);
1280 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1281 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1284 return (AS2 (mov%L0,%k1,%k0));
1287 return AS2 (mov%B0,%1,%0);
1290 (define_insn "movsf_push"
1291 [(set (match_operand:SF 0 "push_operand" "=<,<")
1292 (match_operand:SF 1 "general_operand" "*rfF,m"))]
1293 "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM
1294 || reload_in_progress || reload_completed"
1297 if (STACK_REG_P (operands[1]))
1301 if (! STACK_TOP_P (operands[1]))
1304 xops[0] = AT_SP (SFmode);
1305 xops[1] = GEN_INT (4);
1306 xops[2] = stack_pointer_rtx;
1308 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1310 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1311 output_asm_insn (AS1 (fstp%S0,%0), xops);
1313 output_asm_insn (AS1 (fst%S0,%0), xops);
1318 return AS1 (push%L0,%1);
1322 [(set (match_operand:SF 0 "push_operand" "")
1323 (match_operand:SF 1 "general_operand" ""))]
1324 "reload_completed && STACK_REG_P (operands[1])"
1326 (minus:SI (reg:SI 7) (const_int 4)))
1327 (set (mem:SF (reg:SI 7))
1331 (define_expand "movsf"
1332 [(set (match_operand:SF 0 "general_operand" "")
1333 (match_operand:SF 1 "general_operand" ""))]
1337 /* Don't generate memory->memory moves, go through a register */
1339 && no_new_pseudos == 0
1340 && GET_CODE (operands[0]) == MEM
1341 && GET_CODE (operands[1]) == MEM)
1343 operands[1] = force_reg (SFmode, operands[1]);
1346 /* If we are loading a floating point constant that isn't 0 or 1
1347 into a register, force the value to memory now, since we'll
1348 get better code out the back end. */
1349 else if ((reload_in_progress | reload_completed) == 0
1350 && GET_CODE (operands[0]) != MEM
1351 && GET_CODE (operands[1]) == CONST_DOUBLE
1352 && !standard_80387_constant_p (operands[1]))
1354 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
1358 ;; For the purposes of regclass, prefer FLOAT_REGS.
1360 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r,!m")
1361 (match_operand:SF 1 "general_operand" "fmG,f,*rmF,*rF"))]
1362 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1365 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1367 /* First handle a `pop' insn or a `fld %st(0)' */
1369 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1372 return AS1 (fstp,%y0);
1374 return AS1 (fld,%y0);
1377 /* Handle other kinds of writes from the 387 */
1379 if (STACK_TOP_P (operands[1]))
1382 return AS1 (fstp%z0,%y0);
1384 return AS1 (fst%z0,%y0);
1387 /* Handle other kinds of reads to the 387 */
1389 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1390 return output_move_const_single (operands);
1392 if (STACK_TOP_P (operands[0]))
1393 return AS1 (fld%z1,%y1);
1395 /* Handle all SFmode moves not involving the 387 */
1397 return singlemove_string (operands);
1399 [(set_attr "type" "fld")])
1402 (define_insn "swapsf"
1403 [(set (match_operand:SF 0 "register_operand" "f")
1404 (match_operand:SF 1 "register_operand" "f"))
1410 if (STACK_TOP_P (operands[0]))
1411 return AS1 (fxch,%1);
1413 return AS1 (fxch,%0);
1417 (define_insn "movdf_push"
1418 [(set (match_operand:DF 0 "push_operand" "=<,<")
1419 (match_operand:DF 1 "general_operand" "*rfF,o"))]
1420 "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM
1421 || reload_in_progress || reload_completed"
1424 if (STACK_REG_P (operands[1]))
1428 xops[0] = AT_SP (DFmode);
1429 xops[1] = GEN_INT (8);
1430 xops[2] = stack_pointer_rtx;
1432 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1434 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1435 output_asm_insn (AS1 (fstp%Q0,%0), xops);
1437 output_asm_insn (AS1 (fst%Q0,%0), xops);
1442 if (which_alternative == 1)
1443 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 0, 0);
1445 return output_move_double (operands);
1449 [(set (match_operand:DF 0 "push_operand" "")
1450 (match_operand:DF 1 "register_operand" ""))]
1451 "reload_completed && STACK_REG_P (operands[1])"
1453 (minus:SI (reg:SI 7) (const_int 8)))
1454 (set (mem:DF (reg:SI 7))
1458 (define_expand "movdf"
1459 [(set (match_operand:DF 0 "general_operand" "")
1460 (match_operand:DF 1 "general_operand" ""))]
1464 /* Don't generate memory->memory moves, go through a register */
1466 && no_new_pseudos == 0
1467 && GET_CODE (operands[0]) == MEM
1468 && GET_CODE (operands[1]) == MEM)
1470 operands[1] = force_reg (DFmode, operands[1]);
1473 /* If we are loading a floating point constant that isn't 0 or 1 into a
1474 register, indicate we need the pic register loaded. This could be
1475 optimized into stores of constants if the target eventually moves to
1476 memory, but better safe than sorry. */
1477 else if ((reload_in_progress | reload_completed) == 0
1478 && GET_CODE (operands[0]) != MEM
1479 && GET_CODE (operands[1]) == CONST_DOUBLE
1480 && !standard_80387_constant_p (operands[1]))
1482 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
1486 ;; For the purposes of regclass, prefer FLOAT_REGS.
1488 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r,!o")
1489 (match_operand:DF 1 "general_operand" "fmG,f,*roF,*rF"))]
1490 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1491 || (GET_CODE (operands[1]) != MEM)"
1494 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1496 /* First handle a `pop' insn or a `fld %st(0)' */
1498 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1501 return AS1 (fstp,%y0);
1503 return AS1 (fld,%y0);
1506 /* Handle other kinds of writes from the 387 */
1508 if (STACK_TOP_P (operands[1]))
1511 return AS1 (fstp%z0,%y0);
1513 return AS1 (fst%z0,%y0);
1516 /* Handle other kinds of reads to the 387 */
1518 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1519 return output_move_const_single (operands);
1521 if (STACK_TOP_P (operands[0]))
1522 return AS1 (fld%z1,%y1);
1524 /* Handle all DFmode moves not involving the 387 */
1526 return output_move_double (operands);
1528 [(set_attr "type" "fld")])
1532 (define_insn "swapdf"
1533 [(set (match_operand:DF 0 "register_operand" "f")
1534 (match_operand:DF 1 "register_operand" "f"))
1540 if (STACK_TOP_P (operands[0]))
1541 return AS1 (fxch,%1);
1543 return AS1 (fxch,%0);
1546 (define_insn "movxf_push"
1547 [(set (match_operand:XF 0 "push_operand" "=<,<")
1548 (match_operand:XF 1 "general_operand" "*rfF,o"))]
1549 "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM
1550 || reload_in_progress || reload_completed"
1553 if (STACK_REG_P (operands[1]))
1557 xops[0] = AT_SP (XFmode);
1558 xops[1] = GEN_INT (12);
1559 xops[2] = stack_pointer_rtx;
1561 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1563 output_asm_insn (AS1 (fstp%T0,%0), xops);
1564 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1565 output_asm_insn (AS1 (fld%T0,%0), xops);
1570 if (which_alternative == 1)
1571 return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 0, 0);
1573 return output_move_double (operands);
1577 [(set (match_operand:XF 0 "push_operand" "")
1578 (match_operand:XF 1 "register_operand" ""))]
1579 "reload_completed && STACK_REG_P (operands[1])"
1581 (minus:SI (reg:SI 7) (const_int 12)))
1582 (set (mem:XF (reg:SI 7))
1586 (define_expand "movxf"
1587 [(set (match_operand:XF 0 "general_operand" "")
1588 (match_operand:XF 1 "general_operand" ""))]
1592 /* Don't generate memory->memory moves, go through a register */
1594 && no_new_pseudos == 0
1595 && GET_CODE (operands[0]) == MEM
1596 && GET_CODE (operands[1]) == MEM)
1598 operands[1] = force_reg (XFmode, operands[1]);
1601 /* If we are loading a floating point constant that isn't 0 or 1
1602 into a register, indicate we need the pic register loaded. This could
1603 be optimized into stores of constants if the target eventually moves
1604 to memory, but better safe than sorry. */
1605 else if ((reload_in_progress | reload_completed) == 0
1606 && GET_CODE (operands[0]) != MEM
1607 && GET_CODE (operands[1]) == CONST_DOUBLE
1608 && !standard_80387_constant_p (operands[1]))
1610 operands[1] = validize_mem (force_const_mem (XFmode, operands[1]));
1616 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!*r,!o")
1617 (match_operand:XF 1 "general_operand" "fmG,f,*roF,*rF"))]
1618 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1619 || (GET_CODE (operands[1]) != MEM)"
1622 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1624 /* First handle a `pop' insn or a `fld %st(0)' */
1626 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1629 return AS1 (fstp,%y0);
1631 return AS1 (fld,%y0);
1634 /* Handle other kinds of writes from the 387 */
1636 if (STACK_TOP_P (operands[1]))
1638 output_asm_insn (AS1 (fstp%z0,%y0), operands);
1639 if (! stack_top_dies)
1640 return AS1 (fld%z0,%y0);
1645 /* Handle other kinds of reads to the 387 */
1647 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1648 return output_move_const_single (operands);
1650 if (STACK_TOP_P (operands[0]))
1651 return AS1 (fld%z1,%y1);
1653 /* Handle all XFmode moves not involving the 387 */
1655 return output_move_double (operands);
1658 (define_insn "swapxf"
1659 [(set (match_operand:XF 0 "register_operand" "f")
1660 (match_operand:XF 1 "register_operand" "f"))
1666 if (STACK_TOP_P (operands[0]))
1667 return AS1 (fxch,%1);
1669 return AS1 (fxch,%0);
1673 [(set (match_operand:DI 0 "push_operand" "=<")
1674 (match_operand:DI 1 "general_operand" "riF"))]
1676 "* return output_move_double (operands);")
1679 [(set (match_operand:DI 0 "push_operand" "=<")
1680 (match_operand:DI 1 "memory_operand" "o"))]
1681 "TARGET_PUSH_MEMORY"
1682 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode),0,0);")
1684 (define_expand "movdi"
1685 [(set (match_operand:DI 0 "general_operand" "")
1686 (match_operand:DI 1 "general_operand" ""))]
1690 /* Don't generate memory->memory moves, go through a register */
1692 && no_new_pseudos == 0
1693 && GET_CODE (operands[0]) == MEM
1694 && GET_CODE (operands[1]) == MEM)
1696 operands[1] = force_reg (DImode, operands[1]);
1701 [(set (match_operand:DI 0 "general_operand" "=g,r")
1702 (match_operand:DI 1 "general_operand" "riF,m"))]
1703 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1704 || (GET_CODE (operands[1]) != MEM)"
1705 "* return output_move_double (operands);"
1706 [(set_attr "type" "integer,memory")
1707 (set_attr "memory" "*,load")])
1710 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1711 (match_operand:DI 1 "general_operand" ""))]
1713 && (offsettable_memref_p (operands[0])
1714 || nonmemory_operand (operands[0], DImode))
1715 && (offsettable_memref_p (operands[1])
1716 || nonmemory_operand (operands[1], DImode))
1717 && (! reg_overlap_mentioned_p (gen_lowpart (SImode, operands[0]),
1719 || ! reg_overlap_mentioned_p (gen_highpart (SImode, operands[0]),
1727 split_di (&operands[0], 1, &operands[2], &operands[3]);
1728 split_di (&operands[1], 1, &operands[4], &operands[5]);
1730 if (reg_overlap_mentioned_p (operands[2], operands[1]))
1735 operands[2] = operands[3];
1739 operands[4] = operands[5];
1744 ;;- conversion instructions
1747 ;;- zero extension instructions
1748 ;; See comments by `andsi' for when andl is faster than movzx.
1750 (define_expand "zero_extendhisi2"
1751 [(set (match_operand:SI 0 "register_operand" "")
1752 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1756 ;; When optimizing for the PPro/PII or code size, always use movzwl.
1757 ;; We want to use a different pattern so we can use different constraints
1758 ;; than the generic pattern.
1760 [(set (match_operand:SI 0 "register_operand" "=r")
1761 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
1762 "(optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1763 "* return AS2 (movz%W0%L0,%1,%0);")
1766 [(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
1767 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
1768 "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1773 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1774 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1776 xops[0] = operands[0];
1777 xops[1] = GEN_INT (0xffff);
1778 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1781 if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1]))
1783 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1784 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1788 if (TARGET_ZERO_EXTEND_WITH_AND)
1790 xops[0] = operands[0];
1791 xops[1] = GEN_INT (0xffff);
1792 if (i386_aligned_p (operands[1]))
1793 output_asm_insn (AS2 (mov%L0,%k1,%k0),operands);
1795 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1796 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1801 return AS2 (movzx,%1,%0);
1803 return AS2 (movz%W0%L0,%1,%0);
1808 [(set (match_operand:SI 0 "register_operand" "")
1809 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1810 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])"
1813 (set (strict_low_part (match_dup 2))
1815 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1819 [(set (match_operand:SI 0 "register_operand" "")
1820 (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))]
1821 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])"
1822 [(set (strict_low_part (match_dup 2))
1825 (and:SI (match_dup 0)
1826 (const_int 65535)))]
1827 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1829 (define_expand "zero_extendqihi2"
1830 [(set (match_operand:HI 0 "register_operand" "")
1831 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1836 [(set (match_operand:HI 0 "register_operand" "=r")
1837 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1838 "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
1840 "* return AS2 (movz%B0%W0,%1,%0);")
1843 [(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
1844 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1845 "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1850 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1851 && REG_P (operands[1])
1852 && REGNO (operands[0]) == REGNO (operands[1]))
1854 xops[0] = operands[0];
1855 xops[1] = GEN_INT (0xff);
1856 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1859 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1861 if(!reg_overlap_mentioned_p(operands[0],operands[1]))
1863 output_asm_insn (AS2 (xor%L0,%k0,%k0), operands);
1864 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1868 xops[0] = operands[0];
1869 xops[1] = GEN_INT (0xff);
1870 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1871 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1877 return AS2 (movzx,%1,%0);
1879 return AS2 (movz%B0%W0,%1,%0);
1884 [(set (match_operand:HI 0 "register_operand" "")
1885 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1886 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1887 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1890 (set (strict_low_part (match_dup 2))
1892 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1896 [(set (match_operand:HI 0 "register_operand" "")
1897 (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))]
1898 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1899 && reg_overlap_mentioned_p (operands[0], operands[1])"
1900 [(set (strict_low_part (match_dup 2))
1903 (and:HI (match_dup 0)
1905 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1908 [(set (match_operand:HI 0 "register_operand" "")
1909 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1910 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND"
1914 (and:HI (match_dup 0)
1916 "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0)
1917 operands[1] = SUBREG_REG (operands[1]);
1918 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG
1919 || REGNO (operands[0]) == REGNO (operands[1]))
1921 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));")
1923 (define_expand "zero_extendqisi2"
1924 [(set (match_operand:SI 0 "register_operand" "")
1925 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1930 [(set (match_operand:SI 0 "register_operand" "=r")
1931 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1932 "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
1933 "* return AS2 (movz%B0%L0,%1,%0);")
1936 [(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
1937 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1938 "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1943 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1944 && REG_P (operands[1])
1945 && REGNO (operands[0]) == REGNO (operands[1]))
1947 xops[0] = operands[0];
1948 xops[1] = GEN_INT (0xff);
1949 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1952 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1954 if(!reg_overlap_mentioned_p (operands[0], operands[1]))
1956 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1957 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1961 xops[0] = operands[0];
1962 xops[1] = GEN_INT (0xff);
1963 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1964 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1969 if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG)
1971 xops[0] = operands[0];
1972 xops[1] = GEN_INT (0xff);
1973 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
1974 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
1975 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1980 return AS2 (movzx,%1,%0);
1982 return AS2 (movz%B0%L0,%1,%0);
1987 [(set (match_operand:SI 0 "register_operand" "")
1988 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1989 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1990 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1993 (set (strict_low_part (match_dup 2))
1995 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1999 [(set (match_operand:SI 0 "register_operand" "")
2000 (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))]
2001 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
2002 && reg_overlap_mentioned_p (operands[0], operands[1])"
2003 [(set (strict_low_part (match_dup 2))
2006 (and:SI (match_dup 0)
2008 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2011 [(set (match_operand:SI 0 "register_operand" "")
2012 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2013 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
2014 && ! reg_overlap_mentioned_p (operands[0], operands[1])"
2018 (and:SI (match_dup 0)
2020 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
2022 (define_insn "zero_extendsidi2"
2023 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
2024 (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))]
2029 [(set (match_operand:DI 0 "register_operand" "")
2030 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2031 "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
2032 [(set (match_dup 4) (const_int 0))]
2033 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2036 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2037 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
2039 [(set (match_dup 3) (match_dup 1))
2040 (set (match_dup 4) (const_int 0))]
2041 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2043 ;;- sign extension instructions
2045 (define_insn "extendsidi2"
2046 [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*o")
2047 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,*r")))
2048 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
2052 ;; Extend to memory case when source register does die.
2054 [(set (match_operand:DI 0 "memory_operand" "")
2055 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2056 (clobber (match_operand:SI 2 "register_operand" ""))]
2058 && dead_or_set_p (insn, operands[1])
2059 && !reg_mentioned_p (operands[1], operands[0]))"
2060 [(set (match_dup 3) (match_dup 1))
2061 (set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
2062 (set (match_dup 4) (match_dup 1))]
2063 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2065 ;; Extend to memory case when source register does not die.
2067 [(set (match_operand:DI 0 "memory_operand" "")
2068 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2069 (clobber (match_operand:SI 2 "register_operand" ""))]
2074 split_di (&operands[0], 1, &operands[3], &operands[4]);
2076 emit_move_insn (operands[3], operands[1]);
2078 /* Generate a cltd if possible and doing so it profitable. */
2079 if (true_regnum (operands[1]) == 0
2080 && true_regnum (operands[2]) == 1
2081 && (optimize_size || !TARGET_PENTIUM))
2083 emit_insn (gen_ashrsi3_31 (operands[2], operands[1]));
2087 emit_move_insn (operands[2], operands[1]);
2088 emit_insn (gen_ashrsi3_31 (operands[2], operands[2]));
2090 emit_move_insn (operands[4], operands[2]);
2094 ;; Extend to register case. Optimize case where source and destination
2095 ;; registers match and cases where we can use cltd.
2097 [(set (match_operand:DI 0 "register_operand" "")
2098 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2099 (clobber (match_scratch:SI 2 ""))]
2104 split_di (&operands[0], 1, &operands[3], &operands[4]);
2106 if (true_regnum (operands[3]) != true_regnum (operands[1]))
2107 emit_move_insn (operands[3], operands[1]);
2109 /* Generate a cltd if possible and doing so it profitable. */
2110 if (true_regnum (operands[3]) == 0
2111 && (optimize_size || !TARGET_PENTIUM))
2113 emit_insn (gen_ashrsi3_31 (operands[4], operands[3]));
2117 if (true_regnum (operands[4]) != true_regnum (operands[1]))
2118 emit_move_insn (operands[4], operands[1]);
2120 emit_insn (gen_ashrsi3_31 (operands[4], operands[4]));
2124 ;; Note that the i386 programmers' manual says that the opcodes
2125 ;; are named movsx..., but the assembler on Unix does not accept that.
2126 ;; We use what the Unix assembler expects.
2128 (define_insn "extendhisi2"
2129 [(set (match_operand:SI 0 "register_operand" "=r")
2130 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2134 if (REGNO (operands[0]) == 0
2135 && REG_P (operands[1]) && REGNO (operands[1]) == 0
2136 && (optimize_size || ix86_cpu != PROCESSOR_K6))
2144 return AS2 (movsx,%1,%0);
2146 return AS2 (movs%W0%L0,%1,%0);
2150 (define_insn "extendqihi2"
2151 [(set (match_operand:HI 0 "register_operand" "=r")
2152 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2156 if (REGNO (operands[0]) == 0
2157 && REG_P (operands[1]) && REGNO (operands[1]) == 0
2158 && (optimize_size || ix86_cpu != PROCESSOR_K6))
2162 return AS2 (movsx,%1,%0);
2164 return AS2 (movs%B0%W0,%1,%0);
2168 (define_insn "extendqisi2"
2169 [(set (match_operand:SI 0 "register_operand" "=r")
2170 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2175 return AS2 (movsx,%1,%0);
2177 return AS2 (movs%B0%L0,%1,%0);
2182 ;; Truncation of long long -> 32 bit
2184 (define_expand "truncdisi2"
2185 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2186 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2190 /* Don't generate memory->memory moves, go through a register */
2192 && (reload_in_progress | reload_completed) == 0
2193 && GET_CODE (operands[0]) == MEM
2194 && GET_CODE (operands[1]) == MEM)
2196 rtx target = gen_reg_rtx (SImode);
2197 emit_insn (gen_truncdisi2 (target, operands[1]));
2198 emit_move_insn (operands[0], target);
2204 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2205 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2206 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2209 rtx low[2], high[2], xops[2];
2211 split_di (&operands[1], 1, low, high);
2212 xops[0] = operands[0];
2214 if (!rtx_equal_p (xops[0], xops[1]))
2215 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2221 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2222 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
2224 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2227 rtx low[2], high[2], xops[2];
2229 split_di (&operands[1], 1, low, high);
2230 xops[0] = operands[0];
2232 if (!rtx_equal_p (xops[0], xops[1]))
2233 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2240 ;; Conversions between float and double.
2242 (define_expand "extendsfdf2"
2243 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2245 (match_operand:SF 1 "nonimmediate_operand" "")))
2246 (clobber (match_dup 2))
2247 (clobber (match_dup 3))])]
2251 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2252 operands[1] = force_reg (SFmode, operands[1]);
2254 operands[2] = assign_386_stack_local (SFmode, 0);
2255 operands[3] = assign_386_stack_local (DFmode, 0);
2259 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!f,!*r")
2261 (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f")))
2262 (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m"))
2263 (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))]
2264 "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2265 || GET_CODE (operands[1]) != MEM)"
2268 output_float_extend (insn, operands);
2271 [(set_attr "type" "fld,fpop,fld,fpop")])
2274 [(set (match_operand:DF 0 "register_operand" "")
2275 (float_extend:DF (match_operand:SF 1 "register_operand" "")))
2276 (clobber (match_operand:SF 2 "memory_operand" ""))
2277 (clobber (match_operand:DF 3 "memory_operand" ""))]
2278 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
2282 (float_extend:DF (match_dup 2)))]
2286 [(set (match_operand:DF 0 "register_operand" "")
2287 (float_extend:DF (match_operand:SF 1 "register_operand" "")))
2288 (clobber (match_operand:SF 2 "memory_operand" ""))
2289 (clobber (match_operand:DF 3 "memory_operand" ""))]
2290 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
2292 (float_extend:DF (match_dup 1)))
2298 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2299 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))
2300 (clobber (match_operand:SF 2 "memory_operand" ""))
2301 (clobber (match_operand:DF 3 "memory_operand" ""))]
2302 "TARGET_80387 && reload_completed"
2304 (float_extend:DF (match_dup 1)))]
2308 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
2309 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2310 "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2311 || GET_CODE (operands[1]) != MEM)"
2314 output_float_extend (insn, operands);
2317 [(set_attr "type" "fld,fpop")])
2319 (define_expand "extenddfxf2"
2320 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
2322 (match_operand:DF 1 "nonimmediate_operand" "")))
2323 (clobber (match_dup 2))
2324 (clobber (match_dup 3))])]
2328 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2329 operands[1] = force_reg (DFmode, operands[1]);
2331 operands[2] = assign_386_stack_local (DFmode, 0);
2332 operands[3] = assign_386_stack_local (XFmode, 0);
2336 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r")
2338 (match_operand:DF 1 "nonimmediate_operand" "fm,f,*r,f")))
2339 (clobber (match_operand:DF 2 "memory_operand" "m,m,o,m"))
2340 (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
2341 "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2342 || GET_CODE (operands[1]) != MEM)"
2345 output_float_extend (insn, operands);
2348 [(set_attr "type" "fld,fpop,fld,fpop")])
2351 [(set (match_operand:XF 0 "register_operand" "")
2352 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
2353 (clobber (match_operand:DF 2 "memory_operand" ""))
2354 (clobber (match_operand:XF 3 "memory_operand" ""))]
2355 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
2359 (float_extend:XF (match_dup 2)))]
2363 [(set (match_operand:XF 0 "register_operand" "")
2364 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
2365 (clobber (match_operand:DF 2 "memory_operand" ""))
2366 (clobber (match_operand:XF 3 "memory_operand" ""))]
2367 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
2369 (float_extend:XF (match_dup 1)))
2375 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2376 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))
2377 (clobber (match_operand:DF 2 "memory_operand" ""))
2378 (clobber (match_operand:XF 3 "memory_operand" ""))]
2379 "TARGET_80387 && reload_completed"
2381 (float_extend:XF (match_dup 1)))]
2385 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
2386 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
2387 "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2388 || GET_CODE (operands[1]) != MEM)"
2391 output_float_extend (insn, operands);
2394 [(set_attr "type" "fld,fpop")])
2396 (define_expand "extendsfxf2"
2397 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
2399 (match_operand:SF 1 "nonimmediate_operand" "")))
2400 (clobber (match_dup 2))
2401 (clobber (match_dup 3))])]
2405 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2406 operands[1] = force_reg (SFmode, operands[1]);
2408 operands[2] = assign_386_stack_local (SFmode, 0);
2409 operands[3] = assign_386_stack_local (XFmode, 0);
2413 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r")
2415 (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f")))
2416 (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m"))
2417 (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
2418 "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2419 || GET_CODE (operands[1]) != MEM)"
2422 output_float_extend (insn, operands);
2425 [(set_attr "type" "fld,fpop,fld,fpop")])
2428 [(set (match_operand:XF 0 "register_operand" "")
2429 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
2430 (clobber (match_operand:SF 2 "memory_operand" ""))
2431 (clobber (match_operand:XF 3 "memory_operand" ""))]
2432 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
2436 (float_extend:XF (match_dup 2)))]
2440 [(set (match_operand:XF 0 "register_operand" "")
2441 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
2442 (clobber (match_operand:SF 2 "memory_operand" ""))
2443 (clobber (match_operand:XF 3 "memory_operand" ""))]
2444 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
2446 (float_extend:XF (match_dup 1)))
2452 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2453 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))
2454 (clobber (match_operand:SF 2 "memory_operand" ""))
2455 (clobber (match_operand:XF 3 "memory_operand" ""))]
2456 "TARGET_80387 && reload_completed"
2458 (float_extend:XF (match_dup 1)))]
2462 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
2464 (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2465 "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2466 || GET_CODE (operands[1]) != MEM)"
2469 output_float_extend (insn, operands);
2472 [(set_attr "type" "fld,fpop")])
2474 (define_expand "truncdfsf2"
2475 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2477 (match_operand:DF 1 "register_operand" "")))
2478 (clobber (match_dup 2))])]
2482 operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2486 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r")
2488 (match_operand:DF 1 "register_operand" "0,f,f")))
2489 (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))]
2493 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2496 xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
2498 if (stack_top_dies || STACK_REG_P (operands[0]))
2499 output_asm_insn (AS1 (fstp%z0,%0), xops);
2501 output_asm_insn (AS1 (fst%z0,%0), xops);
2503 if (STACK_REG_P (operands[0]))
2504 return AS1 (fld%z2,%2);
2505 else if (NON_STACK_REG_P (operands[0]))
2506 return AS2 (mov%L0,%2,%0);
2510 [(set_attr "type" "fpop")])
2513 [(set (match_operand:SF 0 "register_operand" "")
2514 (float_truncate:SF (match_operand:DF 1 "register_operand" "")))
2515 (clobber (match_operand:SF 2 "memory_operand" ""))]
2516 "TARGET_80387 && reload_completed"
2518 (float_truncate:SF (match_dup 1)))
2524 [(set (match_operand:SF 0 "memory_operand" "")
2525 (float_truncate:SF (match_operand:DF 1 "register_operand" "")))
2526 (clobber (match_operand:SF 2 "memory_operand" ""))]
2527 "TARGET_80387 && reload_completed"
2529 (float_truncate:SF (match_dup 1)))]
2532 ;; This cannot output into an f-reg because there is no way to be sure
2533 ;; of truncating in that case.
2536 [(set (match_operand:SF 0 "memory_operand" "=m")
2537 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2541 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2544 return AS1 (fstp%z0,%0);
2546 return AS1 (fst%z0,%0);
2548 [(set_attr "type" "fpop")])
2550 (define_expand "truncxfsf2"
2551 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2553 (match_operand:XF 1 "register_operand" "")))
2554 (clobber (match_dup 2))])]
2558 operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2562 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r")
2564 (match_operand:XF 1 "register_operand" "0,f,f")))
2565 (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))]
2569 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2572 xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
2574 if (stack_top_dies || STACK_REG_P (operands[0]))
2575 output_asm_insn (AS1 (fstp%z0,%0), xops);
2577 output_asm_insn (AS1 (fst%z0,%0), xops);
2579 if (STACK_REG_P (operands[0]))
2580 return AS1 (fld%z2,%2);
2581 else if (NON_STACK_REG_P (operands[0]))
2582 return AS2 (mov%L0,%2,%0);
2586 [(set_attr "type" "fpop")])
2589 [(set (match_operand:SF 0 "register_operand" "")
2590 (float_truncate:SF (match_operand:XF 1 "register_operand" "")))
2591 (clobber (match_operand:SF 2 "memory_operand" ""))]
2592 "TARGET_80387 && reload_completed"
2594 (float_truncate:SF (match_dup 1)))
2600 [(set (match_operand:SF 0 "memory_operand" "")
2601 (float_truncate:SF (match_operand:XF 1 "register_operand" "")))
2602 (clobber (match_operand:SF 2 "memory_operand" ""))]
2603 "TARGET_80387 && reload_completed"
2605 (float_truncate:SF (match_dup 1)))]
2609 [(set (match_operand:SF 0 "memory_operand" "=m")
2610 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
2614 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2617 return AS1 (fstp%z0,%0);
2619 return AS1 (fst%z0,%0);
2621 [(set_attr "type" "fpop")])
2623 (define_expand "truncxfdf2"
2624 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2626 (match_operand:XF 1 "register_operand" "")))
2627 (clobber (match_dup 2))])]
2631 operands[2] = (rtx) assign_386_stack_local (DFmode, 0);
2635 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r")
2637 (match_operand:XF 1 "register_operand" "0,f,f")))
2638 (clobber (match_operand:DF 2 "memory_operand" "m,m,o"))]
2642 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2645 xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
2647 if (stack_top_dies || STACK_REG_P (operands[0]))
2648 output_asm_insn (AS1 (fstp%z0,%0), xops);
2650 output_asm_insn (AS1 (fst%z0,%0), xops);
2652 if (STACK_REG_P (operands[0]))
2653 return AS1 (fld%z2,%2);
2654 else if (NON_STACK_REG_P (operands[0]))
2656 xops[0] = operands[0];
2657 xops[1] = operands[2];
2658 output_asm_insn (output_move_double (xops), xops);
2663 [(set_attr "type" "fpop")])
2666 [(set (match_operand:DF 0 "register_operand" "")
2667 (float_truncate:DF (match_operand:XF 1 "register_operand" "")))
2668 (clobber (match_operand:DF 2 "memory_operand" ""))]
2669 "TARGET_80387 && reload_completed"
2671 (float_truncate:DF (match_dup 1)))
2677 [(set (match_operand:DF 0 "memory_operand" "")
2678 (float_truncate:DF (match_operand:XF 1 "register_operand" "")))
2679 (clobber (match_operand:DF 2 "memory_operand" ""))]
2680 "TARGET_80387 && reload_completed"
2682 (float_truncate:DF (match_dup 1)))]
2686 [(set (match_operand:DF 0 "memory_operand" "=m")
2687 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
2691 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2694 return AS1 (fstp%z0,%0);
2696 return AS1 (fst%z0,%0);
2698 [(set_attr "type" "fpop")])
2700 ;; Conversions between floating point and fix point.
2702 (define_expand "fix_truncsfsi2"
2703 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2704 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))
2705 (clobber (match_dup 2))
2706 (clobber (match_dup 3))
2707 (clobber (match_dup 4))
2708 (clobber (match_scratch:HI 5 ""))])]
2712 operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2713 operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2714 operands[4] = (rtx) assign_386_stack_local (SImode, 0);
2718 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r")
2719 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
2720 (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2721 (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2722 (clobber (match_operand:SI 4 "memory_operand" "m,m"))
2723 (clobber (match_scratch:HI 5 "=&r,&r"))]
2725 "* return output_fix_trunc (insn, operands);"
2726 [(set_attr "type" "fpop")])
2728 (define_expand "fix_truncsfdi2"
2729 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2730 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
2731 (clobber (match_dup 1))
2732 (clobber (match_dup 2))
2733 (clobber (match_dup 3))
2734 (clobber (match_dup 4))
2735 (clobber (match_scratch:HI 5 ""))])]
2739 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
2740 operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2741 operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2742 operands[4] = (rtx) assign_386_stack_local (DImode, 0);
2746 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r")
2747 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
2748 (clobber (match_dup 1))
2749 (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2750 (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2751 (clobber (match_operand:DI 4 "memory_operand" "m,o"))
2752 (clobber (match_scratch:HI 5 "=&r,&r"))]
2754 "* return output_fix_trunc (insn, operands);"
2755 [(set_attr "type" "fpop")])
2757 (define_expand "fix_truncdfsi2"
2758 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2759 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" ""))))
2760 (clobber (match_dup 2))
2761 (clobber (match_dup 3))
2762 (clobber (match_dup 4))
2763 (clobber (match_scratch:HI 5 ""))])]
2767 operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2768 operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2769 operands[4] = (rtx) assign_386_stack_local (SImode, 0);
2773 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r")
2774 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
2775 (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2776 (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2777 (clobber (match_operand:SI 4 "memory_operand" "m,m"))
2778 (clobber (match_scratch:HI 5 "=&r,&r"))]
2780 "* return output_fix_trunc (insn, operands);"
2781 [(set_attr "type" "fpop")])
2783 (define_expand "fix_truncdfdi2"
2784 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2785 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
2786 (clobber (match_dup 1))
2787 (clobber (match_dup 2))
2788 (clobber (match_dup 3))
2789 (clobber (match_dup 4))
2790 (clobber (match_scratch:HI 5 ""))])]
2794 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
2795 operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2796 operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2797 operands[4] = (rtx) assign_386_stack_local (DImode, 0);
2801 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r")
2802 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
2803 (clobber (match_dup 1))
2804 (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2805 (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2806 (clobber (match_operand:DI 4 "memory_operand" "m,o"))
2807 (clobber (match_scratch:HI 5 "=&r,&r"))]
2809 "* return output_fix_trunc (insn, operands);"
2810 [(set_attr "type" "fpop")])
2812 (define_expand "fix_truncxfsi2"
2813 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2814 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" ""))))
2815 (clobber (match_dup 2))
2816 (clobber (match_dup 3))
2817 (clobber (match_dup 4))
2818 (clobber (match_scratch:HI 5 ""))])]
2822 operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2823 operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2824 operands[4] = (rtx) assign_386_stack_local (SImode, 0);
2828 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r")
2829 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
2830 (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2831 (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2832 (clobber (match_operand:SI 4 "memory_operand" "m,m"))
2833 (clobber (match_scratch:HI 5 "=&r,&r"))]
2835 "* return output_fix_trunc (insn, operands);"
2836 [(set_attr "type" "fpop")])
2838 (define_expand "fix_truncxfdi2"
2839 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2840 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" ""))))
2841 (clobber (match_dup 1))
2842 (clobber (match_dup 2))
2843 (clobber (match_dup 3))
2844 (clobber (match_dup 4))
2845 (clobber (match_scratch:HI 5 ""))])]
2849 operands[1] = copy_to_mode_reg (XFmode, operands[1]);
2850 operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2851 operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2852 operands[4] = (rtx) assign_386_stack_local (DImode, 0);
2856 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r")
2857 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
2858 (clobber (match_dup 1))
2859 (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2860 (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2861 (clobber (match_operand:DI 4 "memory_operand" "m,o"))
2862 (clobber (match_scratch:HI 5 "=&r,&r"))]
2864 "* return output_fix_trunc (insn, operands);"
2865 [(set_attr "type" "fpop")])
2867 ;; Conversion between fixed point and floating point.
2869 ;; ??? Possibly represent floatunssidf2 here in gcc2.
2871 (define_expand "floatsisf2"
2872 [(parallel [(set (match_operand:SF 0 "register_operand" "")
2873 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))
2874 (clobber (match_dup 2))])]
2876 "operands[2] = assign_386_stack_local (SImode, 0);")
2879 [(set (match_operand:SF 0 "register_operand" "=f,f")
2880 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
2881 (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
2886 [(set (match_operand:SF 0 "register_operand" "")
2887 (float:SF (match_operand:SI 1 "memory_operand" "")))
2888 (clobber (match_operand:SI 2 "memory_operand" ""))]
2889 "TARGET_80387 && reload_completed"
2891 (float:SF (match_dup 1)))]
2895 [(set (match_operand:SF 0 "register_operand" "")
2896 (float:SF (match_operand:SI 1 "register_operand" "")))
2897 (clobber (match_operand:SI 2 "memory_operand" ""))]
2898 "TARGET_80387 && reload_completed"
2902 (float:SF (match_dup 2)))]
2906 [(set (match_operand:SF 0 "register_operand" "=f")
2907 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
2909 "* return AS1 (fild%z1,%1);"
2910 [(set_attr "type" "fpop")])
2912 (define_expand "floathisf2"
2913 [(parallel [(set (match_operand:SF 0 "register_operand" "")
2914 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))
2915 (clobber (match_dup 2))])]
2917 "operands[2] = assign_386_stack_local (HImode, 0);")
2920 [(set (match_operand:SF 0 "register_operand" "=f,f")
2921 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
2922 (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
2927 [(set (match_operand:SF 0 "register_operand" "")
2928 (float:SF (match_operand:HI 1 "memory_operand" "")))
2929 (clobber (match_operand:HI 2 "memory_operand" ""))]
2930 "TARGET_80387 && reload_completed"
2932 (float:SF (match_dup 1)))]
2936 [(set (match_operand:SF 0 "register_operand" "")
2937 (float:SF (match_operand:HI 1 "register_operand" "")))
2938 (clobber (match_operand:HI 2 "memory_operand" ""))]
2939 "TARGET_80387 && reload_completed"
2943 (float:SF (match_dup 2)))]
2947 [(set (match_operand:SF 0 "register_operand" "=f")
2948 (float:SF (match_operand:HI 1 "memory_operand" "m")))]
2950 "* return AS1 (fild%z1,%1);"
2951 [(set_attr "type" "fpop")])
2953 (define_expand "floatdisf2"
2954 [(parallel [(set (match_operand:SF 0 "register_operand" "")
2955 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))
2956 (clobber (match_dup 2))])]
2958 "operands[2] = assign_386_stack_local (DImode, 0);")
2961 [(set (match_operand:SF 0 "register_operand" "=f,f")
2962 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
2963 (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
2968 [(set (match_operand:SF 0 "register_operand" "")
2969 (float:SF (match_operand:DI 1 "memory_operand" "")))
2970 (clobber (match_operand:DI 2 "memory_operand" ""))]
2971 "TARGET_80387 && reload_completed"
2973 (float:SF (match_dup 1)))]
2977 [(set (match_operand:SF 0 "register_operand" "")
2978 (float:SF (match_operand:DI 1 "register_operand" "")))
2979 (clobber (match_operand:DI 2 "memory_operand" ""))]
2980 "TARGET_80387 && reload_completed"
2984 (float:SF (match_dup 2)))]
2988 [(set (match_operand:SF 0 "register_operand" "=f")
2989 (float:SF (match_operand:DI 1 "memory_operand" "m")))]
2991 "* return AS1 (fild%z1,%1);"
2992 [(set_attr "type" "fpop")])
2994 (define_expand "floatsidf2"
2995 [(parallel [(set (match_operand:DF 0 "register_operand" "")
2996 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
2997 (clobber (match_dup 2))])]
2999 "operands[2] = assign_386_stack_local (SImode, 0);")
3002 [(set (match_operand:DF 0 "register_operand" "=f,f")
3003 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
3004 (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
3009 [(set (match_operand:DF 0 "register_operand" "")
3010 (float:DF (match_operand:SI 1 "memory_operand" "")))
3011 (clobber (match_operand:SI 2 "memory_operand" ""))]
3012 "TARGET_80387 && reload_completed"
3014 (float:DF (match_dup 1)))]
3018 [(set (match_operand:DF 0 "register_operand" "")
3019 (float:DF (match_operand:SI 1 "register_operand" "")))
3020 (clobber (match_operand:SI 2 "memory_operand" ""))]
3021 "TARGET_80387 && reload_completed"
3025 (float:DF (match_dup 2)))]
3029 [(set (match_operand:DF 0 "register_operand" "=f")
3030 (float:DF (match_operand:SI 1 "memory_operand" "m")))]
3032 "* return AS1 (fild%z1,%1);"
3033 [(set_attr "type" "fpop")])
3035 (define_expand "floathidf2"
3036 [(parallel [(set (match_operand:DF 0 "register_operand" "")
3037 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))
3038 (clobber (match_dup 2))])]
3040 "operands[2] = assign_386_stack_local (HImode, 0);")
3043 [(set (match_operand:DF 0 "register_operand" "=f,f")
3044 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
3045 (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
3050 [(set (match_operand:DF 0 "register_operand" "")
3051 (float:DF (match_operand:HI 1 "memory_operand" "")))
3052 (clobber (match_operand:HI 2 "memory_operand" ""))]
3053 "TARGET_80387 && reload_completed"
3055 (float:DF (match_dup 1)))]
3059 [(set (match_operand:DF 0 "register_operand" "")
3060 (float:DF (match_operand:HI 1 "register_operand" "")))
3061 (clobber (match_operand:HI 2 "memory_operand" ""))]
3062 "TARGET_80387 && reload_completed"
3066 (float:DF (match_dup 2)))]
3070 [(set (match_operand:DF 0 "register_operand" "=f")
3071 (float:DF (match_operand:HI 1 "memory_operand" "m")))]
3073 "* return AS1 (fild%z1,%1);"
3074 [(set_attr "type" "fpop")])
3076 (define_expand "floatdidf2"
3077 [(parallel [(set (match_operand:DF 0 "register_operand" "")
3078 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))
3079 (clobber (match_dup 2))])]
3081 "operands[2] = assign_386_stack_local (DImode, 0);")
3084 [(set (match_operand:DF 0 "register_operand" "=f,f")
3085 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
3086 (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
3091 [(set (match_operand:DF 0 "register_operand" "")
3092 (float:DF (match_operand:DI 1 "memory_operand" "")))
3093 (clobber (match_operand:DI 2 "memory_operand" ""))]
3094 "TARGET_80387 && reload_completed"
3096 (float:DF (match_dup 1)))]
3100 [(set (match_operand:DF 0 "register_operand" "")
3101 (float:DF (match_operand:DI 1 "register_operand" "")))
3102 (clobber (match_operand:DI 2 "memory_operand" ""))]
3103 "TARGET_80387 && reload_completed"
3107 (float:DF (match_dup 2)))]
3111 [(set (match_operand:DF 0 "register_operand" "=f")
3112 (float:DF (match_operand:DI 1 "memory_operand" "m")))]
3114 "* return AS1 (fild%z1,%1);"
3115 [(set_attr "type" "fpop")])
3117 (define_expand "floatsixf2"
3118 [(parallel [(set (match_operand:XF 0 "register_operand" "")
3119 (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))
3120 (clobber (match_dup 2))])]
3122 "operands[2] = assign_386_stack_local (SImode, 0);")
3125 [(set (match_operand:XF 0 "register_operand" "=f,f")
3126 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
3127 (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
3132 [(set (match_operand:XF 0 "register_operand" "")
3133 (float:XF (match_operand:SI 1 "memory_operand" "")))
3134 (clobber (match_operand:SI 2 "memory_operand" ""))]
3135 "TARGET_80387 && reload_completed"
3137 (float:XF (match_dup 1)))]
3141 [(set (match_operand:XF 0 "register_operand" "")
3142 (float:XF (match_operand:SI 1 "register_operand" "")))
3143 (clobber (match_operand:SI 2 "memory_operand" ""))]
3144 "TARGET_80387 && reload_completed"
3148 (float:XF (match_dup 2)))]
3152 [(set (match_operand:XF 0 "register_operand" "=f")
3153 (float:XF (match_operand:SI 1 "memory_operand" "m")))]
3155 "* return AS1 (fild%z1,%1);"
3156 [(set_attr "type" "fpop")])
3158 (define_expand "floathixf2"
3159 [(parallel [(set (match_operand:XF 0 "register_operand" "")
3160 (float:XF (match_operand:HI 1 "nonimmediate_operand" "")))
3161 (clobber (match_dup 2))])]
3163 "operands[2] = assign_386_stack_local (HImode, 0);")
3166 [(set (match_operand:XF 0 "register_operand" "=f,f")
3167 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
3168 (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
3173 [(set (match_operand:XF 0 "register_operand" "")
3174 (float:XF (match_operand:HI 1 "memory_operand" "")))
3175 (clobber (match_operand:HI 2 "memory_operand" ""))]
3176 "TARGET_80387 && reload_completed"
3178 (float:XF (match_dup 1)))]
3182 [(set (match_operand:XF 0 "register_operand" "")
3183 (float:XF (match_operand:HI 1 "register_operand" "")))
3184 (clobber (match_operand:HI 2 "memory_operand" ""))]
3185 "TARGET_80387 && reload_completed"
3189 (float:XF (match_dup 2)))]
3193 [(set (match_operand:XF 0 "register_operand" "=f")
3194 (float:XF (match_operand:HI 1 "memory_operand" "m")))]
3196 "* return AS1 (fild%z1,%1);"
3197 [(set_attr "type" "fpop")])
3199 (define_expand "floatdixf2"
3200 [(parallel [(set (match_operand:XF 0 "register_operand" "")
3201 (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))
3202 (clobber (match_dup 2))])]
3204 "operands[2] = assign_386_stack_local (DImode, 0);")
3207 [(set (match_operand:XF 0 "register_operand" "=f,f")
3208 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
3209 (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
3214 [(set (match_operand:XF 0 "register_operand" "")
3215 (float:XF (match_operand:DI 1 "memory_operand" "")))
3216 (clobber (match_operand:DI 2 "memory_operand" ""))]
3217 "TARGET_80387 && reload_completed"
3219 (float:XF (match_dup 1)))]
3223 [(set (match_operand:XF 0 "register_operand" "")
3224 (float:XF (match_operand:DI 1 "register_operand" "")))
3225 (clobber (match_operand:DI 2 "memory_operand" ""))]
3226 "TARGET_80387 && reload_completed"
3230 (float:XF (match_dup 2)))]
3234 [(set (match_operand:XF 0 "register_operand" "=f")
3235 (float:XF (match_operand:DI 1 "memory_operand" "m")))]
3237 "* return AS1 (fild%z1,%1);"
3238 [(set_attr "type" "fpop")])
3240 ;;- add instructions
3242 (define_insn "*addsidi3_1"
3243 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o")
3244 (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o")
3245 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri"))))
3246 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))]
3250 rtx low[3], high[3], xops[7];
3254 split_di (operands, 2, low, high);
3255 high[2] = const0_rtx;
3256 low[2] = operands[2];
3258 if (!rtx_equal_p (operands[0], operands[1]))
3265 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3267 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3268 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3274 xops[6] = operands[3];
3275 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3276 output_asm_insn (AS2 (add%L6,%5,%6), xops);
3277 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3278 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3279 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3280 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3285 output_asm_insn (AS2 (add%L0,%2,%0), low);
3286 output_asm_insn (AS2 (adc%L0,%2,%0), high);
3287 cc_status.value1 = high[0];
3288 cc_status.flags = CC_NO_OVERFLOW;
3291 [(set_attr "type" "binary")])
3293 (define_insn "addsidi3_2"
3294 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o")
3295 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r"))
3296 (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o")))
3297 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))]
3301 rtx low[3], high[3], xops[7];
3305 split_di (operands, 2, low, high);
3306 high[2] = const0_rtx;
3307 low[2] = operands[2];
3309 if (!rtx_equal_p (operands[0], operands[1]))
3316 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3318 if (rtx_equal_p (low[0], operands[2]))
3320 output_asm_insn (AS2 (mov%L0,%2,%0), high);
3321 output_asm_insn (AS2 (add%L0,%1,%0), low);
3322 output_asm_insn (AS2 (adc%L0,%1,%0), high);
3325 if (rtx_equal_p (high[0], operands[2]))
3327 if (GET_CODE (operands[0]) != MEM)
3329 output_asm_insn (AS2 (mov%L0,%2,%0), low);
3330 output_asm_insn (AS2 (mov%L0,%2,%0), high);
3331 output_asm_insn (AS2 (add%L0,%1,%0), low);
3332 output_asm_insn (AS2 (adc%L0,%1,%0), high);
3336 /* It's too late to ask for a scratch now - but this
3337 will probably not happen too often. */
3338 output_asm_insn (AS2 (add%L1,%2,%1), low);
3339 output_asm_insn (AS2 (mov%L0,%1,%0), low);
3340 output_asm_insn (AS2 (mov%L1,%2,%1), low);
3341 output_asm_insn (AS2 (mov%L0,%2,%0), high);
3342 output_asm_insn (AS2 (adc%L0,%1,%0), high);
3343 output_asm_insn (AS2 (sub%L1,%0,%1), low);
3344 output_asm_insn (AS1 (neg%L1,%1), low);
3348 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3349 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3355 xops[6] = operands[3];
3356 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3357 output_asm_insn (AS2 (add%L6,%5,%6), xops);
3358 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3359 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3360 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3361 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3366 output_asm_insn (AS2 (add%L0,%2,%0), low);
3367 output_asm_insn (AS2 (adc%L0,%2,%0), high);
3368 cc_status.value1 = high[0];
3369 cc_status.flags = CC_NO_OVERFLOW;
3372 [(set_attr "type" "binary")])
3374 (define_insn "adddi3"
3375 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
3376 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
3377 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
3378 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
3382 rtx low[3], high[3], xops[7], temp;
3386 if (rtx_equal_p (operands[0], operands[2]))
3389 operands[1] = operands[2];
3393 split_di (operands, 3, low, high);
3394 if (!rtx_equal_p (operands[0], operands[1]))
3401 if (GET_CODE (operands[0]) != MEM)
3403 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3404 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3410 xops[6] = operands[3];
3411 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3412 output_asm_insn (AS2 (add%L6,%5,%6), xops);
3413 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3414 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3415 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3416 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3421 cc_status.value1 = high[0];
3422 cc_status.flags = CC_NO_OVERFLOW;
3424 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
3430 xops[4] = operands[3];
3432 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3433 output_asm_insn (AS2 (add%L1,%4,%1), xops);
3434 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3435 output_asm_insn (AS2 (adc%L0,%4,%0), xops);
3438 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
3440 output_asm_insn (AS2 (add%L0,%2,%0), low);
3441 output_asm_insn (AS2 (adc%L0,%2,%0), high);
3445 output_asm_insn (AS2 (add%L0,%2,%0), high);
3449 [(set_attr "type" "binary")])
3451 ;; On a 486, it is faster to do movl/addl than to do a single leal if
3452 ;; operands[1] and operands[2] are both registers.
3454 (define_expand "addsi3"
3455 [(set (match_operand:SI 0 "nonimmediate_operand" "")
3456 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3457 (match_operand:SI 2 "general_operand" "")))]
3459 "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);")
3462 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
3463 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
3464 (match_operand:SI 2 "general_operand" "rmi,ri,ri")))]
3465 "ix86_binary_operator_ok (PLUS, SImode, operands)"
3468 if (REG_P (operands[0]) && REG_P (operands[1])
3469 && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
3470 && REGNO (operands[0]) != REGNO (operands[1]))
3472 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3473 return AS2 (add%L0,%1,%0);
3475 if (operands[2] == stack_pointer_rtx)
3480 operands[1] = operands[2];
3484 if (operands[2] != stack_pointer_rtx)
3487 operands[1] = SET_SRC (PATTERN (insn));
3488 return AS2 (lea%L0,%a1,%0);
3492 if (!rtx_equal_p (operands[0], operands[1]))
3493 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
3495 if (operands[2] == const1_rtx)
3496 return AS1 (inc%L0,%0);
3498 if (operands[2] == constm1_rtx)
3499 return AS1 (dec%L0,%0);
3501 /* subl $-128,%ebx is smaller than addl $128,%ebx. */
3502 if (GET_CODE (operands[2]) == CONST_INT
3503 && INTVAL (operands[2]) == 128)
3505 /* This doesn't compute the carry bit in the same way
3506 * as add%L0, but we use inc and dec above and they
3507 * don't set the carry bit at all. If inc/dec don't need
3508 * a CC_STATUS_INIT, this doesn't either... */
3509 operands[2] = GEN_INT (-128);
3510 return AS2 (sub%L0,%2,%0);
3513 return AS2 (add%L0,%2,%0);
3515 [(set_attr "type" "binary")])
3517 ;; addsi3 is faster, so put this after.
3519 (define_insn "movsi_lea"
3520 [(set (match_operand:SI 0 "register_operand" "=r")
3521 (match_operand:QI 1 "address_operand" "p"))]
3525 /* Adding a constant to a register is faster with an add. */
3526 /* ??? can this ever happen? */
3527 if (GET_CODE (operands[1]) == PLUS
3528 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
3529 && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
3531 operands[1] = XEXP (operands[1], 1);
3533 if (operands[1] == const1_rtx)
3534 return AS1 (inc%L0,%0);
3536 if (operands[1] == constm1_rtx)
3537 return AS1 (dec%L0,%0);
3539 return AS2 (add%L0,%1,%0);
3543 return AS2 (lea%L0,%a1,%0);
3545 [(set_attr "type" "lea")])
3547 ;; ??? `lea' here, for three operand add? If leaw is used, only %bx,
3548 ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
3549 ;; able to handle the operand. But leal always works?
3551 (define_expand "addhi3"
3552 [(set (match_operand:HI 0 "general_operand" "")
3553 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3554 (match_operand:HI 2 "general_operand" "")))]
3556 "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);")
3559 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,?r")
3560 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
3561 (match_operand:HI 2 "general_operand" "ri,rm,ri")))]
3562 "ix86_binary_operator_ok (PLUS, HImode, operands)"
3565 if (REG_P (operands[0]) && REG_P (operands[1])
3566 && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
3567 && REGNO (operands[0]) != REGNO (operands[1]))
3569 if (operands[2] == stack_pointer_rtx)
3574 = gen_rtx_PLUS (SImode,
3575 gen_rtx_REG (SImode, REGNO (operands[1])),
3576 (! REG_P (operands[2])
3578 : gen_rtx_REG (SImode, REGNO (operands[2]))));
3579 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
3580 return AS2 (lea%L0,%a1,%0);
3583 /* ??? what about offsettable memory references? */
3584 if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */
3585 && QI_REG_P (operands[0])
3586 && GET_CODE (operands[2]) == CONST_INT
3587 && (INTVAL (operands[2]) & 0xff) == 0
3588 && i386_cc_probably_useless_p (insn))
3590 int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
3594 return AS1 (inc%B0,%h0);
3595 else if (byteval == 255)
3596 return AS1 (dec%B0,%h0);
3598 operands[2] = GEN_INT (byteval);
3599 return AS2 (add%B0,%2,%h0);
3602 /* Use a 32-bit operation when possible, to avoid the prefix penalty. */
3603 if (REG_P (operands[0])
3604 && i386_aligned_p (operands[2])
3605 && i386_cc_probably_useless_p (insn))
3609 if (GET_CODE (operands[2]) == CONST_INT)
3611 HOST_WIDE_INT intval = 0xffff & INTVAL (operands[2]);
3614 return AS1 (inc%L0,%k0);
3616 if (intval == 0xffff)
3617 return AS1 (dec%L0,%k0);
3619 operands[2] = i386_sext16_if_const (operands[2]);
3621 return AS2 (add%L0,%k2,%k0);
3624 if (operands[2] == const1_rtx)
3625 return AS1 (inc%W0,%0);
3627 if (operands[2] == constm1_rtx
3628 || (GET_CODE (operands[2]) == CONST_INT
3629 && INTVAL (operands[2]) == 65535))
3630 return AS1 (dec%W0,%0);
3632 return AS2 (add%W0,%2,%0);
3634 [(set_attr "type" "binary")])
3636 (define_expand "addqi3"
3637 [(set (match_operand:QI 0 "general_operand" "")
3638 (plus:QI (match_operand:QI 1 "general_operand" "")
3639 (match_operand:QI 2 "general_operand" "")))]
3641 "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);")
3644 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,?q")
3645 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q")
3646 (match_operand:QI 2 "general_operand" "qn,qmn,qn")))]
3647 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3650 if (REG_P (operands[0]) && REG_P (operands[1])
3651 && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
3652 && (REGNO (operands[0]) != REGNO (operands[1])
3653 || NON_QI_REG_P (operands[1])
3654 || (REG_P (operands[2]) && NON_QI_REG_P (operands[2]))))
3656 if (operands[2] == stack_pointer_rtx)
3661 = gen_rtx_PLUS (SImode,
3662 gen_rtx_REG (SImode, REGNO (operands[1])),
3663 (! REG_P (operands[2])
3665 : gen_rtx_REG (SImode, REGNO (operands[2]))));
3666 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
3667 return AS2 (lea%L0,%a1,%0);
3669 if (operands[2] == const1_rtx)
3670 return AS1 (inc%B0,%0);
3672 if (operands[2] == constm1_rtx
3673 || (GET_CODE (operands[2]) == CONST_INT
3674 && INTVAL (operands[2]) == 255))
3675 return AS1 (dec%B0,%0);
3677 return AS2 (add%B0,%2,%0);
3679 [(set_attr "type" "binary")])
3681 ;Lennart Augustsson <augustss@cs.chalmers.se>
3682 ;says this pattern just makes slower code:
3686 ; leal -80(%ebp),%eax
3690 ; [(set (match_operand:SI 0 "push_operand" "=<")
3691 ; (plus:SI (match_operand:SI 1 "register_operand" "%r")
3692 ; (match_operand:SI 2 "nonmemory_operand" "ri")))]
3697 ; xops[0] = operands[0];
3698 ; xops[1] = operands[1];
3699 ; xops[2] = operands[2];
3700 ; xops[3] = gen_rtx_MEM (SImode, stack_pointer_rtx);
3701 ; output_asm_insn (\"push%z1 %1\", xops);
3702 ; output_asm_insn (AS2 (add%z3,%2,%3), xops);
3706 ;; The patterns that match these are at the end of this file.
3708 (define_expand "addxf3"
3709 [(set (match_operand:XF 0 "register_operand" "")
3710 (plus:XF (match_operand:XF 1 "register_operand" "")
3711 (match_operand:XF 2 "register_operand" "")))]
3715 (define_expand "adddf3"
3716 [(set (match_operand:DF 0 "register_operand" "")
3717 (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3718 (match_operand:DF 2 "nonimmediate_operand" "")))]
3722 (define_expand "addsf3"
3723 [(set (match_operand:SF 0 "register_operand" "")
3724 (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3725 (match_operand:SF 2 "nonimmediate_operand" "")))]
3729 ;;- subtract instructions
3731 (define_insn "subsidi3"
3732 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o")
3733 (minus:DI (match_operand:DI 1 "general_operand" "0iF,0,roiF,roiF,riF,o,o")
3734 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,ri,i,r"))))
3735 (clobber (match_scratch:SI 3 "=X,X,X,X,X,&r,&r"))]
3739 rtx low[3], high[3], xops[7];
3743 split_di (operands, 2, low, high);
3744 high[2] = const0_rtx;
3745 low[2] = operands[2];
3747 if (!rtx_equal_p (operands[0], operands[1]))
3754 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3756 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3757 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3763 xops[6] = operands[3];
3764 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3765 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3766 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3767 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3768 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3769 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3774 output_asm_insn (AS2 (sub%L0,%2,%0), low);
3775 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3776 cc_status.value1 = high[0];
3777 cc_status.flags = CC_NO_OVERFLOW;
3781 [(set_attr "type" "binary")])
3783 (define_insn "subdi3"
3784 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
3785 (minus:DI (match_operand:DI 1 "general_operand" "0,0,0iF,or,roiF,roiF")
3786 (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
3787 (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
3791 rtx low[3], high[3], xops[7];
3795 split_di (operands, 3, low, high);
3797 if (!rtx_equal_p (operands[0], operands[1]))
3804 if (GET_CODE (operands[0]) != MEM)
3806 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3807 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3813 xops[6] = operands[3];
3814 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3815 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3816 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3817 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3818 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3819 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3824 cc_status.value1 = high[0];
3825 cc_status.flags = CC_NO_OVERFLOW;
3827 if (GET_CODE (operands[3]) == REG)
3833 xops[4] = operands[3];
3835 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3836 output_asm_insn (AS2 (sub%L1,%4,%1), xops);
3837 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3838 output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
3841 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
3843 output_asm_insn (AS2 (sub%L0,%2,%0), low);
3844 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3848 output_asm_insn (AS2 (sub%L0,%2,%0), high);
3853 [(set_attr "type" "binary")])
3855 (define_expand "subsi3"
3856 [(set (match_operand:SI 0 "nonimmediate_operand" "")
3857 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3858 (match_operand:SI 2 "general_operand" "")))]
3860 "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);")
3863 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3864 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
3865 (match_operand:SI 2 "general_operand" "ri,rm")))]
3866 "ix86_binary_operator_ok (MINUS, SImode, operands)"
3867 "* return AS2 (sub%L0,%2,%0);"
3868 [(set_attr "type" "binary")])
3870 (define_expand "subhi3"
3871 [(set (match_operand:HI 0 "general_operand" "")
3872 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3873 (match_operand:HI 2 "general_operand" "")))]
3875 "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);")
3878 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3879 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
3880 (match_operand:HI 2 "general_operand" "ri,rm")))]
3881 "ix86_binary_operator_ok (MINUS, HImode, operands)"
3884 if (REG_P (operands[0])
3885 && i386_aligned_p (operands[2])
3886 && i386_cc_probably_useless_p (insn))
3889 operands[2] = i386_sext16_if_const (operands[2]);
3890 return AS2 (sub%L0,%k2,%k0);
3892 return AS2 (sub%W0,%2,%0);
3894 [(set_attr "type" "binary")])
3896 (define_expand "subqi3"
3897 [(set (match_operand:QI 0 "general_operand" "")
3898 (minus:QI (match_operand:QI 1 "general_operand" "")
3899 (match_operand:QI 2 "general_operand" "")))]
3901 "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);")
3904 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3905 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
3906 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3907 "ix86_binary_operator_ok (MINUS, QImode, operands)"
3908 "* return AS2 (sub%B0,%2,%0);"
3909 [(set_attr "type" "binary")])
3911 ;; The patterns that match these are at the end of this file.
3913 (define_expand "subxf3"
3914 [(set (match_operand:XF 0 "register_operand" "")
3915 (minus:XF (match_operand:XF 1 "register_operand" "")
3916 (match_operand:XF 2 "register_operand" "")))]
3920 (define_expand "subdf3"
3921 [(set (match_operand:DF 0 "register_operand" "")
3922 (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3923 (match_operand:DF 2 "nonimmediate_operand" "")))]
3927 (define_expand "subsf3"
3928 [(set (match_operand:SF 0 "register_operand" "")
3929 (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3930 (match_operand:SF 2 "nonimmediate_operand" "")))]
3934 ;;- multiply instructions
3936 ;(define_insn "mulqi3"
3937 ; [(set (match_operand:QI 0 "register_operand" "=a")
3938 ; (mult:QI (match_operand:QI 1 "register_operand" "%0")
3939 ; (match_operand:QI 2 "nonimmediate_operand" "qm")))]
3943 (define_insn "mulhi3"
3944 [(set (match_operand:HI 0 "register_operand" "=r,r")
3945 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%0,rm")
3946 (match_operand:HI 2 "general_operand" "g,i")))]
3950 if (GET_CODE (operands[1]) == REG
3951 && REGNO (operands[1]) == REGNO (operands[0])
3952 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3953 /* Assembler has weird restrictions. */
3954 return AS2 (imul%W0,%2,%0);
3955 return AS3 (imul%W0,%2,%1,%0);
3957 [(set_attr "type" "imul")])
3959 (define_insn "mulsi3"
3960 [(set (match_operand:SI 0 "register_operand" "=r,r")
3961 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
3962 (match_operand:SI 2 "general_operand" "g,i")))]
3966 if (GET_CODE (operands[1]) == REG
3967 && REGNO (operands[1]) == REGNO (operands[0])
3968 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3969 /* Assembler has weird restrictions. */
3970 return AS2 (imul%L0,%2,%0);
3971 return AS3 (imul%L0,%2,%1,%0);
3973 [(set_attr "type" "imul")])
3975 (define_insn "umulqihi3"
3976 [(set (match_operand:HI 0 "register_operand" "=a")
3977 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3978 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3981 [(set_attr "type" "imul")])
3983 (define_insn "mulqihi3"
3984 [(set (match_operand:HI 0 "register_operand" "=a")
3985 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3986 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3989 [(set_attr "type" "imul")])
3991 (define_insn "umulsidi3"
3992 [(set (match_operand:DI 0 "register_operand" "=A")
3993 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3994 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
3995 "TARGET_WIDE_MULTIPLY"
3997 [(set_attr "type" "imul")])
3999 (define_insn "mulsidi3"
4000 [(set (match_operand:DI 0 "register_operand" "=A")
4001 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
4002 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
4003 "TARGET_WIDE_MULTIPLY"
4005 [(set_attr "type" "imul")])
4007 (define_insn "umulsi3_highpart"
4008 [(set (match_operand:SI 0 "register_operand" "=d")
4009 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
4010 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
4012 (clobber (match_scratch:SI 3 "=a"))]
4013 "TARGET_WIDE_MULTIPLY"
4015 [(set_attr "type" "imul")])
4017 (define_insn "smulsi3_highpart"
4018 [(set (match_operand:SI 0 "register_operand" "=d")
4019 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
4020 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
4022 (clobber (match_scratch:SI 3 "=a"))]
4023 "TARGET_WIDE_MULTIPLY"
4025 [(set_attr "type" "imul")])
4027 ;; The patterns that match these are at the end of this file.
4029 (define_expand "mulxf3"
4030 [(set (match_operand:XF 0 "register_operand" "")
4031 (mult:XF (match_operand:XF 1 "register_operand" "")
4032 (match_operand:XF 2 "register_operand" "")))]
4036 (define_expand "muldf3"
4037 [(set (match_operand:DF 0 "register_operand" "")
4038 (mult:DF (match_operand:DF 1 "register_operand" "")
4039 (match_operand:DF 2 "nonimmediate_operand" "")))]
4043 (define_expand "mulsf3"
4044 [(set (match_operand:SF 0 "register_operand" "")
4045 (mult:SF (match_operand:SF 1 "register_operand" "")
4046 (match_operand:SF 2 "nonimmediate_operand" "")))]
4050 ;;- divide instructions
4052 (define_insn "divqi3"
4053 [(set (match_operand:QI 0 "register_operand" "=a")
4054 (div:QI (match_operand:HI 1 "register_operand" "0")
4055 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
4059 (define_insn "udivqi3"
4060 [(set (match_operand:QI 0 "register_operand" "=a")
4061 (udiv:QI (match_operand:HI 1 "register_operand" "0")
4062 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
4065 [(set_attr "type" "idiv")])
4067 ;; The patterns that match these are at the end of this file.
4069 (define_expand "divxf3"
4070 [(set (match_operand:XF 0 "register_operand" "")
4071 (div:XF (match_operand:XF 1 "register_operand" "")
4072 (match_operand:XF 2 "register_operand" "")))]
4076 (define_expand "divdf3"
4077 [(set (match_operand:DF 0 "register_operand" "")
4078 (div:DF (match_operand:DF 1 "register_operand" "")
4079 (match_operand:DF 2 "nonimmediate_operand" "")))]
4083 (define_expand "divsf3"
4084 [(set (match_operand:SF 0 "register_operand" "")
4085 (div:SF (match_operand:SF 1 "register_operand" "")
4086 (match_operand:SF 2 "nonimmediate_operand" "")))]
4090 ;; Remainder instructions.
4092 (define_insn "divmodsi4"
4093 [(set (match_operand:SI 0 "register_operand" "=a")
4094 (div:SI (match_operand:SI 1 "register_operand" "0")
4095 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4096 (set (match_operand:SI 3 "register_operand" "=&d")
4097 (mod:SI (match_dup 1) (match_dup 2)))]
4102 output_asm_insn (\"cdq\", operands);
4104 output_asm_insn (\"cltd\", operands);
4106 return AS1 (idiv%L0,%2);
4108 [(set_attr "type" "idiv")])
4110 (define_insn "divmodhi4"
4111 [(set (match_operand:HI 0 "register_operand" "=a")
4112 (div:HI (match_operand:HI 1 "register_operand" "0")
4113 (match_operand:HI 2 "nonimmediate_operand" "rm")))
4114 (set (match_operand:HI 3 "register_operand" "=&d")
4115 (mod:HI (match_dup 1) (match_dup 2)))]
4118 [(set_attr "type" "idiv")])
4120 ;; ??? Can we make gcc zero extend operand[0]?
4121 (define_insn "udivmodsi4"
4122 [(set (match_operand:SI 0 "register_operand" "=a")
4123 (udiv:SI (match_operand:SI 1 "register_operand" "0")
4124 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4125 (set (match_operand:SI 3 "register_operand" "=&d")
4126 (umod:SI (match_dup 1) (match_dup 2)))]
4130 output_asm_insn (AS2 (xor%L3,%3,%3), operands);
4131 return AS1 (div%L0,%2);
4133 [(set_attr "type" "idiv")])
4135 ;; ??? Can we make gcc zero extend operand[0]?
4136 (define_insn "udivmodhi4"
4137 [(set (match_operand:HI 0 "register_operand" "=a")
4138 (udiv:HI (match_operand:HI 1 "register_operand" "0")
4139 (match_operand:HI 2 "nonimmediate_operand" "rm")))
4140 (set (match_operand:HI 3 "register_operand" "=&d")
4141 (umod:HI (match_dup 1) (match_dup 2)))]
4145 output_asm_insn (AS2 (xor%W0,%3,%3), operands);
4146 return AS1 (div%W0,%2);
4148 [(set_attr "type" "idiv")])
4151 ;;this should be a valid double division which we may want to add
4154 [(set (match_operand:SI 0 "register_operand" "=a")
4155 (udiv:DI (match_operand:DI 1 "register_operand" "a")
4156 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4157 (set (match_operand:SI 3 "register_operand" "=d")
4158 (umod:SI (match_dup 1) (match_dup 2)))]
4161 [(set_attr "type" "idiv")])
4164 ;;- and instructions
4171 ;; but if the reg is %eax, then the "andl" is faster.
4173 ;; On i486, the "andl" is always faster than the "movzbl".
4175 ;; On both i386 and i486, a three operand AND is as fast with movzbl or
4176 ;; movzwl as with andl, if operands[0] != operands[1].
4178 ;; The `r' in `rm' for operand 3 looks redundant, but it causes
4179 ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
4181 (define_insn "andsi3"
4182 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4183 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4184 (match_operand:SI 2 "general_operand" "ri,rm")))]
4188 HOST_WIDE_INT intval;
4189 if (!rtx_equal_p (operands[0], operands[1])
4190 && rtx_equal_p (operands[0], operands[2]))
4194 operands[1] = operands[2];
4197 switch (GET_CODE (operands[2]))
4200 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4202 intval = INTVAL (operands[2]);
4203 /* zero-extend 16->32? */
4204 if (intval == 0xffff && REG_P (operands[0])
4205 && (! REG_P (operands[1])
4206 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
4207 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
4209 /* ??? tege: Should forget CC_STATUS only if we clobber a
4210 remembered operand. Fix that later. */
4213 return AS2 (movzx,%w1,%0);
4215 return AS2 (movz%W0%L0,%w1,%0);
4219 /* zero extend 8->32? */
4220 if (intval == 0xff && REG_P (operands[0])
4221 && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
4222 && (! REG_P (operands[1])
4223 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
4224 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
4226 /* ??? tege: Should forget CC_STATUS only if we clobber a
4227 remembered operand. Fix that later. */
4230 return AS2 (movzx,%b1,%0);
4232 return AS2 (movz%B0%L0,%b1,%0);
4236 /* Check partial bytes.. non-QI-regs are not available */
4237 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4240 /* only low byte has zero bits? */
4241 if (~(intval | 0xff) == 0)
4244 if (REG_P (operands[0]))
4249 return AS2 (xor%B0,%b0,%b0);
4252 /* we're better off with the 32-bit version if reg != EAX */
4253 /* the value is sign-extended in 8 bits */
4254 if (REGNO (operands[0]) != 0 && (intval & 0x80))
4260 operands[2] = GEN_INT (intval);
4263 return AS2 (mov%B0,%2,%b0);
4265 return AS2 (and%B0,%2,%b0);
4268 /* only second byte has zero? */
4269 if (~(intval | 0xff00) == 0)
4273 intval = (intval >> 8) & 0xff;
4274 operands[2] = GEN_INT (intval);
4277 if (REG_P (operands[0]))
4278 return AS2 (xor%B0,%h0,%h0);
4279 operands[0] = adj_offsettable_operand (operands[0], 1);
4280 return AS2 (mov%B0,%2,%b0);
4283 if (REG_P (operands[0]))
4284 return AS2 (and%B0,%2,%h0);
4286 operands[0] = adj_offsettable_operand (operands[0], 1);
4287 return AS2 (and%B0,%2,%b0);
4290 if (REG_P (operands[0]))
4293 /* third byte has zero bits? */
4294 if (~(intval | 0xff0000) == 0)
4296 intval = (intval >> 16) & 0xff;
4297 operands[0] = adj_offsettable_operand (operands[0], 2);
4300 operands[2] = GEN_INT (intval);
4302 return AS2 (mov%B0,%2,%b0);
4303 return AS2 (and%B0,%2,%b0);
4306 /* fourth byte has zero bits? */
4307 if (~(intval | 0xff000000) == 0)
4309 intval = (intval >> 24) & 0xff;
4310 operands[0] = adj_offsettable_operand (operands[0], 3);
4311 goto byte_and_operation;
4314 /* Low word is zero? */
4315 if (intval == 0xffff0000)
4317 word_zero_and_operation:
4319 operands[2] = const0_rtx;
4320 return AS2 (mov%W0,%2,%w0);
4323 /* High word is zero? */
4324 if (intval == 0x0000ffff)
4326 operands[0] = adj_offsettable_operand (operands[0], 2);
4327 goto word_zero_and_operation;
4334 return AS2 (and%L0,%2,%0);
4336 [(set_attr "type" "binary")])
4338 (define_insn "andhi3"
4339 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4340 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4341 (match_operand:HI 2 "general_operand" "ri,rm")))]
4345 if (GET_CODE (operands[2]) == CONST_INT
4346 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
4348 /* Can we ignore the upper byte? */
4349 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
4350 && (INTVAL (operands[2]) & 0xff00) == 0xff00)
4354 if ((INTVAL (operands[2]) & 0xff) == 0)
4356 operands[2] = const0_rtx;
4357 return AS2 (mov%B0,%2,%b0);
4360 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
4361 return AS2 (and%B0,%2,%b0);
4364 /* Can we ignore the lower byte? */
4365 /* ??? what about offsettable memory references? */
4366 if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
4370 if ((INTVAL (operands[2]) & 0xff00) == 0)
4372 operands[2] = const0_rtx;
4373 return AS2 (mov%B0,%2,%h0);
4376 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
4377 return AS2 (and%B0,%2,%h0);
4380 /* use 32-bit ops on registers when there are no sign issues.. */
4381 if (REG_P (operands[0]))
4383 if (!(INTVAL (operands[2]) & ~0x7fff))
4384 return AS2 (and%L0,%2,%k0);
4388 if (REG_P (operands[0])
4389 && i386_aligned_p (operands[2]))
4392 /* If op[2] is constant, we should zero-extend it and */
4393 /* make a note that op[0] has been zero-extended, so */
4394 /* that we could use 32-bit ops on it forthwith, but */
4395 /* there is no such reg-note available. Instead we do */
4396 /* a sign extension as that can result in shorter asm */
4397 operands[2] = i386_sext16_if_const (operands[2]);
4398 return AS2 (and%L0,%k2,%k0);
4401 /* Use a 32-bit word with the upper bits set, invalidate CC */
4402 if (GET_CODE (operands[2]) == CONST_INT
4403 && i386_aligned_p (operands[0]))
4405 HOST_WIDE_INT val = INTVAL (operands[2]);
4408 if (val != INTVAL (operands[2]))
4409 operands[2] = GEN_INT (val);
4410 return AS2 (and%L0,%k2,%k0);
4413 return AS2 (and%W0,%2,%0);
4415 [(set_attr "type" "binary")])
4417 (define_insn "andqi3"
4418 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4419 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4420 (match_operand:QI 2 "general_operand" "qn,qmn")))]
4422 "* return AS2 (and%B0,%2,%0);"
4423 [(set_attr "type" "binary")])
4425 /* I am nervous about these two.. add them later..
4426 ;I presume this means that we have something in say op0= eax which is small
4427 ;and we want to and it with memory so we can do this by just an
4428 ;andb m,%al and have success.
4430 [(set (match_operand:SI 0 "general_operand" "=r")
4431 (and:SI (zero_extend:SI
4432 (match_operand:HI 1 "nonimmediate_operand" "rm"))
4433 (match_operand:SI 2 "general_operand" "0")))]
4434 "GET_CODE (operands[2]) == CONST_INT
4435 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
4439 [(set (match_operand:SI 0 "register_operand" "=q")
4441 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
4442 (match_operand:SI 2 "register_operand" "0")))]
4443 "GET_CODE (operands[2]) == CONST_INT
4444 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
4449 ;;- Bit set (inclusive or) instructions
4451 ;; This optimizes known byte-wide operations to memory, and in some cases
4452 ;; to QI registers.. Note that we don't want to use the QI registers too
4453 ;; aggressively, because often the 32-bit register instruction is the same
4454 ;; size, and likely to be faster on PentiumPro.
4455 (define_insn "iorsi3"
4456 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4457 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4458 (match_operand:SI 2 "general_operand" "ri,rm")))]
4462 HOST_WIDE_INT intval;
4463 switch (GET_CODE (operands[2]))
4467 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4470 /* don't try to optimize volatile accesses */
4471 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4474 intval = INTVAL (operands[2]);
4475 if ((intval & ~0xff) == 0)
4477 if (REG_P (operands[0]))
4479 /* Do low byte access only for %eax or when high bit is set */
4480 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4487 if (intval != INTVAL (operands[2]))
4488 operands[2] = GEN_INT (intval);
4491 return AS2 (mov%B0,%2,%b0);
4493 return AS2 (or%B0,%2,%b0);
4497 if ((intval & ~0xff00) == 0)
4501 if (REG_P (operands[0]))
4504 operands[2] = GEN_INT (intval);
4506 return AS2 (mov%B0,%2,%h0);
4508 return AS2 (or%B0,%2,%h0);
4511 operands[0] = adj_offsettable_operand (operands[0], 1);
4512 goto byte_or_operation;
4515 if (REG_P (operands[0]))
4519 if ((intval & ~0xff0000) == 0)
4522 operands[0] = adj_offsettable_operand (operands[0], 2);
4523 goto byte_or_operation;
4527 if ((intval & ~0xff000000) == 0)
4529 intval = (intval >> 24) & 0xff;
4530 operands[0] = adj_offsettable_operand (operands[0], 3);
4531 goto byte_or_operation;
4538 return AS2 (or%L0,%2,%0);
4540 [(set_attr "type" "binary")])
4542 (define_insn "iorhi3"
4543 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4544 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4545 (match_operand:HI 2 "general_operand" "ri,rm")))]
4549 HOST_WIDE_INT intval;
4550 switch (GET_CODE (operands[2]))
4554 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4557 /* don't try to optimize volatile accesses */
4558 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4561 intval = 0xffff & INTVAL (operands[2]);
4563 if ((intval & 0xff00) == 0)
4565 if (REG_P (operands[0]))
4567 /* Do low byte access only for %eax or when high bit is set */
4568 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4576 return AS2 (mov%B0,%2,%b0);
4578 return AS2 (or%B0,%2,%b0);
4582 if ((intval & 0xff) == 0)
4585 operands[2] = GEN_INT (intval);
4587 if (REG_P (operands[0]))
4591 return AS2 (mov%B0,%2,%h0);
4593 return AS2 (or%B0,%2,%h0);
4596 operands[0] = adj_offsettable_operand (operands[0], 1);
4598 goto byte_or_operation;
4605 if (REG_P (operands[0])
4606 && i386_aligned_p (operands[2]))
4609 operands[2] = i386_sext16_if_const (operands[2]);
4610 return AS2 (or%L0,%k2,%k0);
4613 if (GET_CODE (operands[2]) == CONST_INT
4614 && i386_aligned_p (operands[0]))
4617 intval = 0xffff & INTVAL (operands[2]);
4618 if (intval != INTVAL (operands[2]))
4619 operands[2] = GEN_INT (intval);
4620 return AS2 (or%L0,%2,%k0);
4623 return AS2 (or%W0,%2,%0);
4625 [(set_attr "type" "binary")])
4627 (define_insn "iorqi3"
4628 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4629 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4630 (match_operand:QI 2 "general_operand" "qn,qmn")))]
4632 "* return AS2 (or%B0,%2,%0);"
4633 [(set_attr "type" "binary")])
4635 ;;- xor instructions
4637 (define_insn "xorsi3"
4638 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4639 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4640 (match_operand:SI 2 "general_operand" "ri,rm")))]
4644 HOST_WIDE_INT intval;
4645 switch (GET_CODE (operands[2]))
4649 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4652 /* don't try to optimize volatile accesses */
4653 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4656 intval = INTVAL (operands[2]);
4657 if ((intval & ~0xff) == 0)
4659 if (REG_P (operands[0]))
4661 /* Do low byte access only for %eax or when high bit is set */
4662 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4670 && (!TARGET_PENTIUM || optimize_size
4671 || (GET_CODE (operands[0]) == MEM
4672 && memory_address_info (XEXP (operands[0], 0), 1))))
4673 return AS1 (not%B0,%b0);
4675 if (intval != INTVAL (operands[2]))
4676 operands[2] = GEN_INT (intval);
4677 return AS2 (xor%B0,%2,%b0);
4681 if ((intval & ~0xff00) == 0)
4685 if (REG_P (operands[0]))
4689 && (!TARGET_PENTIUM || optimize_size
4690 || (GET_CODE (operands[0]) == MEM
4691 && memory_address_info (XEXP (operands[0], 0), 1))))
4692 return AS1 (not%B0,%h0);
4694 operands[2] = GEN_INT (intval);
4695 return AS2 (xor%B0,%2,%h0);
4698 operands[0] = adj_offsettable_operand (operands[0], 1);
4700 goto byte_xor_operation;
4703 if (REG_P (operands[0]))
4707 if ((intval & ~0xff0000) == 0)
4710 operands[0] = adj_offsettable_operand (operands[0], 2);
4711 goto byte_xor_operation;
4715 if ((intval & ~0xff000000) == 0)
4717 intval = (intval >> 24) & 0xff;
4718 operands[0] = adj_offsettable_operand (operands[0], 3);
4719 goto byte_xor_operation;
4726 return AS2 (xor%L0,%2,%0);
4728 [(set_attr "type" "binary")])
4730 (define_insn "xorhi3"
4731 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4732 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4733 (match_operand:HI 2 "general_operand" "ri,rm")))]
4737 if (GET_CODE (operands[2]) == CONST_INT
4738 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
4740 /* Can we ignore the upper byte? */
4741 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
4742 && (INTVAL (operands[2]) & 0xff00) == 0)
4745 if (INTVAL (operands[2]) & 0xffff0000)
4746 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
4748 if (INTVAL (operands[2]) == 0xff
4749 && (!TARGET_PENTIUM || optimize_size
4750 || (GET_CODE (operands[0]) == MEM
4751 && memory_address_info (XEXP (operands[0], 0), 1))))
4752 return AS1 (not%B0,%b0);
4754 return AS2 (xor%B0,%2,%b0);
4757 /* Can we ignore the lower byte? */
4758 /* ??? what about offsettable memory references? */
4759 if (QI_REG_P (operands[0])
4760 && (INTVAL (operands[2]) & 0xff) == 0)
4763 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
4765 if (INTVAL (operands[2]) == 0xff
4766 && (!TARGET_PENTIUM || optimize_size
4767 || (GET_CODE (operands[0]) == MEM
4768 && memory_address_info (XEXP (operands[0], 0), 1))))
4769 return AS1 (not%B0,%h0);
4771 return AS2 (xor%B0,%2,%h0);
4775 if (REG_P (operands[0])
4776 && i386_aligned_p (operands[2]))
4779 operands[2] = i386_sext16_if_const (operands[2]);
4780 return AS2 (xor%L0,%k2,%k0);
4783 if (GET_CODE (operands[2]) == CONST_INT
4784 && i386_aligned_p (operands[0]))
4786 HOST_WIDE_INT intval;
4788 intval = 0xffff & INTVAL (operands[2]);
4789 if (intval != INTVAL (operands[2]))
4790 operands[2] = GEN_INT (intval);
4791 return AS2 (xor%L0,%2,%k0);
4794 return AS2 (xor%W0,%2,%0);
4796 [(set_attr "type" "binary")])
4798 (define_insn "xorqi3"
4799 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4800 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4801 (match_operand:QI 2 "general_operand" "qn,qm")))]
4803 "* return AS2 (xor%B0,%2,%0);"
4804 [(set_attr "type" "binary")])
4806 ;; logical operations for DImode
4808 (define_insn "anddi3"
4809 [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4810 (and:DI (match_operand:DI 1 "general_operand" "%0,0")
4811 (match_operand:DI 2 "general_operand" "oriF,riF")))]
4814 [(set_attr "type" "binary")])
4817 (define_insn "iordi3"
4818 [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4819 (ior:DI (match_operand:DI 1 "general_operand" "%0,0")
4820 (match_operand:DI 2 "general_operand" "oriF,riF")))]
4823 [(set_attr "type" "binary")])
4825 (define_insn "xordi3"
4826 [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4827 (xor:DI (match_operand:DI 1 "general_operand" "%0,0")
4828 (match_operand:DI 2 "general_operand" "oriF,riF")))]
4831 [(set_attr "type" "binary")])
4834 [(set (match_operand:DI 0 "general_operand" "")
4835 (match_operator:DI 3 "ix86_logical_operator"
4836 [(match_operand:DI 1 "general_operand" "")
4837 (match_operand:DI 2 "general_operand" "")]))]
4839 [(set (match_dup 4) (match_op_dup:SI 3 [(match_dup 6) (match_dup 8)]))
4840 (set (match_dup 5) (match_op_dup:SI 3 [(match_dup 7) (match_dup 9)]))]
4841 "split_di (&operands[0], 1, &operands[4], &operands[5]);
4842 split_di (&operands[1], 1, &operands[6], &operands[7]);
4843 split_di (&operands[2], 1, &operands[8], &operands[9]);")
4845 ;;- negation instructions
4847 (define_insn "negdi2"
4848 [(set (match_operand:DI 0 "general_operand" "=&ro")
4849 (neg:DI (match_operand:DI 1 "general_operand" "0")))]
4853 rtx xops[2], low[1], high[1];
4857 split_di (operands, 1, low, high);
4858 xops[0] = const0_rtx;
4861 output_asm_insn (AS1 (neg%L0,%0), low);
4862 output_asm_insn (AS2 (adc%L1,%0,%1), xops);
4863 output_asm_insn (AS1 (neg%L0,%0), high);
4867 (define_insn "negsi2"
4868 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4869 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
4873 (define_insn "neghi2"
4874 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4875 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
4878 if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn))
4881 return AS1(neg%L0,%k0);
4883 return AS1(neg%W0,%0);")
4885 (define_insn "negqi2"
4886 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4887 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
4891 (define_insn "negsf2"
4892 [(set (match_operand:SF 0 "register_operand" "=f")
4893 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
4896 [(set_attr "type" "fpop")])
4898 (define_insn "negdf2"
4899 [(set (match_operand:DF 0 "register_operand" "=f")
4900 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
4903 [(set_attr "type" "fpop")])
4906 [(set (match_operand:DF 0 "register_operand" "=f")
4907 (neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
4910 [(set_attr "type" "fpop")])
4912 (define_insn "negxf2"
4913 [(set (match_operand:XF 0 "register_operand" "=f")
4914 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
4917 [(set_attr "type" "fpop")])
4920 [(set (match_operand:XF 0 "register_operand" "=f")
4921 (neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4924 [(set_attr "type" "fpop")])
4926 ;; Absolute value instructions
4928 (define_insn "abssf2"
4929 [(set (match_operand:SF 0 "register_operand" "=f")
4930 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
4933 [(set_attr "type" "fpop")])
4935 (define_insn "absdf2"
4936 [(set (match_operand:DF 0 "register_operand" "=f")
4937 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
4940 [(set_attr "type" "fpop")])
4943 [(set (match_operand:DF 0 "register_operand" "=f")
4944 (abs:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
4947 [(set_attr "type" "fpop")])
4949 (define_insn "absxf2"
4950 [(set (match_operand:XF 0 "register_operand" "=f")
4951 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
4954 [(set_attr "type" "fpop")])
4957 [(set (match_operand:XF 0 "register_operand" "=f")
4958 (abs:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4961 [(set_attr "type" "fpop")])
4963 (define_insn "sqrtsf2"
4964 [(set (match_operand:SF 0 "register_operand" "=f")
4965 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
4966 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4969 (define_insn "sqrtdf2"
4970 [(set (match_operand:DF 0 "register_operand" "=f")
4971 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
4972 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4973 && (TARGET_IEEE_FP || flag_fast_math) "
4977 [(set (match_operand:DF 0 "register_operand" "=f")
4978 (sqrt:DF (float_extend:DF
4979 (match_operand:SF 1 "register_operand" "0"))))]
4980 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4983 (define_insn "sqrtxf2"
4984 [(set (match_operand:XF 0 "register_operand" "=f")
4985 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
4986 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4987 && (TARGET_IEEE_FP || flag_fast_math) "
4991 [(set (match_operand:XF 0 "register_operand" "=f")
4992 (sqrt:XF (float_extend:XF
4993 (match_operand:DF 1 "register_operand" "0"))))]
4994 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4998 [(set (match_operand:XF 0 "register_operand" "=f")
4999 (sqrt:XF (float_extend:XF
5000 (match_operand:SF 1 "register_operand" "0"))))]
5001 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
5004 (define_insn "sindf2"
5005 [(set (match_operand:DF 0 "register_operand" "=f")
5006 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
5007 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5010 (define_insn "sinsf2"
5011 [(set (match_operand:SF 0 "register_operand" "=f")
5012 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
5013 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5017 [(set (match_operand:DF 0 "register_operand" "=f")
5018 (unspec:DF [(float_extend:DF
5019 (match_operand:SF 1 "register_operand" "0"))] 1))]
5020 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5023 (define_insn "sinxf2"
5024 [(set (match_operand:XF 0 "register_operand" "=f")
5025 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
5026 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5029 (define_insn "cosdf2"
5030 [(set (match_operand:DF 0 "register_operand" "=f")
5031 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
5032 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5035 (define_insn "cossf2"
5036 [(set (match_operand:SF 0 "register_operand" "=f")
5037 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
5038 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5042 [(set (match_operand:DF 0 "register_operand" "=f")
5043 (unspec:DF [(float_extend:DF
5044 (match_operand:SF 1 "register_operand" "0"))] 2))]
5045 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5048 (define_insn "cosxf2"
5049 [(set (match_operand:XF 0 "register_operand" "=f")
5050 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
5051 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5054 ;;- one complement instructions
5056 (define_insn "one_cmplsi2"
5057 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5058 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
5062 /* A Pentium NOT is not pariable. Output it only in case of complex
5063 memory address, because XOR will be inpariable anyway because
5064 of immediate/displacement rule. */
5066 if (TARGET_PENTIUM && !optimize_size
5067 && (GET_CODE (operands[0]) != MEM
5068 || memory_address_info (XEXP (operands[0], 0), 1) == 0))
5071 xops[0] = operands[0];
5072 xops[1] = GEN_INT (0xffffffff);
5073 output_asm_insn (AS2 (xor%L0,%1,%0), xops);
5077 return AS1 (not%L0,%0);
5080 (define_insn "one_cmplhi2"
5081 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5082 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
5086 /* A Pentium NOT is not pariable. Output it only in case of complex
5087 memory address, because XOR will be inpariable anyway because
5088 of immediate/displacement rule. */
5090 if (TARGET_PENTIUM && !optimize_size
5091 && (GET_CODE (operands[0]) != MEM
5092 || memory_address_info (XEXP (operands[0], 0), 1) == 0))
5095 xops[0] = operands[0];
5096 xops[1] = GEN_INT (0xffff);
5097 if (REG_P (operands[0])
5098 && i386_cc_probably_useless_p (insn))
5101 output_asm_insn (AS2 (xor%L0,%1,%k0), xops);
5104 output_asm_insn (AS2 (xor%W0,%1,%0), xops);
5109 if (REG_P (operands[0])
5110 && i386_cc_probably_useless_p (insn))
5113 return AS1 (not%L0,%k0);
5115 return AS1 (not%W0,%0);
5119 (define_insn "one_cmplqi2"
5120 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5121 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
5125 /* A Pentium NOT is not pariable. Output it only in case of complex
5126 memory address, because XOR will be inpariable anyway because
5127 of immediate/displacement rule. */
5129 if (TARGET_PENTIUM && !optimize_size
5130 && (GET_CODE (operands[0]) != MEM
5131 || memory_address_info (XEXP (operands[0], 0), 1) == 0))
5134 xops[0] = operands[0];
5135 xops[1] = GEN_INT (0xff);
5136 output_asm_insn (AS2 (xor%B0,%1,%0), xops);
5140 return AS1 (not%B0,%0);
5143 ;;- arithmetic shift instructions
5145 ;; DImode shifts are implemented using the i386 "shift double" opcode,
5146 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
5147 ;; is variable, then the count is in %cl and the "imm" operand is dropped
5148 ;; from the assembler input.
5150 ;; This instruction shifts the target reg/mem as usual, but instead of
5151 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
5152 ;; is a left shift double, bits are taken from the high order bits of
5153 ;; reg, else if the insn is a shift right double, bits are taken from the
5154 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
5155 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
5157 ;; Since sh[lr]d does not change the `reg' operand, that is done
5158 ;; separately, making all shifts emit pairs of shift double and normal
5159 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
5160 ;; support a 63 bit shift, each shift where the count is in a reg expands
5161 ;; to a pair of shifts, a branch, a shift by 32 and a label.
5163 ;; If the shift count is a constant, we need never emit more than one
5164 ;; shift pair, instead using moves and sign extension for counts greater
5167 (define_expand "ashldi3"
5168 [(set (match_operand:DI 0 "register_operand" "")
5169 (ashift:DI (match_operand:DI 1 "register_operand" "")
5170 (match_operand:QI 2 "nonmemory_operand" "")))]
5174 if (GET_CODE (operands[2]) != CONST_INT
5175 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
5177 operands[2] = copy_to_mode_reg (QImode, operands[2]);
5178 emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
5182 emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
5187 (define_insn "ashldi3_const_int"
5188 [(set (match_operand:DI 0 "register_operand" "=&r")
5189 (ashift:DI (match_operand:DI 1 "register_operand" "0")
5190 (match_operand:QI 2 "const_int_operand" "J")))]
5191 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
5194 rtx xops[4], low[1], high[1];
5198 split_di (operands, 1, low, high);
5199 xops[0] = operands[2];
5200 xops[1] = const1_rtx;
5204 if (INTVAL (xops[0]) > 31)
5206 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
5207 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5209 if (INTVAL (xops[0]) > 32)
5211 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
5212 output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
5217 output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
5218 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
5223 (define_insn "ashldi3_non_const_int"
5224 [(set (match_operand:DI 0 "register_operand" "=&r")
5225 (ashift:DI (match_operand:DI 1 "register_operand" "0")
5226 (match_operand:QI 2 "register_operand" "c")))]
5230 rtx xops[5], low[1], high[1];
5234 split_di (operands, 1, low, high);
5235 xops[0] = operands[2];
5236 xops[1] = GEN_INT (32);
5239 xops[4] = gen_label_rtx ();
5241 output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
5242 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
5243 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5244 output_asm_insn (AS1 (je,%X4), xops);
5245 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
5246 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5247 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5248 CODE_LABEL_NUMBER (xops[4]));
5252 (define_expand "ashlsi3"
5253 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5254 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
5255 (match_operand:SI 2 "nonmemory_operand" "")))]
5259 (define_expand "ashlhi3"
5260 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5261 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
5262 (match_operand:HI 2 "nonmemory_operand" "")))]
5266 (define_expand "ashlqi3"
5267 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5268 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
5269 (match_operand:QI 2 "nonmemory_operand" "")))]
5273 ;; Pattern for shifts which can be encoded into an lea instruction.
5274 ;; This is kept as a separate pattern so that regmove can optimize cases
5275 ;; where we know the source and destination must match.
5277 ;; Do not expose this pattern when optimizing for size since we never want
5278 ;; to use lea when optimizing for size since mov+sal is smaller than lea.
5281 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
5282 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
5283 (match_operand:SI 2 "small_shift_operand" "M,M")))]
5285 "* return output_ashl (insn, operands);")
5287 ;; Generic left shift pattern to catch all cases not handled by the
5288 ;; shift pattern above.
5290 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5291 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5292 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5294 "* return output_ashl (insn, operands);")
5297 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r")
5298 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
5299 (match_operand:HI 2 "small_shift_operand" "M,M")))]
5301 "* return output_ashl (insn, operands);")
5304 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5305 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5306 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5308 "* return output_ashl (insn, operands);")
5311 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q")
5312 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,q")
5313 (match_operand:QI 2 "small_shift_operand" "M,M")))]
5315 "* return output_ashl (insn, operands);")
5317 ;; Generic left shift pattern to catch all cases not handled by the
5318 ;; shift pattern above.
5320 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5321 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5322 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5324 "* return output_ashl (insn, operands);")
5326 ;; See comment above `ashldi3' about how this works.
5328 (define_expand "ashrdi3"
5329 [(set (match_operand:DI 0 "register_operand" "")
5330 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5331 (match_operand:QI 2 "nonmemory_operand" "")))]
5335 if (GET_CODE (operands[2]) != CONST_INT
5336 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
5338 operands[2] = copy_to_mode_reg (QImode, operands[2]);
5339 emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1],
5343 emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2]));
5348 (define_insn "ashldi3_32"
5349 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
5350 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
5355 rtx low[2], high[2], xops[4];
5357 split_di (operands, 2, low, high);
5361 xops[3] = const0_rtx;
5362 if (!rtx_equal_p (xops[0], xops[1]))
5363 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
5365 if (GET_CODE (low[0]) == MEM)
5366 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5368 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5373 (define_insn "ashrdi3_const_int"
5374 [(set (match_operand:DI 0 "register_operand" "=&r")
5375 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
5376 (match_operand:QI 2 "const_int_operand" "J")))]
5377 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
5380 rtx xops[4], low[1], high[1];
5384 split_di (operands, 1, low, high);
5385 xops[0] = operands[2];
5386 xops[1] = const1_rtx;
5390 if (INTVAL (xops[0]) > 31)
5392 xops[1] = GEN_INT (31);
5393 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5394 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */
5396 if (INTVAL (xops[0]) > 32)
5398 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
5399 output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */
5404 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
5405 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
5411 (define_insn "ashrdi3_non_const_int"
5412 [(set (match_operand:DI 0 "register_operand" "=&r")
5413 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
5414 (match_operand:QI 2 "register_operand" "c")))]
5418 rtx xops[5], low[1], high[1];
5422 split_di (operands, 1, low, high);
5423 xops[0] = operands[2];
5424 xops[1] = GEN_INT (32);
5427 xops[4] = gen_label_rtx ();
5429 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
5430 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
5431 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5432 output_asm_insn (AS1 (je,%X4), xops);
5433 xops[1] = GEN_INT (31);
5434 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5435 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */
5436 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5437 CODE_LABEL_NUMBER (xops[4]));
5441 (define_insn "ashrsi3_31"
5442 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d")
5443 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a")
5445 "!TARGET_PENTIUM || optimize_size"
5450 (define_insn "ashrsi3"
5451 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5452 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5453 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5457 if (REG_P (operands[2]))
5458 return AS2 (sar%L0,%b2,%0);
5460 return AS2 (sar%L0,%2,%0);
5463 (define_insn "ashrhi3"
5464 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5465 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5466 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5470 if (REG_P (operands[2]))
5471 return AS2 (sar%W0,%b2,%0);
5473 return AS2 (sar%W0,%2,%0);
5476 (define_insn "ashrqi3"
5477 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5478 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5479 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5483 if (REG_P (operands[2]))
5484 return AS2 (sar%B0,%b2,%0);
5486 return AS2 (sar%B0,%2,%0);
5489 ;;- logical shift instructions
5491 ;; See comment above `ashldi3' about how this works.
5493 (define_expand "lshrdi3"
5494 [(set (match_operand:DI 0 "register_operand" "")
5495 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5496 (match_operand:QI 2 "nonmemory_operand" "")))]
5500 if (GET_CODE (operands[2]) != CONST_INT
5501 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
5503 operands[2] = copy_to_mode_reg (QImode, operands[2]);
5504 emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
5508 emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
5513 (define_insn "lshrdi3_32"
5514 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
5515 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
5520 rtx low[2], high[2], xops[4];
5522 split_di (operands, 2, low, high);
5526 xops[3] = const0_rtx;
5527 if (!rtx_equal_p (xops[0], xops[1]))
5528 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
5530 if (GET_CODE (low[0]) == MEM)
5531 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5533 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5538 (define_insn "lshrdi3_const_int"
5539 [(set (match_operand:DI 0 "register_operand" "=&r")
5540 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5541 (match_operand:QI 2 "const_int_operand" "J")))]
5542 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
5545 rtx xops[4], low[1], high[1];
5549 split_di (operands, 1, low, high);
5550 xops[0] = operands[2];
5551 xops[1] = const1_rtx;
5555 if (INTVAL (xops[0]) > 31)
5557 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
5558 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
5560 if (INTVAL (xops[0]) > 32)
5562 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
5563 output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
5568 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
5569 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
5575 (define_insn "lshrdi3_non_const_int"
5576 [(set (match_operand:DI 0 "register_operand" "=&r")
5577 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5578 (match_operand:QI 2 "register_operand" "c")))]
5582 rtx xops[5], low[1], high[1];
5586 split_di (operands, 1, low, high);
5587 xops[0] = operands[2];
5588 xops[1] = GEN_INT (32);
5591 xops[4] = gen_label_rtx ();
5593 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
5594 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
5595 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5596 output_asm_insn (AS1 (je,%X4), xops);
5597 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
5598 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
5599 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5600 CODE_LABEL_NUMBER (xops[4]));
5604 (define_insn "lshrsi3"
5605 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5606 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5607 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5611 if (REG_P (operands[2]))
5612 return AS2 (shr%L0,%b2,%0);
5614 return AS2 (shr%L0,%2,%1);
5617 (define_insn "lshrhi3"
5618 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5619 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5620 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5624 if (REG_P (operands[2]))
5625 return AS2 (shr%W0,%b2,%0);
5627 return AS2 (shr%W0,%2,%0);
5630 (define_insn "lshrqi3"
5631 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5632 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5633 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5637 if (REG_P (operands[2]))
5638 return AS2 (shr%B0,%b2,%0);
5640 return AS2 (shr%B0,%2,%0);
5643 ;;- rotate instructions
5645 (define_insn "rotlsi3"
5646 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5647 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5648 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5652 if (REG_P (operands[2]))
5653 return AS2 (rol%L0,%b2,%0);
5655 return AS2 (rol%L0,%2,%0);
5658 (define_insn "rotlhi3"
5659 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5660 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5661 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5665 if (REG_P (operands[2]))
5666 return AS2 (rol%W0,%b2,%0);
5668 return AS2 (rol%W0,%2,%0);
5671 (define_insn "rotlqi3"
5672 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5673 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5674 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5678 if (REG_P (operands[2]))
5679 return AS2 (rol%B0,%b2,%0);
5681 return AS2 (rol%B0,%2,%0);
5684 (define_insn "rotrsi3"
5685 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5686 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5687 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5691 if (REG_P (operands[2]))
5692 return AS2 (ror%L0,%b2,%0);
5694 return AS2 (ror%L0,%2,%0);
5697 (define_insn "rotrhi3"
5698 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5699 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5700 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5704 if (REG_P (operands[2]))
5705 return AS2 (ror%W0,%b2,%0);
5707 return AS2 (ror%W0,%2,%0);
5710 (define_insn "rotrqi3"
5711 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5712 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5713 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5717 if (REG_P (operands[2]))
5718 return AS2 (ror%B0,%b2,%0);
5720 return AS2 (ror%B0,%2,%0);
5724 ;; This usually looses. But try a define_expand to recognize a few case
5725 ;; we can do efficiently, such as accessing the "high" QImode registers,
5726 ;; %ah, %bh, %ch, %dh.
5727 ;; ??? Note this has a botch on the mode of operand 0, which needs to be
5728 ;; fixed if this is ever enabled.
5730 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
5731 (match_operand:SI 1 "immediate_operand" "i")
5732 (match_operand:SI 2 "immediate_operand" "i"))
5733 (match_operand:SI 3 "nonmemory_operand" "ri"))]
5737 if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
5739 if (GET_CODE (operands[3]) == CONST_INT)
5741 unsigned int mask = (1 << INTVAL (operands[1])) - 1;
5742 operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
5743 output_asm_insn (AS2 (and%L0,%1,%0), operands);
5744 operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
5745 output_asm_insn (AS2 (or%L0,%3,%0), operands);
5749 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
5750 if (INTVAL (operands[2]))
5751 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5752 output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
5753 operands[2] = GEN_INT (BITS_PER_WORD
5754 - INTVAL (operands[1]) - INTVAL (operands[2]));
5755 if (INTVAL (operands[2]))
5756 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5762 ;; ??? There are problems with the mode of operand[3]. The point of this
5763 ;; is to represent an HImode move to a "high byte" register.
5765 (define_expand "insv"
5766 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
5767 (match_operand:SI 1 "immediate_operand" "")
5768 (match_operand:SI 2 "immediate_operand" ""))
5769 (match_operand:QI 3 "nonmemory_operand" "ri"))]
5773 if (GET_CODE (operands[1]) != CONST_INT
5774 || GET_CODE (operands[2]) != CONST_INT)
5777 if (! (INTVAL (operands[1]) == 8
5778 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
5779 && ! INTVAL (operands[1]) == 1)
5784 ;; On i386, the register count for a bit operation is *not* truncated,
5785 ;; so SHIFT_COUNT_TRUNCATED must not be defined.
5787 ;; On i486, the shift & or/and code is faster than bts or btr. If
5788 ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
5790 ;; On i386, bts is a little faster if operands[0] is a reg, and a
5791 ;; little slower if operands[0] is a MEM, than the shift & or/and code.
5792 ;; Use bts & btr, since they reload better.
5794 ;; General bit set and clear.
5796 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm")
5798 (match_operand:SI 2 "register_operand" "r"))
5799 (match_operand:SI 3 "const_int_operand" "n"))]
5800 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5805 if (INTVAL (operands[3]) == 1)
5806 return AS2 (bts%L0,%2,%0);
5808 return AS2 (btr%L0,%2,%0);
5811 ;; Bit complement. See comments on previous pattern.
5812 ;; ??? Is this really worthwhile?
5814 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5815 (xor:SI (ashift:SI (const_int 1)
5816 (match_operand:SI 1 "register_operand" "r"))
5817 (match_operand:SI 2 "nonimmediate_operand" "0")))]
5818 "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT"
5823 return AS2 (btc%L0,%1,%0);
5827 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5828 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5829 (ashift:SI (const_int 1)
5830 (match_operand:SI 2 "register_operand" "r"))))]
5831 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5836 return AS2 (btc%L0,%2,%0);
5839 ;; Recognizers for bit-test instructions.
5841 ;; The bt opcode allows a MEM in operands[0]. But on both i386 and
5842 ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
5843 ;; bt on the MEM directly.
5845 ;; ??? The first argument of a zero_extract must not be reloaded, so
5846 ;; don't allow a MEM in the operand predicate without allowing it in the
5850 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5852 (match_operand:SI 1 "register_operand" "r")))]
5853 "GET_CODE (operands[1]) != CONST_INT"
5856 cc_status.flags |= CC_Z_IN_NOT_C;
5857 return AS2 (bt%L0,%1,%0);
5861 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5862 (match_operand:SI 1 "const_int_operand" "n")
5863 (match_operand:SI 2 "const_int_operand" "n")))]
5869 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5870 operands[1] = GEN_INT (mask);
5872 if (QI_REG_P (operands[0])
5873 /* A Pentium test is pairable only with eax. Not with ah or al. */
5874 && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
5877 if ((mask & ~0xff) == 0)
5879 cc_status.flags |= CC_NOT_NEGATIVE;
5880 return AS2 (test%B0,%1,%b0);
5883 if ((mask & ~0xff00) == 0)
5885 cc_status.flags |= CC_NOT_NEGATIVE;
5886 operands[1] = GEN_INT (mask >> 8);
5887 return AS2 (test%B0,%1,%h0);
5891 return AS2 (test%L0,%1,%0);
5894 ;; ??? All bets are off if operand 0 is a volatile MEM reference.
5895 ;; The CPU may access unspecified bytes around the actual target byte.
5898 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
5899 (match_operand:SI 1 "const_int_operand" "n")
5900 (match_operand:SI 2 "const_int_operand" "n")))]
5901 "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
5906 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5907 operands[1] = GEN_INT (mask);
5909 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
5910 /* A Pentium test is pairable only with eax. Not with ah or al. */
5911 && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
5914 if ((mask & ~0xff) == 0)
5916 cc_status.flags |= CC_NOT_NEGATIVE;
5917 return AS2 (test%B0,%1,%b0);
5920 if ((mask & ~0xff00) == 0)
5922 cc_status.flags |= CC_NOT_NEGATIVE;
5923 operands[1] = GEN_INT (mask >> 8);
5925 if (QI_REG_P (operands[0]))
5926 return AS2 (test%B0,%1,%h0);
5929 operands[0] = adj_offsettable_operand (operands[0], 1);
5930 return AS2 (test%B0,%1,%b0);
5934 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
5936 cc_status.flags |= CC_NOT_NEGATIVE;
5937 operands[1] = GEN_INT (mask >> 16);
5938 operands[0] = adj_offsettable_operand (operands[0], 2);
5939 return AS2 (test%B0,%1,%b0);
5942 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
5944 cc_status.flags |= CC_NOT_NEGATIVE;
5945 operands[1] = GEN_INT (mask >> 24);
5946 operands[0] = adj_offsettable_operand (operands[0], 3);
5947 return AS2 (test%B0,%1,%b0);
5951 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
5952 return AS2 (test%L0,%1,%0);
5954 return AS2 (test%L1,%0,%1);
5957 ;; Store-flag instructions.
5959 ;; For all sCOND expanders, also expand the compare or test insn that
5960 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
5962 (define_expand "seq"
5964 (set (match_operand:QI 0 "register_operand" "")
5965 (eq:QI (cc0) (const_int 0)))]
5970 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5971 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5973 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5976 (define_expand "sne"
5978 (set (match_operand:QI 0 "register_operand" "")
5979 (ne:QI (cc0) (const_int 0)))]
5984 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5985 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5987 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5990 (define_expand "sgt"
5992 (set (match_operand:QI 0 "register_operand" "")
5993 (gt:QI (cc0) (const_int 0)))]
5995 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5997 (define_expand "sgtu"
5999 (set (match_operand:QI 0 "register_operand" "")
6000 (gtu:QI (cc0) (const_int 0)))]
6002 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6004 (define_expand "slt"
6006 (set (match_operand:QI 0 "register_operand" "")
6007 (lt:QI (cc0) (const_int 0)))]
6009 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6011 (define_expand "sltu"
6013 (set (match_operand:QI 0 "register_operand" "")
6014 (ltu:QI (cc0) (const_int 0)))]
6016 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6018 (define_expand "sge"
6020 (set (match_operand:QI 0 "register_operand" "")
6021 (ge:QI (cc0) (const_int 0)))]
6023 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6025 (define_expand "sgeu"
6027 (set (match_operand:QI 0 "register_operand" "")
6028 (geu:QI (cc0) (const_int 0)))]
6030 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6032 (define_expand "sle"
6034 (set (match_operand:QI 0 "register_operand" "")
6035 (le:QI (cc0) (const_int 0)))]
6037 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6039 (define_expand "sleu"
6041 (set (match_operand:QI 0 "register_operand" "")
6042 (leu:QI (cc0) (const_int 0)))]
6044 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6046 ;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may
6047 ;; not have any input reloads. A MEM write might need an input reload
6048 ;; for the address of the MEM. So don't allow MEM as the SET_DEST.
6050 (define_insn "*setcc"
6051 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6052 (match_operator:QI 1 "comparison_operator" [(cc0) (const_int 0)]))]
6053 "reload_completed || register_operand (operands[0], QImode)"
6056 enum rtx_code code = GET_CODE (operands[1]);
6057 if (cc_prev_status.flags & CC_TEST_AX)
6061 operands[2] = gen_rtx_REG (SImode, 0);
6091 if (!TARGET_PENTIUM || optimize_size)
6093 operands[3] = GEN_INT (c >> 8);
6094 output_asm_insn (AS2 (test%B0,%3,%h2), operands);
6098 operands[3] = GEN_INT (c);
6099 output_asm_insn (AS2 (test%L0,%3,%2), operands);
6101 return eq ? AS1 (sete,%0) : AS1 (setne, %0);
6104 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
6106 return AS1(set%D1,%0);
6110 ;; Basic conditional jump instructions.
6111 ;; We ignore the overflow flag for signed branch instructions.
6113 ;; For all bCOND expanders, also expand the compare or test insn that
6114 ;; generates cc0. Generate an equality comparison if `beq' or `bne'.
6116 (define_expand "beq"
6119 (if_then_else (eq (cc0)
6121 (label_ref (match_operand 0 "" ""))
6127 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
6128 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
6130 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
6133 (define_expand "bne"
6136 (if_then_else (ne (cc0)
6138 (label_ref (match_operand 0 "" ""))
6144 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
6145 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
6147 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
6151 (define_expand "bgt"
6154 (if_then_else (gt (cc0)
6156 (label_ref (match_operand 0 "" ""))
6159 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6161 (define_expand "bgtu"
6164 (if_then_else (gtu (cc0)
6166 (label_ref (match_operand 0 "" ""))
6169 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6171 (define_expand "blt"
6174 (if_then_else (lt (cc0)
6176 (label_ref (match_operand 0 "" ""))
6179 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6182 (define_expand "bltu"
6185 (if_then_else (ltu (cc0)
6187 (label_ref (match_operand 0 "" ""))
6190 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6192 (define_expand "bge"
6195 (if_then_else (ge (cc0)
6197 (label_ref (match_operand 0 "" ""))
6200 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6202 (define_expand "bgeu"
6205 (if_then_else (geu (cc0)
6207 (label_ref (match_operand 0 "" ""))
6210 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6212 (define_expand "ble"
6215 (if_then_else (le (cc0)
6217 (label_ref (match_operand 0 "" ""))
6220 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6222 (define_expand "bleu"
6225 (if_then_else (leu (cc0)
6227 (label_ref (match_operand 0 "" ""))
6230 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6234 (if_then_else (match_operator 0 "comparison_operator"
6235 [(cc0) (const_int 0)])
6236 (label_ref (match_operand 1 "" ""))
6241 enum rtx_code code = GET_CODE (operands[0]);
6242 if (cc_prev_status.flags & CC_TEST_AX)
6246 operands[2] = gen_rtx_REG (SImode, 0);
6276 if (!TARGET_PENTIUM || optimize_size)
6278 operands[3] = GEN_INT (c >> 8);
6279 output_asm_insn (AS2 (test%B0,%3,%h2), operands);
6283 operands[3] = GEN_INT (c);
6284 output_asm_insn (AS2 (test%L0,%3,%2), operands);
6286 return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
6288 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
6291 return AS1(j%D0,%l1);
6296 (if_then_else (match_operator 0 "comparison_operator"
6297 [(cc0) (const_int 0)])
6299 (label_ref (match_operand 1 "" ""))))]
6303 enum rtx_code code = GET_CODE (operands[0]);
6304 if (cc_prev_status.flags & CC_TEST_AX)
6308 operands[2] = gen_rtx_REG (SImode, 0);
6338 if (!TARGET_PENTIUM || optimize_size)
6340 operands[3] = GEN_INT (c >> 8);
6341 output_asm_insn (AS2 (test%B0,%3,%h2), operands);
6345 operands[3] = GEN_INT (c);
6346 output_asm_insn (AS2 (test%L0,%3,%2), operands);
6348 return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
6350 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
6353 return AS1(j%d0,%l1);
6356 ;; Unconditional and other jump instructions
6360 (label_ref (match_operand 0 "" "")))]
6363 [(set_attr "memory" "none")])
6365 (define_insn "indirect_jump"
6366 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
6372 return AS1 (jmp,%*%0);
6374 [(set_attr "memory" "none")])
6376 ;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
6377 ;; if S does not change i
6379 (define_expand "decrement_and_branch_until_zero"
6380 [(parallel [(set (pc)
6381 (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "")
6384 (label_ref (match_operand 1 "" ""))
6387 (plus:SI (match_dup 0)
6394 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
6395 [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+c*r,m")
6396 (match_operand:SI 2 "general_operand" "rmi,ri"))
6398 (label_ref (match_operand 3 "" ""))
6401 (plus:SI (match_dup 1)
6408 if (GET_CODE (operands[1]) == REG && REGNO (operands[2]) == 2 &&
6409 operands[2] == constm1_rtx && ix86_cpu == PROCESSOR_K6)
6410 return \"loop %l3\";
6412 if (operands[2] == constm1_rtx)
6413 output_asm_insn (AS1 (dec%L1,%1), operands);
6415 else if (operands[2] == const1_rtx)
6416 output_asm_insn (AS1 (inc%L1,%1), operands);
6419 output_asm_insn (AS2 (add%L1,%2,%1), operands);
6421 return AS1 (%J0,%l3);
6426 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
6427 [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
6428 (match_operand:SI 2 "general_operand" "rmi,ri"))
6430 (label_ref (match_operand 3 "" ""))
6433 (minus:SI (match_dup 1)
6439 if (operands[2] == const1_rtx)
6440 output_asm_insn (AS1 (dec%L1,%1), operands);
6442 else if (operands[1] == constm1_rtx)
6443 output_asm_insn (AS1 (inc%L1,%1), operands);
6446 output_asm_insn (AS2 (sub%L1,%2,%1), operands);
6448 return AS1 (%J0,%l3);
6453 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6455 (label_ref (match_operand 1 "" ""))
6458 (plus:SI (match_dup 0)
6464 operands[2] = const1_rtx;
6465 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6471 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6473 (label_ref (match_operand 1 "" ""))
6476 (plus:SI (match_dup 0)
6482 operands[2] = const1_rtx;
6483 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6489 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6491 (label_ref (match_operand 1 "" ""))
6494 (plus:SI (match_dup 0)
6500 output_asm_insn (AS1 (dec%L0,%0), operands);
6506 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6508 (label_ref (match_operand 1 "" ""))
6511 (plus:SI (match_dup 0)
6517 output_asm_insn (AS1 (dec%L0,%0), operands);
6523 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6525 (label_ref (match_operand 1 "" ""))
6528 (plus:SI (match_dup 0)
6534 output_asm_insn (AS1 (inc%L0,%0), operands);
6540 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6542 (label_ref (match_operand 1 "" ""))
6545 (plus:SI (match_dup 0)
6551 output_asm_insn (AS1 (inc%L0,%0), operands);
6555 ;; Implement switch statements when generating PIC code. Switches are
6556 ;; implemented by `tablejump' when not using -fpic.
6558 ;; Emit code here to do the range checking and make the index zero based.
6560 (define_expand "casesi"
6562 (match_operand:SI 0 "general_operand" ""))
6564 (minus:SI (match_dup 5)
6565 (match_operand:SI 1 "general_operand" "")))
6567 (compare:CC (match_dup 6)
6568 (match_operand:SI 2 "general_operand" "")))
6570 (if_then_else (gtu (cc0)
6572 (label_ref (match_operand 4 "" ""))
6576 (minus:SI (reg:SI 3)
6577 (mem:SI (plus:SI (mult:SI (match_dup 6)
6579 (label_ref (match_operand 3 "" ""))))))
6580 (clobber (match_scratch:SI 7 ""))])]
6584 operands[5] = gen_reg_rtx (SImode);
6585 operands[6] = gen_reg_rtx (SImode);
6586 current_function_uses_pic_offset_table = 1;
6589 ;; Implement a casesi insn.
6591 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
6594 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
6596 ;; 1. An expression involving an external reference may only use the
6597 ;; addition operator, and only with an assembly-time constant.
6598 ;; The example above satisfies this because ".-.L2" is a constant.
6600 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
6601 ;; given the value of "GOT - .", where GOT is the actual address of
6602 ;; the Global Offset Table. Therefore, the .long above actually
6603 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
6604 ;; expression "GOT - .L2" by itself would generate an error from as(1).
6606 ;; The pattern below emits code that looks like this:
6609 ;; subl TABLE@GOTOFF(%ebx,index,4),reg
6612 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
6613 ;; the addr_diff_vec is known to be part of this module.
6615 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
6616 ;; evaluates to just ".L2".
6620 (minus:SI (reg:SI 3)
6622 (mult:SI (match_operand:SI 0 "register_operand" "r")
6624 (label_ref (match_operand 1 "" ""))))))
6625 (clobber (match_scratch:SI 2 "=&r"))]
6631 xops[0] = operands[0];
6632 xops[1] = operands[1];
6633 xops[2] = operands[2];
6634 xops[3] = pic_offset_table_rtx;
6636 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
6637 output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
6638 output_asm_insn (AS1 (jmp,%*%2), xops);
6639 ASM_OUTPUT_ALIGN (asm_out_file, i386_align_jumps);
6643 (define_insn "tablejump"
6644 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
6645 (use (label_ref (match_operand 1 "" "")))]
6651 return AS1 (jmp,%*%0);
6656 ;; If generating PIC code, the predicate indirect_operand will fail
6657 ;; for operands[0] containing symbolic references on all of the named
6658 ;; call* patterns. Each named pattern is followed by an unnamed pattern
6659 ;; that matches any call to a symbolic CONST (ie, a symbol_ref). The
6660 ;; unnamed patterns are only used while generating PIC code, because
6661 ;; otherwise the named patterns match.
6663 ;; Call subroutine returning no value.
6665 (define_expand "call_pop"
6666 [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
6667 (match_operand:SI 1 "general_operand" ""))
6670 (match_operand:SI 3 "immediate_operand" "")))])]
6676 if (operands[3] == const0_rtx)
6678 emit_insn (gen_call (operands[0], operands[1]));
6683 current_function_uses_pic_offset_table = 1;
6685 /* With half-pic, force the address into a register. */
6686 addr = XEXP (operands[0], 0);
6687 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6688 XEXP (operands[0], 0) = force_reg (Pmode, addr);
6690 if (! expander_call_insn_operand (operands[0], QImode))
6692 = change_address (operands[0], VOIDmode,
6693 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
6697 [(call (match_operand:QI 0 "call_insn_operand" "m")
6698 (match_operand:SI 1 "general_operand" "g"))
6699 (set (reg:SI 7) (plus:SI (reg:SI 7)
6700 (match_operand:SI 3 "immediate_operand" "i")))]
6704 if (GET_CODE (operands[0]) == MEM
6705 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6707 operands[0] = XEXP (operands[0], 0);
6708 return AS1 (call,%*%0);
6711 return AS1 (call,%P0);
6715 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6716 (match_operand:SI 1 "general_operand" "g"))
6717 (set (reg:SI 7) (plus:SI (reg:SI 7)
6718 (match_operand:SI 3 "immediate_operand" "i")))]
6722 (define_expand "call"
6723 [(call (match_operand:QI 0 "indirect_operand" "")
6724 (match_operand:SI 1 "general_operand" ""))]
6725 ;; Operand 1 not used on the i386.
6732 current_function_uses_pic_offset_table = 1;
6734 /* With half-pic, force the address into a register. */
6735 addr = XEXP (operands[0], 0);
6736 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6737 XEXP (operands[0], 0) = force_reg (Pmode, addr);
6739 if (! expander_call_insn_operand (operands[0], QImode))
6741 = change_address (operands[0], VOIDmode,
6742 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
6746 [(call (match_operand:QI 0 "call_insn_operand" "m")
6747 (match_operand:SI 1 "general_operand" "g"))]
6748 ;; Operand 1 not used on the i386.
6752 if (GET_CODE (operands[0]) == MEM
6753 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6755 operands[0] = XEXP (operands[0], 0);
6756 return AS1 (call,%*%0);
6759 return AS1 (call,%P0);
6763 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6764 (match_operand:SI 1 "general_operand" "g"))]
6765 ;; Operand 1 not used on the i386.
6769 ;; Call subroutine, returning value in operand 0
6770 ;; (which must be a hard register).
6772 (define_expand "call_value_pop"
6773 [(parallel [(set (match_operand 0 "" "")
6774 (call (match_operand:QI 1 "indirect_operand" "")
6775 (match_operand:SI 2 "general_operand" "")))
6778 (match_operand:SI 4 "immediate_operand" "")))])]
6784 if (operands[4] == const0_rtx)
6786 emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
6791 current_function_uses_pic_offset_table = 1;
6793 /* With half-pic, force the address into a register. */
6794 addr = XEXP (operands[1], 0);
6795 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6796 XEXP (operands[1], 0) = force_reg (Pmode, addr);
6798 if (! expander_call_insn_operand (operands[1], QImode))
6800 = change_address (operands[1], VOIDmode,
6801 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
6805 [(set (match_operand 0 "" "=rf")
6806 (call (match_operand:QI 1 "call_insn_operand" "m")
6807 (match_operand:SI 2 "general_operand" "g")))
6808 (set (reg:SI 7) (plus:SI (reg:SI 7)
6809 (match_operand:SI 4 "immediate_operand" "i")))]
6813 if (GET_CODE (operands[1]) == MEM
6814 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6816 operands[1] = XEXP (operands[1], 0);
6817 output_asm_insn (AS1 (call,%*%1), operands);
6820 output_asm_insn (AS1 (call,%P1), operands);
6826 [(set (match_operand 0 "" "=rf")
6827 (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6828 (match_operand:SI 2 "general_operand" "g")))
6829 (set (reg:SI 7) (plus:SI (reg:SI 7)
6830 (match_operand:SI 4 "immediate_operand" "i")))]
6834 (define_expand "call_value"
6835 [(set (match_operand 0 "" "")
6836 (call (match_operand:QI 1 "indirect_operand" "")
6837 (match_operand:SI 2 "general_operand" "")))]
6838 ;; Operand 2 not used on the i386.
6845 current_function_uses_pic_offset_table = 1;
6847 /* With half-pic, force the address into a register. */
6848 addr = XEXP (operands[1], 0);
6849 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6850 XEXP (operands[1], 0) = force_reg (Pmode, addr);
6852 if (! expander_call_insn_operand (operands[1], QImode))
6854 = change_address (operands[1], VOIDmode,
6855 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
6859 [(set (match_operand 0 "" "=rf")
6860 (call (match_operand:QI 1 "call_insn_operand" "m")
6861 (match_operand:SI 2 "general_operand" "g")))]
6862 ;; Operand 2 not used on the i386.
6866 if (GET_CODE (operands[1]) == MEM
6867 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6869 operands[1] = XEXP (operands[1], 0);
6870 output_asm_insn (AS1 (call,%*%1), operands);
6873 output_asm_insn (AS1 (call,%P1), operands);
6879 [(set (match_operand 0 "" "=rf")
6880 (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6881 (match_operand:SI 2 "general_operand" "g")))]
6882 ;; Operand 2 not used on the i386.
6886 ;; Call subroutine returning any type.
6888 (define_expand "untyped_call"
6889 [(parallel [(call (match_operand 0 "" "")
6891 (match_operand 1 "" "")
6892 (match_operand 2 "" "")])]
6898 /* In order to give reg-stack an easier job in validating two
6899 coprocessor registers as containing a possible return value,
6900 simply pretend the untyped call returns a complex long double
6903 emit_call_insn (TARGET_80387
6904 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
6905 operands[0], const0_rtx)
6906 : gen_call (operands[0], const0_rtx));
6908 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6910 rtx set = XVECEXP (operands[2], 0, i);
6911 emit_move_insn (SET_DEST (set), SET_SRC (set));
6914 /* The optimizer does not know that the call sets the function value
6915 registers we stored in the result block. We avoid problems by
6916 claiming that all hard registers are used and clobbered at this
6918 emit_insn (gen_blockage ());
6923 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6924 ;; all of memory. This blocks insns from being moved across this point.
6926 (define_insn "blockage"
6927 [(unspec_volatile [(const_int 0)] 0)]
6930 [(set_attr "memory" "none")])
6932 ;; Insn emitted into the body of a function to return from a function.
6933 ;; This is only done if the function's epilogue is known to be simple.
6934 ;; See comments for simple_386_epilogue in i386.c.
6936 (define_expand "return"
6938 "ix86_can_use_return_insn_p ()"
6941 (define_insn "return_internal"
6945 [(set_attr "memory" "none")])
6947 (define_insn "return_pop_internal"
6949 (use (match_operand:SI 0 "const_int_operand" ""))]
6952 [(set_attr "memory" "none")])
6958 [(set_attr "memory" "none")])
6960 (define_expand "prologue"
6965 ix86_expand_prologue ();
6969 ;; The use of UNSPEC here is currently not necessary - a simple SET of ebp
6970 ;; to itself would be enough. But this way we are safe even if some optimizer
6971 ;; becomes too clever in the future.
6972 (define_insn "prologue_set_stack_ptr"
6974 (minus:SI (reg:SI 7) (match_operand:SI 0 "immediate_operand" "i")))
6975 (set (reg:SI 6) (unspec:SI [(reg:SI 6)] 4))]
6981 xops[0] = operands[0];
6982 xops[1] = stack_pointer_rtx;
6983 output_asm_insn (AS2 (sub%L1,%0,%1), xops);
6986 [(set_attr "memory" "none")])
6988 (define_insn "prologue_set_got"
6989 [(set (match_operand:SI 0 "" "")
6991 [(plus:SI (match_dup 0)
6992 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
6993 (minus:SI (pc) (match_operand 2 "" ""))))] 1))]
6999 if (TARGET_DEEP_BRANCH_PREDICTION)
7001 sprintf (buffer, \"addl %s,%%0\", XSTR (operands[1], 0));
7002 output_asm_insn (buffer, operands);
7006 sprintf (buffer, \"addl %s+[.-%%X2],%%0\", XSTR (operands[1], 0));
7007 output_asm_insn (buffer, operands);
7012 (define_insn "prologue_get_pc"
7013 [(set (match_operand:SI 0 "" "")
7014 (unspec_volatile [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
7018 output_asm_insn (AS1 (call,%X1), operands);
7019 if (! TARGET_DEEP_BRANCH_PREDICTION)
7021 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1]));
7025 [(set_attr "memory" "none")])
7027 (define_insn "prologue_get_pc_and_set_got"
7028 [(unspec_volatile [(match_operand:SI 0 "" "")] 3)]
7032 operands[1] = gen_label_rtx ();
7033 output_asm_insn (AS1 (call,%X1), operands);
7034 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
7035 CODE_LABEL_NUMBER (operands[1]));
7036 output_asm_insn (AS1 (pop%L0,%0), operands);
7037 output_asm_insn (\"addl $%__GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands);
7040 [(set_attr "memory" "none")])
7042 (define_expand "epilogue"
7047 ix86_expand_epilogue ();
7051 (define_insn "epilogue_set_stack_ptr"
7052 [(set (reg:SI 7) (reg:SI 6))
7053 (clobber (reg:SI 6))]
7059 xops[0] = frame_pointer_rtx;
7060 xops[1] = stack_pointer_rtx;
7061 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
7064 [(set_attr "memory" "none")])
7066 (define_insn "leave"
7068 (clobber (reg:SI 6))
7069 (clobber (reg:SI 7))]
7072 [(set_attr "memory" "none")])
7075 [(set (match_operand:SI 0 "register_operand" "r")
7076 (mem:SI (reg:SI 7)))
7077 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))]
7081 output_asm_insn (AS1 (pop%L0,%P0), operands);
7084 [(set_attr "memory" "load")])
7086 (define_expand "movstrsi"
7087 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
7088 (match_operand:BLK 1 "memory_operand" ""))
7089 (use (match_operand:SI 2 "const_int_operand" ""))
7090 (use (match_operand:SI 3 "const_int_operand" ""))
7091 (clobber (match_scratch:SI 4 ""))
7092 (clobber (match_dup 5))
7093 (clobber (match_dup 6))])]
7099 if (GET_CODE (operands[2]) != CONST_INT)
7102 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7103 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
7105 operands[5] = addr0;
7106 operands[6] = addr1;
7108 operands[0] = change_address (operands[0], VOIDmode, addr0);
7109 operands[1] = change_address (operands[1], VOIDmode, addr1);
7112 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7113 ;; But strength reduction might offset the MEM expression. So we let
7114 ;; reload put the address into %edi & %esi.
7117 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
7118 (mem:BLK (match_operand:SI 1 "address_operand" "S")))
7119 (use (match_operand:SI 2 "const_int_operand" "n"))
7120 (use (match_operand:SI 3 "immediate_operand" "i"))
7121 (clobber (match_scratch:SI 4 "=&c"))
7122 (clobber (match_dup 0))
7123 (clobber (match_dup 1))]
7129 output_asm_insn (\"cld\", operands);
7130 if (GET_CODE (operands[2]) == CONST_INT)
7132 if (INTVAL (operands[2]) & ~0x03)
7134 xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
7135 xops[1] = operands[4];
7137 output_asm_insn (AS2 (mov%L1,%0,%1), xops);
7139 output_asm_insn (\"rep movsd\", xops);
7141 output_asm_insn (\"rep\;movsl\", xops);
7144 if (INTVAL (operands[2]) & 0x02)
7145 output_asm_insn (\"movsw\", operands);
7146 if (INTVAL (operands[2]) & 0x01)
7147 output_asm_insn (\"movsb\", operands);
7154 (define_expand "clrstrsi"
7155 [(set (match_dup 3) (const_int 0))
7156 (parallel [(set (match_operand:BLK 0 "memory_operand" "")
7158 (use (match_operand:SI 1 "const_int_operand" ""))
7159 (use (match_operand:SI 2 "const_int_operand" ""))
7161 (clobber (match_scratch:SI 4 ""))
7162 (clobber (match_dup 5))])]
7168 if (GET_CODE (operands[1]) != CONST_INT)
7171 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7173 operands[3] = gen_reg_rtx (SImode);
7174 operands[5] = addr0;
7176 operands[0] = gen_rtx_MEM (BLKmode, addr0);
7179 ;; It might seem that operand 0 could use predicate register_operand.
7180 ;; But strength reduction might offset the MEM expression. So we let
7181 ;; reload put the address into %edi.
7183 (define_insn "*bzero"
7184 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
7186 (use (match_operand:SI 1 "const_int_operand" "n"))
7187 (use (match_operand:SI 2 "immediate_operand" "i"))
7188 (use (match_operand:SI 3 "register_operand" "a"))
7189 (clobber (match_scratch:SI 4 "=&c"))
7190 (clobber (match_dup 0))]
7196 output_asm_insn (\"cld\", operands);
7197 if (GET_CODE (operands[1]) == CONST_INT)
7199 unsigned int count = INTVAL (operands[1]) & 0xffffffff;
7202 xops[0] = GEN_INT (count / 4);
7203 xops[1] = operands[4];
7205 /* K6: stos takes 1 cycle, rep stos takes 8 + %ecx cycles.
7206 80386: 4/5+5n (+2 for set of ecx)
7207 80486: 5/7+5n (+1 for set of ecx)
7209 if (count / 4 < ((int) ix86_cpu < (int)PROCESSOR_PENTIUM ? 4 : 6))
7213 output_asm_insn (\"stosd\", xops);
7215 output_asm_insn (\"stosl\", xops);
7217 while ((count -= 4) > 3);
7221 output_asm_insn (AS2 (mov%L1,%0,%1), xops);
7223 output_asm_insn (\"rep stosd\", xops);
7225 output_asm_insn (\"rep\;stosl\", xops);
7229 if (INTVAL (operands[1]) & 0x02)
7230 output_asm_insn (\"stosw\", operands);
7231 if (INTVAL (operands[1]) & 0x01)
7232 output_asm_insn (\"stosb\", operands);
7239 (define_expand "cmpstrsi"
7240 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7241 (compare:SI (match_operand:BLK 1 "general_operand" "")
7242 (match_operand:BLK 2 "general_operand" "")))
7243 (use (match_operand:SI 3 "general_operand" ""))
7244 (use (match_operand:SI 4 "immediate_operand" ""))
7245 (clobber (match_dup 5))
7246 (clobber (match_dup 6))
7247 (clobber (match_dup 3))])]
7253 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
7254 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
7255 operands[3] = copy_to_mode_reg (SImode, operands[3]);
7257 operands[5] = addr1;
7258 operands[6] = addr2;
7260 operands[1] = gen_rtx_MEM (BLKmode, addr1);
7261 operands[2] = gen_rtx_MEM (BLKmode, addr2);
7265 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
7266 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
7268 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7269 ;; But strength reduction might offset the MEM expression. So we let
7270 ;; reload put the address into %edi & %esi.
7272 ;; ??? Most comparisons have a constant length, and it's therefore
7273 ;; possible to know that the length is non-zero, and to avoid the extra
7274 ;; code to handle zero-length compares.
7277 [(set (match_operand:SI 0 "register_operand" "=&r")
7278 (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
7279 (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
7280 (use (match_operand:SI 3 "register_operand" "c"))
7281 (use (match_operand:SI 4 "immediate_operand" "i"))
7282 (clobber (match_dup 1))
7283 (clobber (match_dup 2))
7284 (clobber (match_dup 3))]
7290 label = gen_label_rtx ();
7292 output_asm_insn (\"cld\", operands);
7293 output_asm_insn (AS2 (xor%L0,%0,%0), operands);
7294 output_asm_insn (\"repz\;cmps%B2\", operands);
7295 output_asm_insn (\"je %l0\", &label);
7297 xops[0] = operands[0];
7298 xops[1] = const1_rtx;
7299 output_asm_insn (AS2 (sbb%L0,%0,%0), xops);
7300 if (QI_REG_P (xops[0]))
7301 output_asm_insn (AS2 (or%B0,%1,%b0), xops);
7303 output_asm_insn (AS2 (or%L0,%1,%0), xops);
7305 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
7311 (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
7312 (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
7313 (use (match_operand:SI 2 "register_operand" "c"))
7314 (use (match_operand:SI 3 "immediate_operand" "i"))
7315 (clobber (match_dup 0))
7316 (clobber (match_dup 1))
7317 (clobber (match_dup 2))]
7323 cc_status.flags |= CC_NOT_SIGNED;
7325 xops[0] = gen_rtx_REG (QImode, 0);
7326 xops[1] = CONST0_RTX (QImode);
7328 output_asm_insn (\"cld\", operands);
7329 output_asm_insn (AS2 (test%B0,%1,%0), xops);
7330 return \"repz\;cmps%B2\";
7334 ;; Note, you cannot optimize away the branch following the bsfl by assuming
7335 ;; that the destination is not modified if the input is 0, since not all
7336 ;; x86 implementations do this.
7338 (define_expand "ffssi2"
7339 [(set (match_operand:SI 0 "general_operand" "")
7340 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
7344 rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode);
7346 emit_insn (gen_ffssi_1 (temp, operands[1]));
7347 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0);
7348 emit_jump_insn (gen_bne (label));
7349 emit_move_insn (temp, constm1_rtx);
7351 temp = expand_binop (SImode, add_optab, temp, const1_rtx,
7352 operands[0], 0, OPTAB_WIDEN);
7354 if (temp != operands[0])
7355 emit_move_insn (operands[0], temp);
7359 (define_insn "ffssi_1"
7360 [(set (match_operand:SI 0 "register_operand" "=r")
7361 (unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
7363 "* return AS2 (bsf%L0,%1,%0);")
7365 (define_expand "ffshi2"
7366 [(set (match_operand:SI 0 "general_operand" "")
7367 (ffs:HI (match_operand:HI 1 "general_operand" "")))]
7371 rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode);
7373 emit_insn (gen_ffshi_1 (temp, operands[1]));
7374 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0);
7375 emit_jump_insn (gen_bne (label));
7376 emit_move_insn (temp, constm1_rtx);
7378 temp = expand_binop (HImode, add_optab, temp, const1_rtx,
7379 operands[0], 0, OPTAB_WIDEN);
7381 if (temp != operands[0])
7382 emit_move_insn (operands[0], temp);
7386 (define_insn "ffshi_1"
7387 [(set (match_operand:HI 0 "register_operand" "=r")
7388 (unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
7390 "* return AS2 (bsf%W0,%1,%0);")
7392 ;; These patterns match the binary 387 instructions for addM3, subM3,
7393 ;; mulM3 and divM3. There are three patterns for each of DFmode and
7394 ;; SFmode. The first is the normal insn, the second the same insn but
7395 ;; with one operand a conversion, and the third the same insn but with
7396 ;; the other operand a conversion.
7399 [(set (match_operand:DF 0 "register_operand" "=f,f")
7400 (match_operator:DF 3 "binary_387_op"
7401 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
7402 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
7404 "* return output_387_binary_op (insn, operands);"
7406 (cond [(match_operand:DF 3 "is_mul" "")
7407 (const_string "fpmul")
7408 (match_operand:DF 3 "is_div" "")
7409 (const_string "fpdiv")
7411 (const_string "fpop")
7416 [(set (match_operand:XF 0 "register_operand" "=f,f")
7417 (match_operator:XF 3 "binary_387_op"
7418 [(match_operand:XF 1 "register_operand" "0,f")
7419 (match_operand:XF 2 "register_operand" "f,0")]))]
7421 "* return output_387_binary_op (insn, operands);"
7423 (cond [(match_operand:DF 3 "is_mul" "")
7424 (const_string "fpmul")
7425 (match_operand:DF 3 "is_div" "")
7426 (const_string "fpdiv")
7428 (const_string "fpop")
7433 [(set (match_operand:XF 0 "register_operand" "=f,f")
7434 (match_operator:XF 3 "binary_387_op"
7435 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7436 (match_operand:XF 2 "register_operand" "0,f")]))]
7438 "* return output_387_binary_op (insn, operands);"
7440 (cond [(match_operand:DF 3 "is_mul" "")
7441 (const_string "fpmul")
7442 (match_operand:DF 3 "is_div" "")
7443 (const_string "fpdiv")
7445 (const_string "fpop")
7450 [(set (match_operand:XF 0 "register_operand" "=f,f")
7451 (match_operator:XF 3 "binary_387_op"
7452 [(match_operand:XF 1 "register_operand" "0,f")
7454 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7456 "* return output_387_binary_op (insn, operands);"
7458 (cond [(match_operand:DF 3 "is_mul" "")
7459 (const_string "fpmul")
7460 (match_operand:DF 3 "is_div" "")
7461 (const_string "fpdiv")
7463 (const_string "fpop")
7468 [(set (match_operand:DF 0 "register_operand" "=f,f")
7469 (match_operator:DF 3 "binary_387_op"
7470 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7471 (match_operand:DF 2 "register_operand" "0,f")]))]
7473 "* return output_387_binary_op (insn, operands);"
7475 (cond [(match_operand:DF 3 "is_mul" "")
7476 (const_string "fpmul")
7477 (match_operand:DF 3 "is_div" "")
7478 (const_string "fpdiv")
7480 (const_string "fpop")
7485 [(set (match_operand:DF 0 "register_operand" "=f,f")
7486 (match_operator:DF 3 "binary_387_op"
7487 [(match_operand:DF 1 "register_operand" "0,f")
7489 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7491 "* return output_387_binary_op (insn, operands);"
7493 (cond [(match_operand:DF 3 "is_mul" "")
7494 (const_string "fpmul")
7495 (match_operand:DF 3 "is_div" "")
7496 (const_string "fpdiv")
7498 (const_string "fpop")
7503 [(set (match_operand:SF 0 "register_operand" "=f,f")
7504 (match_operator:SF 3 "binary_387_op"
7505 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
7506 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
7508 "* return output_387_binary_op (insn, operands);"
7510 (cond [(match_operand:DF 3 "is_mul" "")
7511 (const_string "fpmul")
7512 (match_operand:DF 3 "is_div" "")
7513 (const_string "fpdiv")
7515 (const_string "fpop")
7519 (define_expand "strlensi"
7520 [(parallel [(set (match_dup 4)
7521 (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
7522 (match_operand:QI 2 "immediate_operand" "")
7523 (match_operand:SI 3 "immediate_operand" "")] 0))
7524 (clobber (match_dup 1))])
7526 (not:SI (match_dup 4)))
7527 (set (match_operand:SI 0 "register_operand" "")
7528 (plus:SI (match_dup 5)
7533 if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1)
7538 /* well it seems that some optimizer does not combine a call like
7539 foo(strlen(bar), strlen(bar));
7540 when the move and the subtraction is done here. It does calculate
7541 the length just once when these instructions are done inside of
7542 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
7543 often used and I use one fewer register for the lifetime of
7544 output_strlen_unroll() this is better. */
7545 scratch = gen_reg_rtx (SImode);
7546 address = force_reg (SImode, XEXP (operands[1], 0));
7548 /* move address to scratch-register
7549 this is done here because the i586 can do the following and
7550 in the same cycle with the following move. */
7551 if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4)
7552 emit_insn (gen_movsi (scratch, address));
7554 emit_insn (gen_movsi (operands[0], address));
7556 if(TARGET_USE_Q_REG)
7557 emit_insn (gen_strlensi_unroll5 (operands[0],
7562 emit_insn (gen_strlensi_unroll4 (operands[0],
7567 /* gen_strlensi_unroll[45] returns the address of the zero
7568 at the end of the string, like memchr(), so compute the
7569 length by subtracting the startaddress. */
7570 emit_insn (gen_subsi3 (operands[0], operands[0], address));
7574 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7575 operands[4] = gen_reg_rtx (SImode);
7576 operands[5] = gen_reg_rtx (SImode);
7579 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7580 ;; But strength reduction might offset the MEM expression. So we let
7581 ;; reload put the address into %edi.
7584 [(set (match_operand:SI 0 "register_operand" "=&c")
7585 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
7586 (match_operand:QI 2 "immediate_operand" "a")
7587 (match_operand:SI 3 "immediate_operand" "i")] 0))
7588 (clobber (match_dup 1))]
7594 xops[0] = operands[0];
7595 xops[1] = constm1_rtx;
7596 output_asm_insn (\"cld\", operands);
7597 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
7598 return \"repnz\;scas%B2\";
7601 /* Conditional move define_insns. */
7603 (define_expand "movsicc"
7604 [(set (match_operand:SI 0 "register_operand" "")
7605 (if_then_else:SI (match_operand 1 "comparison_operator" "")
7606 (match_operand:SI 2 "nonimmediate_operand" "")
7607 (match_operand:SI 3 "nonimmediate_operand" "")))]
7611 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7614 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7615 GET_MODE (i386_compare_op0),
7616 i386_compare_op0, i386_compare_op1);
7620 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
7621 (if_then_else:SI (match_operator 1 "comparison_operator"
7622 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7623 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7624 (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0")
7625 (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7630 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
7631 (if_then_else:SI (match_operator 1 "comparison_operator"
7632 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7633 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7634 (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0")
7635 (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7636 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7640 [(set (match_operand:SI 0 "register_operand" "")
7641 (if_then_else:SI (match_operator 1 "comparison_operator"
7642 [(match_operand 2 "nonimmediate_operand" "")
7644 (match_operand:SI 3 "nonimmediate_operand" "")
7645 (match_operand:SI 4 "nonimmediate_operand" "")))]
7646 "TARGET_CMOVE && reload_completed"
7650 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7651 (match_dup 3) (match_dup 4)))]
7655 [(set (match_operand:SI 0 "register_operand" "")
7656 (if_then_else:SI (match_operator 1 "comparison_operator"
7657 [(match_operand 2 "nonimmediate_operand" "")
7658 (match_operand 3 "general_operand" "")])
7659 (match_operand:SI 4 "nonimmediate_operand" "")
7660 (match_operand:SI 5 "nonimmediate_operand" "")))]
7661 "TARGET_CMOVE && reload_completed"
7662 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7664 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7665 (match_dup 4) (match_dup 5)))]
7669 [(set (match_operand:SI 0 "register_operand" "=r,r")
7670 (if_then_else:SI (match_operator 1 "comparison_operator"
7671 [(cc0) (const_int 0)])
7672 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
7673 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
7674 "TARGET_CMOVE && reload_completed"
7675 "* return output_int_conditional_move (which_alternative, operands);")
7677 (define_expand "movhicc"
7678 [(set (match_operand:HI 0 "register_operand" "")
7679 (if_then_else:HI (match_operand 1 "comparison_operator" "")
7680 (match_operand:HI 2 "nonimmediate_operand" "")
7681 (match_operand:HI 3 "nonimmediate_operand" "")))]
7685 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7688 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7689 GET_MODE (i386_compare_op0),
7690 i386_compare_op0, i386_compare_op1);
7694 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
7695 (if_then_else:HI (match_operator 1 "comparison_operator"
7696 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7697 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7698 (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0")
7699 (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7704 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
7705 (if_then_else:HI (match_operator 1 "comparison_operator"
7706 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7707 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7708 (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0")
7709 (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7710 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7714 [(set (match_operand:HI 0 "register_operand" "")
7715 (if_then_else:HI (match_operator 1 "comparison_operator"
7716 [(match_operand 2 "nonimmediate_operand" "")
7718 (match_operand:HI 3 "nonimmediate_operand" "")
7719 (match_operand:HI 4 "nonimmediate_operand" "")))]
7720 "TARGET_CMOVE && reload_completed"
7724 (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7725 (match_dup 3) (match_dup 4)))]
7729 [(set (match_operand:HI 0 "register_operand" "")
7730 (if_then_else:HI (match_operator 1 "comparison_operator"
7731 [(match_operand 2 "nonimmediate_operand" "")
7732 (match_operand 3 "general_operand" "")])
7733 (match_operand:HI 4 "nonimmediate_operand" "")
7734 (match_operand:HI 5 "nonimmediate_operand" "")))]
7735 "TARGET_CMOVE && reload_completed"
7737 (compare (match_dup 2) (match_dup 3)))
7739 (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7740 (match_dup 4) (match_dup 5)))]
7744 [(set (match_operand:HI 0 "register_operand" "=r,r")
7745 (if_then_else:HI (match_operator 1 "comparison_operator"
7746 [(cc0) (const_int 0)])
7747 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
7748 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
7749 "TARGET_CMOVE && reload_completed"
7750 "* return output_int_conditional_move (which_alternative, operands);")
7752 (define_expand "movsfcc"
7753 [(set (match_operand:SF 0 "register_operand" "")
7754 (if_then_else:SF (match_operand 1 "comparison_operator" "")
7755 (match_operand:SF 2 "register_operand" "")
7756 (match_operand:SF 3 "register_operand" "")))]
7762 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7765 /* The floating point conditional move instructions don't directly
7766 support conditions resulting from a signed integer comparison. */
7768 switch (GET_CODE (operands[1]))
7774 temp = emit_store_flag (gen_reg_rtx (QImode),
7775 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7781 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7785 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7786 GET_MODE (i386_compare_op0),
7787 i386_compare_op0, i386_compare_op1);
7793 [(set (match_operand:SF 0 "register_operand" "=f,f,f,f")
7794 (if_then_else:SF (match_operator 1 "comparison_operator"
7795 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7796 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7797 (match_operand:SF 4 "register_operand" "f,f,0,0")
7798 (match_operand:SF 5 "register_operand" "0,0,f,f")))]
7800 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7801 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7805 [(set (match_operand:SF 0 "register_operand" "=f,f,f,f")
7806 (if_then_else:SF (match_operator 1 "comparison_operator"
7807 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7808 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7809 (match_operand:SF 4 "register_operand" "f,f,0,0")
7810 (match_operand:SF 5 "register_operand" "0,0,f,f")))]
7811 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7812 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7813 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7817 [(set (match_operand:SF 0 "register_operand" "")
7818 (if_then_else:SF (match_operator 1 "comparison_operator"
7819 [(match_operand 2 "nonimmediate_operand" "")
7821 (match_operand:SF 3 "register_operand" "")
7822 (match_operand:SF 4 "register_operand" "")))]
7823 "TARGET_CMOVE && reload_completed"
7827 (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7828 (match_dup 3) (match_dup 4)))]
7832 [(set (match_operand:SF 0 "register_operand" "")
7833 (if_then_else:SF (match_operator 1 "comparison_operator"
7834 [(match_operand 2 "nonimmediate_operand" "")
7835 (match_operand 3 "general_operand" "")])
7836 (match_operand:SF 4 "register_operand" "")
7837 (match_operand:SF 5 "register_operand" "")))]
7838 "TARGET_CMOVE && reload_completed"
7839 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7841 (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7842 (match_dup 4) (match_dup 5)))]
7846 [(set (match_operand:SF 0 "register_operand" "=f,f")
7847 (if_then_else:SF (match_operator 1 "comparison_operator"
7848 [(cc0) (const_int 0)])
7849 (match_operand:SF 2 "register_operand" "f,0")
7850 (match_operand:SF 3 "register_operand" "0,f")))]
7851 "TARGET_CMOVE && reload_completed"
7852 "* return output_fp_conditional_move (which_alternative, operands);")
7854 (define_expand "movdfcc"
7855 [(set (match_operand:DF 0 "register_operand" "")
7856 (if_then_else:DF (match_operand 1 "comparison_operator" "")
7857 (match_operand:DF 2 "register_operand" "")
7858 (match_operand:DF 3 "register_operand" "")))]
7864 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7867 /* The floating point conditional move instructions don't directly
7868 support conditions resulting from a signed integer comparison. */
7870 switch (GET_CODE (operands[1]))
7876 temp = emit_store_flag (gen_reg_rtx (QImode),
7877 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7883 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7887 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7888 GET_MODE (i386_compare_op0),
7889 i386_compare_op0, i386_compare_op1);
7895 [(set (match_operand:DF 0 "register_operand" "=f,f,f,f")
7896 (if_then_else:DF (match_operator 1 "comparison_operator"
7897 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7898 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7899 (match_operand:DF 4 "register_operand" "f,f,0,0")
7900 (match_operand:DF 5 "register_operand" "0,0,f,f")))]
7902 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7903 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7907 [(set (match_operand:DF 0 "register_operand" "=f,f,f,f")
7908 (if_then_else:DF (match_operator 1 "comparison_operator"
7909 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7910 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7911 (match_operand:DF 4 "register_operand" "f,f,0,0")
7912 (match_operand:DF 5 "register_operand" "0,0,f,f")))]
7913 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7914 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7915 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7919 [(set (match_operand:DF 0 "register_operand" "")
7920 (if_then_else:DF (match_operator 1 "comparison_operator"
7921 [(match_operand 2 "nonimmediate_operand" "")
7923 (match_operand:DF 3 "register_operand" "")
7924 (match_operand:DF 4 "register_operand" "")))]
7925 "TARGET_CMOVE && reload_completed"
7929 (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7930 (match_dup 3) (match_dup 4)))]
7934 [(set (match_operand:DF 0 "register_operand" "")
7935 (if_then_else:DF (match_operator 1 "comparison_operator"
7936 [(match_operand 2 "nonimmediate_operand" "")
7937 (match_operand 3 "general_operand" "")])
7938 (match_operand:DF 4 "register_operand" "")
7939 (match_operand:DF 5 "register_operand" "")))]
7940 "TARGET_CMOVE && reload_completed"
7941 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7943 (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7944 (match_dup 4) (match_dup 5)))]
7948 [(set (match_operand:DF 0 "register_operand" "=f,f")
7949 (if_then_else:DF (match_operator 1 "comparison_operator"
7950 [(cc0) (const_int 0)])
7951 (match_operand:DF 2 "register_operand" "f,0")
7952 (match_operand:DF 3 "register_operand" "0,f")))]
7953 "TARGET_CMOVE && reload_completed"
7954 "* return output_fp_conditional_move (which_alternative, operands);")
7956 (define_expand "movxfcc"
7957 [(set (match_operand:XF 0 "register_operand" "")
7958 (if_then_else:XF (match_operand 1 "comparison_operator" "")
7959 (match_operand:XF 2 "register_operand" "")
7960 (match_operand:XF 3 "register_operand" "")))]
7966 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7969 /* The floating point conditional move instructions don't directly
7970 support conditions resulting from a signed integer comparison. */
7972 switch (GET_CODE (operands[1]))
7978 temp = emit_store_flag (gen_reg_rtx (QImode),
7979 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7985 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7989 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7990 GET_MODE (i386_compare_op0),
7991 i386_compare_op0, i386_compare_op1);
7997 [(set (match_operand:XF 0 "register_operand" "=f,f,f,f")
7998 (if_then_else:XF (match_operator 1 "comparison_operator"
7999 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
8000 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
8001 (match_operand:XF 4 "register_operand" "f,f,0,0")
8002 (match_operand:XF 5 "register_operand" "0,0,f,f")))]
8004 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
8005 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
8009 [(set (match_operand:XF 0 "register_operand" "=f,f,f,f")
8010 (if_then_else:XF (match_operator 1 "comparison_operator"
8011 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
8012 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
8013 (match_operand:XF 4 "register_operand" "f,f,0,0")
8014 (match_operand:XF 5 "register_operand" "0,0,f,f")))]
8015 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
8016 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
8017 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
8021 [(set (match_operand:XF 0 "register_operand" "")
8022 (if_then_else:XF (match_operator 1 "comparison_operator"
8023 [(match_operand 2 "nonimmediate_operand" "")
8025 (match_operand:XF 3 "register_operand" "")
8026 (match_operand:XF 4 "register_operand" "")))]
8027 "TARGET_CMOVE && reload_completed"
8031 (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
8032 (match_dup 3) (match_dup 4)))]
8036 [(set (match_operand:XF 0 "register_operand" "")
8037 (if_then_else:XF (match_operator 1 "comparison_operator"
8038 [(match_operand 2 "nonimmediate_operand" "")
8039 (match_operand 3 "general_operand" "")])
8040 (match_operand:XF 4 "register_operand" "")
8041 (match_operand:XF 5 "register_operand" "")))]
8042 "TARGET_CMOVE && reload_completed"
8043 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
8045 (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
8046 (match_dup 4) (match_dup 5)))]
8050 [(set (match_operand:XF 0 "register_operand" "=f,f")
8051 (if_then_else:XF (match_operator 1 "comparison_operator"
8052 [(cc0) (const_int 0)])
8053 (match_operand:XF 2 "register_operand" "f,0")
8054 (match_operand:XF 3 "register_operand" "0,f")))]
8055 "TARGET_CMOVE && reload_completed"
8056 "* return output_fp_conditional_move (which_alternative, operands);")
8058 (define_expand "movdicc"
8059 [(set (match_operand:DI 0 "register_operand" "")
8060 (if_then_else:DI (match_operand 1 "comparison_operator" "")
8061 (match_operand:DI 2 "nonimmediate_operand" "")
8062 (match_operand:DI 3 "nonimmediate_operand" "")))]
8066 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
8069 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
8070 GET_MODE (i386_compare_op0),
8071 i386_compare_op0, i386_compare_op1);
8075 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r")
8076 (if_then_else:DI (match_operator 1 "comparison_operator"
8077 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
8078 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
8079 (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0")
8080 (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))]
8085 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r")
8086 (if_then_else:DI (match_operator 1 "comparison_operator"
8087 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
8088 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
8089 (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0")
8090 (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))]
8091 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
8095 [(set (match_operand:DI 0 "register_operand" "")
8096 (if_then_else:DI (match_operator 1 "comparison_operator"
8097 [(match_operand 2 "nonimmediate_operand" "")
8099 (match_operand:DI 3 "nonimmediate_operand" "")
8100 (match_operand:DI 4 "nonimmediate_operand" "")))]
8101 "TARGET_CMOVE && reload_completed"
8105 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8106 (match_dup 7) (match_dup 9)))
8108 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8109 (match_dup 8) (match_dup 10)))]
8110 "split_di (&operands[0], 1, &operands[5], &operands[6]);
8111 split_di (&operands[3], 1, &operands[7], &operands[8]);
8112 split_di (&operands[4], 1, &operands[9], &operands[10]);")
8115 [(set (match_operand:DI 0 "register_operand" "")
8116 (if_then_else:DI (match_operator 1 "comparison_operator"
8117 [(match_operand 2 "nonimmediate_operand" "")
8118 (match_operand 3 "general_operand" "")])
8119 (match_operand:DI 4 "nonimmediate_operand" "")
8120 (match_operand:DI 5 "nonimmediate_operand" "")))]
8121 "TARGET_CMOVE && reload_completed"
8122 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
8124 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8125 (match_dup 8) (match_dup 10)))
8127 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8128 (match_dup 9) (match_dup 11)))]
8129 "split_di (&operands[0], 1, &operands[6], &operands[7]);
8130 split_di (&operands[4], 1, &operands[8], &operands[9]);
8131 split_di (&operands[5], 1, &operands[10], &operands[11]);")
8133 (define_insn "strlensi_unroll"
8134 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
8135 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r"))
8136 (match_operand:SI 2 "immediate_operand" "i,i")] 0))
8137 (clobber (match_scratch:SI 3 "=&q,&r"))]
8139 "* return output_strlen_unroll (operands);")
8141 ;; the only difference between the following patterns is the register preference
8142 ;; on a pentium using a q-register saves one clock cycle per 4 characters
8144 (define_insn "strlensi_unroll4"
8145 [(set (match_operand:SI 0 "register_operand" "=r,r")
8146 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0"))
8147 (match_operand:SI 1 "immediate_operand" "i,i")
8148 (match_operand:SI 2 "register_operand" "+q,!r")] 0))
8149 (clobber (match_dup 2))]
8150 "(TARGET_USE_ANY_REG && optimize > 1)"
8151 "* return output_strlen_unroll (operands);")
8153 (define_insn "strlensi_unroll5"
8154 [(set (match_operand:SI 0 "register_operand" "=r")
8155 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0"))
8156 (match_operand:SI 1 "immediate_operand" "i")
8157 (match_operand:SI 2 "register_operand" "+q")] 0))
8158 (clobber (match_dup 2))]
8159 "(TARGET_USE_Q_REG && optimize > 1)"
8160 "* return output_strlen_unroll (operands);"
8163 (define_insn "allocate_stack_worker"
8164 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
8165 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
8166 (clobber (match_dup 0))]
8167 "TARGET_STACK_PROBE"
8168 "* return AS1(call,__alloca);"
8169 [(set_attr "memory" "none")])
8171 (define_expand "allocate_stack"
8172 [(set (match_operand:SI 0 "register_operand" "=r")
8173 (minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" "")))
8174 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))]
8175 "TARGET_STACK_PROBE"
8178 #ifdef CHECK_STACK_LIMIT
8179 if (GET_CODE (operands[1]) == CONST_INT
8180 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
8181 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
8185 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
8188 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
8192 (define_expand "exception_receiver"
8197 load_pic_register (1);
8201 (define_expand "builtin_setjmp_receiver"
8202 [(label_ref (match_operand 0 "" ""))]
8206 load_pic_register (1);