1 ;; GCC machine description for Intel X86.
2 ;; Copyright (C) 1988, 1994, 1995 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
5 ;; This file is part of GNU CC.
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
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 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'Q' Print the opcode suffix for a 64-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'.
63 ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
64 ;; But restricting MEM here would mean that gcc could not remove a redundant
65 ;; test in cases like "incl MEM / je TARGET".
67 ;; We don't want to allow a constant operand for test insns because
68 ;; (set (cc0) (const_int foo)) has no mode information. Such insns will
69 ;; be folded while optimizing anyway.
71 ;; All test insns have expanders that save the operands away without
72 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
73 ;; after the tstM or cmp) will actually emit the tstM or cmpM.
75 (define_insn "tstsi_1"
77 (match_operand:SI 0 "nonimmediate_operand" "rm"))]
81 if (REG_P (operands[0]))
82 return AS2 (test%L0,%0,%0);
84 operands[1] = const0_rtx;
85 return AS2 (cmp%L0,%1,%0);
88 (define_expand "tstsi"
90 (match_operand:SI 0 "nonimmediate_operand" ""))]
94 i386_compare_gen = gen_tstsi_1;
95 i386_compare_op0 = operands[0];
99 (define_insn "tsthi_1"
101 (match_operand:HI 0 "nonimmediate_operand" "rm"))]
105 if (REG_P (operands[0]))
106 return AS2 (test%W0,%0,%0);
108 operands[1] = const0_rtx;
109 return AS2 (cmp%W0,%1,%0);
112 (define_expand "tsthi"
114 (match_operand:HI 0 "nonimmediate_operand" ""))]
118 i386_compare_gen = gen_tsthi_1;
119 i386_compare_op0 = operands[0];
123 (define_insn "tstqi_1"
125 (match_operand:QI 0 "nonimmediate_operand" "qm"))]
129 if (REG_P (operands[0]))
130 return AS2 (test%B0,%0,%0);
132 operands[1] = const0_rtx;
133 return AS2 (cmp%B0,%1,%0);
136 (define_expand "tstqi"
138 (match_operand:QI 0 "nonimmediate_operand" ""))]
142 i386_compare_gen = gen_tstqi_1;
143 i386_compare_op0 = operands[0];
147 (define_insn "tstsf_cc"
149 (match_operand:SF 0 "register_operand" "f"))
150 (clobber (match_scratch:HI 1 "=a"))]
151 "TARGET_80387 && ! TARGET_IEEE_FP"
154 if (! STACK_TOP_P (operands[0]))
157 output_asm_insn (\"ftst\", operands);
159 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
160 output_asm_insn (AS1 (fstp,%y0), operands);
162 return output_fp_cc0_set (insn);
165 ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
166 ;; isn't IEEE compliant.
168 (define_expand "tstsf"
169 [(parallel [(set (cc0)
170 (match_operand:SF 0 "register_operand" ""))
171 (clobber (match_scratch:HI 1 ""))])]
172 "TARGET_80387 && ! TARGET_IEEE_FP"
175 i386_compare_gen = gen_tstsf_cc;
176 i386_compare_op0 = operands[0];
180 (define_insn "tstdf_cc"
182 (match_operand:DF 0 "register_operand" "f"))
183 (clobber (match_scratch:HI 1 "=a"))]
184 "TARGET_80387 && ! TARGET_IEEE_FP"
187 if (! STACK_TOP_P (operands[0]))
190 output_asm_insn (\"ftst\", operands);
192 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
193 output_asm_insn (AS1 (fstp,%y0), operands);
195 return output_fp_cc0_set (insn);
198 ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
199 ;; isn't IEEE compliant.
201 (define_expand "tstdf"
202 [(parallel [(set (cc0)
203 (match_operand:DF 0 "register_operand" ""))
204 (clobber (match_scratch:HI 1 ""))])]
205 "TARGET_80387 && ! TARGET_IEEE_FP"
208 i386_compare_gen = gen_tstdf_cc;
209 i386_compare_op0 = operands[0];
213 (define_insn "tstxf_cc"
215 (match_operand:XF 0 "register_operand" "f"))
216 (clobber (match_scratch:HI 1 "=a"))]
217 "TARGET_80387 && ! TARGET_IEEE_FP"
220 if (! STACK_TOP_P (operands[0]))
223 output_asm_insn (\"ftst\", operands);
225 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
226 output_asm_insn (AS1 (fstp,%y0), operands);
228 return output_fp_cc0_set (insn);
231 ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
232 ;; isn't IEEE compliant.
234 (define_expand "tstxf"
235 [(parallel [(set (cc0)
236 (match_operand:XF 0 "register_operand" ""))
237 (clobber (match_scratch:HI 1 ""))])]
238 "TARGET_80387 && ! TARGET_IEEE_FP"
241 i386_compare_gen = gen_tstxf_cc;
242 i386_compare_op0 = operands[0];
246 ;;- compare instructions. See comments above tstM patterns about
247 ;; expansion of these insns.
249 (define_insn "cmpsi_1"
251 (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
252 (match_operand:SI 1 "general_operand" "ri,mr")))]
253 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
256 if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
258 cc_status.flags |= CC_REVERSED;
259 return AS2 (cmp%L0,%0,%1);
261 return AS2 (cmp%L0,%1,%0);
264 (define_expand "cmpsi"
266 (compare (match_operand:SI 0 "nonimmediate_operand" "")
267 (match_operand:SI 1 "general_operand" "")))]
271 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
272 operands[0] = force_reg (SImode, operands[0]);
274 i386_compare_gen = gen_cmpsi_1;
275 i386_compare_op0 = operands[0];
276 i386_compare_op1 = operands[1];
280 (define_insn "cmphi_1"
282 (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
283 (match_operand:HI 1 "general_operand" "ri,mr")))]
284 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
287 if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
289 cc_status.flags |= CC_REVERSED;
290 return AS2 (cmp%W0,%0,%1);
292 return AS2 (cmp%W0,%1,%0);
295 (define_expand "cmphi"
297 (compare (match_operand:HI 0 "nonimmediate_operand" "")
298 (match_operand:HI 1 "general_operand" "")))]
302 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
303 operands[0] = force_reg (HImode, operands[0]);
305 i386_compare_gen = gen_cmphi_1;
306 i386_compare_op0 = operands[0];
307 i386_compare_op1 = operands[1];
311 (define_insn "cmpqi_1"
313 (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
314 (match_operand:QI 1 "general_operand" "qm,nq")))]
315 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
318 if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
320 cc_status.flags |= CC_REVERSED;
321 return AS2 (cmp%B0,%0,%1);
323 return AS2 (cmp%B0,%1,%0);
326 (define_expand "cmpqi"
328 (compare (match_operand:QI 0 "nonimmediate_operand" "")
329 (match_operand:QI 1 "general_operand" "")))]
333 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
334 operands[0] = force_reg (QImode, operands[0]);
336 i386_compare_gen = gen_cmpqi_1;
337 i386_compare_op0 = operands[0];
338 i386_compare_op1 = operands[1];
342 ;; These implement float point compares. For each of DFmode and
343 ;; SFmode, there is the normal insn, and an insn where the second operand
344 ;; is converted to the desired mode.
348 (match_operator 2 "VOIDmode_compare_op"
349 [(match_operand:XF 0 "nonimmediate_operand" "f")
350 (match_operand:XF 1 "nonimmediate_operand" "f")]))
351 (clobber (match_scratch:HI 3 "=a"))]
353 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
354 "* return output_float_compare (insn, operands);")
358 (match_operator 2 "VOIDmode_compare_op"
359 [(match_operand:XF 0 "register_operand" "f")
361 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
362 (clobber (match_scratch:HI 3 "=a"))]
364 "* return output_float_compare (insn, operands);")
368 (match_operator 2 "VOIDmode_compare_op"
370 (match_operand:SI 0 "nonimmediate_operand" "rm"))
371 (match_operand:XF 1 "register_operand" "f")]))
372 (clobber (match_scratch:HI 3 "=a"))]
374 "* return output_float_compare (insn, operands);")
378 (match_operator 2 "VOIDmode_compare_op"
379 [(match_operand:XF 0 "register_operand" "f")
381 (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
382 (clobber (match_scratch:HI 3 "=a"))]
384 "* return output_float_compare (insn, operands);")
388 (match_operator 2 "VOIDmode_compare_op"
389 [(match_operand:XF 0 "register_operand" "f")
391 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
392 (clobber (match_scratch:HI 3 "=a"))]
394 "* return output_float_compare (insn, operands);")
398 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
399 (match_operand:XF 1 "register_operand" "f")))
400 (clobber (match_scratch:HI 2 "=a"))]
402 "* return output_float_compare (insn, operands);")
406 (match_operator 2 "VOIDmode_compare_op"
407 [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
408 (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
409 (clobber (match_scratch:HI 3 "=a,a"))]
411 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
412 "* return output_float_compare (insn, operands);")
416 (match_operator 2 "VOIDmode_compare_op"
417 [(match_operand:DF 0 "register_operand" "f")
419 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
420 (clobber (match_scratch:HI 3 "=a"))]
422 "* return output_float_compare (insn, operands);")
426 (match_operator 2 "VOIDmode_compare_op"
428 (match_operand:SI 0 "nonimmediate_operand" "rm"))
429 (match_operand:DF 1 "register_operand" "f")]))
430 (clobber (match_scratch:HI 3 "=a"))]
432 "* return output_float_compare (insn, operands);")
436 (match_operator 2 "VOIDmode_compare_op"
437 [(match_operand:DF 0 "register_operand" "f")
439 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
440 (clobber (match_scratch:HI 3 "=a"))]
442 "* return output_float_compare (insn, operands);")
446 (match_operator 2 "VOIDmode_compare_op"
448 (match_operand:SF 0 "nonimmediate_operand" "fm"))
449 (match_operand:DF 1 "register_operand" "f")]))
450 (clobber (match_scratch:HI 3 "=a"))]
452 "* return output_float_compare (insn, operands);")
456 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
457 (match_operand:DF 1 "register_operand" "f")))
458 (clobber (match_scratch:HI 2 "=a"))]
460 "* return output_float_compare (insn, operands);")
462 ;; These two insns will never be generated by combine due to the mode of
466 ; (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
468 ; (match_operand:SF 1 "register_operand" "f"))))
469 ; (clobber (match_scratch:HI 2 "=a"))]
471 ; "* return output_float_compare (insn, operands);")
475 ; (compare:CCFPEQ (float_extend:DF
476 ; (match_operand:SF 0 "register_operand" "f"))
477 ; (match_operand:DF 1 "register_operand" "f")))
478 ; (clobber (match_scratch:HI 2 "=a"))]
480 ; "* return output_float_compare (insn, operands);")
482 (define_insn "cmpsf_cc_1"
484 (match_operator 2 "VOIDmode_compare_op"
485 [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
486 (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
487 (clobber (match_scratch:HI 3 "=a,a"))]
489 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
490 "* return output_float_compare (insn, operands);")
494 (match_operator 2 "VOIDmode_compare_op"
495 [(match_operand:SF 0 "register_operand" "f")
497 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
498 (clobber (match_scratch:HI 3 "=a"))]
500 "* return output_float_compare (insn, operands);")
504 (match_operator 2 "VOIDmode_compare_op"
506 (match_operand:SI 0 "nonimmediate_operand" "rm"))
507 (match_operand:SF 1 "register_operand" "f")]))
508 (clobber (match_scratch:HI 3 "=a"))]
510 "* return output_float_compare (insn, operands);")
514 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
515 (match_operand:SF 1 "register_operand" "f")))
516 (clobber (match_scratch:HI 2 "=a"))]
518 "* return output_float_compare (insn, operands);")
520 (define_expand "cmpxf"
522 (compare (match_operand:XF 0 "register_operand" "")
523 (match_operand:XF 1 "nonimmediate_operand" "")))]
527 i386_compare_gen = gen_cmpxf_cc;
528 i386_compare_gen_eq = gen_cmpxf_ccfpeq;
529 i386_compare_op0 = operands[0];
530 i386_compare_op1 = operands[1];
534 (define_expand "cmpdf"
536 (compare (match_operand:DF 0 "register_operand" "")
537 (match_operand:DF 1 "nonimmediate_operand" "")))]
541 i386_compare_gen = gen_cmpdf_cc;
542 i386_compare_gen_eq = gen_cmpdf_ccfpeq;
543 i386_compare_op0 = operands[0];
544 i386_compare_op1 = operands[1];
548 (define_expand "cmpsf"
550 (compare (match_operand:SF 0 "register_operand" "")
551 (match_operand:SF 1 "nonimmediate_operand" "")))]
555 i386_compare_gen = gen_cmpsf_cc;
556 i386_compare_gen_eq = gen_cmpsf_ccfpeq;
557 i386_compare_op0 = operands[0];
558 i386_compare_op1 = operands[1];
562 (define_expand "cmpxf_cc"
563 [(parallel [(set (cc0)
564 (compare (match_operand:XF 0 "register_operand" "")
565 (match_operand:XF 1 "register_operand" "")))
566 (clobber (match_scratch:HI 2 ""))])]
570 (define_expand "cmpxf_ccfpeq"
571 [(parallel [(set (cc0)
572 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
573 (match_operand:XF 1 "register_operand" "")))
574 (clobber (match_scratch:HI 2 ""))])]
578 if (! register_operand (operands[1], XFmode))
579 operands[1] = copy_to_mode_reg (XFmode, operands[1]);
582 (define_expand "cmpdf_cc"
583 [(parallel [(set (cc0)
584 (compare (match_operand:DF 0 "register_operand" "")
585 (match_operand:DF 1 "register_operand" "")))
586 (clobber (match_scratch:HI 2 ""))])]
590 (define_expand "cmpdf_ccfpeq"
591 [(parallel [(set (cc0)
592 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
593 (match_operand:DF 1 "register_operand" "")))
594 (clobber (match_scratch:HI 2 ""))])]
598 if (! register_operand (operands[1], DFmode))
599 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
602 (define_expand "cmpsf_cc"
603 [(parallel [(set (cc0)
604 (compare (match_operand:SF 0 "register_operand" "")
605 (match_operand:SF 1 "register_operand" "")))
606 (clobber (match_scratch:HI 2 ""))])]
610 (define_expand "cmpsf_ccfpeq"
611 [(parallel [(set (cc0)
612 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
613 (match_operand:SF 1 "register_operand" "")))
614 (clobber (match_scratch:HI 2 ""))])]
618 if (! register_operand (operands[1], SFmode))
619 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
626 (and:SI (match_operand:SI 0 "general_operand" "%ro")
627 (match_operand:SI 1 "general_operand" "ri")))]
631 /* For small integers, we may actually use testb. */
632 if (GET_CODE (operands[1]) == CONST_INT
633 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
634 && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
636 /* We may set the sign bit spuriously. */
638 if ((INTVAL (operands[1]) & ~0xff) == 0)
640 cc_status.flags |= CC_NOT_NEGATIVE;
641 return AS2 (test%B0,%1,%b0);
644 if ((INTVAL (operands[1]) & ~0xff00) == 0)
646 cc_status.flags |= CC_NOT_NEGATIVE;
647 operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
649 if (QI_REG_P (operands[0]))
650 return AS2 (test%B0,%1,%h0);
653 operands[0] = adj_offsettable_operand (operands[0], 1);
654 return AS2 (test%B0,%1,%b0);
658 if (GET_CODE (operands[0]) == MEM
659 && (INTVAL (operands[1]) & ~0xff0000) == 0)
661 cc_status.flags |= CC_NOT_NEGATIVE;
662 operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
663 operands[0] = adj_offsettable_operand (operands[0], 2);
664 return AS2 (test%B0,%1,%b0);
667 if (GET_CODE (operands[0]) == MEM
668 && (INTVAL (operands[1]) & ~0xff000000) == 0)
670 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
671 operands[0] = adj_offsettable_operand (operands[0], 3);
672 return AS2 (test%B0,%1,%b0);
676 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
677 return AS2 (test%L0,%1,%0);
679 return AS2 (test%L1,%0,%1);
684 (and:HI (match_operand:HI 0 "general_operand" "%ro")
685 (match_operand:HI 1 "general_operand" "ri")))]
689 if (GET_CODE (operands[1]) == CONST_INT
690 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
691 && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
693 if ((INTVAL (operands[1]) & 0xff00) == 0)
695 /* ??? This might not be necessary. */
696 if (INTVAL (operands[1]) & 0xffff0000)
697 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
699 /* We may set the sign bit spuriously. */
700 cc_status.flags |= CC_NOT_NEGATIVE;
701 return AS2 (test%B0,%1,%b0);
704 if ((INTVAL (operands[1]) & 0xff) == 0)
706 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
708 if (QI_REG_P (operands[0]))
709 return AS2 (test%B0,%1,%h0);
712 operands[0] = adj_offsettable_operand (operands[0], 1);
713 return AS2 (test%B0,%1,%b0);
718 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
719 return AS2 (test%W0,%1,%0);
721 return AS2 (test%W1,%0,%1);
726 (and:QI (match_operand:QI 0 "general_operand" "%qm")
727 (match_operand:QI 1 "general_operand" "qi")))]
731 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
732 return AS2 (test%B0,%1,%0);
734 return AS2 (test%B1,%0,%1);
737 ;; move instructions.
738 ;; There is one for each machine mode,
739 ;; and each is preceded by a corresponding push-insn pattern
740 ;; (since pushes are not general_operands on the 386).
743 [(set (match_operand:SI 0 "push_operand" "=<")
744 (match_operand:SI 1 "general_operand" "g"))]
748 ;; On a 486, it is faster to move MEM to a REG and then push, rather than
749 ;; push MEM directly.
752 [(set (match_operand:SI 0 "push_operand" "=<")
753 (match_operand:SI 1 "nonmemory_operand" "ri"))]
754 "!TARGET_386 && TARGET_MOVE"
758 [(set (match_operand:SI 0 "push_operand" "=<")
759 (match_operand:SI 1 "general_operand" "ri"))]
760 "!TARGET_386 && !TARGET_MOVE"
763 ;; General case of fullword move.
765 ;; If generating PIC code and operands[1] is a symbolic CONST, emit a
766 ;; move to get the address of the symbolic object from the GOT.
768 (define_expand "movsi"
769 [(set (match_operand:SI 0 "general_operand" "")
770 (match_operand:SI 1 "general_operand" ""))]
776 if (flag_pic && SYMBOLIC_CONST (operands[1]))
777 emit_pic_move (operands, SImode);
779 /* Don't generate memory->memory moves, go through a register */
781 && (reload_in_progress | reload_completed) == 0
782 && GET_CODE (operands[0]) == MEM
783 && GET_CODE (operands[1]) == MEM)
785 operands[1] = force_reg (SImode, operands[1]);
789 ;; On i486, incl reg is faster than movl $1,reg.
792 [(set (match_operand:SI 0 "general_operand" "=g,r")
793 (match_operand:SI 1 "general_operand" "ri,m"))]
794 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
798 if (operands[1] == const0_rtx && REG_P (operands[0]))
799 return AS2 (xor%L0,%0,%0);
801 if (operands[1] == const1_rtx
802 && (link = find_reg_note (insn, REG_WAS_0, 0))
803 /* Make sure the insn that stored the 0 is still present. */
804 && ! INSN_DELETED_P (XEXP (link, 0))
805 && GET_CODE (XEXP (link, 0)) != NOTE
806 /* Make sure cross jumping didn't happen here. */
807 && no_labels_between_p (XEXP (link, 0), insn)
808 /* Make sure the reg hasn't been clobbered. */
809 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
810 /* Fastest way to change a 0 to a 1. */
811 return AS1 (inc%L0,%0);
813 if (flag_pic && SYMBOLIC_CONST (operands[1]))
814 return AS2 (lea%L0,%a1,%0);
816 return AS2 (mov%L0,%1,%0);
820 [(set (match_operand:HI 0 "push_operand" "=<")
821 (match_operand:HI 1 "general_operand" "g"))]
826 [(set (match_operand:HI 0 "push_operand" "=<")
827 (match_operand:HI 1 "nonmemory_operand" "ri"))]
828 "!TARGET_386 && TARGET_MOVE"
832 [(set (match_operand:HI 0 "push_operand" "=<")
833 (match_operand:HI 1 "general_operand" "ri"))]
834 "!TARGET_386 && !TARGET_MOVE"
837 ;; On i486, an incl and movl are both faster than incw and movw.
839 (define_expand "movhi"
840 [(set (match_operand:HI 0 "general_operand" "")
841 (match_operand:HI 1 "general_operand" ""))]
845 /* Don't generate memory->memory moves, go through a register */
847 && (reload_in_progress | reload_completed) == 0
848 && GET_CODE (operands[0]) == MEM
849 && GET_CODE (operands[1]) == MEM)
851 operands[1] = force_reg (HImode, operands[1]);
856 [(set (match_operand:HI 0 "general_operand" "=g,r")
857 (match_operand:HI 1 "general_operand" "ri,m"))]
858 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
862 if (REG_P (operands[0]) && operands[1] == const0_rtx)
863 return AS2 (xor%L0,%k0,%k0);
865 if (REG_P (operands[0]) && operands[1] == const1_rtx
866 && (link = find_reg_note (insn, REG_WAS_0, 0))
867 /* Make sure the insn that stored the 0 is still present. */
868 && ! INSN_DELETED_P (XEXP (link, 0))
869 && GET_CODE (XEXP (link, 0)) != NOTE
870 /* Make sure cross jumping didn't happen here. */
871 && no_labels_between_p (XEXP (link, 0), insn)
872 /* Make sure the reg hasn't been clobbered. */
873 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
874 /* Fastest way to change a 0 to a 1. */
875 return AS1 (inc%L0,%k0);
877 if (REG_P (operands[0]))
879 if (REG_P (operands[1]))
880 return AS2 (mov%L0,%k1,%k0);
881 else if (CONSTANT_P (operands[1]))
882 return AS2 (mov%L0,%1,%k0);
885 return AS2 (mov%W0,%1,%0);
888 (define_expand "movstricthi"
889 [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
890 (match_operand:HI 1 "general_operand" ""))]
894 /* Don't generate memory->memory moves, go through a register */
896 && (reload_in_progress | reload_completed) == 0
897 && GET_CODE (operands[0]) == MEM
898 && GET_CODE (operands[1]) == MEM)
900 operands[1] = force_reg (HImode, operands[1]);
905 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
906 (match_operand:HI 1 "general_operand" "ri,m"))]
907 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
911 if (operands[1] == const0_rtx && REG_P (operands[0]))
912 return AS2 (xor%W0,%0,%0);
914 if (operands[1] == const1_rtx
915 && (link = find_reg_note (insn, REG_WAS_0, 0))
916 /* Make sure the insn that stored the 0 is still present. */
917 && ! INSN_DELETED_P (XEXP (link, 0))
918 && GET_CODE (XEXP (link, 0)) != NOTE
919 /* Make sure cross jumping didn't happen here. */
920 && no_labels_between_p (XEXP (link, 0), insn)
921 /* Make sure the reg hasn't been clobbered. */
922 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
923 /* Fastest way to change a 0 to a 1. */
924 return AS1 (inc%W0,%0);
926 return AS2 (mov%W0,%1,%0);
929 ;; emit_push_insn when it calls move_by_pieces
930 ;; requires an insn to "push a byte".
931 ;; But actually we use pushw, which has the effect of rounding
932 ;; the amount pushed up to a halfword.
934 [(set (match_operand:QI 0 "push_operand" "=<")
935 (match_operand:QI 1 "immediate_operand" "n"))]
937 "* return AS1 (push%W0,%1);")
940 [(set (match_operand:QI 0 "push_operand" "=<")
941 (match_operand:QI 1 "nonimmediate_operand" "q"))]
945 operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
946 return AS1 (push%W0,%1);
950 [(set (match_operand:QI 0 "push_operand" "=<")
951 (match_operand:QI 1 "register_operand" "q"))]
955 operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
956 return AS1 (push%W0,%1);
959 ;; On i486, incb reg is faster than movb $1,reg.
961 ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
962 ;; or writes %ah, %bh, %ch, %dh.
964 (define_expand "movqi"
965 [(set (match_operand:QI 0 "general_operand" "")
966 (match_operand:QI 1 "general_operand" ""))]
970 /* Don't generate memory->memory moves, go through a register */
972 && (reload_in_progress | reload_completed) == 0
973 && GET_CODE (operands[0]) == MEM
974 && GET_CODE (operands[1]) == MEM)
976 operands[1] = force_reg (QImode, operands[1]);
981 [(set (match_operand:QI 0 "general_operand" "=q,*r,qm")
982 (match_operand:QI 1 "general_operand" "*g,q,qn"))]
983 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
987 if (operands[1] == const0_rtx && REG_P (operands[0]))
988 return AS2 (xor%B0,%0,%0);
990 if (operands[1] == const1_rtx
991 && (link = find_reg_note (insn, REG_WAS_0, 0))
992 /* Make sure the insn that stored the 0 is still present. */
993 && ! INSN_DELETED_P (XEXP (link, 0))
994 && GET_CODE (XEXP (link, 0)) != NOTE
995 /* Make sure cross jumping didn't happen here. */
996 && no_labels_between_p (XEXP (link, 0), insn)
997 /* Make sure the reg hasn't been clobbered. */
998 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
999 /* Fastest way to change a 0 to a 1. */
1000 return AS1 (inc%B0,%0);
1002 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1003 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1004 return (AS2 (mov%L0,%k1,%k0));
1006 return (AS2 (mov%B0,%1,%0));
1009 ;; If it becomes necessary to support movstrictqi into %esi or %edi,
1010 ;; use the insn sequence:
1012 ;; shrdl $8,srcreg,dstreg
1015 ;; If operands[1] is a constant, then an andl/orl sequence would be
1018 (define_expand "movstrictqi"
1019 [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
1020 (match_operand:QI 1 "general_operand" ""))]
1024 /* Don't generate memory->memory moves, go through a register */
1026 && (reload_in_progress | reload_completed) == 0
1027 && GET_CODE (operands[0]) == MEM
1028 && GET_CODE (operands[1]) == MEM)
1030 operands[1] = force_reg (QImode, operands[1]);
1035 [(set (strict_low_part (match_operand:QI 0 "general_operand" "+qm,q"))
1036 (match_operand:QI 1 "general_operand" "*qn,m"))]
1037 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1041 if (operands[1] == const0_rtx && REG_P (operands[0]))
1042 return AS2 (xor%B0,%0,%0);
1044 if (operands[1] == const1_rtx
1045 && (link = find_reg_note (insn, REG_WAS_0, 0))
1046 /* Make sure the insn that stored the 0 is still present. */
1047 && ! INSN_DELETED_P (XEXP (link, 0))
1048 && GET_CODE (XEXP (link, 0)) != NOTE
1049 /* Make sure cross jumping didn't happen here. */
1050 && no_labels_between_p (XEXP (link, 0), insn)
1051 /* Make sure the reg hasn't been clobbered. */
1052 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1053 /* Fastest way to change a 0 to a 1. */
1054 return AS1 (inc%B0,%0);
1056 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1057 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1060 return (AS2 (mov%L0,%k1,%k0));
1063 return AS2 (mov%B0,%1,%0);
1066 (define_expand "movsf"
1067 [(set (match_operand:SF 0 "general_operand" "")
1068 (match_operand:SF 1 "general_operand" ""))]
1072 /* Special case memory->memory moves and pushes */
1074 && (reload_in_progress | reload_completed) == 0
1075 && GET_CODE (operands[0]) == MEM
1076 && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], SFmode)))
1078 rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], SFmode))
1082 emit_insn ((*genfunc) (operands[0], operands[1]));
1086 /* If we are loading a floating point constant that isn't 0 or 1 into a register,
1087 indicate we need the pic register loaded. This could be optimized into stores
1088 of constants if the target eventually moves to memory, but better safe than
1091 && GET_CODE (operands[0]) != MEM
1092 && GET_CODE (operands[1]) == CONST_DOUBLE
1093 && !standard_80387_constant_p (operands[1]))
1095 current_function_uses_pic_offset_table = 1;
1099 (define_insn "movsf_push_nomove"
1100 [(set (match_operand:SF 0 "push_operand" "=<,<")
1101 (match_operand:SF 1 "general_operand" "gF,f"))]
1105 if (STACK_REG_P (operands[1]))
1109 if (! STACK_TOP_P (operands[1]))
1112 xops[0] = AT_SP (SFmode);
1113 xops[1] = GEN_INT (4);
1114 xops[2] = stack_pointer_rtx;
1116 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1118 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1119 output_asm_insn (AS1 (fstp%S0,%0), xops);
1121 output_asm_insn (AS1 (fst%S0,%0), xops);
1124 return AS1 (push%L1,%1);
1127 (define_insn "movsf_push"
1128 [(set (match_operand:SF 0 "push_operand" "=<,<,<,<")
1129 (match_operand:SF 1 "general_operand" "rF,f,m,m"))
1130 (clobber (match_scratch:SI 2 "=X,X,r,X"))]
1134 if (STACK_REG_P (operands[1]))
1138 if (! STACK_TOP_P (operands[1]))
1141 xops[0] = AT_SP (SFmode);
1142 xops[1] = GEN_INT (4);
1143 xops[2] = stack_pointer_rtx;
1145 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1147 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1148 output_asm_insn (AS1 (fstp%S0,%0), xops);
1150 output_asm_insn (AS1 (fst%S0,%0), xops);
1154 else if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != REG)
1155 return AS1 (push%L1,%1);
1159 output_asm_insn (AS2 (mov%L2,%1,%2), operands);
1160 return AS1 (push%L2,%2);
1164 ;; Special memory<->memory pattern that combine will recreate from the
1165 ;; moves to pseudos.
1166 (define_insn "movsf_mem"
1167 [(set (match_operand:SF 0 "memory_operand" "=m")
1168 (match_operand:SF 1 "memory_operand" "m"))
1169 (clobber (match_scratch:SI 2 "=&r"))]
1173 output_asm_insn (AS2 (mov%L2,%1,%2), operands);
1174 return AS2 (mov%L0,%2,%0);
1177 ;; For the purposes of regclass, prefer FLOAT_REGS.
1178 (define_insn "movsf_normal"
1179 [(set (match_operand:SF 0 "general_operand" "=*rfm,*rf,f,!*rm")
1180 (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
1181 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1184 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1186 /* First handle a `pop' insn or a `fld %st(0)' */
1188 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1191 return AS1 (fstp,%y0);
1193 return AS1 (fld,%y0);
1196 /* Handle a transfer between the 387 and a 386 register */
1198 if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
1200 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1204 if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
1206 output_to_reg (operands[0], stack_top_dies);
1210 /* Handle other kinds of writes from the 387 */
1212 if (STACK_TOP_P (operands[1]))
1215 return AS1 (fstp%z0,%y0);
1217 return AS1 (fst%z0,%y0);
1220 /* Handle other kinds of reads to the 387 */
1222 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1223 return output_move_const_single (operands);
1225 if (STACK_TOP_P (operands[0]))
1226 return AS1 (fld%z1,%y1);
1228 /* Handle all SFmode moves not involving the 387 */
1230 return singlemove_string (operands);
1233 (define_insn "swapsf"
1234 [(set (match_operand:SF 0 "register_operand" "f")
1235 (match_operand:SF 1 "register_operand" "f"))
1241 if (STACK_TOP_P (operands[0]))
1242 return AS1 (fxch,%1);
1244 return AS1 (fxch,%0);
1247 (define_expand "movdf"
1248 [(set (match_operand:DF 0 "general_operand" "")
1249 (match_operand:DF 1 "general_operand" ""))]
1253 /* Special case memory->memory moves and pushes */
1255 && (reload_in_progress | reload_completed) == 0
1256 && GET_CODE (operands[0]) == MEM
1257 && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], DFmode)))
1259 rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], DFmode))
1263 emit_insn ((*genfunc) (operands[0], operands[1]));
1267 /* If we are loading a floating point constant that isn't 0 or 1 into a register,
1268 indicate we need the pic register loaded. This could be optimized into stores
1269 of constants if the target eventually moves to memory, but better safe than
1272 && GET_CODE (operands[0]) != MEM
1273 && GET_CODE (operands[1]) == CONST_DOUBLE
1274 && !standard_80387_constant_p (operands[1]))
1276 current_function_uses_pic_offset_table = 1;
1280 (define_insn "movdf_push_nomove"
1281 [(set (match_operand:DF 0 "push_operand" "=<,<")
1282 (match_operand:DF 1 "general_operand" "gF,f"))]
1286 if (STACK_REG_P (operands[1]))
1290 xops[0] = AT_SP (SFmode);
1291 xops[1] = GEN_INT (8);
1292 xops[2] = stack_pointer_rtx;
1294 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1296 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1297 output_asm_insn (AS1 (fstp%Q0,%0), xops);
1299 output_asm_insn (AS1 (fst%Q0,%0), xops);
1304 return output_move_double (operands);
1307 (define_insn "movdf_push"
1308 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<")
1309 (match_operand:DF 1 "general_operand" "rF,f,o,o,o"))
1310 (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
1311 (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
1315 if (STACK_REG_P (operands[1]))
1319 xops[0] = AT_SP (SFmode);
1320 xops[1] = GEN_INT (8);
1321 xops[2] = stack_pointer_rtx;
1323 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1325 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1326 output_asm_insn (AS1 (fstp%Q0,%0), xops);
1328 output_asm_insn (AS1 (fst%Q0,%0), xops);
1333 else if (GET_CODE (operands[1]) != MEM)
1334 return output_move_double (operands);
1337 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);
1340 (define_insn "movdf_mem"
1341 [(set (match_operand:DF 0 "memory_operand" "=o,o")
1342 (match_operand:DF 1 "memory_operand" "o,o"))
1343 (clobber (match_scratch:SI 2 "=&r,&r"))
1344 (clobber (match_scratch:SI 3 "=&r,X"))]
1346 "* return output_move_memory (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);")
1348 ;; For the purposes of regclass, prefer FLOAT_REGS.
1349 (define_insn "movdf_normal"
1350 [(set (match_operand:DF 0 "general_operand" "=f,fm,!*rf,!*rm")
1351 (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
1352 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1355 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1357 /* First handle a `pop' insn or a `fld %st(0)' */
1359 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1362 return AS1 (fstp,%y0);
1364 return AS1 (fld,%y0);
1367 /* Handle a transfer between the 387 and a 386 register */
1369 if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
1371 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1375 if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
1377 output_to_reg (operands[0], stack_top_dies);
1381 /* Handle other kinds of writes from the 387 */
1383 if (STACK_TOP_P (operands[1]))
1386 return AS1 (fstp%z0,%y0);
1388 return AS1 (fst%z0,%y0);
1391 /* Handle other kinds of reads to the 387 */
1393 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1394 return output_move_const_single (operands);
1396 if (STACK_TOP_P (operands[0]))
1397 return AS1 (fld%z1,%y1);
1399 /* Handle all DFmode moves not involving the 387 */
1401 return output_move_double (operands);
1404 (define_insn "swapdf"
1405 [(set (match_operand:DF 0 "register_operand" "f")
1406 (match_operand:DF 1 "register_operand" "f"))
1412 if (STACK_TOP_P (operands[0]))
1413 return AS1 (fxch,%1);
1415 return AS1 (fxch,%0);
1418 (define_expand "movxf"
1419 [(set (match_operand:XF 0 "general_operand" "")
1420 (match_operand:XF 1 "general_operand" ""))]
1424 /* Special case memory->memory moves and pushes */
1426 && (reload_in_progress | reload_completed) == 0
1427 && GET_CODE (operands[0]) == MEM
1428 && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], XFmode)))
1430 rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], XFmode))
1434 emit_insn ((*genfunc) (operands[0], operands[1]));
1438 /* If we are loading a floating point constant that isn't 0 or 1 into a register,
1439 indicate we need the pic register loaded. This could be optimized into stores
1440 of constants if the target eventually moves to memory, but better safe than
1443 && GET_CODE (operands[0]) != MEM
1444 && GET_CODE (operands[1]) == CONST_DOUBLE
1445 && !standard_80387_constant_p (operands[1]))
1447 current_function_uses_pic_offset_table = 1;
1452 (define_insn "movxf_push_nomove"
1453 [(set (match_operand:XF 0 "push_operand" "=<,<")
1454 (match_operand:XF 1 "general_operand" "gF,f"))]
1458 if (STACK_REG_P (operands[1]))
1462 xops[0] = AT_SP (SFmode);
1463 xops[1] = GEN_INT (12);
1464 xops[2] = stack_pointer_rtx;
1466 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1467 output_asm_insn (AS1 (fstp%T0,%0), xops);
1468 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1469 output_asm_insn (AS1 (fld%T0,%0), xops);
1474 return output_move_double (operands);
1477 (define_insn "movxf_push"
1478 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
1479 (match_operand:XF 1 "general_operand" "rF,f,o,o,o"))
1480 (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
1481 (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
1485 if (STACK_REG_P (operands[1]))
1489 xops[0] = AT_SP (SFmode);
1490 xops[1] = GEN_INT (12);
1491 xops[2] = stack_pointer_rtx;
1493 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1494 output_asm_insn (AS1 (fstp%T0,%0), xops);
1495 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1496 output_asm_insn (AS1 (fld%T0,%0), xops);
1501 else if (GET_CODE (operands[1]) != MEM
1502 || GET_CODE (operands[2]) != REG)
1503 return output_move_double (operands);
1506 return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);
1509 (define_insn "movxf_mem"
1510 [(set (match_operand:XF 0 "memory_operand" "=o,o")
1511 (match_operand:XF 1 "memory_operand" "o,o"))
1512 (clobber (match_scratch:SI 2 "=&r,&r"))
1513 (clobber (match_scratch:SI 3 "=&r,X"))]
1515 "* return output_move_memory (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);")
1517 (define_insn "movxf_normal"
1518 [(set (match_operand:XF 0 "general_operand" "=f,fm,!*rf,!*rm")
1519 (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
1520 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1523 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1525 /* First handle a `pop' insn or a `fld %st(0)' */
1527 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1530 return AS1 (fstp,%y0);
1532 return AS1 (fld,%y0);
1535 /* Handle a transfer between the 387 and a 386 register */
1537 if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
1539 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1543 if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
1545 output_to_reg (operands[0], stack_top_dies);
1549 /* Handle other kinds of writes from the 387 */
1551 if (STACK_TOP_P (operands[1]))
1553 output_asm_insn (AS1 (fstp%z0,%y0), operands);
1554 if (! stack_top_dies)
1555 return AS1 (fld%z0,%y0);
1560 /* Handle other kinds of reads to the 387 */
1562 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1563 return output_move_const_single (operands);
1565 if (STACK_TOP_P (operands[0]))
1566 return AS1 (fld%z1,%y1);
1568 /* Handle all XFmode moves not involving the 387 */
1570 return output_move_double (operands);
1573 (define_insn "swapxf"
1574 [(set (match_operand:XF 0 "register_operand" "f")
1575 (match_operand:XF 1 "register_operand" "f"))
1581 if (STACK_TOP_P (operands[0]))
1582 return AS1 (fxch,%1);
1584 return AS1 (fxch,%0);
1588 [(set (match_operand:DI 0 "push_operand" "=<,<,<,<")
1589 (match_operand:DI 1 "general_operand" "riF,o,o,o"))
1590 (clobber (match_scratch:SI 2 "=X,&r,&r,X"))
1591 (clobber (match_scratch:SI 3 "=X,&r,X,X"))]
1595 if (GET_CODE (operands[1]) != MEM)
1596 return output_move_double (operands);
1599 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
1602 (define_insn "movdi"
1603 [(set (match_operand:DI 0 "general_operand" "=o,o,r,rm")
1604 (match_operand:DI 1 "general_operand" "o,o,m,riF"))
1605 (clobber (match_scratch:SI 2 "=&r,&r,X,X"))
1606 (clobber (match_scratch:SI 3 "=&r,X,X,X"))]
1610 rtx low[2], high[2], xop[6];
1612 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1613 return output_move_double (operands);
1615 return output_move_memory (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
1619 ;;- conversion instructions
1622 ;;- zero extension instructions
1623 ;; See comments by `andsi' for when andl is faster than movzx.
1625 (define_insn "zero_extendhisi2"
1626 [(set (match_operand:SI 0 "general_operand" "=r")
1628 (match_operand:HI 1 "nonimmediate_operand" "rm")))]
1632 if ((!TARGET_386 || REGNO (operands[0]) == 0)
1633 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1636 xops[0] = operands[0];
1637 xops[1] = GEN_INT (0xffff);
1638 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1643 return AS2 (movzx,%1,%0);
1645 return AS2 (movz%W0%L0,%1,%0);
1649 (define_insn "zero_extendqihi2"
1650 [(set (match_operand:HI 0 "general_operand" "=r")
1652 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1656 if ((!TARGET_386 || REGNO (operands[0]) == 0)
1657 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1660 xops[0] = operands[0];
1661 xops[1] = GEN_INT (0xff);
1662 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1667 return AS2 (movzx,%1,%0);
1669 return AS2 (movz%B0%W0,%1,%0);
1673 (define_insn "zero_extendqisi2"
1674 [(set (match_operand:SI 0 "general_operand" "=r")
1676 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1680 if ((!TARGET_386 || REGNO (operands[0]) == 0)
1681 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1684 xops[0] = operands[0];
1685 xops[1] = GEN_INT (0xff);
1686 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1691 return AS2 (movzx,%1,%0);
1693 return AS2 (movz%B0%L0,%1,%0);
1697 (define_insn "zero_extendsidi2"
1698 [(set (match_operand:DI 0 "register_operand" "=r")
1700 (match_operand:SI 1 "register_operand" "0")))]
1704 operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1705 return AS2 (xor%L0,%0,%0);
1708 ;;- sign extension instructions
1710 (define_insn "extendsidi2"
1711 [(set (match_operand:DI 0 "register_operand" "=r")
1713 (match_operand:SI 1 "register_operand" "0")))]
1717 if (REGNO (operands[0]) == 0)
1719 /* This used to be cwtl, but that extends HI to SI somehow. */
1727 operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1728 output_asm_insn (AS2 (mov%L0,%0,%1), operands);
1730 operands[0] = GEN_INT (31);
1731 return AS2 (sar%L1,%0,%1);
1734 ;; Note that the i386 programmers' manual says that the opcodes
1735 ;; are named movsx..., but the assembler on Unix does not accept that.
1736 ;; We use what the Unix assembler expects.
1738 (define_insn "extendhisi2"
1739 [(set (match_operand:SI 0 "general_operand" "=r")
1741 (match_operand:HI 1 "nonimmediate_operand" "rm")))]
1745 if (REGNO (operands[0]) == 0
1746 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
1754 return AS2 (movsx,%1,%0);
1756 return AS2 (movs%W0%L0,%1,%0);
1760 (define_insn "extendqihi2"
1761 [(set (match_operand:HI 0 "general_operand" "=r")
1763 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1767 if (REGNO (operands[0]) == 0
1768 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
1772 return AS2 (movsx,%1,%0);
1774 return AS2 (movs%B0%W0,%1,%0);
1778 (define_insn "extendqisi2"
1779 [(set (match_operand:SI 0 "general_operand" "=r")
1781 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1786 return AS2 (movsx,%1,%0);
1788 return AS2 (movs%B0%L0,%1,%0);
1792 ;; Conversions between float and double.
1794 (define_insn "extendsfdf2"
1795 [(set (match_operand:DF 0 "general_operand" "=fm,f")
1797 (match_operand:SF 1 "general_operand" "f,fm")))]
1801 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1803 if (NON_STACK_REG_P (operands[1]))
1805 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1809 if (NON_STACK_REG_P (operands[0]))
1811 output_to_reg (operands[0], stack_top_dies);
1815 if (STACK_TOP_P (operands[0]))
1816 return AS1 (fld%z1,%y1);
1818 if (GET_CODE (operands[0]) == MEM)
1821 return AS1 (fstp%z0,%y0);
1823 return AS1 (fst%z0,%y0);
1829 (define_insn "extenddfxf2"
1830 [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r")
1832 (match_operand:DF 1 "general_operand" "f,fm,!*r,f")))]
1836 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1838 if (NON_STACK_REG_P (operands[1]))
1840 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1844 if (NON_STACK_REG_P (operands[0]))
1846 output_to_reg (operands[0], stack_top_dies);
1850 if (STACK_TOP_P (operands[0]))
1851 return AS1 (fld%z1,%y1);
1853 if (GET_CODE (operands[0]) == MEM)
1855 output_asm_insn (AS1 (fstp%z0,%y0), operands);
1856 if (! stack_top_dies)
1857 return AS1 (fld%z0,%y0);
1864 (define_insn "extendsfxf2"
1865 [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r")
1867 (match_operand:SF 1 "general_operand" "f,fm,!*r,f")))]
1871 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1873 if (NON_STACK_REG_P (operands[1]))
1875 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1879 if (NON_STACK_REG_P (operands[0]))
1881 output_to_reg (operands[0], stack_top_dies);
1885 if (STACK_TOP_P (operands[0]))
1886 return AS1 (fld%z1,%y1);
1888 if (GET_CODE (operands[0]) == MEM)
1890 output_asm_insn (AS1 (fstp%z0,%y0), operands);
1891 if (! stack_top_dies)
1892 return AS1 (fld%z0,%y0);
1899 (define_expand "truncdfsf2"
1900 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
1902 (match_operand:DF 1 "register_operand" "")))
1903 (clobber (match_dup 2))])]
1907 operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
1910 ;; This cannot output into an f-reg because there is no way to be sure
1911 ;; of truncating in that case. Otherwise this is just like a simple move
1912 ;; insn. So we pretend we can output to a reg in order to get better
1913 ;; register preferencing, but we really use a stack slot.
1916 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
1918 (match_operand:DF 1 "register_operand" "0,f")))
1919 (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
1923 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1925 if (GET_CODE (operands[0]) == MEM)
1928 return AS1 (fstp%z0,%0);
1930 return AS1 (fst%z0,%0);
1932 else if (STACK_TOP_P (operands[0]))
1934 output_asm_insn (AS1 (fstp%z2,%y2), operands);
1935 return AS1 (fld%z2,%y2);
1941 (define_insn "truncxfsf2"
1942 [(set (match_operand:SF 0 "general_operand" "=m,!*r")
1944 (match_operand:XF 1 "register_operand" "f,f")))]
1948 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1950 if (NON_STACK_REG_P (operands[0]))
1952 if (stack_top_dies == 0)
1954 output_asm_insn (AS1 (fld,%y1), operands);
1957 output_to_reg (operands[0], stack_top_dies);
1960 else if (GET_CODE (operands[0]) == MEM)
1963 return AS1 (fstp%z0,%0);
1966 output_asm_insn (AS1 (fld,%y1), operands);
1967 return AS1 (fstp%z0,%0);
1974 (define_insn "truncxfdf2"
1975 [(set (match_operand:DF 0 "general_operand" "=m,!*r")
1977 (match_operand:XF 1 "register_operand" "f,f")))]
1981 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1983 if (NON_STACK_REG_P (operands[0]))
1985 if (stack_top_dies == 0)
1987 output_asm_insn (AS1 (fld,%y1), operands);
1990 output_to_reg (operands[0], stack_top_dies);
1993 else if (GET_CODE (operands[0]) == MEM)
1996 return AS1 (fstp%z0,%0);
1999 output_asm_insn (AS1 (fld,%y1), operands);
2000 return AS1 (fstp%z0,%0);
2008 ;; The 387 requires that the stack top dies after converting to DImode.
2010 ;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
2011 ;; doing a signed conversion to DImode, and then taking just the low
2014 (define_expand "fixuns_truncxfsi2"
2016 (match_operand:XF 1 "register_operand" ""))
2017 (parallel [(set (match_dup 2)
2018 (fix:DI (fix:XF (match_dup 4))))
2019 (clobber (match_dup 4))
2020 (clobber (match_dup 5))
2021 (clobber (match_dup 6))
2022 (clobber (match_scratch:SI 7 ""))])
2023 (set (match_operand:SI 0 "general_operand" "")
2028 operands[2] = gen_reg_rtx (DImode);
2029 operands[3] = gen_lowpart (SImode, operands[2]);
2030 operands[4] = gen_reg_rtx (XFmode);
2031 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2032 operands[6] = (rtx) assign_386_stack_local (SImode, 1);
2035 (define_expand "fixuns_truncdfsi2"
2037 (match_operand:DF 1 "register_operand" ""))
2038 (parallel [(set (match_dup 2)
2039 (fix:DI (fix:DF (match_dup 4))))
2040 (clobber (match_dup 4))
2041 (clobber (match_dup 5))
2042 (clobber (match_dup 6))
2043 (clobber (match_scratch:SI 7 ""))])
2044 (set (match_operand:SI 0 "general_operand" "")
2049 operands[2] = gen_reg_rtx (DImode);
2050 operands[3] = gen_lowpart (SImode, operands[2]);
2051 operands[4] = gen_reg_rtx (DFmode);
2052 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2053 operands[6] = (rtx) assign_386_stack_local (SImode, 1);
2056 (define_expand "fixuns_truncsfsi2"
2058 (match_operand:SF 1 "register_operand" ""))
2059 (parallel [(set (match_dup 2)
2060 (fix:DI (fix:SF (match_dup 4))))
2061 (clobber (match_dup 4))
2062 (clobber (match_dup 5))
2063 (clobber (match_dup 6))
2064 (clobber (match_scratch:SI 7 ""))])
2065 (set (match_operand:SI 0 "general_operand" "")
2070 operands[2] = gen_reg_rtx (DImode);
2071 operands[3] = gen_lowpart (SImode, operands[2]);
2072 operands[4] = gen_reg_rtx (SFmode);
2073 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2074 operands[6] = (rtx) assign_386_stack_local (SImode, 1);
2077 ;; Signed conversion to DImode.
2079 (define_expand "fix_truncxfdi2"
2081 (match_operand:XF 1 "register_operand" ""))
2082 (parallel [(set (match_operand:DI 0 "general_operand" "")
2083 (fix:DI (fix:XF (match_dup 2))))
2084 (clobber (match_dup 2))
2085 (clobber (match_dup 3))
2086 (clobber (match_dup 4))
2087 (clobber (match_scratch:SI 5 ""))])]
2091 operands[1] = copy_to_mode_reg (XFmode, operands[1]);
2092 operands[2] = gen_reg_rtx (XFmode);
2093 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2094 operands[4] = (rtx) assign_386_stack_local (SImode, 1);
2097 (define_expand "fix_truncdfdi2"
2099 (match_operand:DF 1 "register_operand" ""))
2100 (parallel [(set (match_operand:DI 0 "general_operand" "")
2101 (fix:DI (fix:DF (match_dup 2))))
2102 (clobber (match_dup 2))
2103 (clobber (match_dup 3))
2104 (clobber (match_dup 4))
2105 (clobber (match_scratch:SI 5 ""))])]
2109 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
2110 operands[2] = gen_reg_rtx (DFmode);
2111 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2112 operands[4] = (rtx) assign_386_stack_local (SImode, 1);
2115 (define_expand "fix_truncsfdi2"
2117 (match_operand:SF 1 "register_operand" ""))
2118 (parallel [(set (match_operand:DI 0 "general_operand" "")
2119 (fix:DI (fix:SF (match_dup 2))))
2120 (clobber (match_dup 2))
2121 (clobber (match_dup 3))
2122 (clobber (match_dup 4))
2123 (clobber (match_scratch:SI 5 ""))])]
2127 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
2128 operands[2] = gen_reg_rtx (SFmode);
2129 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2130 operands[4] = (rtx) assign_386_stack_local (SImode, 1);
2133 ;; These match a signed conversion of either DFmode or SFmode to DImode.
2136 [(set (match_operand:DI 0 "general_operand" "=rm")
2137 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
2138 (clobber (match_dup 1))
2139 (clobber (match_operand:SI 2 "memory_operand" "m"))
2140 (clobber (match_operand:SI 3 "memory_operand" "m"))
2141 (clobber (match_scratch:SI 4 "=&q"))]
2143 "* return output_fix_trunc (insn, operands);")
2146 [(set (match_operand:DI 0 "general_operand" "=rm")
2147 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2148 (clobber (match_dup 1))
2149 (clobber (match_operand:SI 2 "memory_operand" "m"))
2150 (clobber (match_operand:SI 3 "memory_operand" "m"))
2151 (clobber (match_scratch:SI 4 "=&q"))]
2153 "* return output_fix_trunc (insn, operands);")
2156 [(set (match_operand:DI 0 "general_operand" "=rm")
2157 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
2158 (clobber (match_dup 1))
2159 (clobber (match_operand:SI 2 "memory_operand" "m"))
2160 (clobber (match_operand:SI 3 "memory_operand" "m"))
2161 (clobber (match_scratch:SI 4 "=&q"))]
2163 "* return output_fix_trunc (insn, operands);")
2165 ;; Signed MODE_FLOAT conversion to SImode.
2167 (define_expand "fix_truncxfsi2"
2168 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2170 (fix:XF (match_operand:XF 1 "register_operand" ""))))
2171 (clobber (match_dup 2))
2172 (clobber (match_dup 3))
2173 (clobber (match_scratch:SI 4 ""))])]
2177 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2178 operands[3] = (rtx) assign_386_stack_local (SImode, 1);
2181 (define_expand "fix_truncdfsi2"
2182 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2184 (fix:DF (match_operand:DF 1 "register_operand" ""))))
2185 (clobber (match_dup 2))
2186 (clobber (match_dup 3))
2187 (clobber (match_scratch:SI 4 ""))])]
2191 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2192 operands[3] = (rtx) assign_386_stack_local (SImode, 1);
2195 (define_expand "fix_truncsfsi2"
2196 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2198 (fix:SF (match_operand:SF 1 "register_operand" ""))))
2199 (clobber (match_dup 2))
2200 (clobber (match_dup 3))
2201 (clobber (match_scratch:SI 4 ""))])]
2205 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2206 operands[3] = (rtx) assign_386_stack_local (SImode, 1);
2210 [(set (match_operand:SI 0 "general_operand" "=rm")
2211 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
2212 (clobber (match_operand:SI 2 "memory_operand" "m"))
2213 (clobber (match_operand:SI 3 "memory_operand" "m"))
2214 (clobber (match_scratch:SI 4 "=&q"))]
2216 "* return output_fix_trunc (insn, operands);")
2219 [(set (match_operand:SI 0 "general_operand" "=rm")
2220 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2221 (clobber (match_operand:SI 2 "memory_operand" "m"))
2222 (clobber (match_operand:SI 3 "memory_operand" "m"))
2223 (clobber (match_scratch:SI 4 "=&q"))]
2225 "* return output_fix_trunc (insn, operands);")
2228 [(set (match_operand:SI 0 "general_operand" "=rm")
2229 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
2230 (clobber (match_operand:SI 2 "memory_operand" "m"))
2231 (clobber (match_operand:SI 3 "memory_operand" "m"))
2232 (clobber (match_scratch:SI 4 "=&q"))]
2234 "* return output_fix_trunc (insn, operands);")
2236 ;; Conversion between fixed point and floating point.
2237 ;; The actual pattern that matches these is at the end of this file.
2239 ;; ??? Possibly represent floatunssidf2 here in gcc2.
2241 (define_expand "floatsisf2"
2242 [(set (match_operand:SF 0 "register_operand" "")
2243 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
2247 (define_expand "floatdisf2"
2248 [(set (match_operand:SF 0 "register_operand" "")
2249 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
2253 (define_expand "floatsidf2"
2254 [(set (match_operand:DF 0 "register_operand" "")
2255 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
2259 (define_expand "floatdidf2"
2260 [(set (match_operand:DF 0 "register_operand" "")
2261 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
2265 (define_expand "floatsixf2"
2266 [(set (match_operand:XF 0 "register_operand" "")
2267 (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
2271 (define_expand "floatdixf2"
2272 [(set (match_operand:XF 0 "register_operand" "")
2273 (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
2277 ;; This will convert from SImode or DImode to MODE_FLOAT.
2280 [(set (match_operand:XF 0 "register_operand" "=f")
2281 (float:XF (match_operand:DI 1 "general_operand" "rm")))]
2285 if (NON_STACK_REG_P (operands[1]))
2287 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2290 else if (GET_CODE (operands[1]) == MEM)
2291 return AS1 (fild%z1,%1);
2297 [(set (match_operand:DF 0 "register_operand" "=f")
2298 (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2302 if (NON_STACK_REG_P (operands[1]))
2304 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2307 else if (GET_CODE (operands[1]) == MEM)
2308 return AS1 (fild%z1,%1);
2314 [(set (match_operand:SF 0 "register_operand" "=f")
2315 (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2319 if (NON_STACK_REG_P (operands[1]))
2321 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2324 else if (GET_CODE (operands[1]) == MEM)
2325 return AS1 (fild%z1,%1);
2331 [(set (match_operand:DF 0 "register_operand" "=f")
2332 (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
2336 if (NON_STACK_REG_P (operands[1]))
2338 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2341 else if (GET_CODE (operands[1]) == MEM)
2342 return AS1 (fild%z1,%1);
2348 [(set (match_operand:XF 0 "register_operand" "=f,f")
2349 (float:XF (match_operand:SI 1 "general_operand" "m,!*r")))]
2353 if (NON_STACK_REG_P (operands[1]))
2355 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2358 else if (GET_CODE (operands[1]) == MEM)
2359 return AS1 (fild%z1,%1);
2365 [(set (match_operand:SF 0 "register_operand" "=f")
2366 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
2370 if (NON_STACK_REG_P (operands[1]))
2372 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2375 else if (GET_CODE (operands[1]) == MEM)
2376 return AS1 (fild%z1,%1);
2381 ;;- add instructions
2383 (define_insn "adddi3"
2384 [(set (match_operand:DI 0 "general_operand" "=&r,ro,o,&r,ro,o,&r,o,o,o")
2385 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,o,riF,o,or,riF,riF,o")
2386 (match_operand:DI 2 "general_operand" "o,riF,o,0,0,0,oriF,riF,o,o")))
2387 (clobber (match_scratch:SI 3 "=X,X,&r,X,&r,&r,X,&r,&r,&r"))]
2391 rtx low[3], high[3], xops[7], temp;
2395 if (rtx_equal_p (operands[0], operands[2]))
2398 operands[1] = operands[2];
2402 split_di (operands, 3, low, high);
2403 if (!rtx_equal_p (operands[0], operands[1]))
2410 if (GET_CODE (operands[0]) != MEM)
2412 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2413 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2419 xops[6] = operands[3];
2420 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2421 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2422 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2423 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2424 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2425 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2430 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
2436 xops[4] = operands[3];
2438 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
2439 output_asm_insn (AS2 (add%L1,%4,%1), xops);
2440 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
2441 output_asm_insn (AS2 (adc%L0,%4,%0), xops);
2444 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
2446 output_asm_insn (AS2 (add%L0,%2,%0), low);
2447 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2451 output_asm_insn (AS2 (add%L0,%2,%0), high);
2456 ;; On a 486, it is faster to do movl/addl than to do a single leal if
2457 ;; operands[1] and operands[2] are both registers.
2459 (define_insn "addsi3"
2460 [(set (match_operand:SI 0 "general_operand" "=?r,rm,r")
2461 (plus:SI (match_operand:SI 1 "general_operand" "%r,0,0")
2462 (match_operand:SI 2 "general_operand" "ri,ri,rm")))]
2466 if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
2468 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
2469 return AS2 (add%L0,%1,%0);
2471 if (operands[2] == stack_pointer_rtx)
2476 operands[1] = operands[2];
2480 if (operands[2] != stack_pointer_rtx)
2483 operands[1] = SET_SRC (PATTERN (insn));
2484 return AS2 (lea%L0,%a1,%0);
2487 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
2490 if (operands[2] == const1_rtx)
2491 return AS1 (inc%L0,%0);
2493 if (operands[2] == constm1_rtx)
2494 return AS1 (dec%L0,%0);
2496 return AS2 (add%L0,%2,%0);
2499 ;; ??? `lea' here, for three operand add? If leaw is used, only %bx,
2500 ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
2501 ;; able to handle the operand. But leal always works?
2503 (define_insn "addhi3"
2504 [(set (match_operand:HI 0 "general_operand" "=rm,r")
2505 (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
2506 (match_operand:HI 2 "general_operand" "ri,rm")))]
2510 /* ??? what about offsettable memory references? */
2511 if (QI_REG_P (operands[0])
2512 && GET_CODE (operands[2]) == CONST_INT
2513 && (INTVAL (operands[2]) & 0xff) == 0)
2515 int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
2519 return AS1 (inc%B0,%h0);
2520 else if (byteval == 255)
2521 return AS1 (dec%B0,%h0);
2523 operands[2] = GEN_INT (byteval);
2524 return AS2 (add%B0,%2,%h0);
2527 if (operands[2] == const1_rtx)
2528 return AS1 (inc%W0,%0);
2530 if (operands[2] == constm1_rtx
2531 || (GET_CODE (operands[2]) == CONST_INT
2532 && INTVAL (operands[2]) == 65535))
2533 return AS1 (dec%W0,%0);
2535 return AS2 (add%W0,%2,%0);
2538 (define_insn "addqi3"
2539 [(set (match_operand:QI 0 "general_operand" "=qm,q")
2540 (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
2541 (match_operand:QI 2 "general_operand" "qn,qmn")))]
2545 if (operands[2] == const1_rtx)
2546 return AS1 (inc%B0,%0);
2548 if (operands[2] == constm1_rtx
2549 || (GET_CODE (operands[2]) == CONST_INT
2550 && INTVAL (operands[2]) == 255))
2551 return AS1 (dec%B0,%0);
2553 return AS2 (add%B0,%2,%0);
2556 ;Lennart Augustsson <augustss@cs.chalmers.se>
2557 ;says this pattern just makes slower code:
2561 ; leal -80(%ebp),%eax
2565 ; [(set (match_operand:SI 0 "push_operand" "=<")
2566 ; (plus:SI (match_operand:SI 1 "general_operand" "%r")
2567 ; (match_operand:SI 2 "general_operand" "ri")))]
2572 ; xops[0] = operands[0];
2573 ; xops[1] = operands[1];
2574 ; xops[2] = operands[2];
2575 ; xops[3] = gen_rtx (MEM, SImode, stack_pointer_rtx);
2576 ; output_asm_insn (\"push%z1 %1\", xops);
2577 ; output_asm_insn (AS2 (add%z3,%2,%3), xops);
2581 ;; addsi3 is faster, so put this after.
2583 (define_insn "movsi_lea"
2584 [(set (match_operand:SI 0 "register_operand" "=r")
2585 (match_operand:QI 1 "address_operand" "p"))]
2590 /* Adding a constant to a register is faster with an add. */
2591 /* ??? can this ever happen? */
2592 if (GET_CODE (operands[1]) == PLUS
2593 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
2594 && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
2596 operands[1] = XEXP (operands[1], 1);
2598 if (operands[1] == const1_rtx)
2599 return AS1 (inc%L0,%0);
2601 if (operands[1] == constm1_rtx)
2602 return AS1 (dec%L0,%0);
2604 return AS2 (add%L0,%1,%0);
2606 return AS2 (lea%L0,%a1,%0);
2609 ;; The patterns that match these are at the end of this file.
2611 (define_expand "addxf3"
2612 [(set (match_operand:XF 0 "register_operand" "")
2613 (plus:XF (match_operand:XF 1 "nonimmediate_operand" "")
2614 (match_operand:XF 2 "nonimmediate_operand" "")))]
2618 (define_expand "adddf3"
2619 [(set (match_operand:DF 0 "register_operand" "")
2620 (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
2621 (match_operand:DF 2 "nonimmediate_operand" "")))]
2625 (define_expand "addsf3"
2626 [(set (match_operand:SF 0 "register_operand" "")
2627 (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
2628 (match_operand:SF 2 "nonimmediate_operand" "")))]
2632 ;;- subtract instructions
2634 (define_insn "subdi3"
2635 [(set (match_operand:DI 0 "general_operand" "=&r,ro,&r,o,o")
2636 (minus:DI (match_operand:DI 1 "general_operand" "0,0,roiF,riF,o")
2637 (match_operand:DI 2 "general_operand" "o,riF,roiF,riF,o")))
2638 (clobber (match_scratch:SI 3 "=X,X,X,&r,&r"))]
2642 rtx low[3], high[3], xops[7];
2646 split_di (operands, 3, low, high);
2648 if (!rtx_equal_p (operands[0], operands[1]))
2655 if (GET_CODE (operands[0]) != MEM)
2657 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2658 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2664 xops[6] = operands[3];
2665 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2666 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
2667 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2668 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2669 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
2670 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2675 if (GET_CODE (operands[3]) == REG)
2681 xops[4] = operands[3];
2683 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
2684 output_asm_insn (AS2 (sub%L1,%4,%1), xops);
2685 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
2686 output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
2689 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
2691 output_asm_insn (AS2 (sub%L0,%2,%0), low);
2692 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
2696 output_asm_insn (AS2 (sub%L0,%2,%0), high);
2701 (define_insn "subsi3"
2702 [(set (match_operand:SI 0 "general_operand" "=rm,r")
2703 (minus:SI (match_operand:SI 1 "general_operand" "0,0")
2704 (match_operand:SI 2 "general_operand" "ri,rm")))]
2706 "* return AS2 (sub%L0,%2,%0);")
2708 (define_insn "subhi3"
2709 [(set (match_operand:HI 0 "general_operand" "=rm,r")
2710 (minus:HI (match_operand:HI 1 "general_operand" "0,0")
2711 (match_operand:HI 2 "general_operand" "ri,rm")))]
2713 "* return AS2 (sub%W0,%2,%0);")
2715 (define_insn "subqi3"
2716 [(set (match_operand:QI 0 "general_operand" "=qm,q")
2717 (minus:QI (match_operand:QI 1 "general_operand" "0,0")
2718 (match_operand:QI 2 "general_operand" "qn,qmn")))]
2720 "* return AS2 (sub%B0,%2,%0);")
2722 ;; The patterns that match these are at the end of this file.
2724 (define_expand "subxf3"
2725 [(set (match_operand:XF 0 "register_operand" "")
2726 (minus:XF (match_operand:XF 1 "nonimmediate_operand" "")
2727 (match_operand:XF 2 "nonimmediate_operand" "")))]
2731 (define_expand "subdf3"
2732 [(set (match_operand:DF 0 "register_operand" "")
2733 (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
2734 (match_operand:DF 2 "nonimmediate_operand" "")))]
2738 (define_expand "subsf3"
2739 [(set (match_operand:SF 0 "register_operand" "")
2740 (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
2741 (match_operand:SF 2 "nonimmediate_operand" "")))]
2745 ;;- multiply instructions
2747 ;(define_insn "mulqi3"
2748 ; [(set (match_operand:QI 0 "general_operand" "=a")
2749 ; (mult:QI (match_operand:QI 1 "general_operand" "%0")
2750 ; (match_operand:QI 2 "general_operand" "qm")))]
2755 [(set (match_operand:HI 0 "general_operand" "=r")
2756 (mult:HI (match_operand:HI 1 "general_operand" "%0")
2757 (match_operand:HI 2 "general_operand" "r")))]
2758 "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
2759 "* return AS2 (imul%W0,%2,%0);")
2761 (define_insn "mulhi3"
2762 [(set (match_operand:HI 0 "general_operand" "=r,r")
2763 (mult:HI (match_operand:HI 1 "general_operand" "%0,rm")
2764 (match_operand:HI 2 "general_operand" "g,i")))]
2768 if (GET_CODE (operands[1]) == REG
2769 && REGNO (operands[1]) == REGNO (operands[0])
2770 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
2771 /* Assembler has weird restrictions. */
2772 return AS2 (imul%W0,%2,%0);
2773 return AS3 (imul%W0,%2,%1,%0);
2777 [(set (match_operand:SI 0 "general_operand" "=r")
2778 (mult:SI (match_operand:SI 1 "general_operand" "%0")
2779 (match_operand:SI 2 "general_operand" "r")))]
2780 "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
2781 "* return AS2 (imul%L0,%2,%0);")
2783 (define_insn "mulsi3"
2784 [(set (match_operand:SI 0 "general_operand" "=r,r")
2785 (mult:SI (match_operand:SI 1 "general_operand" "%0,rm")
2786 (match_operand:SI 2 "general_operand" "g,i")))]
2790 if (GET_CODE (operands[1]) == REG
2791 && REGNO (operands[1]) == REGNO (operands[0])
2792 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
2793 /* Assembler has weird restrictions. */
2794 return AS2 (imul%L0,%2,%0);
2795 return AS3 (imul%L0,%2,%1,%0);
2798 (define_insn "umulqihi3"
2799 [(set (match_operand:HI 0 "general_operand" "=a")
2800 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
2801 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
2805 (define_insn "mulqihi3"
2806 [(set (match_operand:HI 0 "general_operand" "=a")
2807 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
2808 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
2812 (define_insn "umulsidi3"
2813 [(set (match_operand:DI 0 "register_operand" "=A")
2814 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
2815 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
2816 "TARGET_WIDE_MULTIPLY"
2819 (define_insn "mulsidi3"
2820 [(set (match_operand:DI 0 "register_operand" "=A")
2821 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
2822 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
2823 "TARGET_WIDE_MULTIPLY"
2826 (define_insn "umulsi3_highpart"
2827 [(set (match_operand:SI 0 "register_operand" "=d")
2828 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
2829 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
2831 (clobber (match_scratch:SI 3 "=a"))]
2832 "TARGET_WIDE_MULTIPLY"
2835 (define_insn "smulsi3_highpart"
2836 [(set (match_operand:SI 0 "register_operand" "=d")
2837 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
2838 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
2840 (clobber (match_scratch:SI 3 "=a"))]
2841 "TARGET_WIDE_MULTIPLY"
2844 ;; The patterns that match these are at the end of this file.
2846 (define_expand "mulxf3"
2847 [(set (match_operand:XF 0 "register_operand" "")
2848 (mult:XF (match_operand:XF 1 "nonimmediate_operand" "")
2849 (match_operand:XF 2 "nonimmediate_operand" "")))]
2853 (define_expand "muldf3"
2854 [(set (match_operand:DF 0 "register_operand" "")
2855 (mult:DF (match_operand:DF 1 "nonimmediate_operand" "")
2856 (match_operand:DF 2 "nonimmediate_operand" "")))]
2860 (define_expand "mulsf3"
2861 [(set (match_operand:SF 0 "register_operand" "")
2862 (mult:SF (match_operand:SF 1 "nonimmediate_operand" "")
2863 (match_operand:SF 2 "nonimmediate_operand" "")))]
2867 ;;- divide instructions
2869 (define_insn "divqi3"
2870 [(set (match_operand:QI 0 "general_operand" "=a")
2871 (div:QI (match_operand:HI 1 "general_operand" "0")
2872 (match_operand:QI 2 "general_operand" "qm")))]
2876 (define_insn "udivqi3"
2877 [(set (match_operand:QI 0 "general_operand" "=a")
2878 (udiv:QI (match_operand:HI 1 "general_operand" "0")
2879 (match_operand:QI 2 "general_operand" "qm")))]
2883 ;; The patterns that match these are at the end of this file.
2885 (define_expand "divxf3"
2886 [(set (match_operand:XF 0 "register_operand" "")
2887 (div:XF (match_operand:XF 1 "nonimmediate_operand" "")
2888 (match_operand:XF 2 "nonimmediate_operand" "")))]
2892 (define_expand "divdf3"
2893 [(set (match_operand:DF 0 "register_operand" "")
2894 (div:DF (match_operand:DF 1 "nonimmediate_operand" "")
2895 (match_operand:DF 2 "nonimmediate_operand" "")))]
2899 (define_expand "divsf3"
2900 [(set (match_operand:SF 0 "register_operand" "")
2901 (div:SF (match_operand:SF 1 "nonimmediate_operand" "")
2902 (match_operand:SF 2 "nonimmediate_operand" "")))]
2906 ;; Remainder instructions.
2908 (define_insn "divmodsi4"
2909 [(set (match_operand:SI 0 "register_operand" "=a")
2910 (div:SI (match_operand:SI 1 "register_operand" "0")
2911 (match_operand:SI 2 "general_operand" "rm")))
2912 (set (match_operand:SI 3 "register_operand" "=&d")
2913 (mod:SI (match_dup 1) (match_dup 2)))]
2918 output_asm_insn (\"cdq\", operands);
2920 output_asm_insn (\"cltd\", operands);
2922 return AS1 (idiv%L0,%2);
2925 (define_insn "divmodhi4"
2926 [(set (match_operand:HI 0 "register_operand" "=a")
2927 (div:HI (match_operand:HI 1 "register_operand" "0")
2928 (match_operand:HI 2 "general_operand" "rm")))
2929 (set (match_operand:HI 3 "register_operand" "=&d")
2930 (mod:HI (match_dup 1) (match_dup 2)))]
2934 ;; ??? Can we make gcc zero extend operand[0]?
2935 (define_insn "udivmodsi4"
2936 [(set (match_operand:SI 0 "register_operand" "=a")
2937 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2938 (match_operand:SI 2 "general_operand" "rm")))
2939 (set (match_operand:SI 3 "register_operand" "=&d")
2940 (umod:SI (match_dup 1) (match_dup 2)))]
2944 output_asm_insn (AS2 (xor%L3,%3,%3), operands);
2945 return AS1 (div%L0,%2);
2948 ;; ??? Can we make gcc zero extend operand[0]?
2949 (define_insn "udivmodhi4"
2950 [(set (match_operand:HI 0 "register_operand" "=a")
2951 (udiv:HI (match_operand:HI 1 "register_operand" "0")
2952 (match_operand:HI 2 "general_operand" "rm")))
2953 (set (match_operand:HI 3 "register_operand" "=&d")
2954 (umod:HI (match_dup 1) (match_dup 2)))]
2958 output_asm_insn (AS2 (xor%W0,%3,%3), operands);
2959 return AS1 (div%W0,%2);
2963 ;;this should be a valid double division which we may want to add
2966 [(set (match_operand:SI 0 "register_operand" "=a")
2967 (udiv:DI (match_operand:DI 1 "register_operand" "a")
2968 (match_operand:SI 2 "general_operand" "rm")))
2969 (set (match_operand:SI 3 "register_operand" "=d")
2970 (umod:SI (match_dup 1) (match_dup 2)))]
2975 ;;- and instructions
2982 ;; but if the reg is %eax, then the "andl" is faster.
2984 ;; On i486, the "andl" is always faster than the "movzbl".
2986 ;; On both i386 and i486, a three operand AND is as fast with movzbl or
2987 ;; movzwl as with andl, if operands[0] != operands[1].
2989 ;; The `r' in `rm' for operand 3 looks redundant, but it causes
2990 ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
2992 ;; ??? What if we only change one byte of an offsettable memory reference?
2993 (define_insn "andsi3"
2994 [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r")
2995 (and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0")
2996 (match_operand:SI 2 "general_operand" "L,K,ri,rm")))]
3000 if (GET_CODE (operands[2]) == CONST_INT
3001 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
3003 if (INTVAL (operands[2]) == 0xffff && REG_P (operands[0])
3004 && (! REG_P (operands[1])
3005 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
3006 && (TARGET_386 || ! rtx_equal_p (operands[0], operands[1])))
3008 /* ??? tege: Should forget CC_STATUS only if we clobber a
3009 remembered operand. Fix that later. */
3012 return AS2 (movzx,%w1,%0);
3014 return AS2 (movz%W0%L0,%w1,%0);
3018 if (INTVAL (operands[2]) == 0xff && REG_P (operands[0])
3019 && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
3020 && (! REG_P (operands[1])
3021 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
3022 && (TARGET_386 || ! rtx_equal_p (operands[0], operands[1])))
3024 /* ??? tege: Should forget CC_STATUS only if we clobber a
3025 remembered operand. Fix that later. */
3028 return AS2 (movzx,%b1,%0);
3030 return AS2 (movz%B0%L0,%b1,%0);
3034 if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff) == 0)
3038 if (INTVAL (operands[2]) == 0xffffff00)
3040 operands[2] = const0_rtx;
3041 return AS2 (mov%B0,%2,%b0);
3044 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
3045 return AS2 (and%B0,%2,%b0);
3048 if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff00) == 0)
3052 if (INTVAL (operands[2]) == 0xffff00ff)
3054 operands[2] = const0_rtx;
3055 return AS2 (mov%B0,%2,%h0);
3058 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
3059 return AS2 (and%B0,%2,%h0);
3062 if (GET_CODE (operands[0]) == MEM && INTVAL (operands[2]) == 0xffff0000)
3064 operands[2] = const0_rtx;
3065 return AS2 (mov%W0,%2,%w0);
3069 return AS2 (and%L0,%2,%0);
3072 (define_insn "andhi3"
3073 [(set (match_operand:HI 0 "general_operand" "=rm,r")
3074 (and:HI (match_operand:HI 1 "general_operand" "%0,0")
3075 (match_operand:HI 2 "general_operand" "ri,rm")))]
3079 if (GET_CODE (operands[2]) == CONST_INT
3080 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
3082 /* Can we ignore the upper byte? */
3083 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
3084 && (INTVAL (operands[2]) & 0xff00) == 0xff00)
3088 if ((INTVAL (operands[2]) & 0xff) == 0)
3090 operands[2] = const0_rtx;
3091 return AS2 (mov%B0,%2,%b0);
3094 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
3095 return AS2 (and%B0,%2,%b0);
3098 /* Can we ignore the lower byte? */
3099 /* ??? what about offsettable memory references? */
3100 if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
3104 if ((INTVAL (operands[2]) & 0xff00) == 0)
3106 operands[2] = const0_rtx;
3107 return AS2 (mov%B0,%2,%h0);
3110 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
3111 return AS2 (and%B0,%2,%h0);
3115 return AS2 (and%W0,%2,%0);
3118 (define_insn "andqi3"
3119 [(set (match_operand:QI 0 "general_operand" "=qm,q")
3120 (and:QI (match_operand:QI 1 "general_operand" "%0,0")
3121 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3123 "* return AS2 (and%B0,%2,%0);")
3125 /* I am nervous about these two.. add them later..
3126 ;I presume this means that we have something in say op0= eax which is small
3127 ;and we want to and it with memory so we can do this by just an
3128 ;andb m,%al and have success.
3130 [(set (match_operand:SI 0 "general_operand" "=r")
3131 (and:SI (zero_extend:SI
3132 (match_operand:HI 1 "nonimmediate_operand" "rm"))
3133 (match_operand:SI 2 "general_operand" "0")))]
3134 "GET_CODE (operands[2]) == CONST_INT
3135 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
3139 [(set (match_operand:SI 0 "general_operand" "=q")
3141 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
3142 (match_operand:SI 2 "general_operand" "0")))]
3143 "GET_CODE (operands[2]) == CONST_INT
3144 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
3149 ;;- Bit set (inclusive or) instructions
3151 ;; ??? What if we only change one byte of an offsettable memory reference?
3152 (define_insn "iorsi3"
3153 [(set (match_operand:SI 0 "general_operand" "=rm,r")
3154 (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
3155 (match_operand:SI 2 "general_operand" "ri,rm")))]
3159 if (GET_CODE (operands[2]) == CONST_INT
3160 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
3162 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
3163 && (INTVAL (operands[2]) & ~0xff) == 0)
3167 if (INTVAL (operands[2]) == 0xff)
3168 return AS2 (mov%B0,%2,%b0);
3170 return AS2 (or%B0,%2,%b0);
3173 if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)
3176 operands[2] = GEN_INT (INTVAL (operands[2]) >> 8);
3178 if (INTVAL (operands[2]) == 0xff)
3179 return AS2 (mov%B0,%2,%h0);
3181 return AS2 (or%B0,%2,%h0);
3185 return AS2 (or%L0,%2,%0);
3188 (define_insn "iorhi3"
3189 [(set (match_operand:HI 0 "general_operand" "=rm,r")
3190 (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
3191 (match_operand:HI 2 "general_operand" "ri,rm")))]
3195 if (GET_CODE (operands[2]) == CONST_INT
3196 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
3198 /* Can we ignore the upper byte? */
3199 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
3200 && (INTVAL (operands[2]) & 0xff00) == 0)
3203 if (INTVAL (operands[2]) & 0xffff0000)
3204 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
3206 if (INTVAL (operands[2]) == 0xff)
3207 return AS2 (mov%B0,%2,%b0);
3209 return AS2 (or%B0,%2,%b0);
3212 /* Can we ignore the lower byte? */
3213 /* ??? what about offsettable memory references? */
3214 if (QI_REG_P (operands[0])
3215 && (INTVAL (operands[2]) & 0xff) == 0)
3218 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
3220 if (INTVAL (operands[2]) == 0xff)
3221 return AS2 (mov%B0,%2,%h0);
3223 return AS2 (or%B0,%2,%h0);
3227 return AS2 (or%W0,%2,%0);
3230 (define_insn "iorqi3"
3231 [(set (match_operand:QI 0 "general_operand" "=qm,q")
3232 (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
3233 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3235 "* return AS2 (or%B0,%2,%0);")
3237 ;;- xor instructions
3239 ;; ??? What if we only change one byte of an offsettable memory reference?
3240 (define_insn "xorsi3"
3241 [(set (match_operand:SI 0 "general_operand" "=rm,r")
3242 (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
3243 (match_operand:SI 2 "general_operand" "ri,rm")))]
3247 if (GET_CODE (operands[2]) == CONST_INT
3248 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
3250 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
3251 && (INTVAL (operands[2]) & ~0xff) == 0)
3255 if (INTVAL (operands[2]) == 0xff)
3256 return AS1 (not%B0,%b0);
3258 return AS2 (xor%B0,%2,%b0);
3261 if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)
3264 operands[2] = GEN_INT (INTVAL (operands[2]) >> 8);
3266 if (INTVAL (operands[2]) == 0xff)
3267 return AS1 (not%B0,%h0);
3269 return AS2 (xor%B0,%2,%h0);
3273 return AS2 (xor%L0,%2,%0);
3276 (define_insn "xorhi3"
3277 [(set (match_operand:HI 0 "general_operand" "=rm,r")
3278 (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
3279 (match_operand:HI 2 "general_operand" "ri,rm")))]
3283 if (GET_CODE (operands[2]) == CONST_INT
3284 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
3286 /* Can we ignore the upper byte? */
3287 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
3288 && (INTVAL (operands[2]) & 0xff00) == 0)
3291 if (INTVAL (operands[2]) & 0xffff0000)
3292 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
3294 if (INTVAL (operands[2]) == 0xff)
3295 return AS1 (not%B0,%b0);
3297 return AS2 (xor%B0,%2,%b0);
3300 /* Can we ignore the lower byte? */
3301 /* ??? what about offsettable memory references? */
3302 if (QI_REG_P (operands[0])
3303 && (INTVAL (operands[2]) & 0xff) == 0)
3306 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
3308 if (INTVAL (operands[2]) == 0xff)
3309 return AS1 (not%B0,%h0);
3311 return AS2 (xor%B0,%2,%h0);
3315 return AS2 (xor%W0,%2,%0);
3318 (define_insn "xorqi3"
3319 [(set (match_operand:QI 0 "general_operand" "=qm,q")
3320 (xor:QI (match_operand:QI 1 "general_operand" "%0,0")
3321 (match_operand:QI 2 "general_operand" "qn,qm")))]
3323 "* return AS2 (xor%B0,%2,%0);")
3325 ;;- negation instructions
3327 (define_insn "negdi2"
3328 [(set (match_operand:DI 0 "general_operand" "=&ro")
3329 (neg:DI (match_operand:DI 1 "general_operand" "0")))]
3333 rtx xops[2], low[1], high[1];
3337 split_di (operands, 1, low, high);
3338 xops[0] = const0_rtx;
3341 output_asm_insn (AS1 (neg%L0,%0), low);
3342 output_asm_insn (AS2 (adc%L1,%0,%1), xops);
3343 output_asm_insn (AS1 (neg%L0,%0), high);
3347 (define_insn "negsi2"
3348 [(set (match_operand:SI 0 "general_operand" "=rm")
3349 (neg:SI (match_operand:SI 1 "general_operand" "0")))]
3353 (define_insn "neghi2"
3354 [(set (match_operand:HI 0 "general_operand" "=rm")
3355 (neg:HI (match_operand:HI 1 "general_operand" "0")))]
3359 (define_insn "negqi2"
3360 [(set (match_operand:QI 0 "general_operand" "=qm")
3361 (neg:QI (match_operand:QI 1 "general_operand" "0")))]
3365 (define_insn "negsf2"
3366 [(set (match_operand:SF 0 "register_operand" "=f")
3367 (neg:SF (match_operand:SF 1 "general_operand" "0")))]
3371 (define_insn "negdf2"
3372 [(set (match_operand:DF 0 "register_operand" "=f")
3373 (neg:DF (match_operand:DF 1 "general_operand" "0")))]
3378 [(set (match_operand:DF 0 "register_operand" "=f")
3379 (neg:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
3383 (define_insn "negxf2"
3384 [(set (match_operand:XF 0 "register_operand" "=f")
3385 (neg:XF (match_operand:XF 1 "general_operand" "0")))]
3390 [(set (match_operand:XF 0 "register_operand" "=f")
3391 (neg:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
3395 ;; Absolute value instructions
3397 (define_insn "abssf2"
3398 [(set (match_operand:SF 0 "register_operand" "=f")
3399 (abs:SF (match_operand:SF 1 "general_operand" "0")))]
3403 (define_insn "absdf2"
3404 [(set (match_operand:DF 0 "register_operand" "=f")
3405 (abs:DF (match_operand:DF 1 "general_operand" "0")))]
3410 [(set (match_operand:DF 0 "register_operand" "=f")
3411 (abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
3415 (define_insn "absxf2"
3416 [(set (match_operand:XF 0 "register_operand" "=f")
3417 (abs:XF (match_operand:XF 1 "general_operand" "0")))]
3422 [(set (match_operand:XF 0 "register_operand" "=f")
3423 (abs:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
3427 (define_insn "sqrtsf2"
3428 [(set (match_operand:SF 0 "register_operand" "=f")
3429 (sqrt:SF (match_operand:SF 1 "general_operand" "0")))]
3430 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3431 && (TARGET_IEEE_FP || flag_fast_math) "
3434 (define_insn "sqrtdf2"
3435 [(set (match_operand:DF 0 "register_operand" "=f")
3436 (sqrt:DF (match_operand:DF 1 "general_operand" "0")))]
3437 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3438 && (TARGET_IEEE_FP || flag_fast_math) "
3442 [(set (match_operand:DF 0 "register_operand" "=f")
3443 (sqrt:DF (float_extend:DF
3444 (match_operand:SF 1 "general_operand" "0"))))]
3445 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3446 && (TARGET_IEEE_FP || flag_fast_math) "
3449 (define_insn "sqrtxf2"
3450 [(set (match_operand:XF 0 "register_operand" "=f")
3451 (sqrt:XF (match_operand:XF 1 "general_operand" "0")))]
3452 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3453 && (TARGET_IEEE_FP || flag_fast_math) "
3457 [(set (match_operand:XF 0 "register_operand" "=f")
3458 (sqrt:XF (float_extend:XF
3459 (match_operand:DF 1 "general_operand" "0"))))]
3460 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3461 && (TARGET_IEEE_FP || flag_fast_math) "
3465 [(set (match_operand:XF 0 "register_operand" "=f")
3466 (sqrt:XF (float_extend:XF
3467 (match_operand:SF 1 "general_operand" "0"))))]
3468 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3469 && (TARGET_IEEE_FP || flag_fast_math) "
3472 (define_insn "sindf2"
3473 [(set (match_operand:DF 0 "register_operand" "=f")
3474 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
3475 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3476 && (TARGET_IEEE_FP || flag_fast_math) "
3479 (define_insn "sinsf2"
3480 [(set (match_operand:SF 0 "register_operand" "=f")
3481 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
3482 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3483 && (TARGET_IEEE_FP || flag_fast_math) "
3487 [(set (match_operand:DF 0 "register_operand" "=f")
3488 (unspec:DF [(float_extend:DF
3489 (match_operand:SF 1 "register_operand" "0"))] 1))]
3490 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3491 && (TARGET_IEEE_FP || flag_fast_math) "
3494 (define_insn "sinxf2"
3495 [(set (match_operand:XF 0 "register_operand" "=f")
3496 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
3497 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3498 && (TARGET_IEEE_FP || flag_fast_math) "
3501 (define_insn "cosdf2"
3502 [(set (match_operand:DF 0 "register_operand" "=f")
3503 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
3504 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3505 && (TARGET_IEEE_FP || flag_fast_math) "
3508 (define_insn "cossf2"
3509 [(set (match_operand:SF 0 "register_operand" "=f")
3510 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
3511 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3512 && (TARGET_IEEE_FP || flag_fast_math) "
3516 [(set (match_operand:DF 0 "register_operand" "=f")
3517 (unspec:DF [(float_extend:DF
3518 (match_operand:SF 1 "register_operand" "0"))] 2))]
3519 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3520 && (TARGET_IEEE_FP || flag_fast_math) "
3523 (define_insn "cosxf2"
3524 [(set (match_operand:XF 0 "register_operand" "=f")
3525 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
3526 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
3527 && (TARGET_IEEE_FP || flag_fast_math) "
3530 ;;- one complement instructions
3532 (define_insn "one_cmplsi2"
3533 [(set (match_operand:SI 0 "general_operand" "=rm")
3534 (not:SI (match_operand:SI 1 "general_operand" "0")))]
3538 (define_insn "one_cmplhi2"
3539 [(set (match_operand:HI 0 "general_operand" "=rm")
3540 (not:HI (match_operand:HI 1 "general_operand" "0")))]
3544 (define_insn "one_cmplqi2"
3545 [(set (match_operand:QI 0 "general_operand" "=qm")
3546 (not:QI (match_operand:QI 1 "general_operand" "0")))]
3550 ;;- arithmetic shift instructions
3552 ;; DImode shifts are implemented using the i386 "shift double" opcode,
3553 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
3554 ;; is variable, then the count is in %cl and the "imm" operand is dropped
3555 ;; from the assembler input.
3557 ;; This instruction shifts the target reg/mem as usual, but instead of
3558 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
3559 ;; is a left shift double, bits are taken from the high order bits of
3560 ;; reg, else if the insn is a shift right double, bits are taken from the
3561 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
3562 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
3564 ;; Since sh[lr]d does not change the `reg' operand, that is done
3565 ;; separately, making all shifts emit pairs of shift double and normal
3566 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
3567 ;; support a 63 bit shift, each shift where the count is in a reg expands
3568 ;; to three pairs. If the overall shift is by N bits, then the first two
3569 ;; pairs shift by N / 2 and the last pair by N & 1.
3571 ;; If the shift count is a constant, we need never emit more than one
3572 ;; shift pair, instead using moves and sign extension for counts greater
3575 (define_expand "ashldi3"
3576 [(set (match_operand:DI 0 "register_operand" "")
3577 (ashift:DI (match_operand:DI 1 "register_operand" "")
3578 (match_operand:QI 2 "nonmemory_operand" "")))]
3582 if (GET_CODE (operands[2]) != CONST_INT
3583 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
3585 operands[2] = copy_to_mode_reg (QImode, operands[2]);
3586 emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
3590 emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
3595 (define_insn "ashldi3_const_int"
3596 [(set (match_operand:DI 0 "register_operand" "=&r")
3597 (ashift:DI (match_operand:DI 1 "register_operand" "0")
3598 (match_operand:QI 2 "const_int_operand" "J")))]
3602 rtx xops[4], low[1], high[1];
3606 split_di (operands, 1, low, high);
3607 xops[0] = operands[2];
3608 xops[1] = const1_rtx;
3612 if (INTVAL (xops[0]) > 31)
3614 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
3615 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
3617 if (INTVAL (xops[0]) > 32)
3619 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
3620 output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
3625 output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
3626 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
3631 (define_insn "ashldi3_non_const_int"
3632 [(set (match_operand:DI 0 "register_operand" "=&r")
3633 (ashift:DI (match_operand:DI 1 "register_operand" "0")
3634 (match_operand:QI 2 "register_operand" "c")))
3635 (clobber (match_dup 2))]
3639 rtx xops[4], low[1], high[1];
3643 split_di (operands, 1, low, high);
3644 xops[0] = operands[2];
3645 xops[1] = const1_rtx;
3649 output_asm_insn (AS2 (ror%B0,%1,%0), xops); /* shift count / 2 */
3651 output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
3652 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
3653 output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
3654 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
3656 xops[1] = GEN_INT (7); /* shift count & 1 */
3658 output_asm_insn (AS2 (shr%B0,%1,%0), xops);
3660 output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
3661 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
3666 ;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
3667 ;; On i486, movl/sall appears slightly faster than leal, but the leal
3668 ;; is smaller - use leal for now unless the shift count is 1.
3670 (define_insn "ashlsi3"
3671 [(set (match_operand:SI 0 "general_operand" "=r,rm")
3672 (ashift:SI (match_operand:SI 1 "general_operand" "r,0")
3673 (match_operand:SI 2 "nonmemory_operand" "M,cI")))]
3677 if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
3679 if (!TARGET_386 && INTVAL (operands[2]) == 1)
3681 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
3682 return AS2 (add%L0,%1,%0);
3688 if (operands[1] == stack_pointer_rtx)
3690 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
3691 operands[1] = operands[0];
3693 operands[1] = gen_rtx (MULT, SImode, operands[1],
3694 GEN_INT (1 << INTVAL (operands[2])));
3695 return AS2 (lea%L0,%a1,%0);
3699 if (REG_P (operands[2]))
3700 return AS2 (sal%L0,%b2,%0);
3702 if (REG_P (operands[0]) && operands[2] == const1_rtx)
3703 return AS2 (add%L0,%0,%0);
3705 return AS2 (sal%L0,%2,%0);
3708 (define_insn "ashlhi3"
3709 [(set (match_operand:HI 0 "general_operand" "=rm")
3710 (ashift:HI (match_operand:HI 1 "general_operand" "0")
3711 (match_operand:HI 2 "nonmemory_operand" "cI")))]
3715 if (REG_P (operands[2]))
3716 return AS2 (sal%W0,%b2,%0);
3718 if (REG_P (operands[0]) && operands[2] == const1_rtx)
3719 return AS2 (add%W0,%0,%0);
3721 return AS2 (sal%W0,%2,%0);
3724 (define_insn "ashlqi3"
3725 [(set (match_operand:QI 0 "general_operand" "=qm")
3726 (ashift:QI (match_operand:QI 1 "general_operand" "0")
3727 (match_operand:QI 2 "nonmemory_operand" "cI")))]
3731 if (REG_P (operands[2]))
3732 return AS2 (sal%B0,%b2,%0);
3734 if (REG_P (operands[0]) && operands[2] == const1_rtx)
3735 return AS2 (add%B0,%0,%0);
3737 return AS2 (sal%B0,%2,%0);
3740 ;; See comment above `ashldi3' about how this works.
3742 (define_expand "ashrdi3"
3743 [(set (match_operand:DI 0 "register_operand" "")
3744 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
3745 (match_operand:QI 2 "nonmemory_operand" "")))]
3749 if (GET_CODE (operands[2]) != CONST_INT
3750 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
3752 operands[2] = copy_to_mode_reg (QImode, operands[2]);
3753 emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1],
3757 emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2]));
3762 (define_insn "ashrdi3_const_int"
3763 [(set (match_operand:DI 0 "register_operand" "=&r")
3764 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
3765 (match_operand:QI 2 "const_int_operand" "J")))]
3769 rtx xops[4], low[1], high[1];
3773 split_di (operands, 1, low, high);
3774 xops[0] = operands[2];
3775 xops[1] = const1_rtx;
3779 if (INTVAL (xops[0]) > 31)
3781 xops[1] = GEN_INT (31);
3782 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
3783 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */
3785 if (INTVAL (xops[0]) > 32)
3787 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
3788 output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */
3793 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
3794 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
3800 (define_insn "ashrdi3_non_const_int"
3801 [(set (match_operand:DI 0 "register_operand" "=&r")
3802 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
3803 (match_operand:QI 2 "register_operand" "c")))
3804 (clobber (match_dup 2))]
3808 rtx xops[4], low[1], high[1];
3812 split_di (operands, 1, low, high);
3813 xops[0] = operands[2];
3814 xops[1] = const1_rtx;
3818 output_asm_insn (AS2 (ror%B0,%1,%0), xops); /* shift count / 2 */
3820 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
3821 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
3822 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
3823 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
3825 xops[1] = GEN_INT (7); /* shift count & 1 */
3827 output_asm_insn (AS2 (shr%B0,%1,%0), xops);
3829 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
3830 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
3835 (define_insn "ashrsi3"
3836 [(set (match_operand:SI 0 "general_operand" "=rm")
3837 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
3838 (match_operand:SI 2 "nonmemory_operand" "cI")))]
3842 if (REG_P (operands[2]))
3843 return AS2 (sar%L0,%b2,%0);
3845 return AS2 (sar%L0,%2,%0);
3848 (define_insn "ashrhi3"
3849 [(set (match_operand:HI 0 "general_operand" "=rm")
3850 (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
3851 (match_operand:HI 2 "nonmemory_operand" "cI")))]
3855 if (REG_P (operands[2]))
3856 return AS2 (sar%W0,%b2,%0);
3858 return AS2 (sar%W0,%2,%0);
3861 (define_insn "ashrqi3"
3862 [(set (match_operand:QI 0 "general_operand" "=qm")
3863 (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
3864 (match_operand:QI 2 "nonmemory_operand" "cI")))]
3868 if (REG_P (operands[2]))
3869 return AS2 (sar%B0,%b2,%0);
3871 return AS2 (sar%B0,%2,%0);
3874 ;;- logical shift instructions
3876 ;; See comment above `ashldi3' about how this works.
3878 (define_expand "lshrdi3"
3879 [(set (match_operand:DI 0 "register_operand" "")
3880 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
3881 (match_operand:QI 2 "nonmemory_operand" "")))]
3885 if (GET_CODE (operands[2]) != CONST_INT
3886 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
3888 operands[2] = copy_to_mode_reg (QImode, operands[2]);
3889 emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
3893 emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
3898 (define_insn "lshrdi3_const_int"
3899 [(set (match_operand:DI 0 "register_operand" "=&r")
3900 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
3901 (match_operand:QI 2 "const_int_operand" "J")))]
3905 rtx xops[4], low[1], high[1];
3909 split_di (operands, 1, low, high);
3910 xops[0] = operands[2];
3911 xops[1] = const1_rtx;
3915 if (INTVAL (xops[0]) > 31)
3917 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
3918 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
3920 if (INTVAL (xops[0]) > 32)
3922 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
3923 output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
3928 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
3929 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
3935 (define_insn "lshrdi3_non_const_int"
3936 [(set (match_operand:DI 0 "register_operand" "=&r")
3937 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
3938 (match_operand:QI 2 "register_operand" "c")))
3939 (clobber (match_dup 2))]
3943 rtx xops[4], low[1], high[1];
3947 split_di (operands, 1, low, high);
3948 xops[0] = operands[2];
3949 xops[1] = const1_rtx;
3953 output_asm_insn (AS2 (ror%B0,%1,%0), xops); /* shift count / 2 */
3955 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
3956 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
3957 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
3958 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
3960 xops[1] = GEN_INT (7); /* shift count & 1 */
3962 output_asm_insn (AS2 (shr%B0,%1,%0), xops);
3964 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
3965 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
3970 (define_insn "lshrsi3"
3971 [(set (match_operand:SI 0 "general_operand" "=rm")
3972 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
3973 (match_operand:SI 2 "nonmemory_operand" "cI")))]
3977 if (REG_P (operands[2]))
3978 return AS2 (shr%L0,%b2,%0);
3980 return AS2 (shr%L0,%2,%1);
3983 (define_insn "lshrhi3"
3984 [(set (match_operand:HI 0 "general_operand" "=rm")
3985 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
3986 (match_operand:HI 2 "nonmemory_operand" "cI")))]
3990 if (REG_P (operands[2]))
3991 return AS2 (shr%W0,%b2,%0);
3993 return AS2 (shr%W0,%2,%0);
3996 (define_insn "lshrqi3"
3997 [(set (match_operand:QI 0 "general_operand" "=qm")
3998 (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
3999 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4003 if (REG_P (operands[2]))
4004 return AS2 (shr%B0,%b2,%0);
4006 return AS2 (shr%B0,%2,%0);
4009 ;;- rotate instructions
4011 (define_insn "rotlsi3"
4012 [(set (match_operand:SI 0 "general_operand" "=rm")
4013 (rotate:SI (match_operand:SI 1 "general_operand" "0")
4014 (match_operand:SI 2 "nonmemory_operand" "cI")))]
4018 if (REG_P (operands[2]))
4019 return AS2 (rol%L0,%b2,%0);
4021 return AS2 (rol%L0,%2,%0);
4024 (define_insn "rotlhi3"
4025 [(set (match_operand:HI 0 "general_operand" "=rm")
4026 (rotate:HI (match_operand:HI 1 "general_operand" "0")
4027 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4031 if (REG_P (operands[2]))
4032 return AS2 (rol%W0,%b2,%0);
4034 return AS2 (rol%W0,%2,%0);
4037 (define_insn "rotlqi3"
4038 [(set (match_operand:QI 0 "general_operand" "=qm")
4039 (rotate:QI (match_operand:QI 1 "general_operand" "0")
4040 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4044 if (REG_P (operands[2]))
4045 return AS2 (rol%B0,%b2,%0);
4047 return AS2 (rol%B0,%2,%0);
4050 (define_insn "rotrsi3"
4051 [(set (match_operand:SI 0 "general_operand" "=rm")
4052 (rotatert:SI (match_operand:SI 1 "general_operand" "0")
4053 (match_operand:SI 2 "nonmemory_operand" "cI")))]
4057 if (REG_P (operands[2]))
4058 return AS2 (ror%L0,%b2,%0);
4060 return AS2 (ror%L0,%2,%0);
4063 (define_insn "rotrhi3"
4064 [(set (match_operand:HI 0 "general_operand" "=rm")
4065 (rotatert:HI (match_operand:HI 1 "general_operand" "0")
4066 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4070 if (REG_P (operands[2]))
4071 return AS2 (ror%W0,%b2,%0);
4073 return AS2 (ror%W0,%2,%0);
4076 (define_insn "rotrqi3"
4077 [(set (match_operand:QI 0 "general_operand" "=qm")
4078 (rotatert:QI (match_operand:QI 1 "general_operand" "0")
4079 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4083 if (REG_P (operands[2]))
4084 return AS2 (ror%B0,%b2,%0);
4086 return AS2 (ror%B0,%2,%0);
4090 ;; This usually looses. But try a define_expand to recognize a few case
4091 ;; we can do efficiently, such as accessing the "high" QImode registers,
4092 ;; %ah, %bh, %ch, %dh.
4094 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
4095 (match_operand:SI 1 "general_operand" "i")
4096 (match_operand:SI 2 "general_operand" "i"))
4097 (match_operand:SI 3 "general_operand" "ri"))]
4101 if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
4103 if (GET_CODE (operands[3]) == CONST_INT)
4105 unsigned int mask = (1 << INTVAL (operands[1])) - 1;
4106 operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
4107 output_asm_insn (AS2 (and%L0,%1,%0), operands);
4108 operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
4109 output_asm_insn (AS2 (or%L0,%3,%0), operands);
4113 operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
4114 if (INTVAL (operands[2]))
4115 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
4116 output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
4117 operands[2] = GEN_INT (BITS_PER_WORD
4118 - INTVAL (operands[1]) - INTVAL (operands[2]));
4119 if (INTVAL (operands[2]))
4120 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
4126 ;; ??? There are problems with the mode of operand[3]. The point of this
4127 ;; is to represent an HImode move to a "high byte" register.
4129 (define_expand "insv"
4130 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
4131 (match_operand:SI 1 "immediate_operand" "")
4132 (match_operand:SI 2 "immediate_operand" ""))
4133 (match_operand:QI 3 "general_operand" "ri"))]
4137 if (GET_CODE (operands[1]) != CONST_INT
4138 || GET_CODE (operands[2]) != CONST_INT)
4141 if (! (INTVAL (operands[1]) == 8
4142 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
4143 && ! INTVAL (operands[1]) == 1)
4147 ;; ??? Are these constraints right?
4149 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+&qo")
4152 (match_operand:QI 1 "general_operand" "qn"))]
4156 if (REG_P (operands[0]))
4157 return AS2 (mov%B0,%1,%h0);
4159 operands[0] = adj_offsettable_operand (operands[0], 1);
4160 return AS2 (mov%B0,%1,%0);
4164 ;; On i386, the register count for a bit operation is *not* truncated,
4165 ;; so SHIFT_COUNT_TRUNCATED must not be defined.
4167 ;; On i486, the shift & or/and code is faster than bts or btr. If
4168 ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
4170 ;; On i386, bts is a little faster if operands[0] is a reg, and a
4171 ;; little slower if operands[0] is a MEM, than the shift & or/and code.
4172 ;; Use bts & btr, since they reload better.
4174 ;; General bit set and clear.
4176 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+rm")
4178 (match_operand:SI 2 "general_operand" "r"))
4179 (match_operand:SI 3 "const_int_operand" "n"))]
4180 "TARGET_386 && GET_CODE (operands[2]) != CONST_INT"
4185 if (INTVAL (operands[3]) == 1)
4186 return AS2 (bts%L0,%2,%0);
4188 return AS2 (btr%L0,%2,%0);
4191 ;; Bit complement. See comments on previous pattern.
4192 ;; ??? Is this really worthwhile?
4194 [(set (match_operand:SI 0 "general_operand" "=rm")
4195 (xor:SI (ashift:SI (const_int 1)
4196 (match_operand:SI 1 "general_operand" "r"))
4197 (match_operand:SI 2 "general_operand" "0")))]
4198 "TARGET_386 && GET_CODE (operands[1]) != CONST_INT"
4203 return AS2 (btc%L0,%1,%0);
4207 [(set (match_operand:SI 0 "general_operand" "=rm")
4208 (xor:SI (match_operand:SI 1 "general_operand" "0")
4209 (ashift:SI (const_int 1)
4210 (match_operand:SI 2 "general_operand" "r"))))]
4211 "TARGET_386 && GET_CODE (operands[2]) != CONST_INT"
4216 return AS2 (btc%L0,%2,%0);
4219 ;; Recognizers for bit-test instructions.
4221 ;; The bt opcode allows a MEM in operands[0]. But on both i386 and
4222 ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
4223 ;; bt on the MEM directly.
4225 ;; ??? The first argument of a zero_extract must not be reloaded, so
4226 ;; don't allow a MEM in the operand predicate without allowing it in the
4230 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
4232 (match_operand:SI 1 "general_operand" "r")))]
4233 "GET_CODE (operands[1]) != CONST_INT"
4236 cc_status.flags |= CC_Z_IN_NOT_C;
4237 return AS2 (bt%L0,%1,%0);
4241 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
4242 (match_operand:SI 1 "const_int_operand" "n")
4243 (match_operand:SI 2 "const_int_operand" "n")))]
4249 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
4250 operands[1] = GEN_INT (mask);
4252 if (QI_REG_P (operands[0]))
4254 if ((mask & ~0xff) == 0)
4256 cc_status.flags |= CC_NOT_NEGATIVE;
4257 return AS2 (test%B0,%1,%b0);
4260 if ((mask & ~0xff00) == 0)
4262 cc_status.flags |= CC_NOT_NEGATIVE;
4263 operands[1] = GEN_INT (mask >> 8);
4264 return AS2 (test%B0,%1,%h0);
4268 return AS2 (test%L0,%1,%0);
4271 ;; ??? All bets are off if operand 0 is a volatile MEM reference.
4272 ;; The CPU may access unspecified bytes around the actual target byte.
4275 [(set (cc0) (zero_extract (match_operand:QI 0 "general_operand" "rm")
4276 (match_operand:SI 1 "const_int_operand" "n")
4277 (match_operand:SI 2 "const_int_operand" "n")))]
4278 "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
4283 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
4284 operands[1] = GEN_INT (mask);
4286 if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
4288 if ((mask & ~0xff) == 0)
4290 cc_status.flags |= CC_NOT_NEGATIVE;
4291 return AS2 (test%B0,%1,%b0);
4294 if ((mask & ~0xff00) == 0)
4296 cc_status.flags |= CC_NOT_NEGATIVE;
4297 operands[1] = GEN_INT (mask >> 8);
4299 if (QI_REG_P (operands[0]))
4300 return AS2 (test%B0,%1,%h0);
4303 operands[0] = adj_offsettable_operand (operands[0], 1);
4304 return AS2 (test%B0,%1,%b0);
4308 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
4310 cc_status.flags |= CC_NOT_NEGATIVE;
4311 operands[1] = GEN_INT (mask >> 16);
4312 operands[0] = adj_offsettable_operand (operands[0], 2);
4313 return AS2 (test%B0,%1,%b0);
4316 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
4318 cc_status.flags |= CC_NOT_NEGATIVE;
4319 operands[1] = GEN_INT (mask >> 24);
4320 operands[0] = adj_offsettable_operand (operands[0], 3);
4321 return AS2 (test%B0,%1,%b0);
4325 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
4326 return AS2 (test%L0,%1,%0);
4328 return AS2 (test%L1,%0,%1);
4331 ;; Store-flag instructions.
4333 ;; For all sCOND expanders, also expand the compare or test insn that
4334 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
4336 ;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may
4337 ;; not have any input reloads. A MEM write might need an input reload
4338 ;; for the address of the MEM. So don't allow MEM as the SET_DEST.
4340 (define_expand "seq"
4342 (set (match_operand:QI 0 "register_operand" "")
4343 (eq:QI (cc0) (const_int 0)))]
4348 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
4349 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
4351 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
4355 [(set (match_operand:QI 0 "register_operand" "=q")
4356 (eq:QI (cc0) (const_int 0)))]
4360 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
4361 return AS1 (setnb,%0);
4363 return AS1 (sete,%0);
4366 (define_expand "sne"
4368 (set (match_operand:QI 0 "register_operand" "")
4369 (ne:QI (cc0) (const_int 0)))]
4374 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
4375 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
4377 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
4381 [(set (match_operand:QI 0 "register_operand" "=q")
4382 (ne:QI (cc0) (const_int 0)))]
4386 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
4387 return AS1 (setb,%0);
4389 return AS1 (setne,%0);
4393 (define_expand "sgt"
4395 (set (match_operand:QI 0 "register_operand" "")
4396 (gt:QI (cc0) (const_int 0)))]
4398 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4401 [(set (match_operand:QI 0 "register_operand" "=q")
4402 (gt:QI (cc0) (const_int 0)))]
4406 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
4407 return AS1 (sete,%0);
4409 OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR);
4412 (define_expand "sgtu"
4414 (set (match_operand:QI 0 "register_operand" "")
4415 (gtu:QI (cc0) (const_int 0)))]
4417 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4420 [(set (match_operand:QI 0 "register_operand" "=q")
4421 (gtu:QI (cc0) (const_int 0)))]
4423 "* return \"seta %0\"; ")
4425 (define_expand "slt"
4427 (set (match_operand:QI 0 "register_operand" "")
4428 (lt:QI (cc0) (const_int 0)))]
4430 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4433 [(set (match_operand:QI 0 "register_operand" "=q")
4434 (lt:QI (cc0) (const_int 0)))]
4438 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
4439 return AS1 (sete,%0);
4441 OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\");
4444 (define_expand "sltu"
4446 (set (match_operand:QI 0 "register_operand" "")
4447 (ltu:QI (cc0) (const_int 0)))]
4449 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4452 [(set (match_operand:QI 0 "register_operand" "=q")
4453 (ltu:QI (cc0) (const_int 0)))]
4455 "* return \"setb %0\"; ")
4457 (define_expand "sge"
4459 (set (match_operand:QI 0 "register_operand" "")
4460 (ge:QI (cc0) (const_int 0)))]
4462 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4465 [(set (match_operand:QI 0 "register_operand" "=q")
4466 (ge:QI (cc0) (const_int 0)))]
4470 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
4471 return AS1 (sete,%0);
4473 OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\");
4476 (define_expand "sgeu"
4478 (set (match_operand:QI 0 "register_operand" "")
4479 (geu:QI (cc0) (const_int 0)))]
4481 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4484 [(set (match_operand:QI 0 "register_operand" "=q")
4485 (geu:QI (cc0) (const_int 0)))]
4487 "* return \"setae %0\"; ")
4489 (define_expand "sle"
4491 (set (match_operand:QI 0 "register_operand" "")
4492 (le:QI (cc0) (const_int 0)))]
4494 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4497 [(set (match_operand:QI 0 "register_operand" "=q")
4498 (le:QI (cc0) (const_int 0)))]
4502 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
4503 return AS1 (setb,%0);
4505 OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR);
4508 (define_expand "sleu"
4510 (set (match_operand:QI 0 "register_operand" "")
4511 (leu:QI (cc0) (const_int 0)))]
4513 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4516 [(set (match_operand:QI 0 "register_operand" "=q")
4517 (leu:QI (cc0) (const_int 0)))]
4519 "* return \"setbe %0\"; ")
4521 ;; Basic conditional jump instructions.
4522 ;; We ignore the overflow flag for signed branch instructions.
4524 ;; For all bCOND expanders, also expand the compare or test insn that
4525 ;; generates cc0. Generate an equality comparison if `beq' or `bne'.
4527 (define_expand "beq"
4530 (if_then_else (eq (cc0)
4532 (label_ref (match_operand 0 "" ""))
4538 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
4539 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
4541 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
4546 (if_then_else (eq (cc0)
4548 (label_ref (match_operand 0 "" ""))
4553 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
4559 (define_expand "bne"
4562 (if_then_else (ne (cc0)
4564 (label_ref (match_operand 0 "" ""))
4570 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
4571 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
4573 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
4578 (if_then_else (ne (cc0)
4580 (label_ref (match_operand 0 "" ""))
4585 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
4591 (define_expand "bgt"
4594 (if_then_else (gt (cc0)
4596 (label_ref (match_operand 0 "" ""))
4599 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4603 (if_then_else (gt (cc0)
4605 (label_ref (match_operand 0 "" ""))
4610 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
4611 return AS1 (je,%l0);
4613 OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
4616 (define_expand "bgtu"
4619 (if_then_else (gtu (cc0)
4621 (label_ref (match_operand 0 "" ""))
4624 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4628 (if_then_else (gtu (cc0)
4630 (label_ref (match_operand 0 "" ""))
4635 (define_expand "blt"
4638 (if_then_else (lt (cc0)
4640 (label_ref (match_operand 0 "" ""))
4643 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4647 (if_then_else (lt (cc0)
4649 (label_ref (match_operand 0 "" ""))
4654 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
4655 return AS1 (je,%l0);
4657 OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
4660 (define_expand "bltu"
4663 (if_then_else (ltu (cc0)
4665 (label_ref (match_operand 0 "" ""))
4668 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4672 (if_then_else (ltu (cc0)
4674 (label_ref (match_operand 0 "" ""))
4679 (define_expand "bge"
4682 (if_then_else (ge (cc0)
4684 (label_ref (match_operand 0 "" ""))
4687 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4691 (if_then_else (ge (cc0)
4693 (label_ref (match_operand 0 "" ""))
4698 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
4699 return AS1 (je,%l0);
4701 OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
4704 (define_expand "bgeu"
4707 (if_then_else (geu (cc0)
4709 (label_ref (match_operand 0 "" ""))
4712 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4716 (if_then_else (geu (cc0)
4718 (label_ref (match_operand 0 "" ""))
4723 (define_expand "ble"
4726 (if_then_else (le (cc0)
4728 (label_ref (match_operand 0 "" ""))
4731 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4735 (if_then_else (le (cc0)
4737 (label_ref (match_operand 0 "" ""))
4742 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
4743 return AS1 (jb,%l0);
4745 OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
4748 (define_expand "bleu"
4751 (if_then_else (leu (cc0)
4753 (label_ref (match_operand 0 "" ""))
4756 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
4760 (if_then_else (leu (cc0)
4762 (label_ref (match_operand 0 "" ""))
4767 ;; Negated conditional jump instructions.
4771 (if_then_else (eq (cc0)
4774 (label_ref (match_operand 0 "" ""))))]
4778 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
4786 (if_then_else (ne (cc0)
4789 (label_ref (match_operand 0 "" ""))))]
4793 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
4801 (if_then_else (gt (cc0)
4804 (label_ref (match_operand 0 "" ""))))]
4808 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
4809 return AS1 (jne,%l0);
4811 OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
4816 (if_then_else (gtu (cc0)
4819 (label_ref (match_operand 0 "" ""))))]
4825 (if_then_else (lt (cc0)
4828 (label_ref (match_operand 0 "" ""))))]
4832 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
4833 return AS1 (jne,%l0);
4835 OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
4840 (if_then_else (ltu (cc0)
4843 (label_ref (match_operand 0 "" ""))))]
4849 (if_then_else (ge (cc0)
4852 (label_ref (match_operand 0 "" ""))))]
4856 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
4857 return AS1 (jne,%l0);
4859 OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
4864 (if_then_else (geu (cc0)
4867 (label_ref (match_operand 0 "" ""))))]
4873 (if_then_else (le (cc0)
4876 (label_ref (match_operand 0 "" ""))))]
4880 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
4881 return AS1 (jae,%l0);
4883 OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
4888 (if_then_else (leu (cc0)
4891 (label_ref (match_operand 0 "" ""))))]
4895 ;; Unconditional and other jump instructions
4899 (label_ref (match_operand 0 "" "")))]
4903 (define_insn "indirect_jump"
4904 [(set (pc) (match_operand:SI 0 "general_operand" "rm"))]
4910 return AS1 (jmp,%*%0);
4913 ;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
4914 ;; if S does not change i
4916 (define_expand "decrement_and_branch_until_zero"
4917 [(parallel [(set (pc)
4918 (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "")
4921 (label_ref (match_operand 1 "" ""))
4924 (plus:SI (match_dup 0)
4931 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
4932 [(plus:SI (match_operand:SI 1 "general_operand" "+r,m")
4933 (match_operand:SI 2 "general_operand" "rmi,ri"))
4935 (label_ref (match_operand 3 "" ""))
4938 (plus:SI (match_dup 1)
4944 if (operands[2] == constm1_rtx)
4945 output_asm_insn (AS1 (dec%L1,%1), operands);
4947 else if (operands[1] == const1_rtx)
4948 output_asm_insn (AS1 (inc%L1,%1), operands);
4951 output_asm_insn (AS2 (add%L1,%2,%1), operands);
4953 return AS1 (%J0,%l3);
4958 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
4959 [(minus:SI (match_operand:SI 1 "general_operand" "+r,m")
4960 (match_operand:SI 2 "general_operand" "rmi,ri"))
4962 (label_ref (match_operand 3 "" ""))
4965 (minus:SI (match_dup 1)
4971 if (operands[2] == const1_rtx)
4972 output_asm_insn (AS1 (dec%L1,%1), operands);
4974 else if (operands[1] == constm1_rtx)
4975 output_asm_insn (AS1 (inc%L1,%1), operands);
4978 output_asm_insn (AS2 (sub%L1,%2,%1), operands);
4980 return AS1 (%J0,%l3);
4983 ;; Implement switch statements when generating PIC code. Switches are
4984 ;; implemented by `tablejump' when not using -fpic.
4986 ;; Emit code here to do the range checking and make the index zero based.
4988 (define_expand "casesi"
4990 (minus:SI (match_operand:SI 0 "general_operand" "")
4991 (match_operand:SI 1 "general_operand" "")))
4993 (compare:CC (match_dup 5)
4994 (match_operand:SI 2 "general_operand" "")))
4996 (if_then_else (gtu (cc0)
4998 (label_ref (match_operand 4 "" ""))
5002 (minus:SI (reg:SI 3)
5003 (mem:SI (plus:SI (mult:SI (match_dup 5)
5005 (label_ref (match_operand 3 "" ""))))))
5006 (clobber (match_scratch:SI 6 ""))])]
5010 operands[5] = gen_reg_rtx (SImode);
5011 current_function_uses_pic_offset_table = 1;
5014 ;; Implement a casesi insn.
5016 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
5019 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
5021 ;; 1. An expression involving an external reference may only use the
5022 ;; addition operator, and only with an assembly-time constant.
5023 ;; The example above satisfies this because ".-.L2" is a constant.
5025 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
5026 ;; given the value of "GOT - .", where GOT is the actual address of
5027 ;; the Global Offset Table. Therefore, the .long above actually
5028 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
5029 ;; expression "GOT - .L2" by itself would generate an error from as(1).
5031 ;; The pattern below emits code that looks like this:
5034 ;; subl TABLE@GOTOFF(%ebx,index,4),reg
5037 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
5038 ;; the addr_diff_vec is known to be part of this module.
5040 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
5041 ;; evaluates to just ".L2".
5045 (minus:SI (reg:SI 3)
5047 (mult:SI (match_operand:SI 0 "register_operand" "r")
5049 (label_ref (match_operand 1 "" ""))))))
5050 (clobber (match_scratch:SI 2 "=&r"))]
5056 xops[0] = operands[0];
5057 xops[1] = operands[1];
5058 xops[2] = operands[2];
5059 xops[3] = pic_offset_table_rtx;
5061 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5062 output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
5063 output_asm_insn (AS1 (jmp,%*%2), xops);
5064 ASM_OUTPUT_ALIGN_CODE (asm_out_file);
5068 (define_insn "tablejump"
5069 [(set (pc) (match_operand:SI 0 "general_operand" "rm"))
5070 (use (label_ref (match_operand 1 "" "")))]
5076 return AS1 (jmp,%*%0);
5081 ;; If generating PIC code, the predicate indirect_operand will fail
5082 ;; for operands[0] containing symbolic references on all of the named
5083 ;; call* patterns. Each named pattern is followed by an unnamed pattern
5084 ;; that matches any call to a symbolic CONST (ie, a symbol_ref). The
5085 ;; unnamed patterns are only used while generating PIC code, because
5086 ;; otherwise the named patterns match.
5088 ;; Call subroutine returning no value.
5090 (define_expand "call_pop"
5091 [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
5092 (match_operand:SI 1 "general_operand" ""))
5095 (match_operand:SI 3 "immediate_operand" "")))])]
5102 current_function_uses_pic_offset_table = 1;
5104 /* With half-pic, force the address into a register. */
5105 addr = XEXP (operands[0], 0);
5106 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
5107 XEXP (operands[0], 0) = force_reg (Pmode, addr);
5109 if (! expander_call_insn_operand (operands[0], QImode))
5111 = change_address (operands[0], VOIDmode,
5112 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
5116 [(call (match_operand:QI 0 "call_insn_operand" "m")
5117 (match_operand:SI 1 "general_operand" "g"))
5118 (set (reg:SI 7) (plus:SI (reg:SI 7)
5119 (match_operand:SI 3 "immediate_operand" "i")))]
5123 if (GET_CODE (operands[0]) == MEM
5124 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
5126 operands[0] = XEXP (operands[0], 0);
5127 return AS1 (call,%*%0);
5130 return AS1 (call,%P0);
5134 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
5135 (match_operand:SI 1 "general_operand" "g"))
5136 (set (reg:SI 7) (plus:SI (reg:SI 7)
5137 (match_operand:SI 3 "immediate_operand" "i")))]
5141 (define_expand "call"
5142 [(call (match_operand:QI 0 "indirect_operand" "")
5143 (match_operand:SI 1 "general_operand" ""))]
5144 ;; Operand 1 not used on the i386.
5151 current_function_uses_pic_offset_table = 1;
5153 /* With half-pic, force the address into a register. */
5154 addr = XEXP (operands[0], 0);
5155 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
5156 XEXP (operands[0], 0) = force_reg (Pmode, addr);
5158 if (! expander_call_insn_operand (operands[0], QImode))
5160 = change_address (operands[0], VOIDmode,
5161 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
5165 [(call (match_operand:QI 0 "call_insn_operand" "m")
5166 (match_operand:SI 1 "general_operand" "g"))]
5167 ;; Operand 1 not used on the i386.
5171 if (GET_CODE (operands[0]) == MEM
5172 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
5174 operands[0] = XEXP (operands[0], 0);
5175 return AS1 (call,%*%0);
5178 return AS1 (call,%P0);
5182 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
5183 (match_operand:SI 1 "general_operand" "g"))]
5184 ;; Operand 1 not used on the i386.
5188 ;; Call subroutine, returning value in operand 0
5189 ;; (which must be a hard register).
5191 (define_expand "call_value_pop"
5192 [(parallel [(set (match_operand 0 "" "")
5193 (call (match_operand:QI 1 "indirect_operand" "")
5194 (match_operand:SI 2 "general_operand" "")))
5197 (match_operand:SI 4 "immediate_operand" "")))])]
5204 current_function_uses_pic_offset_table = 1;
5206 /* With half-pic, force the address into a register. */
5207 addr = XEXP (operands[1], 0);
5208 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
5209 XEXP (operands[1], 0) = force_reg (Pmode, addr);
5211 if (! expander_call_insn_operand (operands[1], QImode))
5213 = change_address (operands[1], VOIDmode,
5214 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
5218 [(set (match_operand 0 "" "=rf")
5219 (call (match_operand:QI 1 "call_insn_operand" "m")
5220 (match_operand:SI 2 "general_operand" "g")))
5221 (set (reg:SI 7) (plus:SI (reg:SI 7)
5222 (match_operand:SI 4 "immediate_operand" "i")))]
5226 if (GET_CODE (operands[1]) == MEM
5227 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
5229 operands[1] = XEXP (operands[1], 0);
5230 output_asm_insn (AS1 (call,%*%1), operands);
5233 output_asm_insn (AS1 (call,%P1), operands);
5239 [(set (match_operand 0 "" "=rf")
5240 (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
5241 (match_operand:SI 2 "general_operand" "g")))
5242 (set (reg:SI 7) (plus:SI (reg:SI 7)
5243 (match_operand:SI 4 "immediate_operand" "i")))]
5247 (define_expand "call_value"
5248 [(set (match_operand 0 "" "")
5249 (call (match_operand:QI 1 "indirect_operand" "")
5250 (match_operand:SI 2 "general_operand" "")))]
5251 ;; Operand 2 not used on the i386.
5258 current_function_uses_pic_offset_table = 1;
5260 /* With half-pic, force the address into a register. */
5261 addr = XEXP (operands[1], 0);
5262 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
5263 XEXP (operands[1], 0) = force_reg (Pmode, addr);
5265 if (! expander_call_insn_operand (operands[1], QImode))
5267 = change_address (operands[1], VOIDmode,
5268 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
5272 [(set (match_operand 0 "" "=rf")
5273 (call (match_operand:QI 1 "call_insn_operand" "m")
5274 (match_operand:SI 2 "general_operand" "g")))]
5275 ;; Operand 2 not used on the i386.
5279 if (GET_CODE (operands[1]) == MEM
5280 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
5282 operands[1] = XEXP (operands[1], 0);
5283 output_asm_insn (AS1 (call,%*%1), operands);
5286 output_asm_insn (AS1 (call,%P1), operands);
5292 [(set (match_operand 0 "" "=rf")
5293 (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
5294 (match_operand:SI 2 "general_operand" "g")))]
5295 ;; Operand 2 not used on the i386.
5299 ;; Call subroutine returning any type.
5301 (define_expand "untyped_call"
5302 [(parallel [(call (match_operand 0 "" "")
5304 (match_operand 1 "" "")
5305 (match_operand 2 "" "")])]
5311 /* In order to give reg-stack an easier job in validating two
5312 coprocessor registers as containing a possible return value,
5313 simply pretend the untyped call returns a complex long double
5316 /* this may be part of (set (reg: ..) (call_insn ...)), and we can't
5317 directly set a fp register from the call. so we revert to the
5318 old behavior - jlemon@netcom.com (Jonathan Lemon) */
5319 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
5321 emit_call_insn (TARGET_80387
5322 ? gen_call_value (gen_rtx (REG, XCmode, FIRST_FLOAT_REG),
5323 operands[0], const0_rtx)
5324 : gen_call (operands[0], const0_rtx));
5327 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5329 rtx set = XVECEXP (operands[2], 0, i);
5330 emit_move_insn (SET_DEST (set), SET_SRC (set));
5333 /* The optimizer does not know that the call sets the function value
5334 registers we stored in the result block. We avoid problems by
5335 claiming that all hard registers are used and clobbered at this
5337 emit_insn (gen_blockage ());
5342 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
5343 ;; all of memory. This blocks insns from being moved across this point.
5345 (define_insn "blockage"
5346 [(unspec_volatile [(const_int 0)] 0)]
5350 ;; Insn emitted into the body of a function to return from a function.
5351 ;; This is only done if the function's epilogue is known to be simple.
5352 ;; See comments for simple_386_epilogue in i386.c.
5354 (define_insn "return"
5356 "simple_386_epilogue ()"
5359 function_epilogue (asm_out_file, get_frame_size ());
5368 (define_expand "movstrsi"
5369 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
5370 (match_operand:BLK 1 "memory_operand" ""))
5371 (use (match_operand:SI 2 "const_int_operand" ""))
5372 (use (match_operand:SI 3 "const_int_operand" ""))
5373 (clobber (match_scratch:SI 4 ""))
5374 (clobber (match_dup 5))
5375 (clobber (match_dup 6))])]
5381 if (GET_CODE (operands[2]) != CONST_INT)
5384 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
5385 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
5387 operands[5] = addr0;
5388 operands[6] = addr1;
5390 operands[0] = gen_rtx (MEM, BLKmode, addr0);
5391 operands[1] = gen_rtx (MEM, BLKmode, addr1);
5394 ;; It might seem that operands 0 & 1 could use predicate register_operand.
5395 ;; But strength reduction might offset the MEM expression. So we let
5396 ;; reload put the address into %edi & %esi.
5399 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
5400 (mem:BLK (match_operand:SI 1 "address_operand" "S")))
5401 (use (match_operand:SI 2 "const_int_operand" "n"))
5402 (use (match_operand:SI 3 "immediate_operand" "i"))
5403 (clobber (match_scratch:SI 4 "=&c"))
5404 (clobber (match_dup 0))
5405 (clobber (match_dup 1))]
5411 output_asm_insn (\"cld\", operands);
5412 if (GET_CODE (operands[2]) == CONST_INT)
5414 if (INTVAL (operands[2]) & ~0x03)
5416 xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
5417 xops[1] = operands[4];
5419 output_asm_insn (AS2 (mov%L1,%0,%1), xops);
5421 output_asm_insn (\"rep movsd\", xops);
5423 output_asm_insn (\"rep\;movsl\", xops);
5426 if (INTVAL (operands[2]) & 0x02)
5427 output_asm_insn (\"movsw\", operands);
5428 if (INTVAL (operands[2]) & 0x01)
5429 output_asm_insn (\"movsb\", operands);
5436 (define_expand "cmpstrsi"
5437 [(parallel [(set (match_operand:SI 0 "general_operand" "")
5438 (compare:SI (match_operand:BLK 1 "general_operand" "")
5439 (match_operand:BLK 2 "general_operand" "")))
5440 (use (match_operand:SI 3 "general_operand" ""))
5441 (use (match_operand:SI 4 "immediate_operand" ""))
5442 (clobber (match_dup 5))
5443 (clobber (match_dup 6))
5444 (clobber (match_dup 3))])]
5450 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
5451 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
5452 operands[3] = copy_to_mode_reg (SImode, operands[3]);
5454 operands[5] = addr1;
5455 operands[6] = addr2;
5457 operands[1] = gen_rtx (MEM, BLKmode, addr1);
5458 operands[2] = gen_rtx (MEM, BLKmode, addr2);
5462 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
5463 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
5465 ;; It might seem that operands 0 & 1 could use predicate register_operand.
5466 ;; But strength reduction might offset the MEM expression. So we let
5467 ;; reload put the address into %edi & %esi.
5469 ;; ??? Most comparisons have a constant length, and it's therefore
5470 ;; possible to know that the length is non-zero, and to avoid the extra
5471 ;; code to handle zero-length compares.
5474 [(set (match_operand:SI 0 "general_operand" "=&r")
5475 (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
5476 (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
5477 (use (match_operand:SI 3 "register_operand" "c"))
5478 (use (match_operand:SI 4 "immediate_operand" "i"))
5479 (clobber (match_dup 1))
5480 (clobber (match_dup 2))
5481 (clobber (match_dup 3))]
5487 label = gen_label_rtx ();
5489 output_asm_insn (\"cld\", operands);
5490 output_asm_insn (AS2 (xor%L0,%0,%0), operands);
5491 output_asm_insn (\"repz\;cmps%B2\", operands);
5492 output_asm_insn (\"je %l0\", &label);
5494 xops[0] = operands[0];
5495 xops[1] = gen_rtx (MEM, QImode,
5496 gen_rtx (PLUS, SImode, operands[1], constm1_rtx));
5497 xops[2] = gen_rtx (MEM, QImode,
5498 gen_rtx (PLUS, SImode, operands[2], constm1_rtx));
5499 xops[3] = operands[3];
5501 output_asm_insn (AS2 (movz%B1%L0,%1,%0), xops);
5502 output_asm_insn (AS2 (movz%B2%L3,%2,%3), xops);
5504 output_asm_insn (AS2 (sub%L0,%3,%0), xops);
5505 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
5511 (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
5512 (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
5513 (use (match_operand:SI 2 "register_operand" "c"))
5514 (use (match_operand:SI 3 "immediate_operand" "i"))
5515 (clobber (match_dup 0))
5516 (clobber (match_dup 1))
5517 (clobber (match_dup 2))]
5523 cc_status.flags |= CC_NOT_SIGNED;
5525 xops[0] = gen_rtx (REG, QImode, 0);
5526 xops[1] = CONST0_RTX (QImode);
5528 output_asm_insn (\"cld\", operands);
5529 output_asm_insn (AS2 (test%B0,%1,%0), xops);
5530 return \"repz\;cmps%B2\";
5533 (define_expand "ffssi2"
5535 (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" ""))
5537 (set (match_operand:SI 0 "general_operand" "")
5538 (plus:SI (match_dup 2) (const_int 1)))]
5540 "operands[2] = gen_reg_rtx (SImode);")
5542 ;; Note, you cannot optimize away the branch following the bsfl by assuming
5543 ;; that the destination is not modified if the input is 0, since not all
5544 ;; x86 implementations do this.
5547 [(set (match_operand:SI 0 "general_operand" "=&r")
5548 (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" "rm"))
5554 static int ffssi_label_number;
5557 xops[0] = operands[0];
5558 xops[1] = operands[1];
5559 xops[2] = constm1_rtx;
5560 output_asm_insn (AS2 (bsf%L0,%1,%0), xops);
5561 #ifdef LOCAL_LABEL_PREFIX
5562 sprintf (buffer, \"jnz %sLFFSSI%d\",
5563 LOCAL_LABEL_PREFIX, ffssi_label_number);
5565 sprintf (buffer, \"jnz %sLFFSSI%d\",
5566 \"\", ffssi_label_number);
5568 output_asm_insn (buffer, xops);
5569 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
5570 #ifdef LOCAL_LABEL_PREFIX
5571 sprintf (buffer, \"%sLFFSSI%d:\",
5572 LOCAL_LABEL_PREFIX, ffssi_label_number);
5574 sprintf (buffer, \"%sLFFSSI%d:\",
5575 \"\", ffssi_label_number);
5577 output_asm_insn (buffer, xops);
5579 ffssi_label_number++;
5583 (define_expand "ffshi2"
5585 (plus:HI (ffs:HI (match_operand:HI 1 "general_operand" ""))
5587 (set (match_operand:HI 0 "general_operand" "")
5588 (plus:HI (match_dup 2) (const_int 1)))]
5590 "operands[2] = gen_reg_rtx (HImode);")
5593 [(set (match_operand:HI 0 "general_operand" "=&r")
5594 (plus:HI (ffs:HI (match_operand:SI 1 "general_operand" "rm"))
5600 static int ffshi_label_number;
5603 xops[0] = operands[0];
5604 xops[1] = operands[1];
5605 xops[2] = constm1_rtx;
5606 output_asm_insn (AS2 (bsf%W0,%1,%0), xops);
5607 #ifdef LOCAL_LABEL_PREFIX
5608 sprintf (buffer, \"jnz %sLFFSHI%d\",
5609 LOCAL_LABEL_PREFIX, ffshi_label_number);
5611 sprintf (buffer, \"jnz %sLFFSHI%d\",
5612 \"\", ffshi_label_number);
5614 output_asm_insn (buffer, xops);
5615 output_asm_insn (AS2 (mov%W0,%2,%0), xops);
5616 #ifdef LOCAL_LABEL_PREFIX
5617 sprintf (buffer, \"%sLFFSHI%d:\",
5618 LOCAL_LABEL_PREFIX, ffshi_label_number);
5620 sprintf (buffer, \"%sLFFSHI%d:\",
5621 \"\", ffshi_label_number);
5623 output_asm_insn (buffer, xops);
5625 ffshi_label_number++;
5629 ;; These patterns match the binary 387 instructions for addM3, subM3,
5630 ;; mulM3 and divM3. There are three patterns for each of DFmode and
5631 ;; SFmode. The first is the normal insn, the second the same insn but
5632 ;; with one operand a conversion, and the third the same insn but with
5633 ;; the other operand a conversion. The conversion may be SFmode or
5634 ;; SImode if the target mode DFmode, but only SImode if the target mode
5638 [(set (match_operand:DF 0 "register_operand" "=f,f")
5639 (match_operator:DF 3 "binary_387_op"
5640 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
5641 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
5643 "* return output_387_binary_op (insn, operands);")
5646 [(set (match_operand:DF 0 "register_operand" "=f")
5647 (match_operator:DF 3 "binary_387_op"
5648 [(float:DF (match_operand:SI 1 "general_operand" "rm"))
5649 (match_operand:DF 2 "general_operand" "0")]))]
5651 "* return output_387_binary_op (insn, operands);")
5654 [(set (match_operand:XF 0 "register_operand" "=f,f")
5655 (match_operator:XF 3 "binary_387_op"
5656 [(match_operand:XF 1 "nonimmediate_operand" "0,f")
5657 (match_operand:XF 2 "nonimmediate_operand" "f,0")]))]
5659 "* return output_387_binary_op (insn, operands);")
5662 [(set (match_operand:XF 0 "register_operand" "=f")
5663 (match_operator:XF 3 "binary_387_op"
5664 [(float:XF (match_operand:SI 1 "general_operand" "rm"))
5665 (match_operand:XF 2 "general_operand" "0")]))]
5667 "* return output_387_binary_op (insn, operands);")
5670 [(set (match_operand:XF 0 "register_operand" "=f,f")
5671 (match_operator:XF 3 "binary_387_op"
5672 [(float_extend:XF (match_operand:SF 1 "general_operand" "fm,0"))
5673 (match_operand:XF 2 "general_operand" "0,f")]))]
5675 "* return output_387_binary_op (insn, operands);")
5678 [(set (match_operand:XF 0 "register_operand" "=f")
5679 (match_operator:XF 3 "binary_387_op"
5680 [(match_operand:XF 1 "general_operand" "0")
5681 (float:XF (match_operand:SI 2 "general_operand" "rm"))]))]
5683 "* return output_387_binary_op (insn, operands);")
5686 [(set (match_operand:XF 0 "register_operand" "=f,f")
5687 (match_operator:XF 3 "binary_387_op"
5688 [(match_operand:XF 1 "general_operand" "0,f")
5690 (match_operand:SF 2 "general_operand" "fm,0"))]))]
5692 "* return output_387_binary_op (insn, operands);")
5695 [(set (match_operand:DF 0 "register_operand" "=f,f")
5696 (match_operator:DF 3 "binary_387_op"
5697 [(float_extend:DF (match_operand:SF 1 "general_operand" "fm,0"))
5698 (match_operand:DF 2 "general_operand" "0,f")]))]
5700 "* return output_387_binary_op (insn, operands);")
5703 [(set (match_operand:DF 0 "register_operand" "=f")
5704 (match_operator:DF 3 "binary_387_op"
5705 [(match_operand:DF 1 "general_operand" "0")
5706 (float:DF (match_operand:SI 2 "general_operand" "rm"))]))]
5708 "* return output_387_binary_op (insn, operands);")
5711 [(set (match_operand:DF 0 "register_operand" "=f,f")
5712 (match_operator:DF 3 "binary_387_op"
5713 [(match_operand:DF 1 "general_operand" "0,f")
5715 (match_operand:SF 2 "general_operand" "fm,0"))]))]
5717 "* return output_387_binary_op (insn, operands);")
5720 [(set (match_operand:SF 0 "register_operand" "=f,f")
5721 (match_operator:SF 3 "binary_387_op"
5722 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
5723 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
5725 "* return output_387_binary_op (insn, operands);")
5728 [(set (match_operand:SF 0 "register_operand" "=f")
5729 (match_operator:SF 3 "binary_387_op"
5730 [(float:SF (match_operand:SI 1 "general_operand" "rm"))
5731 (match_operand:SF 2 "general_operand" "0")]))]
5733 "* return output_387_binary_op (insn, operands);")
5736 [(set (match_operand:SF 0 "register_operand" "=f")
5737 (match_operator:SF 3 "binary_387_op"
5738 [(match_operand:SF 1 "general_operand" "0")
5739 (float:SF (match_operand:SI 2 "general_operand" "rm"))]))]
5741 "* return output_387_binary_op (insn, operands);")
5743 (define_expand "strlensi"
5744 [(parallel [(set (match_dup 4)
5745 (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
5746 (match_operand:QI 2 "register_operand" "")
5747 (match_operand:SI 3 "immediate_operand" "")] 0))
5748 (clobber (match_dup 1))])
5750 (not:SI (match_dup 4)))
5751 (set (match_operand:SI 0 "register_operand" "")
5752 (minus:SI (match_dup 5)
5757 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5758 operands[4] = gen_reg_rtx (SImode);
5759 operands[5] = gen_reg_rtx (SImode);
5762 ;; It might seem that operands 0 & 1 could use predicate register_operand.
5763 ;; But strength reduction might offset the MEM expression. So we let
5764 ;; reload put the address into %edi.
5767 [(set (match_operand:SI 0 "register_operand" "=&c")
5768 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
5769 (match_operand:QI 2 "register_operand" "a")
5770 (match_operand:SI 3 "immediate_operand" "i")] 0))
5771 (clobber (match_dup 1))]
5777 xops[0] = operands[0];
5778 xops[1] = constm1_rtx;
5779 output_asm_insn (\"cld\", operands);
5780 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
5781 return \"repnz\;scas%B2\";