1 ; GCC machine description for Intel X86.
2 ;; Copyright (C) 1988, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
5 ;; This file is part of GNU CC.
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
28 ;; updates for most instructions.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; the special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
52 ;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode.
53 ;; operand 0 is the memory address to scan.
54 ;; operand 1 is a register containing the value to scan for. The mode
55 ;; of the scas opcode will be the same as the mode of this operand.
56 ;; operand 2 is the known alignment of operand 0.
57 ;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT.
58 ;; operand 0 is the argument for `sin'.
59 ;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT.
60 ;; operand 0 is the argument for `cos'.
61 ;; 3 This is part of a `stack probe' operation. The mode of the UNSPEC is
62 ;; always SImode. operand 0 is the size of the stack allocation.
63 ;; 4 This is the source of a fake SET of the frame pointer which is used to
64 ;; prevent insns referencing it being scheduled across the initial
65 ;; decrement of the stack pointer.
66 ;; 5 This is a `bsf' operation.
68 ;; This shadows the processor_type enumeration, so changes must be made
69 ;; to i386.h at the same time.
71 (define_attr "type" "integer,idiv,imul,fld,fpop,fpdiv,fpmul"
72 (const_string "integer"))
76 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
77 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
79 ; pentiumpro has a reservation station with 5 ports
80 ; port 0 has integer, float add, integer divide, float divide, float
81 ; multiply, and shifter units.
82 ; port 1 has integer, and jump units.
83 ; port 2 has the load address generation unit
84 ; ports 3 and 4 have the store address generation units
86 ; pentium has two integer pipelines, the main u pipe and the secondary v pipe.
87 ; and a float pipeline
91 (define_function_unit "fp" 1 0
92 (and (eq_attr "type" "fpop") (eq_attr "cpu" "i386,i486"))
95 (define_function_unit "fp" 1 0
96 (and (eq_attr "type" "fpop") (eq_attr "cpu" "pentium,pentiumpro"))
99 (define_function_unit "fp" 1 0
100 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentium"))
103 (define_function_unit "fp" 1 0
104 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentiumpro"))
107 (define_function_unit "fp" 1 0
108 (and (eq_attr "type" "idiv") (eq_attr "cpu" "pentiumpro"))
111 (define_function_unit "fp" 1 0
112 (and (eq_attr "type" "imul") (eq_attr "cpu" "pentiumpro"))
115 (define_function_unit "fp" 1 0
116 (eq_attr "type" "fpdiv")
119 (define_function_unit "fp" 1 0
120 (eq_attr "type" "fld")
123 (define_function_unit "integer" 1 0
124 (and (eq_attr "type" "integer") (eq_attr "cpu" "!i386"))
128 ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
129 ;; But restricting MEM here would mean that gcc could not remove a redundant
130 ;; test in cases like "incl MEM / je TARGET".
132 ;; We don't want to allow a constant operand for test insns because
133 ;; (set (cc0) (const_int foo)) has no mode information. Such insns will
134 ;; be folded while optimizing anyway.
136 ;; All test insns have expanders that save the operands away without
137 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
138 ;; after the tstM or cmp) will actually emit the tstM or cmpM.
140 ;; Processor type -- this attribute must exactly match the processor_type
141 ;; enumeration in i386.h.
143 (define_attr "cpu" "i386,i486,pentium,pentiumpro"
144 (const (symbol_ref "ix86_cpu")))
146 (define_insn "tstsi_1"
148 (match_operand:SI 0 "nonimmediate_operand" "rm"))]
152 if (REG_P (operands[0]))
153 return AS2 (test%L0,%0,%0);
155 operands[1] = const0_rtx;
156 return AS2 (cmp%L0,%1,%0);
159 (define_expand "tstsi"
161 (match_operand:SI 0 "nonimmediate_operand" ""))]
165 i386_compare_gen = gen_tstsi_1;
166 i386_compare_op0 = operands[0];
170 (define_insn "tsthi_1"
172 (match_operand:HI 0 "nonimmediate_operand" "rm"))]
176 if (REG_P (operands[0]))
177 return AS2 (test%W0,%0,%0);
179 operands[1] = const0_rtx;
180 return AS2 (cmp%W0,%1,%0);
183 (define_expand "tsthi"
185 (match_operand:HI 0 "nonimmediate_operand" ""))]
189 i386_compare_gen = gen_tsthi_1;
190 i386_compare_op0 = operands[0];
194 (define_insn "tstqi_1"
196 (match_operand:QI 0 "nonimmediate_operand" "qm"))]
200 if (REG_P (operands[0]))
201 return AS2 (test%B0,%0,%0);
203 operands[1] = const0_rtx;
204 return AS2 (cmp%B0,%1,%0);
207 (define_expand "tstqi"
209 (match_operand:QI 0 "nonimmediate_operand" ""))]
213 i386_compare_gen = gen_tstqi_1;
214 i386_compare_op0 = operands[0];
218 (define_insn "tstsf_cc"
220 (match_operand:SF 0 "register_operand" "f"))
221 (clobber (match_scratch:HI 1 "=a"))]
222 "TARGET_80387 && ! TARGET_IEEE_FP"
225 if (! STACK_TOP_P (operands[0]))
228 output_asm_insn (\"ftst\", operands);
230 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
231 output_asm_insn (AS1 (fstp,%y0), operands);
233 return output_fp_cc0_set (insn);
236 ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
237 ;; isn't IEEE compliant.
239 (define_expand "tstsf"
240 [(parallel [(set (cc0)
241 (match_operand:SF 0 "register_operand" ""))
242 (clobber (match_scratch:HI 1 ""))])]
243 "TARGET_80387 && ! TARGET_IEEE_FP"
246 i386_compare_gen = gen_tstsf_cc;
247 i386_compare_op0 = operands[0];
251 (define_insn "tstdf_cc"
253 (match_operand:DF 0 "register_operand" "f"))
254 (clobber (match_scratch:HI 1 "=a"))]
255 "TARGET_80387 && ! TARGET_IEEE_FP"
258 if (! STACK_TOP_P (operands[0]))
261 output_asm_insn (\"ftst\", operands);
263 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
264 output_asm_insn (AS1 (fstp,%y0), operands);
266 return output_fp_cc0_set (insn);
269 ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
270 ;; isn't IEEE compliant.
272 (define_expand "tstdf"
273 [(parallel [(set (cc0)
274 (match_operand:DF 0 "register_operand" ""))
275 (clobber (match_scratch:HI 1 ""))])]
276 "TARGET_80387 && ! TARGET_IEEE_FP"
279 i386_compare_gen = gen_tstdf_cc;
280 i386_compare_op0 = operands[0];
284 (define_insn "tstxf_cc"
286 (match_operand:XF 0 "register_operand" "f"))
287 (clobber (match_scratch:HI 1 "=a"))]
288 "TARGET_80387 && ! TARGET_IEEE_FP"
291 if (! STACK_TOP_P (operands[0]))
294 output_asm_insn (\"ftst\", operands);
296 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
297 output_asm_insn (AS1 (fstp,%y0), operands);
299 return output_fp_cc0_set (insn);
302 ;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode
303 ;; isn't IEEE compliant.
305 (define_expand "tstxf"
306 [(parallel [(set (cc0)
307 (match_operand:XF 0 "register_operand" ""))
308 (clobber (match_scratch:HI 1 ""))])]
309 "TARGET_80387 && ! TARGET_IEEE_FP"
312 i386_compare_gen = gen_tstxf_cc;
313 i386_compare_op0 = operands[0];
317 ;;- compare instructions. See comments above tstM patterns about
318 ;; expansion of these insns.
320 (define_insn "cmpsi_1"
322 (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
323 (match_operand:SI 1 "general_operand" "ri,mr")))]
324 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
327 if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
329 cc_status.flags |= CC_REVERSED;
330 return AS2 (cmp%L0,%0,%1);
332 return AS2 (cmp%L0,%1,%0);
335 (define_expand "cmpsi"
337 (compare (match_operand:SI 0 "nonimmediate_operand" "")
338 (match_operand:SI 1 "general_operand" "")))]
342 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
343 operands[0] = force_reg (SImode, operands[0]);
345 i386_compare_gen = gen_cmpsi_1;
346 i386_compare_op0 = operands[0];
347 i386_compare_op1 = operands[1];
351 (define_insn "cmphi_1"
353 (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
354 (match_operand:HI 1 "general_operand" "ri,mr")))]
355 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
358 if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
360 cc_status.flags |= CC_REVERSED;
361 return AS2 (cmp%W0,%0,%1);
363 return AS2 (cmp%W0,%1,%0);
366 (define_expand "cmphi"
368 (compare (match_operand:HI 0 "nonimmediate_operand" "")
369 (match_operand:HI 1 "general_operand" "")))]
373 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
374 operands[0] = force_reg (HImode, operands[0]);
376 i386_compare_gen = gen_cmphi_1;
377 i386_compare_op0 = operands[0];
378 i386_compare_op1 = operands[1];
382 (define_insn "cmpqi_1"
384 (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
385 (match_operand:QI 1 "general_operand" "qm,nq")))]
386 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
389 if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
391 cc_status.flags |= CC_REVERSED;
392 return AS2 (cmp%B0,%0,%1);
394 return AS2 (cmp%B0,%1,%0);
397 (define_expand "cmpqi"
399 (compare (match_operand:QI 0 "nonimmediate_operand" "")
400 (match_operand:QI 1 "general_operand" "")))]
404 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
405 operands[0] = force_reg (QImode, operands[0]);
407 i386_compare_gen = gen_cmpqi_1;
408 i386_compare_op0 = operands[0];
409 i386_compare_op1 = operands[1];
413 ;; These implement float point compares. For each of DFmode and
414 ;; SFmode, there is the normal insn, and an insn where the second operand
415 ;; is converted to the desired mode.
419 (match_operator 2 "VOIDmode_compare_op"
420 [(match_operand:XF 0 "register_operand" "f")
421 (match_operand:XF 1 "register_operand" "f")]))
422 (clobber (match_scratch:HI 3 "=a"))]
424 "* return output_float_compare (insn, operands);")
428 (match_operator 2 "VOIDmode_compare_op"
429 [(match_operand:XF 0 "register_operand" "f")
431 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
432 (clobber (match_scratch:HI 3 "=a"))]
434 "* return output_float_compare (insn, operands);")
438 (match_operator 2 "VOIDmode_compare_op"
440 (match_operand:SI 0 "nonimmediate_operand" "rm"))
441 (match_operand:XF 1 "register_operand" "f")]))
442 (clobber (match_scratch:HI 3 "=a"))]
444 "* return output_float_compare (insn, operands);")
448 (match_operator 2 "VOIDmode_compare_op"
449 [(match_operand:XF 0 "register_operand" "f")
451 (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
452 (clobber (match_scratch:HI 3 "=a"))]
454 "* return output_float_compare (insn, operands);")
458 (match_operator 2 "VOIDmode_compare_op"
460 (match_operand:DF 1 "nonimmediate_operand" "fm"))
461 (match_operand:XF 0 "register_operand" "f")]))
462 (clobber (match_scratch:HI 3 "=a"))]
464 "* return output_float_compare (insn, operands);")
468 (match_operator 2 "VOIDmode_compare_op"
469 [(match_operand:XF 0 "register_operand" "f")
471 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
472 (clobber (match_scratch:HI 3 "=a"))]
474 "* return output_float_compare (insn, operands);")
478 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
479 (match_operand:XF 1 "register_operand" "f")))
480 (clobber (match_scratch:HI 2 "=a"))]
482 "* return output_float_compare (insn, operands);")
486 (match_operator 2 "VOIDmode_compare_op"
487 [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
488 (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
489 (clobber (match_scratch:HI 3 "=a,a"))]
491 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
492 "* return output_float_compare (insn, operands);")
496 (match_operator 2 "VOIDmode_compare_op"
497 [(match_operand:DF 0 "register_operand" "f")
499 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
500 (clobber (match_scratch:HI 3 "=a"))]
502 "* return output_float_compare (insn, operands);")
506 (match_operator 2 "VOIDmode_compare_op"
508 (match_operand:SI 0 "nonimmediate_operand" "rm"))
509 (match_operand:DF 1 "register_operand" "f")]))
510 (clobber (match_scratch:HI 3 "=a"))]
512 "* return output_float_compare (insn, operands);")
516 (match_operator 2 "VOIDmode_compare_op"
517 [(match_operand:DF 0 "register_operand" "f")
519 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
520 (clobber (match_scratch:HI 3 "=a"))]
522 "* return output_float_compare (insn, operands);")
526 (match_operator 2 "VOIDmode_compare_op"
528 (match_operand:SF 0 "nonimmediate_operand" "fm"))
529 (match_operand:DF 1 "register_operand" "f")]))
530 (clobber (match_scratch:HI 3 "=a"))]
532 "* return output_float_compare (insn, operands);")
536 (match_operator 2 "VOIDmode_compare_op"
538 (match_operand:SF 0 "register_operand" "f"))
539 (match_operand:DF 1 "nonimmediate_operand" "fm")]))
540 (clobber (match_scratch:HI 3 "=a"))]
542 "* return output_float_compare (insn, operands);")
546 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
547 (match_operand:DF 1 "register_operand" "f")))
548 (clobber (match_scratch:HI 2 "=a"))]
550 "* return output_float_compare (insn, operands);")
552 ;; These two insns will never be generated by combine due to the mode of
556 ; (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
558 ; (match_operand:SF 1 "register_operand" "f"))))
559 ; (clobber (match_scratch:HI 2 "=a"))]
561 ; "* return output_float_compare (insn, operands);")
565 ; (compare:CCFPEQ (float_extend:DF
566 ; (match_operand:SF 0 "register_operand" "f"))
567 ; (match_operand:DF 1 "register_operand" "f")))
568 ; (clobber (match_scratch:HI 2 "=a"))]
570 ; "* return output_float_compare (insn, operands);")
572 (define_insn "cmpsf_cc_1"
574 (match_operator 2 "VOIDmode_compare_op"
575 [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
576 (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
577 (clobber (match_scratch:HI 3 "=a,a"))]
579 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
580 "* return output_float_compare (insn, operands);")
584 (match_operator 2 "VOIDmode_compare_op"
585 [(match_operand:SF 0 "register_operand" "f")
587 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
588 (clobber (match_scratch:HI 3 "=a"))]
590 "* return output_float_compare (insn, operands);")
594 (match_operator 2 "VOIDmode_compare_op"
596 (match_operand:SI 0 "nonimmediate_operand" "rm"))
597 (match_operand:SF 1 "register_operand" "f")]))
598 (clobber (match_scratch:HI 3 "=a"))]
600 "* return output_float_compare (insn, operands);")
604 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
605 (match_operand:SF 1 "register_operand" "f")))
606 (clobber (match_scratch:HI 2 "=a"))]
608 "* return output_float_compare (insn, operands);")
610 (define_expand "cmpxf"
612 (compare (match_operand:XF 0 "register_operand" "")
613 (match_operand:XF 1 "register_operand" "")))]
617 i386_compare_gen = gen_cmpxf_cc;
618 i386_compare_gen_eq = gen_cmpxf_ccfpeq;
619 i386_compare_op0 = operands[0];
620 i386_compare_op1 = operands[1];
624 (define_expand "cmpdf"
626 (compare (match_operand:DF 0 "register_operand" "")
627 (match_operand:DF 1 "general_operand" "")))]
631 i386_compare_gen = gen_cmpdf_cc;
632 i386_compare_gen_eq = gen_cmpdf_ccfpeq;
633 i386_compare_op0 = operands[0];
634 i386_compare_op1 = (immediate_operand (operands[1], DFmode))
635 ? copy_to_mode_reg (DFmode, operands[1]) : operands[1];
639 (define_expand "cmpsf"
641 (compare (match_operand:SF 0 "register_operand" "")
642 (match_operand:SF 1 "general_operand" "")))]
646 i386_compare_gen = gen_cmpsf_cc;
647 i386_compare_gen_eq = gen_cmpsf_ccfpeq;
648 i386_compare_op0 = operands[0];
649 i386_compare_op1 = (immediate_operand (operands[1], SFmode))
650 ? copy_to_mode_reg (SFmode, operands[1]) : operands[1];
654 (define_expand "cmpxf_cc"
655 [(parallel [(set (cc0)
656 (compare (match_operand:XF 0 "register_operand" "")
657 (match_operand:XF 1 "register_operand" "")))
658 (clobber (match_scratch:HI 2 ""))])]
662 (define_expand "cmpxf_ccfpeq"
663 [(parallel [(set (cc0)
664 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
665 (match_operand:XF 1 "register_operand" "")))
666 (clobber (match_scratch:HI 2 ""))])]
670 (define_expand "cmpdf_cc"
671 [(parallel [(set (cc0)
672 (compare (match_operand:DF 0 "register_operand" "")
673 (match_operand:DF 1 "register_operand" "")))
674 (clobber (match_scratch:HI 2 ""))])]
678 (define_expand "cmpdf_ccfpeq"
679 [(parallel [(set (cc0)
680 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
681 (match_operand:DF 1 "register_operand" "")))
682 (clobber (match_scratch:HI 2 ""))])]
686 if (! register_operand (operands[1], DFmode))
687 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
690 (define_expand "cmpsf_cc"
691 [(parallel [(set (cc0)
692 (compare (match_operand:SF 0 "register_operand" "")
693 (match_operand:SF 1 "register_operand" "")))
694 (clobber (match_scratch:HI 2 ""))])]
698 (define_expand "cmpsf_ccfpeq"
699 [(parallel [(set (cc0)
700 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
701 (match_operand:SF 1 "register_operand" "")))
702 (clobber (match_scratch:HI 2 ""))])]
706 if (! register_operand (operands[1], SFmode))
707 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
714 (and:SI (match_operand:SI 0 "general_operand" "%ro")
715 (match_operand:SI 1 "nonmemory_operand" "ri")))]
719 /* For small integers, we may actually use testb. */
720 if (GET_CODE (operands[1]) == CONST_INT
721 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
722 && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
724 /* We may set the sign bit spuriously. */
726 if ((INTVAL (operands[1]) & ~0xff) == 0)
728 cc_status.flags |= CC_NOT_NEGATIVE;
729 return AS2 (test%B0,%1,%b0);
732 if ((INTVAL (operands[1]) & ~0xff00) == 0)
734 cc_status.flags |= CC_NOT_NEGATIVE;
735 operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
737 if (QI_REG_P (operands[0]))
738 return AS2 (test%B0,%1,%h0);
741 operands[0] = adj_offsettable_operand (operands[0], 1);
742 return AS2 (test%B0,%1,%b0);
746 if (GET_CODE (operands[0]) == MEM
747 && (INTVAL (operands[1]) & ~0xff0000) == 0)
749 cc_status.flags |= CC_NOT_NEGATIVE;
750 operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
751 operands[0] = adj_offsettable_operand (operands[0], 2);
752 return AS2 (test%B0,%1,%b0);
755 if (GET_CODE (operands[0]) == MEM
756 && (INTVAL (operands[1]) & ~0xff000000) == 0)
758 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
759 operands[0] = adj_offsettable_operand (operands[0], 3);
760 return AS2 (test%B0,%1,%b0);
764 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
765 return AS2 (test%L0,%1,%0);
767 return AS2 (test%L1,%0,%1);
772 (and:HI (match_operand:HI 0 "general_operand" "%ro")
773 (match_operand:HI 1 "nonmemory_operand" "ri")))]
777 if (GET_CODE (operands[1]) == CONST_INT
778 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
779 && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
781 if ((INTVAL (operands[1]) & 0xff00) == 0)
783 /* ??? This might not be necessary. */
784 if (INTVAL (operands[1]) & 0xffff0000)
785 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
787 /* We may set the sign bit spuriously. */
788 cc_status.flags |= CC_NOT_NEGATIVE;
789 return AS2 (test%B0,%1,%b0);
792 if ((INTVAL (operands[1]) & 0xff) == 0)
794 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
796 if (QI_REG_P (operands[0]))
797 return AS2 (test%B0,%1,%h0);
800 operands[0] = adj_offsettable_operand (operands[0], 1);
801 return AS2 (test%B0,%1,%b0);
806 /* use 32-bit test instruction if there are no sign issues */
807 if (GET_CODE (operands[1]) == CONST_INT
808 && !(INTVAL (operands[1]) & ~0x7fff)
809 && i386_aligned_p (operands[0]))
810 return AS2 (test%L0,%1,%k0);
812 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
813 return AS2 (test%W0,%1,%0);
815 return AS2 (test%W1,%0,%1);
820 (and:QI (match_operand:QI 0 "nonimmediate_operand" "%qm")
821 (match_operand:QI 1 "nonmemory_operand" "qi")))]
825 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
826 return AS2 (test%B0,%1,%0);
828 return AS2 (test%B1,%0,%1);
831 ;; move instructions.
832 ;; There is one for each machine mode,
833 ;; and each is preceded by a corresponding push-insn pattern
834 ;; (since pushes are not general_operands on the 386).
837 [(set (match_operand:SI 0 "push_operand" "=<")
838 (match_operand:SI 1 "nonmemory_operand" "rn"))]
840 "* return AS1 (push%L0,%1);")
843 [(set (match_operand:SI 0 "push_operand" "=<")
844 (match_operand:SI 1 "nonmemory_operand" "ri"))]
846 "* return AS1 (push%L0,%1);")
848 ;; On a 386, it is faster to push MEM directly.
851 [(set (match_operand:SI 0 "push_operand" "=<")
852 (match_operand:SI 1 "memory_operand" "m"))]
854 "* return AS1 (push%L0,%1);")
856 ;; General case of fullword move.
858 ;; If generating PIC code and operands[1] is a symbolic CONST, emit a
859 ;; move to get the address of the symbolic object from the GOT.
861 (define_expand "movsi"
862 [(set (match_operand:SI 0 "general_operand" "")
863 (match_operand:SI 1 "general_operand" ""))]
869 if (flag_pic && SYMBOLIC_CONST (operands[1]))
870 emit_pic_move (operands, SImode);
872 /* Don't generate memory->memory moves, go through a register */
874 && (reload_in_progress | reload_completed) == 0
875 && GET_CODE (operands[0]) == MEM
876 && GET_CODE (operands[1]) == MEM)
878 operands[1] = force_reg (SImode, operands[1]);
882 ;; On i486, incl reg is faster than movl $1,reg.
885 [(set (match_operand:SI 0 "general_operand" "=g,r")
886 (match_operand:SI 1 "general_operand" "rn,im"))]
887 "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
888 || (GET_CODE (operands[1]) != MEM))
893 if (operands[1] == const0_rtx && REG_P (operands[0]))
894 return AS2 (xor%L0,%0,%0);
896 if (operands[1] == const1_rtx
897 && (link = find_reg_note (insn, REG_WAS_0, 0))
898 /* Make sure the insn that stored the 0 is still present. */
899 && ! INSN_DELETED_P (XEXP (link, 0))
900 && GET_CODE (XEXP (link, 0)) != NOTE
901 /* Make sure cross jumping didn't happen here. */
902 && no_labels_between_p (XEXP (link, 0), insn)
903 /* Make sure the reg hasn't been clobbered. */
904 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
905 /* Fastest way to change a 0 to a 1. */
906 return AS1 (inc%L0,%0);
908 if (SYMBOLIC_CONST (operands[1]))
909 return AS2 (lea%L0,%a1,%0);
911 return AS2 (mov%L0,%1,%0);
915 [(set (match_operand:SI 0 "general_operand" "=g,r")
916 (match_operand:SI 1 "general_operand" "ri,m"))]
917 "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
918 || (GET_CODE (operands[1]) != MEM))
923 if (operands[1] == const0_rtx && REG_P (operands[0]))
924 return AS2 (xor%L0,%0,%0);
926 if (operands[1] == const1_rtx
927 && (link = find_reg_note (insn, REG_WAS_0, 0))
928 /* Make sure the insn that stored the 0 is still present. */
929 && ! INSN_DELETED_P (XEXP (link, 0))
930 && GET_CODE (XEXP (link, 0)) != NOTE
931 /* Make sure cross jumping didn't happen here. */
932 && no_labels_between_p (XEXP (link, 0), insn)
933 /* Make sure the reg hasn't been clobbered. */
934 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
935 /* Fastest way to change a 0 to a 1. */
936 return AS1 (inc%L0,%0);
938 return AS2 (mov%L0,%1,%0);
942 [(set (match_operand:HI 0 "push_operand" "=<")
943 (match_operand:HI 1 "nonmemory_operand" "ri"))]
945 "* return AS1 (push%W0,%1);")
948 [(set (match_operand:HI 0 "push_operand" "=<")
949 (match_operand:HI 1 "memory_operand" "m"))]
951 "* return AS1 (push%W0,%1);")
953 ;; On i486, an incl and movl are both faster than incw and movw.
955 (define_expand "movhi"
956 [(set (match_operand:HI 0 "general_operand" "")
957 (match_operand:HI 1 "general_operand" ""))]
961 /* Don't generate memory->memory moves, go through a register */
963 && (reload_in_progress | reload_completed) == 0
964 && GET_CODE (operands[0]) == MEM
965 && GET_CODE (operands[1]) == MEM)
967 operands[1] = force_reg (HImode, operands[1]);
972 [(set (match_operand:HI 0 "general_operand" "=g,r")
973 (match_operand:HI 1 "general_operand" "ri,m"))]
974 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
978 if (REG_P (operands[0]) && operands[1] == const0_rtx)
979 return AS2 (xor%L0,%k0,%k0);
981 if (REG_P (operands[0]) && operands[1] == const1_rtx
982 && (link = find_reg_note (insn, REG_WAS_0, 0))
983 /* Make sure the insn that stored the 0 is still present. */
984 && ! INSN_DELETED_P (XEXP (link, 0))
985 && GET_CODE (XEXP (link, 0)) != NOTE
986 /* Make sure cross jumping didn't happen here. */
987 && no_labels_between_p (XEXP (link, 0), insn)
988 /* Make sure the reg hasn't been clobbered. */
989 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
990 /* Fastest way to change a 0 to a 1. */
991 return AS1 (inc%L0,%k0);
993 if (REG_P (operands[0]))
995 if (i386_aligned_p (operands[1]))
997 operands[1] = i386_sext16_if_const (operands[1]);
998 return AS2 (mov%L0,%k1,%k0);
1000 if (TARGET_PENTIUMPRO)
1002 /* movzwl is faster than movw on the Pentium Pro,
1003 * although not as fast as an aligned movl. */
1005 return AS2 (movzx,%1,%k0);
1007 return AS2 (movz%W0%L0,%1,%k0);
1012 return AS2 (mov%W0,%1,%0);
1015 (define_expand "movstricthi"
1016 [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
1017 (match_operand:HI 1 "general_operand" ""))]
1021 /* Don't generate memory->memory moves, go through a register */
1023 && (reload_in_progress | reload_completed) == 0
1024 && GET_CODE (operands[0]) == MEM
1025 && GET_CODE (operands[1]) == MEM)
1027 operands[1] = force_reg (HImode, operands[1]);
1032 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
1033 (match_operand:HI 1 "general_operand" "ri,m"))]
1034 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1038 if (operands[1] == const0_rtx && REG_P (operands[0]))
1039 return AS2 (xor%W0,%0,%0);
1041 if (operands[1] == const1_rtx
1042 && (link = find_reg_note (insn, REG_WAS_0, 0))
1043 /* Make sure the insn that stored the 0 is still present. */
1044 && ! INSN_DELETED_P (XEXP (link, 0))
1045 && GET_CODE (XEXP (link, 0)) != NOTE
1046 /* Make sure cross jumping didn't happen here. */
1047 && no_labels_between_p (XEXP (link, 0), insn)
1048 /* Make sure the reg hasn't been clobbered. */
1049 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1050 /* Fastest way to change a 0 to a 1. */
1051 return AS1 (inc%W0,%0);
1053 return AS2 (mov%W0,%1,%0);
1056 ;; emit_push_insn when it calls move_by_pieces
1057 ;; requires an insn to "push a byte".
1058 ;; But actually we use pushw, which has the effect of rounding
1059 ;; the amount pushed up to a halfword.
1061 [(set (match_operand:QI 0 "push_operand" "=<")
1062 (match_operand:QI 1 "const_int_operand" "n"))]
1064 "* return AS1(push%W0,%1);")
1067 [(set (match_operand:QI 0 "push_operand" "=<")
1068 (match_operand:QI 1 "register_operand" "q"))]
1072 operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]));
1073 return AS1 (push%W0,%1);
1076 ;; On i486, incb reg is faster than movb $1,reg.
1078 ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
1079 ;; or writes %ah, %bh, %ch, %dh.
1081 (define_expand "movqi"
1082 [(set (match_operand:QI 0 "general_operand" "")
1083 (match_operand:QI 1 "general_operand" ""))]
1087 /* Don't generate memory->memory moves, go through a register */
1089 && (reload_in_progress | reload_completed) == 0
1090 && GET_CODE (operands[0]) == MEM
1091 && GET_CODE (operands[1]) == MEM)
1093 operands[1] = force_reg (QImode, operands[1]);
1098 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,*r,qm")
1099 (match_operand:QI 1 "general_operand" "*g,*rn,qn"))]
1100 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1104 if (operands[1] == const0_rtx && REG_P (operands[0]))
1105 return AS2 (xor%L0,%k0,%k0);
1107 if (operands[1] == const1_rtx
1108 && (link = find_reg_note (insn, REG_WAS_0, 0))
1109 /* Make sure the insn that stored the 0 is still present. */
1110 && ! INSN_DELETED_P (XEXP (link, 0))
1111 && GET_CODE (XEXP (link, 0)) != NOTE
1112 /* Make sure cross jumping didn't happen here. */
1113 && no_labels_between_p (XEXP (link, 0), insn)
1114 /* Make sure the reg hasn't been clobbered. */
1115 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1116 /* Fastest way to change a 0 to a 1. */
1117 return AS1 (inc%B0,%0);
1119 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1120 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1121 return (AS2 (mov%L0,%k1,%k0));
1123 return (AS2 (mov%B0,%1,%0));
1126 ;; If it becomes necessary to support movstrictqi into %esi or %edi,
1127 ;; use the insn sequence:
1129 ;; shrdl $8,srcreg,dstreg
1132 ;; If operands[1] is a constant, then an andl/orl sequence would be
1135 (define_expand "movstrictqi"
1136 [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
1137 (match_operand:QI 1 "general_operand" ""))]
1141 /* Don't generate memory->memory moves, go through a register */
1143 && (reload_in_progress | reload_completed) == 0
1144 && GET_CODE (operands[0]) == MEM
1145 && GET_CODE (operands[1]) == MEM)
1147 operands[1] = force_reg (QImode, operands[1]);
1152 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1153 (match_operand:QI 1 "general_operand" "*qn,m"))]
1154 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1158 if (operands[1] == const0_rtx && REG_P (operands[0]))
1159 return AS2 (xor%B0,%0,%0);
1161 if (operands[1] == const1_rtx
1162 && (link = find_reg_note (insn, REG_WAS_0, 0))
1163 /* Make sure the insn that stored the 0 is still present. */
1164 && ! INSN_DELETED_P (XEXP (link, 0))
1165 && GET_CODE (XEXP (link, 0)) != NOTE
1166 /* Make sure cross jumping didn't happen here. */
1167 && no_labels_between_p (XEXP (link, 0), insn)
1168 /* Make sure the reg hasn't been clobbered. */
1169 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1170 /* Fastest way to change a 0 to a 1. */
1171 return AS1 (inc%B0,%0);
1173 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1174 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1177 return (AS2 (mov%L0,%k1,%k0));
1180 return AS2 (mov%B0,%1,%0);
1183 (define_expand "movsf"
1184 [(set (match_operand:SF 0 "general_operand" "")
1185 (match_operand:SF 1 "general_operand" ""))]
1189 /* Special case memory->memory moves and pushes */
1191 && (reload_in_progress | reload_completed) == 0
1192 && GET_CODE (operands[0]) == MEM
1193 && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], SFmode)))
1195 rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], SFmode))
1199 emit_insn ((*genfunc) (operands[0], operands[1]));
1203 /* If we are loading a floating point constant that isn't 0 or 1
1204 into a register, indicate we need the pic register loaded. This could
1205 be optimized into stores of constants if the target eventually moves
1206 to memory, but better safe than sorry. */
1207 if ((reload_in_progress | reload_completed) == 0
1208 && GET_CODE (operands[0]) != MEM
1209 && GET_CODE (operands[1]) == CONST_DOUBLE
1210 && !standard_80387_constant_p (operands[1]))
1212 rtx insn, note, fp_const;
1214 fp_const = force_const_mem (SFmode, operands[1]);
1216 current_function_uses_pic_offset_table = 1;
1218 insn = emit_insn (gen_rtx_SET (SFmode, operands[0], fp_const));
1219 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
1222 XEXP (note, 0) = operands[1];
1224 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn));
1228 (define_insn "movsf_push_nomove"
1229 [(set (match_operand:SF 0 "push_operand" "=<,<")
1230 (match_operand:SF 1 "general_operand" "gF,f"))]
1234 if (STACK_REG_P (operands[1]))
1238 if (! STACK_TOP_P (operands[1]))
1241 xops[0] = AT_SP (SFmode);
1242 xops[1] = GEN_INT (4);
1243 xops[2] = stack_pointer_rtx;
1245 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1247 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1248 output_asm_insn (AS1 (fstp%S0,%0), xops);
1250 output_asm_insn (AS1 (fst%S0,%0), xops);
1253 return AS1 (push%L1,%1);
1256 (define_insn "movsf_push"
1257 [(set (match_operand:SF 0 "push_operand" "=<,<,<,<")
1258 (match_operand:SF 1 "general_operand" "rF,f,m,m"))
1259 (clobber (match_scratch:SI 2 "=X,X,r,X"))]
1263 if (STACK_REG_P (operands[1]))
1267 if (! STACK_TOP_P (operands[1]))
1270 xops[0] = AT_SP (SFmode);
1271 xops[1] = GEN_INT (4);
1272 xops[2] = stack_pointer_rtx;
1274 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1276 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1277 output_asm_insn (AS1 (fstp%S0,%0), xops);
1279 output_asm_insn (AS1 (fst%S0,%0), xops);
1283 else if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != REG)
1284 return AS1 (push%L1,%1);
1288 output_asm_insn (AS2 (mov%L2,%1,%2), operands);
1289 return AS1 (push%L2,%2);
1293 ;; Special memory<->memory pattern that combine will recreate from the
1294 ;; moves to pseudos.
1295 (define_insn "movsf_mem"
1296 [(set (match_operand:SF 0 "memory_operand" "=m")
1297 (match_operand:SF 1 "memory_operand" "m"))
1298 (clobber (match_scratch:SI 2 "=&r"))]
1302 output_asm_insn (AS2 (mov%L2,%1,%2), operands);
1303 return AS2 (mov%L0,%2,%0);
1306 ;; For the purposes of regclass, prefer FLOAT_REGS.
1307 (define_insn "movsf_normal"
1308 [(set (match_operand:SF 0 "nonimmediate_operand" "=*rfm,*rf,f,!*rm")
1309 (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
1310 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1313 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1315 /* First handle a `pop' insn or a `fld %st(0)' */
1317 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1320 return AS1 (fstp,%y0);
1322 return AS1 (fld,%y0);
1325 /* Handle a transfer between the 387 and a 386 register */
1327 if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
1329 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1333 if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
1335 output_to_reg (operands[0], stack_top_dies, 0);
1339 /* Handle other kinds of writes from the 387 */
1341 if (STACK_TOP_P (operands[1]))
1344 return AS1 (fstp%z0,%y0);
1346 return AS1 (fst%z0,%y0);
1349 /* Handle other kinds of reads to the 387 */
1351 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1352 return output_move_const_single (operands);
1354 if (STACK_TOP_P (operands[0]))
1355 return AS1 (fld%z1,%y1);
1357 /* Handle all SFmode moves not involving the 387 */
1359 return singlemove_string (operands);
1361 [(set_attr "type" "fld")])
1364 (define_insn "swapsf"
1365 [(set (match_operand:SF 0 "register_operand" "f")
1366 (match_operand:SF 1 "register_operand" "f"))
1372 if (STACK_TOP_P (operands[0]))
1373 return AS1 (fxch,%1);
1375 return AS1 (fxch,%0);
1378 (define_expand "movdf"
1379 [(set (match_operand:DF 0 "general_operand" "")
1380 (match_operand:DF 1 "general_operand" ""))]
1384 /* Special case memory->memory moves and pushes */
1386 && (reload_in_progress | reload_completed) == 0
1387 && GET_CODE (operands[0]) == MEM
1388 && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], DFmode)))
1390 rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], DFmode))
1394 emit_insn ((*genfunc) (operands[0], operands[1]));
1398 /* If we are loading a floating point constant that isn't 0 or 1 into a
1399 register, indicate we need the pic register loaded. This could be
1400 optimized into stores of constants if the target eventually moves to
1401 memory, but better safe than sorry. */
1402 if ((reload_in_progress | reload_completed) == 0
1403 && GET_CODE (operands[0]) != MEM
1404 && GET_CODE (operands[1]) == CONST_DOUBLE
1405 && !standard_80387_constant_p (operands[1]))
1407 rtx insn, note, fp_const;
1409 fp_const = force_const_mem (DFmode, operands[1]);
1411 current_function_uses_pic_offset_table = 1;
1413 insn = emit_insn (gen_rtx_SET (DFmode, operands[0], fp_const));
1414 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
1417 XEXP (note, 0) = operands[1];
1419 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn));
1423 (define_insn "movdf_push_nomove"
1424 [(set (match_operand:DF 0 "push_operand" "=<,<")
1425 (match_operand:DF 1 "general_operand" "gF,f"))]
1429 if (STACK_REG_P (operands[1]))
1433 xops[0] = AT_SP (SFmode);
1434 xops[1] = GEN_INT (8);
1435 xops[2] = stack_pointer_rtx;
1437 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1439 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1440 output_asm_insn (AS1 (fstp%Q0,%0), xops);
1442 output_asm_insn (AS1 (fst%Q0,%0), xops);
1447 return output_move_double (operands);
1450 (define_insn "movdf_push"
1451 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<")
1452 (match_operand:DF 1 "general_operand" "rF,f,o,o,o"))
1453 (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
1454 (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
1458 if (STACK_REG_P (operands[1]))
1462 xops[0] = AT_SP (SFmode);
1463 xops[1] = GEN_INT (8);
1464 xops[2] = stack_pointer_rtx;
1466 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1468 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1469 output_asm_insn (AS1 (fstp%Q0,%0), xops);
1471 output_asm_insn (AS1 (fst%Q0,%0), xops);
1476 else if (GET_CODE (operands[1]) != MEM)
1477 return output_move_double (operands);
1480 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);
1483 (define_insn "movdf_mem"
1484 [(set (match_operand:DF 0 "memory_operand" "=o,o")
1485 (match_operand:DF 1 "memory_operand" "o,o"))
1486 (clobber (match_scratch:SI 2 "=&r,&r"))
1487 (clobber (match_scratch:SI 3 "=&r,X"))]
1489 "* return output_move_memory (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);")
1491 ;; For the purposes of regclass, prefer FLOAT_REGS.
1493 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
1494 (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
1495 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1496 || (GET_CODE (operands[1]) != MEM)"
1499 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1501 /* First handle a `pop' insn or a `fld %st(0)' */
1503 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1506 return AS1 (fstp,%y0);
1508 return AS1 (fld,%y0);
1511 /* Handle a transfer between the 387 and a 386 register */
1513 if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
1515 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1519 if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
1521 output_to_reg (operands[0], stack_top_dies, 0);
1525 /* Handle other kinds of writes from the 387 */
1527 if (STACK_TOP_P (operands[1]))
1530 return AS1 (fstp%z0,%y0);
1532 return AS1 (fst%z0,%y0);
1535 /* Handle other kinds of reads to the 387 */
1537 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1538 return output_move_const_single (operands);
1540 if (STACK_TOP_P (operands[0]))
1541 return AS1 (fld%z1,%y1);
1543 /* Handle all DFmode moves not involving the 387 */
1545 return output_move_double (operands);
1547 [(set_attr "type" "fld")])
1551 (define_insn "swapdf"
1552 [(set (match_operand:DF 0 "register_operand" "f")
1553 (match_operand:DF 1 "register_operand" "f"))
1559 if (STACK_TOP_P (operands[0]))
1560 return AS1 (fxch,%1);
1562 return AS1 (fxch,%0);
1565 (define_expand "movxf"
1566 [(set (match_operand:XF 0 "general_operand" "")
1567 (match_operand:XF 1 "general_operand" ""))]
1571 /* Special case memory->memory moves and pushes */
1573 && (reload_in_progress | reload_completed) == 0
1574 && GET_CODE (operands[0]) == MEM
1575 && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], XFmode)))
1577 rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], XFmode))
1581 emit_insn ((*genfunc) (operands[0], operands[1]));
1585 /* If we are loading a floating point constant that isn't 0 or 1
1586 into a register, indicate we need the pic register loaded. This could
1587 be optimized into stores of constants if the target eventually moves
1588 to memory, but better safe than sorry. */
1589 if ((reload_in_progress | reload_completed) == 0
1590 && GET_CODE (operands[0]) != MEM
1591 && GET_CODE (operands[1]) == CONST_DOUBLE
1592 && !standard_80387_constant_p (operands[1]))
1594 rtx insn, note, fp_const;
1596 fp_const = force_const_mem (XFmode, operands[1]);
1598 current_function_uses_pic_offset_table = 1;
1600 insn = emit_insn (gen_rtx_SET (XFmode, operands[0], fp_const));
1601 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
1604 XEXP (note, 0) = operands[1];
1606 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn));
1611 (define_insn "movxf_push_nomove"
1612 [(set (match_operand:XF 0 "push_operand" "=<,<")
1613 (match_operand:XF 1 "general_operand" "gF,f"))]
1617 if (STACK_REG_P (operands[1]))
1621 xops[0] = AT_SP (SFmode);
1622 xops[1] = GEN_INT (12);
1623 xops[2] = stack_pointer_rtx;
1625 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1626 output_asm_insn (AS1 (fstp%T0,%0), xops);
1627 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1628 output_asm_insn (AS1 (fld%T0,%0), xops);
1633 return output_move_double (operands);
1636 (define_insn "movxf_push"
1637 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
1638 (match_operand:XF 1 "general_operand" "rF,f,o,o,o"))
1639 (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
1640 (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
1644 if (STACK_REG_P (operands[1]))
1648 xops[0] = AT_SP (SFmode);
1649 xops[1] = GEN_INT (12);
1650 xops[2] = stack_pointer_rtx;
1652 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1653 output_asm_insn (AS1 (fstp%T0,%0), xops);
1654 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1655 output_asm_insn (AS1 (fld%T0,%0), xops);
1660 else if (GET_CODE (operands[1]) != MEM
1661 || GET_CODE (operands[2]) != REG)
1662 return output_move_double (operands);
1665 return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);
1668 (define_insn "movxf_mem"
1669 [(set (match_operand:XF 0 "memory_operand" "=o,o")
1670 (match_operand:XF 1 "memory_operand" "o,o"))
1671 (clobber (match_scratch:SI 2 "=&r,&r"))
1672 (clobber (match_scratch:SI 3 "=&r,X"))]
1674 "* return output_move_memory (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);")
1677 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
1678 (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
1679 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1680 || (GET_CODE (operands[1]) != MEM)"
1683 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1685 /* First handle a `pop' insn or a `fld %st(0)' */
1687 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1690 return AS1 (fstp,%y0);
1692 return AS1 (fld,%y0);
1695 /* Handle a transfer between the 387 and a 386 register */
1697 if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
1699 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1703 if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
1705 output_to_reg (operands[0], stack_top_dies, 0);
1709 /* Handle other kinds of writes from the 387 */
1711 if (STACK_TOP_P (operands[1]))
1713 output_asm_insn (AS1 (fstp%z0,%y0), operands);
1714 if (! stack_top_dies)
1715 return AS1 (fld%z0,%y0);
1720 /* Handle other kinds of reads to the 387 */
1722 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1723 return output_move_const_single (operands);
1725 if (STACK_TOP_P (operands[0]))
1726 return AS1 (fld%z1,%y1);
1728 /* Handle all XFmode moves not involving the 387 */
1730 return output_move_double (operands);
1733 (define_insn "swapxf"
1734 [(set (match_operand:XF 0 "register_operand" "f")
1735 (match_operand:XF 1 "register_operand" "f"))
1741 if (STACK_TOP_P (operands[0]))
1742 return AS1 (fxch,%1);
1744 return AS1 (fxch,%0);
1748 [(set (match_operand:DI 0 "push_operand" "=<,<,<,<")
1749 (match_operand:DI 1 "general_operand" "riF,o,o,o"))
1750 (clobber (match_scratch:SI 2 "=X,&r,&r,X"))
1751 (clobber (match_scratch:SI 3 "=X,&r,X,X"))]
1755 if (GET_CODE (operands[1]) != MEM)
1756 return output_move_double (operands);
1759 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
1762 (define_insn "movdi"
1763 [(set (match_operand:DI 0 "general_operand" "=o,o,r,rm")
1764 (match_operand:DI 1 "general_operand" "o,o,m,riF"))
1765 (clobber (match_scratch:SI 2 "=&r,&r,X,X"))
1766 (clobber (match_scratch:SI 3 "=&r,X,X,X"))]
1770 rtx low[2], high[2], xop[6];
1772 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1773 return output_move_double (operands);
1775 return output_move_memory (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
1779 ;;- conversion instructions
1782 ;;- zero extension instructions
1783 ;; See comments by `andsi' for when andl is faster than movzx.
1785 (define_insn "zero_extendhisi2"
1786 [(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
1787 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
1793 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1794 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1796 xops[0] = operands[0];
1797 xops[1] = GEN_INT (0xffff);
1798 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1801 if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1]))
1803 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1804 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1808 if (TARGET_ZERO_EXTEND_WITH_AND)
1810 xops[0] = operands[0];
1811 xops[1] = GEN_INT (0xffff);
1812 if (i386_aligned_p (operands[1]))
1813 output_asm_insn (AS2 (mov%L0,%k1,%k0),operands);
1815 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1816 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1821 return AS2 (movzx,%1,%0);
1823 return AS2 (movz%W0%L0,%1,%0);
1828 [(set (match_operand:SI 0 "register_operand" "")
1829 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1830 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])"
1833 (set (strict_low_part (match_dup 2))
1835 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1839 [(set (match_operand:SI 0 "register_operand" "")
1840 (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))]
1841 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])"
1842 [(set (strict_low_part (match_dup 2))
1845 (and:SI (match_dup 0)
1846 (const_int 65535)))]
1847 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1849 (define_insn "zero_extendqihi2"
1850 [(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
1851 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1857 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1858 && REG_P (operands[1])
1859 && REGNO (operands[0]) == REGNO (operands[1]))
1861 xops[0] = operands[0];
1862 xops[1] = GEN_INT (0xff);
1863 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1866 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1868 if(!reg_overlap_mentioned_p(operands[0],operands[1]))
1870 output_asm_insn (AS2 (xor%L0,%k0,%k0), operands);
1871 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1875 xops[0] = operands[0];
1876 xops[1] = GEN_INT (0xff);
1877 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1878 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1884 return AS2 (movzx,%1,%0);
1886 return AS2 (movz%B0%W0,%1,%0);
1891 [(set (match_operand:HI 0 "register_operand" "")
1892 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1893 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1894 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1897 (set (strict_low_part (match_dup 2))
1899 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1903 [(set (match_operand:HI 0 "register_operand" "")
1904 (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))]
1905 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1906 && reg_overlap_mentioned_p (operands[0], operands[1])"
1907 [(set (strict_low_part (match_dup 2))
1910 (and:HI (match_dup 0)
1912 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1915 [(set (match_operand:HI 0 "register_operand" "")
1916 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1917 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND"
1921 (and:HI (match_dup 0)
1923 "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0)
1924 operands[1] = SUBREG_REG (operands[1]);
1925 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG
1926 || REGNO (operands[0]) == REGNO (operands[1]))
1928 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));")
1930 (define_insn "zero_extendqisi2"
1931 [(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
1932 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1938 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1939 && REG_P (operands[1])
1940 && REGNO (operands[0]) == REGNO (operands[1]))
1942 xops[0] = operands[0];
1943 xops[1] = GEN_INT (0xff);
1944 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1947 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1949 if(!reg_overlap_mentioned_p (operands[0], operands[1]))
1951 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1952 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1956 xops[0] = operands[0];
1957 xops[1] = GEN_INT (0xff);
1958 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1959 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1964 if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG)
1966 xops[0] = operands[0];
1967 xops[1] = GEN_INT (0xff);
1968 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
1969 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
1970 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1975 return AS2 (movzx,%1,%0);
1977 return AS2 (movz%B0%L0,%1,%0);
1982 [(set (match_operand:SI 0 "register_operand" "")
1983 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1984 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1985 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1988 (set (strict_low_part (match_dup 2))
1990 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1994 [(set (match_operand:SI 0 "register_operand" "")
1995 (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))]
1996 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1997 && reg_overlap_mentioned_p (operands[0], operands[1])"
1998 [(set (strict_low_part (match_dup 2))
2001 (and:SI (match_dup 0)
2003 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2006 [(set (match_operand:SI 0 "register_operand" "")
2007 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2008 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
2009 && ! reg_overlap_mentioned_p (operands[0], operands[1])"
2013 (and:SI (match_dup 0)
2015 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
2017 (define_insn "zero_extendsidi2"
2018 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m")
2019 (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))]
2023 rtx high[2], low[2], xops[4];
2025 if (REG_P (operands[0]) && REG_P (operands[1])
2026 && REGNO (operands[0]) == REGNO (operands[1]))
2028 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2029 return AS2 (xor%L0,%0,%0);
2032 split_di (operands, 1, low, high);
2034 xops[1] = operands[1];
2036 xops[3] = const0_rtx;
2038 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2039 if (GET_CODE (low[0]) == MEM)
2040 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
2042 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
2047 ;;- sign extension instructions
2049 (define_insn "extendsidi2"
2050 [(set (match_operand:DI 0 "register_operand" "=r")
2051 (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))]
2055 if (REGNO (operands[0]) == 0)
2057 /* This used to be cwtl, but that extends HI to SI somehow. */
2065 operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2066 output_asm_insn (AS2 (mov%L0,%0,%1), operands);
2068 operands[0] = GEN_INT (31);
2069 return AS2 (sar%L1,%0,%1);
2072 ;; Note that the i386 programmers' manual says that the opcodes
2073 ;; are named movsx..., but the assembler on Unix does not accept that.
2074 ;; We use what the Unix assembler expects.
2076 (define_insn "extendhisi2"
2077 [(set (match_operand:SI 0 "register_operand" "=r")
2078 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2082 if (REGNO (operands[0]) == 0
2083 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
2091 return AS2 (movsx,%1,%0);
2093 return AS2 (movs%W0%L0,%1,%0);
2097 (define_insn "extendqihi2"
2098 [(set (match_operand:HI 0 "register_operand" "=r")
2099 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2103 if (REGNO (operands[0]) == 0
2104 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
2108 return AS2 (movsx,%1,%0);
2110 return AS2 (movs%B0%W0,%1,%0);
2114 (define_insn "extendqisi2"
2115 [(set (match_operand:SI 0 "register_operand" "=r")
2116 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2121 return AS2 (movsx,%1,%0);
2123 return AS2 (movs%B0%L0,%1,%0);
2128 ;; Truncation of long long -> 32 bit
2130 (define_expand "truncdisi2"
2131 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2132 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2136 /* Don't generate memory->memory moves, go through a register */
2138 && (reload_in_progress | reload_completed) == 0
2139 && GET_CODE (operands[0]) == MEM
2140 && GET_CODE (operands[1]) == MEM)
2142 rtx target = gen_reg_rtx (SImode);
2143 emit_insn (gen_truncdisi2 (target, operands[1]));
2144 emit_move_insn (operands[0], target);
2150 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2151 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2152 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2155 rtx low[2], high[2], xops[2];
2157 split_di (&operands[1], 1, low, high);
2158 xops[0] = operands[0];
2160 if (!rtx_equal_p (xops[0], xops[1]))
2161 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2167 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2168 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
2170 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2173 rtx low[2], high[2], xops[2];
2175 split_di (&operands[1], 1, low, high);
2176 xops[0] = operands[0];
2178 if (!rtx_equal_p (xops[0], xops[1]))
2179 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2186 ;; Conversions between float and double.
2188 (define_insn "extendsfdf2"
2189 [(set (match_operand:DF 0 "nonimmediate_operand" "=fm,f")
2191 (match_operand:SF 1 "nonimmediate_operand" "f,fm")))]
2195 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2197 if (NON_STACK_REG_P (operands[1]))
2199 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2203 if (NON_STACK_REG_P (operands[0]))
2205 output_to_reg (operands[0], stack_top_dies, 0);
2209 if (STACK_TOP_P (operands[0]))
2210 return AS1 (fld%z1,%y1);
2212 if (GET_CODE (operands[0]) == MEM)
2215 return AS1 (fstp%z0,%y0);
2217 return AS1 (fst%z0,%y0);
2223 (define_insn "extenddfxf2"
2224 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
2226 (match_operand:DF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
2230 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2232 if (NON_STACK_REG_P (operands[1]))
2234 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2238 if (NON_STACK_REG_P (operands[0]))
2240 output_to_reg (operands[0], stack_top_dies, 0);
2244 if (STACK_TOP_P (operands[0]))
2245 return AS1 (fld%z1,%y1);
2247 if (GET_CODE (operands[0]) == MEM)
2249 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2250 if (! stack_top_dies)
2251 return AS1 (fld%z0,%y0);
2258 (define_insn "extendsfxf2"
2259 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
2261 (match_operand:SF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
2265 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2267 if (NON_STACK_REG_P (operands[1]))
2269 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2273 if (NON_STACK_REG_P (operands[0]))
2275 output_to_reg (operands[0], stack_top_dies, 0);
2279 if (STACK_TOP_P (operands[0]))
2280 return AS1 (fld%z1,%y1);
2282 if (GET_CODE (operands[0]) == MEM)
2284 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2285 if (! stack_top_dies)
2286 return AS1 (fld%z0,%y0);
2293 (define_expand "truncdfsf2"
2294 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2296 (match_operand:DF 1 "register_operand" "")))
2297 (clobber (match_dup 2))])]
2301 operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2304 ;; This cannot output into an f-reg because there is no way to be sure
2305 ;; of truncating in that case. Otherwise this is just like a simple move
2306 ;; insn. So we pretend we can output to a reg in order to get better
2307 ;; register preferencing, but we really use a stack slot.
2310 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
2312 (match_operand:DF 1 "register_operand" "0,f")))
2313 (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
2317 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2319 if (GET_CODE (operands[0]) == MEM)
2322 return AS1 (fstp%z0,%0);
2324 return AS1 (fst%z0,%0);
2326 else if (STACK_TOP_P (operands[0]))
2328 output_asm_insn (AS1 (fstp%z2,%y2), operands);
2329 return AS1 (fld%z2,%y2);
2335 (define_insn "truncxfsf2"
2336 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r")
2338 (match_operand:XF 1 "register_operand" "f,f")))]
2342 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2344 if (NON_STACK_REG_P (operands[0]))
2346 if (stack_top_dies == 0)
2348 output_asm_insn (AS1 (fld,%y1), operands);
2351 output_to_reg (operands[0], stack_top_dies, 0);
2354 else if (GET_CODE (operands[0]) == MEM)
2357 return AS1 (fstp%z0,%0);
2360 output_asm_insn (AS1 (fld,%y1), operands);
2361 return AS1 (fstp%z0,%0);
2368 (define_insn "truncxfdf2"
2369 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!*r")
2371 (match_operand:XF 1 "register_operand" "f,f")))]
2375 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2377 if (NON_STACK_REG_P (operands[0]))
2379 if (stack_top_dies == 0)
2381 output_asm_insn (AS1 (fld,%y1), operands);
2384 output_to_reg (operands[0], stack_top_dies, 0);
2387 else if (GET_CODE (operands[0]) == MEM)
2390 return AS1 (fstp%z0,%0);
2393 output_asm_insn (AS1 (fld,%y1), operands);
2394 return AS1 (fstp%z0,%0);
2402 ;; The 387 requires that the stack top dies after converting to DImode.
2404 ;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
2405 ;; doing a signed conversion to DImode, and then taking just the low
2408 (define_expand "fixuns_truncxfsi2"
2410 (match_operand:XF 1 "register_operand" ""))
2411 (parallel [(set (match_dup 2)
2412 (fix:DI (fix:XF (match_dup 4))))
2413 (clobber (match_dup 4))
2414 (clobber (match_dup 5))
2415 (clobber (match_dup 6))
2416 (clobber (match_scratch:SI 7 ""))])
2417 (set (match_operand:SI 0 "general_operand" "")
2422 operands[2] = gen_reg_rtx (DImode);
2423 operands[3] = gen_lowpart (SImode, operands[2]);
2424 operands[4] = gen_reg_rtx (XFmode);
2425 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2426 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2429 (define_expand "fixuns_truncdfsi2"
2431 (match_operand:DF 1 "register_operand" ""))
2432 (parallel [(set (match_dup 2)
2433 (fix:DI (fix:DF (match_dup 4))))
2434 (clobber (match_dup 4))
2435 (clobber (match_dup 5))
2436 (clobber (match_dup 6))
2437 (clobber (match_scratch:SI 7 ""))])
2438 (set (match_operand:SI 0 "general_operand" "")
2443 operands[2] = gen_reg_rtx (DImode);
2444 operands[3] = gen_lowpart (SImode, operands[2]);
2445 operands[4] = gen_reg_rtx (DFmode);
2446 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2447 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2450 (define_expand "fixuns_truncsfsi2"
2452 (match_operand:SF 1 "register_operand" ""))
2453 (parallel [(set (match_dup 2)
2454 (fix:DI (fix:SF (match_dup 4))))
2455 (clobber (match_dup 4))
2456 (clobber (match_dup 5))
2457 (clobber (match_dup 6))
2458 (clobber (match_scratch:SI 7 ""))])
2459 (set (match_operand:SI 0 "general_operand" "")
2464 operands[2] = gen_reg_rtx (DImode);
2465 operands[3] = gen_lowpart (SImode, operands[2]);
2466 operands[4] = gen_reg_rtx (SFmode);
2467 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2468 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2471 ;; Signed conversion to DImode.
2473 (define_expand "fix_truncxfdi2"
2475 (match_operand:XF 1 "register_operand" ""))
2476 (parallel [(set (match_operand:DI 0 "general_operand" "")
2477 (fix:DI (fix:XF (match_dup 2))))
2478 (clobber (match_dup 2))
2479 (clobber (match_dup 3))
2480 (clobber (match_dup 4))
2481 (clobber (match_scratch:SI 5 ""))])]
2485 operands[1] = copy_to_mode_reg (XFmode, operands[1]);
2486 operands[2] = gen_reg_rtx (XFmode);
2487 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2488 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2491 (define_expand "fix_truncdfdi2"
2493 (match_operand:DF 1 "register_operand" ""))
2494 (parallel [(set (match_operand:DI 0 "general_operand" "")
2495 (fix:DI (fix:DF (match_dup 2))))
2496 (clobber (match_dup 2))
2497 (clobber (match_dup 3))
2498 (clobber (match_dup 4))
2499 (clobber (match_scratch:SI 5 ""))])]
2503 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
2504 operands[2] = gen_reg_rtx (DFmode);
2505 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2506 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2509 (define_expand "fix_truncsfdi2"
2511 (match_operand:SF 1 "register_operand" ""))
2512 (parallel [(set (match_operand:DI 0 "general_operand" "")
2513 (fix:DI (fix:SF (match_dup 2))))
2514 (clobber (match_dup 2))
2515 (clobber (match_dup 3))
2516 (clobber (match_dup 4))
2517 (clobber (match_scratch:SI 5 ""))])]
2521 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
2522 operands[2] = gen_reg_rtx (SFmode);
2523 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2524 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2527 ;; These match a signed conversion of either DFmode or SFmode to DImode.
2530 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2531 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
2532 (clobber (match_dup 1))
2533 (clobber (match_operand:SI 2 "memory_operand" "m"))
2534 (clobber (match_operand:DI 3 "memory_operand" "m"))
2535 (clobber (match_scratch:SI 4 "=&q"))]
2537 "* return output_fix_trunc (insn, operands);")
2540 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2541 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2542 (clobber (match_dup 1))
2543 (clobber (match_operand:SI 2 "memory_operand" "m"))
2544 (clobber (match_operand:DI 3 "memory_operand" "m"))
2545 (clobber (match_scratch:SI 4 "=&q"))]
2547 "* return output_fix_trunc (insn, operands);")
2550 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2551 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
2552 (clobber (match_dup 1))
2553 (clobber (match_operand:SI 2 "memory_operand" "m"))
2554 (clobber (match_operand:DI 3 "memory_operand" "m"))
2555 (clobber (match_scratch:SI 4 "=&q"))]
2557 "* return output_fix_trunc (insn, operands);")
2559 ;; Signed MODE_FLOAT conversion to SImode.
2561 (define_expand "fix_truncxfsi2"
2562 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2564 (fix:XF (match_operand:XF 1 "register_operand" ""))))
2565 (clobber (match_dup 2))
2566 (clobber (match_dup 3))
2567 (clobber (match_scratch:SI 4 ""))])]
2571 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2572 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2575 (define_expand "fix_truncdfsi2"
2576 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2578 (fix:DF (match_operand:DF 1 "register_operand" ""))))
2579 (clobber (match_dup 2))
2580 (clobber (match_dup 3))
2581 (clobber (match_scratch:SI 4 ""))])]
2585 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2586 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2589 (define_expand "fix_truncsfsi2"
2590 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2592 (fix:SF (match_operand:SF 1 "register_operand" ""))))
2593 (clobber (match_dup 2))
2594 (clobber (match_dup 3))
2595 (clobber (match_scratch:SI 4 ""))])]
2599 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2600 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2604 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2605 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
2606 (clobber (match_operand:SI 2 "memory_operand" "m"))
2607 (clobber (match_operand:DI 3 "memory_operand" "m"))
2608 (clobber (match_scratch:SI 4 "=&q"))]
2610 "* return output_fix_trunc (insn, operands);")
2613 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2614 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2615 (clobber (match_operand:SI 2 "memory_operand" "m"))
2616 (clobber (match_operand:DI 3 "memory_operand" "m"))
2617 (clobber (match_scratch:SI 4 "=&q"))]
2619 "* return output_fix_trunc (insn, operands);")
2622 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2623 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
2624 (clobber (match_operand:SI 2 "memory_operand" "m"))
2625 (clobber (match_operand:DI 3 "memory_operand" "m"))
2626 (clobber (match_scratch:SI 4 "=&q"))]
2628 "* return output_fix_trunc (insn, operands);")
2630 ;; Conversion between fixed point and floating point.
2631 ;; The actual pattern that matches these is at the end of this file.
2633 ;; ??? Possibly represent floatunssidf2 here in gcc2.
2635 (define_expand "floatsisf2"
2636 [(set (match_operand:SF 0 "register_operand" "")
2637 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
2641 (define_expand "floatdisf2"
2642 [(set (match_operand:SF 0 "register_operand" "")
2643 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
2647 (define_expand "floatsidf2"
2648 [(set (match_operand:DF 0 "register_operand" "")
2649 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
2653 (define_expand "floatdidf2"
2654 [(set (match_operand:DF 0 "register_operand" "")
2655 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
2659 (define_expand "floatsixf2"
2660 [(set (match_operand:XF 0 "register_operand" "")
2661 (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
2665 (define_expand "floatdixf2"
2666 [(set (match_operand:XF 0 "register_operand" "")
2667 (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
2668 "TARGET_80387 && LONG_DOUBLE_TYPE_SIZE == 96"
2671 ;; This will convert from SImode or DImode to MODE_FLOAT.
2674 [(set (match_operand:XF 0 "register_operand" "=f")
2675 (float:XF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2679 if (NON_STACK_REG_P (operands[1]))
2681 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2684 else if (GET_CODE (operands[1]) == MEM)
2685 return AS1 (fild%z1,%1);
2691 [(set (match_operand:DF 0 "register_operand" "=f")
2692 (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2696 if (NON_STACK_REG_P (operands[1]))
2698 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2701 else if (GET_CODE (operands[1]) == MEM)
2702 return AS1 (fild%z1,%1);
2708 [(set (match_operand:SF 0 "register_operand" "=f")
2709 (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2713 if (NON_STACK_REG_P (operands[1]))
2715 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2718 else if (GET_CODE (operands[1]) == MEM)
2719 return AS1 (fild%z1,%1);
2725 [(set (match_operand:DF 0 "register_operand" "=f")
2726 (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
2730 if (NON_STACK_REG_P (operands[1]))
2732 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2735 else if (GET_CODE (operands[1]) == MEM)
2736 return AS1 (fild%z1,%1);
2742 [(set (match_operand:XF 0 "register_operand" "=f,f")
2743 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!*r")))]
2747 if (NON_STACK_REG_P (operands[1]))
2749 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2752 else if (GET_CODE (operands[1]) == MEM)
2753 return AS1 (fild%z1,%1);
2759 [(set (match_operand:SF 0 "register_operand" "=f")
2760 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
2764 if (NON_STACK_REG_P (operands[1]))
2766 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2769 else if (GET_CODE (operands[1]) == MEM)
2770 return AS1 (fild%z1,%1);
2775 ;;- add instructions
2777 (define_insn "addsidi3_1"
2778 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o")
2779 (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o")
2780 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri"))))
2781 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))]
2785 rtx low[3], high[3], xops[7], temp;
2789 split_di (operands, 2, low, high);
2790 high[2] = const0_rtx;
2791 low[2] = operands[2];
2793 if (!rtx_equal_p (operands[0], operands[1]))
2800 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2802 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2803 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2809 xops[6] = operands[3];
2810 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2811 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2812 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2813 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2814 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2815 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2820 output_asm_insn (AS2 (add%L0,%2,%0), low);
2821 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2825 (define_insn "addsidi3_2"
2826 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o")
2827 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r"))
2828 (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o")))
2829 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))]
2833 rtx low[3], high[3], xops[7], temp;
2837 split_di (operands, 2, low, high);
2838 high[2] = const0_rtx;
2839 low[2] = operands[2];
2841 if (!rtx_equal_p (operands[0], operands[1]))
2848 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2850 if (rtx_equal_p (low[0], operands[2]))
2852 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2853 output_asm_insn (AS2 (add%L0,%1,%0), low);
2854 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2857 if (rtx_equal_p (high[0], operands[2]))
2859 if (GET_CODE (operands[0]) != MEM)
2861 output_asm_insn (AS2 (mov%L0,%2,%0), low);
2862 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2863 output_asm_insn (AS2 (add%L0,%1,%0), low);
2864 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2868 /* It's too late to ask for a scratch now - but this
2869 will probably not happen too often. */
2870 output_asm_insn (AS2 (add%L1,%2,%1), low);
2871 output_asm_insn (AS2 (mov%L0,%1,%0), low);
2872 output_asm_insn (AS2 (mov%L1,%2,%1), low);
2873 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2874 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2875 output_asm_insn (AS2 (sub%L1,%0,%1), low);
2876 output_asm_insn (AS1 (neg%L1,%1), low);
2880 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2881 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2887 xops[6] = operands[3];
2888 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2889 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2890 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2891 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2892 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2893 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2898 output_asm_insn (AS2 (add%L0,%2,%0), low);
2899 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2903 (define_insn "adddi3"
2904 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
2905 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
2906 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
2907 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
2911 rtx low[3], high[3], xops[7], temp;
2915 if (rtx_equal_p (operands[0], operands[2]))
2918 operands[1] = operands[2];
2922 split_di (operands, 3, low, high);
2923 if (!rtx_equal_p (operands[0], operands[1]))
2930 if (GET_CODE (operands[0]) != MEM)
2932 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2933 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2939 xops[6] = operands[3];
2940 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2941 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2942 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2943 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2944 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2945 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2950 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
2956 xops[4] = operands[3];
2958 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
2959 output_asm_insn (AS2 (add%L1,%4,%1), xops);
2960 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
2961 output_asm_insn (AS2 (adc%L0,%4,%0), xops);
2964 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
2966 output_asm_insn (AS2 (add%L0,%2,%0), low);
2967 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2971 output_asm_insn (AS2 (add%L0,%2,%0), high);
2976 ;; On a 486, it is faster to do movl/addl than to do a single leal if
2977 ;; operands[1] and operands[2] are both registers.
2979 (define_expand "addsi3"
2980 [(set (match_operand:SI 0 "nonimmediate_operand" "")
2981 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
2982 (match_operand:SI 2 "general_operand" "")))]
2984 "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);")
2987 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
2988 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
2989 (match_operand:SI 2 "general_operand" "rmi,ri,ri")))]
2990 "ix86_binary_operator_ok (PLUS, SImode, operands)"
2993 if (REG_P (operands[0]) && REG_P (operands[1])
2994 && (REG_P (operands[2]) || GET_CODE (operands[2]) == CONST_INT)
2995 && REGNO (operands[0]) != REGNO (operands[1]))
2997 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
2998 return AS2 (add%L0,%1,%0);
3000 if (operands[2] == stack_pointer_rtx)
3005 operands[1] = operands[2];
3009 if (operands[2] != stack_pointer_rtx)
3012 operands[1] = SET_SRC (PATTERN (insn));
3013 return AS2 (lea%L0,%a1,%0);
3017 if (!rtx_equal_p (operands[0], operands[1]))
3018 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
3020 if (operands[2] == const1_rtx)
3021 return AS1 (inc%L0,%0);
3023 if (operands[2] == constm1_rtx)
3024 return AS1 (dec%L0,%0);
3026 /* subl $-128,%ebx is smaller than addl $128,%ebx. */
3027 if (GET_CODE (operands[2]) == CONST_INT
3028 && INTVAL (operands[2]) == 128)
3030 /* This doesn't compute the carry bit in the same way
3031 * as add%L0, but we use inc and dec above and they
3032 * don't set the carry bit at all. If inc/dec don't need
3033 * a CC_STATUS_INIT, this doesn't either... */
3034 operands[2] = GEN_INT (-128);
3035 return AS2 (sub%L0,%2,%0);
3038 return AS2 (add%L0,%2,%0);
3041 ;; addsi3 is faster, so put this after.
3043 (define_insn "movsi_lea"
3044 [(set (match_operand:SI 0 "register_operand" "=r")
3045 (match_operand:QI 1 "address_operand" "p"))]
3049 /* Adding a constant to a register is faster with an add. */
3050 /* ??? can this ever happen? */
3051 if (GET_CODE (operands[1]) == PLUS
3052 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
3053 && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
3055 operands[1] = XEXP (operands[1], 1);
3057 if (operands[1] == const1_rtx)
3058 return AS1 (inc%L0,%0);
3060 if (operands[1] == constm1_rtx)
3061 return AS1 (dec%L0,%0);
3063 return AS2 (add%L0,%1,%0);
3067 return AS2 (lea%L0,%a1,%0);
3070 ;; ??? `lea' here, for three operand add? If leaw is used, only %bx,
3071 ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
3072 ;; able to handle the operand. But leal always works?
3074 (define_expand "addhi3"
3075 [(set (match_operand:HI 0 "general_operand" "")
3076 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3077 (match_operand:HI 2 "general_operand" "")))]
3079 "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);")
3082 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3083 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3084 (match_operand:HI 2 "general_operand" "ri,rm")))]
3085 "ix86_binary_operator_ok (PLUS, HImode, operands)"
3088 /* ??? what about offsettable memory references? */
3089 if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */
3090 && QI_REG_P (operands[0])
3091 && GET_CODE (operands[2]) == CONST_INT
3092 && (INTVAL (operands[2]) & 0xff) == 0
3093 && i386_cc_probably_useless_p (insn))
3095 int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
3099 return AS1 (inc%B0,%h0);
3100 else if (byteval == 255)
3101 return AS1 (dec%B0,%h0);
3103 operands[2] = GEN_INT (byteval);
3104 return AS2 (add%B0,%2,%h0);
3107 /* Use a 32-bit operation when possible, to avoid the prefix penalty. */
3108 if (REG_P (operands[0])
3109 && i386_aligned_p (operands[2])
3110 && i386_cc_probably_useless_p (insn))
3114 if (GET_CODE (operands[2]) == CONST_INT)
3116 HOST_WIDE_INT intval = 0xffff & INTVAL (operands[2]);
3119 return AS1 (inc%L0,%k0);
3121 if (intval == 0xffff)
3122 return AS1 (dec%L0,%k0);
3124 operands[2] = i386_sext16_if_const (operands[2]);
3126 return AS2 (add%L0,%k2,%k0);
3129 if (operands[2] == const1_rtx)
3130 return AS1 (inc%W0,%0);
3132 if (operands[2] == constm1_rtx
3133 || (GET_CODE (operands[2]) == CONST_INT
3134 && INTVAL (operands[2]) == 65535))
3135 return AS1 (dec%W0,%0);
3137 return AS2 (add%W0,%2,%0);
3140 (define_expand "addqi3"
3141 [(set (match_operand:QI 0 "general_operand" "")
3142 (plus:QI (match_operand:QI 1 "general_operand" "")
3143 (match_operand:QI 2 "general_operand" "")))]
3145 "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);")
3148 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3149 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3150 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3151 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3154 if (operands[2] == const1_rtx)
3155 return AS1 (inc%B0,%0);
3157 if (operands[2] == constm1_rtx
3158 || (GET_CODE (operands[2]) == CONST_INT
3159 && INTVAL (operands[2]) == 255))
3160 return AS1 (dec%B0,%0);
3162 return AS2 (add%B0,%2,%0);
3165 ;Lennart Augustsson <augustss@cs.chalmers.se>
3166 ;says this pattern just makes slower code:
3170 ; leal -80(%ebp),%eax
3174 ; [(set (match_operand:SI 0 "push_operand" "=<")
3175 ; (plus:SI (match_operand:SI 1 "register_operand" "%r")
3176 ; (match_operand:SI 2 "nonmemory_operand" "ri")))]
3181 ; xops[0] = operands[0];
3182 ; xops[1] = operands[1];
3183 ; xops[2] = operands[2];
3184 ; xops[3] = gen_rtx_MEM (SImode, stack_pointer_rtx);
3185 ; output_asm_insn (\"push%z1 %1\", xops);
3186 ; output_asm_insn (AS2 (add%z3,%2,%3), xops);
3190 ;; The patterns that match these are at the end of this file.
3192 (define_expand "addxf3"
3193 [(set (match_operand:XF 0 "register_operand" "")
3194 (plus:XF (match_operand:XF 1 "register_operand" "")
3195 (match_operand:XF 2 "register_operand" "")))]
3199 (define_expand "adddf3"
3200 [(set (match_operand:DF 0 "register_operand" "")
3201 (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3202 (match_operand:DF 2 "nonimmediate_operand" "")))]
3206 (define_expand "addsf3"
3207 [(set (match_operand:SF 0 "register_operand" "")
3208 (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3209 (match_operand:SF 2 "nonimmediate_operand" "")))]
3213 ;;- subtract instructions
3215 (define_insn "subsidi3"
3216 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o")
3217 (minus:DI (match_operand:DI 1 "general_operand" "0iF,0,roiF,roiF,riF,o,o")
3218 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,ri,i,r"))))
3219 (clobber (match_scratch:SI 3 "=X,X,X,X,X,&r,&r"))]
3223 rtx low[3], high[3], xops[7];
3227 split_di (operands, 2, low, high);
3228 high[2] = const0_rtx;
3229 low[2] = operands[2];
3231 if (!rtx_equal_p (operands[0], operands[1]))
3238 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3240 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3241 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3247 xops[6] = operands[3];
3248 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3249 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3250 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3251 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3252 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3253 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3258 output_asm_insn (AS2 (sub%L0,%2,%0), low);
3259 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3263 (define_insn "subdi3"
3264 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
3265 (minus:DI (match_operand:DI 1 "general_operand" "0,0,0iF,or,roiF,roiF")
3266 (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
3267 (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
3271 rtx low[3], high[3], xops[7];
3275 split_di (operands, 3, low, high);
3277 if (!rtx_equal_p (operands[0], operands[1]))
3284 if (GET_CODE (operands[0]) != MEM)
3286 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3287 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3293 xops[6] = operands[3];
3294 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3295 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3296 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3297 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3298 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3299 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3304 if (GET_CODE (operands[3]) == REG)
3310 xops[4] = operands[3];
3312 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3313 output_asm_insn (AS2 (sub%L1,%4,%1), xops);
3314 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3315 output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
3318 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
3320 output_asm_insn (AS2 (sub%L0,%2,%0), low);
3321 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3325 output_asm_insn (AS2 (sub%L0,%2,%0), high);
3330 (define_expand "subsi3"
3331 [(set (match_operand:SI 0 "nonimmediate_operand" "")
3332 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3333 (match_operand:SI 2 "general_operand" "")))]
3335 "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);")
3338 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3339 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
3340 (match_operand:SI 2 "general_operand" "ri,rm")))]
3341 "ix86_binary_operator_ok (MINUS, SImode, operands)"
3342 "* return AS2 (sub%L0,%2,%0);")
3344 (define_expand "subhi3"
3345 [(set (match_operand:HI 0 "general_operand" "")
3346 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3347 (match_operand:HI 2 "general_operand" "")))]
3349 "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);")
3352 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3353 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
3354 (match_operand:HI 2 "general_operand" "ri,rm")))]
3355 "ix86_binary_operator_ok (MINUS, HImode, operands)"
3358 if (REG_P (operands[0])
3359 && i386_aligned_p (operands[2])
3360 && i386_cc_probably_useless_p (insn))
3363 operands[2] = i386_sext16_if_const (operands[2]);
3364 return AS2 (sub%L0,%k2,%k0);
3366 return AS2 (sub%W0,%2,%0);
3369 (define_expand "subqi3"
3370 [(set (match_operand:QI 0 "general_operand" "")
3371 (minus:QI (match_operand:QI 1 "general_operand" "")
3372 (match_operand:QI 2 "general_operand" "")))]
3374 "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);")
3377 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3378 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
3379 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3380 "ix86_binary_operator_ok (MINUS, QImode, operands)"
3381 "* return AS2 (sub%B0,%2,%0);")
3383 ;; The patterns that match these are at the end of this file.
3385 (define_expand "subxf3"
3386 [(set (match_operand:XF 0 "register_operand" "")
3387 (minus:XF (match_operand:XF 1 "register_operand" "")
3388 (match_operand:XF 2 "register_operand" "")))]
3392 (define_expand "subdf3"
3393 [(set (match_operand:DF 0 "register_operand" "")
3394 (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3395 (match_operand:DF 2 "nonimmediate_operand" "")))]
3399 (define_expand "subsf3"
3400 [(set (match_operand:SF 0 "register_operand" "")
3401 (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3402 (match_operand:SF 2 "nonimmediate_operand" "")))]
3406 ;;- multiply instructions
3408 ;(define_insn "mulqi3"
3409 ; [(set (match_operand:QI 0 "register_operand" "=a")
3410 ; (mult:QI (match_operand:QI 1 "register_operand" "%0")
3411 ; (match_operand:QI 2 "nonimmediate_operand" "qm")))]
3415 (define_insn "mulhi3"
3416 [(set (match_operand:HI 0 "register_operand" "=r,r")
3417 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%0,rm")
3418 (match_operand:HI 2 "general_operand" "g,i")))]
3422 if (GET_CODE (operands[1]) == REG
3423 && REGNO (operands[1]) == REGNO (operands[0])
3424 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3425 /* Assembler has weird restrictions. */
3426 return AS2 (imul%W0,%2,%0);
3427 return AS3 (imul%W0,%2,%1,%0);
3429 [(set_attr "type" "imul")])
3431 (define_insn "mulsi3"
3432 [(set (match_operand:SI 0 "register_operand" "=r,r")
3433 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
3434 (match_operand:SI 2 "general_operand" "g,i")))]
3438 if (GET_CODE (operands[1]) == REG
3439 && REGNO (operands[1]) == REGNO (operands[0])
3440 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3441 /* Assembler has weird restrictions. */
3442 return AS2 (imul%L0,%2,%0);
3443 return AS3 (imul%L0,%2,%1,%0);
3445 [(set_attr "type" "imul")])
3447 (define_insn "umulqihi3"
3448 [(set (match_operand:HI 0 "register_operand" "=a")
3449 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3450 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3453 [(set_attr "type" "imul")])
3455 (define_insn "mulqihi3"
3456 [(set (match_operand:HI 0 "register_operand" "=a")
3457 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3458 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3461 [(set_attr "type" "imul")])
3463 (define_insn "umulsidi3"
3464 [(set (match_operand:DI 0 "register_operand" "=A")
3465 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3466 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
3467 "TARGET_WIDE_MULTIPLY"
3469 [(set_attr "type" "imul")])
3471 (define_insn "mulsidi3"
3472 [(set (match_operand:DI 0 "register_operand" "=A")
3473 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3474 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
3475 "TARGET_WIDE_MULTIPLY"
3477 [(set_attr "type" "imul")])
3479 (define_insn "umulsi3_highpart"
3480 [(set (match_operand:SI 0 "register_operand" "=d")
3481 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
3482 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
3484 (clobber (match_scratch:SI 3 "=a"))]
3485 "TARGET_WIDE_MULTIPLY"
3487 [(set_attr "type" "imul")])
3489 (define_insn "smulsi3_highpart"
3490 [(set (match_operand:SI 0 "register_operand" "=d")
3491 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
3492 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
3494 (clobber (match_scratch:SI 3 "=a"))]
3495 "TARGET_WIDE_MULTIPLY"
3497 [(set_attr "type" "imul")])
3499 ;; The patterns that match these are at the end of this file.
3501 (define_expand "mulxf3"
3502 [(set (match_operand:XF 0 "register_operand" "")
3503 (mult:XF (match_operand:XF 1 "register_operand" "")
3504 (match_operand:XF 2 "register_operand" "")))]
3508 (define_expand "muldf3"
3509 [(set (match_operand:DF 0 "register_operand" "")
3510 (mult:DF (match_operand:DF 1 "register_operand" "")
3511 (match_operand:DF 2 "nonimmediate_operand" "")))]
3515 (define_expand "mulsf3"
3516 [(set (match_operand:SF 0 "register_operand" "")
3517 (mult:SF (match_operand:SF 1 "register_operand" "")
3518 (match_operand:SF 2 "nonimmediate_operand" "")))]
3522 ;;- divide instructions
3524 (define_insn "divqi3"
3525 [(set (match_operand:QI 0 "register_operand" "=a")
3526 (div:QI (match_operand:HI 1 "register_operand" "0")
3527 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
3531 (define_insn "udivqi3"
3532 [(set (match_operand:QI 0 "register_operand" "=a")
3533 (udiv:QI (match_operand:HI 1 "register_operand" "0")
3534 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
3537 [(set_attr "type" "idiv")])
3539 ;; The patterns that match these are at the end of this file.
3541 (define_expand "divxf3"
3542 [(set (match_operand:XF 0 "register_operand" "")
3543 (div:XF (match_operand:XF 1 "register_operand" "")
3544 (match_operand:XF 2 "register_operand" "")))]
3548 (define_expand "divdf3"
3549 [(set (match_operand:DF 0 "register_operand" "")
3550 (div:DF (match_operand:DF 1 "register_operand" "")
3551 (match_operand:DF 2 "nonimmediate_operand" "")))]
3555 (define_expand "divsf3"
3556 [(set (match_operand:SF 0 "register_operand" "")
3557 (div:SF (match_operand:SF 1 "register_operand" "")
3558 (match_operand:SF 2 "nonimmediate_operand" "")))]
3562 ;; Remainder instructions.
3564 (define_insn "divmodsi4"
3565 [(set (match_operand:SI 0 "register_operand" "=a")
3566 (div:SI (match_operand:SI 1 "register_operand" "0")
3567 (match_operand:SI 2 "nonimmediate_operand" "rm")))
3568 (set (match_operand:SI 3 "register_operand" "=&d")
3569 (mod:SI (match_dup 1) (match_dup 2)))]
3574 output_asm_insn (\"cdq\", operands);
3576 output_asm_insn (\"cltd\", operands);
3578 return AS1 (idiv%L0,%2);
3580 [(set_attr "type" "idiv")])
3582 (define_insn "divmodhi4"
3583 [(set (match_operand:HI 0 "register_operand" "=a")
3584 (div:HI (match_operand:HI 1 "register_operand" "0")
3585 (match_operand:HI 2 "nonimmediate_operand" "rm")))
3586 (set (match_operand:HI 3 "register_operand" "=&d")
3587 (mod:HI (match_dup 1) (match_dup 2)))]
3590 [(set_attr "type" "idiv")])
3592 ;; ??? Can we make gcc zero extend operand[0]?
3593 (define_insn "udivmodsi4"
3594 [(set (match_operand:SI 0 "register_operand" "=a")
3595 (udiv:SI (match_operand:SI 1 "register_operand" "0")
3596 (match_operand:SI 2 "nonimmediate_operand" "rm")))
3597 (set (match_operand:SI 3 "register_operand" "=&d")
3598 (umod:SI (match_dup 1) (match_dup 2)))]
3602 output_asm_insn (AS2 (xor%L3,%3,%3), operands);
3603 return AS1 (div%L0,%2);
3605 [(set_attr "type" "idiv")])
3607 ;; ??? Can we make gcc zero extend operand[0]?
3608 (define_insn "udivmodhi4"
3609 [(set (match_operand:HI 0 "register_operand" "=a")
3610 (udiv:HI (match_operand:HI 1 "register_operand" "0")
3611 (match_operand:HI 2 "nonimmediate_operand" "rm")))
3612 (set (match_operand:HI 3 "register_operand" "=&d")
3613 (umod:HI (match_dup 1) (match_dup 2)))]
3617 output_asm_insn (AS2 (xor%W0,%3,%3), operands);
3618 return AS1 (div%W0,%2);
3620 [(set_attr "type" "idiv")])
3623 ;;this should be a valid double division which we may want to add
3626 [(set (match_operand:SI 0 "register_operand" "=a")
3627 (udiv:DI (match_operand:DI 1 "register_operand" "a")
3628 (match_operand:SI 2 "nonimmediate_operand" "rm")))
3629 (set (match_operand:SI 3 "register_operand" "=d")
3630 (umod:SI (match_dup 1) (match_dup 2)))]
3633 [(set_attr "type" "idiv")])
3636 ;;- and instructions
3643 ;; but if the reg is %eax, then the "andl" is faster.
3645 ;; On i486, the "andl" is always faster than the "movzbl".
3647 ;; On both i386 and i486, a three operand AND is as fast with movzbl or
3648 ;; movzwl as with andl, if operands[0] != operands[1].
3650 ;; The `r' in `rm' for operand 3 looks redundant, but it causes
3651 ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
3653 (define_insn "andsi3"
3654 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3655 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3656 (match_operand:SI 2 "general_operand" "ri,rm")))]
3660 HOST_WIDE_INT intval;
3661 if (!rtx_equal_p (operands[0], operands[1])
3662 && rtx_equal_p (operands[0], operands[2]))
3666 operands[1] = operands[2];
3669 switch (GET_CODE (operands[2]))
3672 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
3674 intval = INTVAL (operands[2]);
3675 /* zero-extend 16->32? */
3676 if (intval == 0xffff && REG_P (operands[0])
3677 && (! REG_P (operands[1])
3678 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
3679 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
3681 /* ??? tege: Should forget CC_STATUS only if we clobber a
3682 remembered operand. Fix that later. */
3685 return AS2 (movzx,%w1,%0);
3687 return AS2 (movz%W0%L0,%w1,%0);
3691 /* zero extend 8->32? */
3692 if (intval == 0xff && REG_P (operands[0])
3693 && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
3694 && (! REG_P (operands[1])
3695 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
3696 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
3698 /* ??? tege: Should forget CC_STATUS only if we clobber a
3699 remembered operand. Fix that later. */
3702 return AS2 (movzx,%b1,%0);
3704 return AS2 (movz%B0%L0,%b1,%0);
3708 /* Check partial bytes.. non-QI-regs are not available */
3709 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
3712 /* only low byte has zero bits? */
3713 if (~(intval | 0xff) == 0)
3716 if (REG_P (operands[0]))
3721 return AS2 (xor%B0,%b0,%b0);
3724 /* we're better off with the 32-bit version if reg != EAX */
3725 /* the value is sign-extended in 8 bits */
3726 if (REGNO (operands[0]) != 0 && (intval & 0x80))
3732 operands[2] = GEN_INT (intval);
3735 return AS2 (mov%B0,%2,%b0);
3737 return AS2 (and%B0,%2,%b0);
3740 /* only second byte has zero? */
3741 if (~(intval | 0xff00) == 0)
3745 intval = (intval >> 8) & 0xff;
3746 operands[2] = GEN_INT (intval);
3749 if (REG_P (operands[0]))
3750 return AS2 (xor%B0,%h0,%h0);
3751 operands[0] = adj_offsettable_operand (operands[0], 1);
3752 return AS2 (mov%B0,%2,%b0);
3755 if (REG_P (operands[0]))
3756 return AS2 (and%B0,%2,%h0);
3758 operands[0] = adj_offsettable_operand (operands[0], 1);
3759 return AS2 (and%B0,%2,%b0);
3762 if (REG_P (operands[0]))
3765 /* third byte has zero bits? */
3766 if (~(intval | 0xff0000) == 0)
3768 intval = (intval >> 16) & 0xff;
3769 operands[0] = adj_offsettable_operand (operands[0], 2);
3772 operands[2] = GEN_INT (intval);
3774 return AS2 (mov%B0,%2,%b0);
3775 return AS2 (and%B0,%2,%b0);
3778 /* fourth byte has zero bits? */
3779 if (~(intval | 0xff000000) == 0)
3781 intval = (intval >> 24) & 0xff;
3782 operands[0] = adj_offsettable_operand (operands[0], 3);
3783 goto byte_and_operation;
3786 /* Low word is zero? */
3787 if (intval == 0xffff0000)
3789 word_zero_and_operation:
3791 operands[2] = const0_rtx;
3792 return AS2 (mov%W0,%2,%w0);
3795 /* High word is zero? */
3796 if (intval == 0x0000ffff)
3798 operands[0] = adj_offsettable_operand (operands[0], 2);
3799 goto word_zero_and_operation;
3806 return AS2 (and%L0,%2,%0);
3809 (define_insn "andhi3"
3810 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3811 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3812 (match_operand:HI 2 "general_operand" "ri,rm")))]
3816 if (GET_CODE (operands[2]) == CONST_INT
3817 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
3819 /* Can we ignore the upper byte? */
3820 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
3821 && (INTVAL (operands[2]) & 0xff00) == 0xff00)
3825 if ((INTVAL (operands[2]) & 0xff) == 0)
3827 operands[2] = const0_rtx;
3828 return AS2 (mov%B0,%2,%b0);
3831 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
3832 return AS2 (and%B0,%2,%b0);
3835 /* Can we ignore the lower byte? */
3836 /* ??? what about offsettable memory references? */
3837 if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
3841 if ((INTVAL (operands[2]) & 0xff00) == 0)
3843 operands[2] = const0_rtx;
3844 return AS2 (mov%B0,%2,%h0);
3847 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
3848 return AS2 (and%B0,%2,%h0);
3851 /* use 32-bit ops on registers when there are no sign issues.. */
3852 if (REG_P (operands[0]))
3854 if (!(INTVAL (operands[2]) & ~0x7fff))
3855 return AS2 (and%L0,%2,%k0);
3859 if (REG_P (operands[0])
3860 && i386_aligned_p (operands[2]))
3863 /* If op[2] is constant, we should zero-extend it and */
3864 /* make a note that op[0] has been zero-extended, so */
3865 /* that we could use 32-bit ops on it forthwith, but */
3866 /* there is no such reg-note available. Instead we do */
3867 /* a sign extension as that can result in shorter asm */
3868 operands[2] = i386_sext16_if_const (operands[2]);
3869 return AS2 (and%L0,%k2,%k0);
3872 /* Use a 32-bit word with the upper bits set, invalidate CC */
3873 if (GET_CODE (operands[2]) == CONST_INT
3874 && i386_aligned_p (operands[0]))
3876 HOST_WIDE_INT val = INTVAL (operands[2]);
3879 if (val != INTVAL (operands[2]))
3880 operands[2] = GEN_INT (val);
3881 return AS2 (and%L0,%k2,%k0);
3884 return AS2 (and%W0,%2,%0);
3887 (define_insn "andqi3"
3888 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3889 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3890 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3892 "* return AS2 (and%B0,%2,%0);")
3894 /* I am nervous about these two.. add them later..
3895 ;I presume this means that we have something in say op0= eax which is small
3896 ;and we want to and it with memory so we can do this by just an
3897 ;andb m,%al and have success.
3899 [(set (match_operand:SI 0 "general_operand" "=r")
3900 (and:SI (zero_extend:SI
3901 (match_operand:HI 1 "nonimmediate_operand" "rm"))
3902 (match_operand:SI 2 "general_operand" "0")))]
3903 "GET_CODE (operands[2]) == CONST_INT
3904 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
3908 [(set (match_operand:SI 0 "register_operand" "=q")
3910 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
3911 (match_operand:SI 2 "register_operand" "0")))]
3912 "GET_CODE (operands[2]) == CONST_INT
3913 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
3918 ;;- Bit set (inclusive or) instructions
3920 ;; This optimizes known byte-wide operations to memory, and in some cases
3921 ;; to QI registers.. Note that we don't want to use the QI registers too
3922 ;; aggressively, because often the 32-bit register instruction is the same
3923 ;; size, and likely to be faster on PentiumPro.
3924 (define_insn "iorsi3"
3925 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3926 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3927 (match_operand:SI 2 "general_operand" "ri,rm")))]
3931 HOST_WIDE_INT intval;
3932 switch (GET_CODE (operands[2]))
3936 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
3939 /* don't try to optimize volatile accesses */
3940 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
3943 intval = INTVAL (operands[2]);
3944 if ((intval & ~0xff) == 0)
3946 if (REG_P (operands[0]))
3948 /* Do low byte access only for %eax or when high bit is set */
3949 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
3956 if (intval != INTVAL (operands[2]))
3957 operands[2] = GEN_INT (intval);
3960 return AS2 (mov%B0,%2,%b0);
3962 return AS2 (or%B0,%2,%b0);
3966 if ((intval & ~0xff00) == 0)
3970 if (REG_P (operands[0]))
3973 operands[2] = GEN_INT (intval);
3975 return AS2 (mov%B0,%2,%h0);
3977 return AS2 (or%B0,%2,%h0);
3980 operands[0] = adj_offsettable_operand (operands[0], 1);
3981 goto byte_or_operation;
3984 if (REG_P (operands[0]))
3988 if ((intval & ~0xff0000) == 0)
3991 operands[0] = adj_offsettable_operand (operands[0], 2);
3992 goto byte_or_operation;
3996 if ((intval & ~0xff000000) == 0)
3998 intval = (intval >> 24) & 0xff;
3999 operands[0] = adj_offsettable_operand (operands[0], 3);
4000 goto byte_or_operation;
4007 return AS2 (or%L0,%2,%0);
4010 (define_insn "iorhi3"
4011 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4012 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4013 (match_operand:HI 2 "general_operand" "ri,rm")))]
4017 HOST_WIDE_INT intval;
4018 switch (GET_CODE (operands[2]))
4022 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4025 /* don't try to optimize volatile accesses */
4026 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4029 intval = 0xffff & INTVAL (operands[2]);
4031 if ((intval & 0xff00) == 0)
4033 if (REG_P (operands[0]))
4035 /* Do low byte access only for %eax or when high bit is set */
4036 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4044 return AS2 (mov%B0,%2,%b0);
4046 return AS2 (or%B0,%2,%b0);
4050 if ((intval & 0xff) == 0)
4053 operands[2] = GEN_INT (intval);
4055 if (REG_P (operands[0]))
4059 return AS2 (mov%B0,%2,%h0);
4061 return AS2 (or%B0,%2,%h0);
4064 operands[0] = adj_offsettable_operand (operands[0], 1);
4066 goto byte_or_operation;
4073 if (REG_P (operands[0])
4074 && i386_aligned_p (operands[2]))
4077 operands[2] = i386_sext16_if_const (operands[2]);
4078 return AS2 (or%L0,%k2,%k0);
4081 if (GET_CODE (operands[2]) == CONST_INT
4082 && i386_aligned_p (operands[0]))
4085 intval = 0xffff & INTVAL (operands[2]);
4086 if (intval != INTVAL (operands[2]))
4087 operands[2] = GEN_INT (intval);
4088 return AS2 (or%L0,%2,%k0);
4091 return AS2 (or%W0,%2,%0);
4094 (define_insn "iorqi3"
4095 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4096 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4097 (match_operand:QI 2 "general_operand" "qn,qmn")))]
4099 "* return AS2 (or%B0,%2,%0);")
4101 ;;- xor instructions
4103 (define_insn "xorsi3"
4104 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4105 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4106 (match_operand:SI 2 "general_operand" "ri,rm")))]
4110 HOST_WIDE_INT intval;
4111 switch (GET_CODE (operands[2]))
4115 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4118 /* don't try to optimize volatile accesses */
4119 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4122 intval = INTVAL (operands[2]);
4123 if ((intval & ~0xff) == 0)
4125 if (REG_P (operands[0]))
4127 /* Do low byte access only for %eax or when high bit is set */
4128 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4136 return AS1 (not%B0,%b0);
4138 if (intval != INTVAL (operands[2]))
4139 operands[2] = GEN_INT (intval);
4140 return AS2 (xor%B0,%2,%b0);
4144 if ((intval & ~0xff00) == 0)
4148 if (REG_P (operands[0]))
4152 return AS1 (not%B0,%h0);
4154 operands[2] = GEN_INT (intval);
4155 return AS2 (xor%B0,%2,%h0);
4158 operands[0] = adj_offsettable_operand (operands[0], 1);
4160 goto byte_xor_operation;
4163 if (REG_P (operands[0]))
4167 if ((intval & ~0xff0000) == 0)
4170 operands[0] = adj_offsettable_operand (operands[0], 2);
4171 goto byte_xor_operation;
4175 if ((intval & ~0xff000000) == 0)
4177 intval = (intval >> 24) & 0xff;
4178 operands[0] = adj_offsettable_operand (operands[0], 3);
4179 goto byte_xor_operation;
4186 return AS2 (xor%L0,%2,%0);
4189 (define_insn "xorhi3"
4190 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4191 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4192 (match_operand:HI 2 "general_operand" "ri,rm")))]
4196 if (GET_CODE (operands[2]) == CONST_INT
4197 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
4199 /* Can we ignore the upper byte? */
4200 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
4201 && (INTVAL (operands[2]) & 0xff00) == 0)
4204 if (INTVAL (operands[2]) & 0xffff0000)
4205 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
4207 if (INTVAL (operands[2]) == 0xff)
4208 return AS1 (not%B0,%b0);
4210 return AS2 (xor%B0,%2,%b0);
4213 /* Can we ignore the lower byte? */
4214 /* ??? what about offsettable memory references? */
4215 if (QI_REG_P (operands[0])
4216 && (INTVAL (operands[2]) & 0xff) == 0)
4219 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
4221 if (INTVAL (operands[2]) == 0xff)
4222 return AS1 (not%B0,%h0);
4224 return AS2 (xor%B0,%2,%h0);
4228 if (REG_P (operands[0])
4229 && i386_aligned_p (operands[2]))
4232 operands[2] = i386_sext16_if_const (operands[2]);
4233 return AS2 (xor%L0,%k2,%k0);
4236 if (GET_CODE (operands[2]) == CONST_INT
4237 && i386_aligned_p (operands[0]))
4239 HOST_WIDE_INT intval;
4241 intval = 0xffff & INTVAL (operands[2]);
4242 if (intval != INTVAL (operands[2]))
4243 operands[2] = GEN_INT (intval);
4244 return AS2 (xor%L0,%2,%k0);
4247 return AS2 (xor%W0,%2,%0);
4250 (define_insn "xorqi3"
4251 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4252 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4253 (match_operand:QI 2 "general_operand" "qn,qm")))]
4255 "* return AS2 (xor%B0,%2,%0);")
4257 ;; logical operations for DImode
4260 (define_insn "anddi3"
4261 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4262 (and:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
4263 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
4264 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
4268 (define_insn "iordi3"
4269 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4270 (ior:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
4271 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
4272 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
4276 (define_insn "xordi3"
4277 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4278 (xor:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
4279 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
4280 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
4285 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4286 (match_operator:DI 4 "ix86_logical_operator"
4287 [(match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
4288 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")]))
4289 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
4294 rtx low[3], high[3], xops[7], temp;
4295 rtx (*genfunc)() = (GET_CODE (operands[4]) == AND ? gen_andsi3
4296 : GET_CODE (operands[4]) == IOR ? gen_iorsi3
4297 : GET_CODE (operands[4]) == XOR ? gen_xorsi3
4300 if (rtx_equal_p (operands[0], operands[2]))
4303 operands[1] = operands[2];
4307 split_di (operands, 3, low, high);
4308 if (!rtx_equal_p (operands[0], operands[1]))
4315 if (GET_CODE (operands[0]) != MEM)
4317 emit_insn (gen_movsi (xops[1], xops[3]));
4318 emit_insn (gen_movsi (xops[0], xops[2]));
4324 xops[6] = operands[3];
4325 emit_insn (gen_movsi (xops[6], xops[3]));
4326 emit_insn ((*genfunc) (xops[6], xops[6], xops[5]));
4327 emit_insn (gen_movsi (xops[1], xops[6]));
4328 emit_insn (gen_movsi (xops[6], xops[2]));
4329 emit_insn ((*genfunc) (xops[6], xops[6], xops[4]));
4330 emit_insn (gen_movsi (xops[0], xops[6]));
4335 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
4341 xops[4] = operands[3];
4343 emit_insn (gen_movsi (xops[4], xops[3]));
4344 emit_insn ((*genfunc) (xops[1], xops[1], xops[4]));
4345 emit_insn (gen_movsi (xops[4], xops[2]));
4346 emit_insn ((*genfunc) (xops[0], xops[0], xops[4]));
4351 emit_insn ((*genfunc) (low[0], low[0], low[2]));
4352 emit_insn ((*genfunc) (high[0], high[0], high[2]));
4358 ;;- negation instructions
4360 (define_insn "negdi2"
4361 [(set (match_operand:DI 0 "general_operand" "=&ro")
4362 (neg:DI (match_operand:DI 1 "general_operand" "0")))]
4366 rtx xops[2], low[1], high[1];
4370 split_di (operands, 1, low, high);
4371 xops[0] = const0_rtx;
4374 output_asm_insn (AS1 (neg%L0,%0), low);
4375 output_asm_insn (AS2 (adc%L1,%0,%1), xops);
4376 output_asm_insn (AS1 (neg%L0,%0), high);
4380 (define_insn "negsi2"
4381 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4382 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
4386 (define_insn "neghi2"
4387 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4388 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
4392 (define_insn "negqi2"
4393 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4394 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
4398 (define_insn "negsf2"
4399 [(set (match_operand:SF 0 "register_operand" "=f")
4400 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
4404 (define_insn "negdf2"
4405 [(set (match_operand:DF 0 "register_operand" "=f")
4406 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
4411 [(set (match_operand:DF 0 "register_operand" "=f")
4412 (neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
4416 (define_insn "negxf2"
4417 [(set (match_operand:XF 0 "register_operand" "=f")
4418 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
4423 [(set (match_operand:XF 0 "register_operand" "=f")
4424 (neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4428 ;; Absolute value instructions
4430 (define_insn "abssf2"
4431 [(set (match_operand:SF 0 "register_operand" "=f")
4432 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
4435 [(set_attr "type" "fpop")])
4437 (define_insn "absdf2"
4438 [(set (match_operand:DF 0 "register_operand" "=f")
4439 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
4442 [(set_attr "type" "fpop")])
4445 [(set (match_operand:DF 0 "register_operand" "=f")
4446 (abs:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
4449 [(set_attr "type" "fpop")])
4451 (define_insn "absxf2"
4452 [(set (match_operand:XF 0 "register_operand" "=f")
4453 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
4456 [(set_attr "type" "fpop")])
4459 [(set (match_operand:XF 0 "register_operand" "=f")
4460 (abs:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4463 [(set_attr "type" "fpop")])
4465 (define_insn "sqrtsf2"
4466 [(set (match_operand:SF 0 "register_operand" "=f")
4467 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
4468 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4471 (define_insn "sqrtdf2"
4472 [(set (match_operand:DF 0 "register_operand" "=f")
4473 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
4474 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4475 && (TARGET_IEEE_FP || flag_fast_math) "
4479 [(set (match_operand:DF 0 "register_operand" "=f")
4480 (sqrt:DF (float_extend:DF
4481 (match_operand:SF 1 "register_operand" "0"))))]
4482 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4485 (define_insn "sqrtxf2"
4486 [(set (match_operand:XF 0 "register_operand" "=f")
4487 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
4488 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4489 && (TARGET_IEEE_FP || flag_fast_math) "
4493 [(set (match_operand:XF 0 "register_operand" "=f")
4494 (sqrt:XF (float_extend:XF
4495 (match_operand:DF 1 "register_operand" "0"))))]
4496 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4500 [(set (match_operand:XF 0 "register_operand" "=f")
4501 (sqrt:XF (float_extend:XF
4502 (match_operand:SF 1 "register_operand" "0"))))]
4503 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4506 (define_insn "sindf2"
4507 [(set (match_operand:DF 0 "register_operand" "=f")
4508 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
4509 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4512 (define_insn "sinsf2"
4513 [(set (match_operand:SF 0 "register_operand" "=f")
4514 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
4515 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4519 [(set (match_operand:DF 0 "register_operand" "=f")
4520 (unspec:DF [(float_extend:DF
4521 (match_operand:SF 1 "register_operand" "0"))] 1))]
4522 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4525 (define_insn "sinxf2"
4526 [(set (match_operand:XF 0 "register_operand" "=f")
4527 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
4528 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4531 (define_insn "cosdf2"
4532 [(set (match_operand:DF 0 "register_operand" "=f")
4533 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
4534 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4537 (define_insn "cossf2"
4538 [(set (match_operand:SF 0 "register_operand" "=f")
4539 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
4540 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4544 [(set (match_operand:DF 0 "register_operand" "=f")
4545 (unspec:DF [(float_extend:DF
4546 (match_operand:SF 1 "register_operand" "0"))] 2))]
4547 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4550 (define_insn "cosxf2"
4551 [(set (match_operand:XF 0 "register_operand" "=f")
4552 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
4553 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4556 ;;- one complement instructions
4558 (define_insn "one_cmplsi2"
4559 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4560 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
4564 (define_insn "one_cmplhi2"
4565 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4566 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
4570 (define_insn "one_cmplqi2"
4571 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4572 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
4576 ;;- arithmetic shift instructions
4578 ;; DImode shifts are implemented using the i386 "shift double" opcode,
4579 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
4580 ;; is variable, then the count is in %cl and the "imm" operand is dropped
4581 ;; from the assembler input.
4583 ;; This instruction shifts the target reg/mem as usual, but instead of
4584 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
4585 ;; is a left shift double, bits are taken from the high order bits of
4586 ;; reg, else if the insn is a shift right double, bits are taken from the
4587 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
4588 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
4590 ;; Since sh[lr]d does not change the `reg' operand, that is done
4591 ;; separately, making all shifts emit pairs of shift double and normal
4592 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
4593 ;; support a 63 bit shift, each shift where the count is in a reg expands
4594 ;; to a pair of shifts, a branch, a shift by 32 and a label.
4596 ;; If the shift count is a constant, we need never emit more than one
4597 ;; shift pair, instead using moves and sign extension for counts greater
4600 (define_expand "ashldi3"
4601 [(set (match_operand:DI 0 "register_operand" "")
4602 (ashift:DI (match_operand:DI 1 "register_operand" "")
4603 (match_operand:QI 2 "nonmemory_operand" "")))]
4607 if (GET_CODE (operands[2]) != CONST_INT
4608 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4610 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4611 emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
4615 emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
4620 (define_insn "ashldi3_const_int"
4621 [(set (match_operand:DI 0 "register_operand" "=&r")
4622 (ashift:DI (match_operand:DI 1 "register_operand" "0")
4623 (match_operand:QI 2 "const_int_operand" "J")))]
4624 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
4627 rtx xops[4], low[1], high[1];
4631 split_di (operands, 1, low, high);
4632 xops[0] = operands[2];
4633 xops[1] = const1_rtx;
4637 if (INTVAL (xops[0]) > 31)
4639 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
4640 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4642 if (INTVAL (xops[0]) > 32)
4644 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
4645 output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
4650 output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
4651 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
4656 (define_insn "ashldi3_non_const_int"
4657 [(set (match_operand:DI 0 "register_operand" "=&r")
4658 (ashift:DI (match_operand:DI 1 "register_operand" "0")
4659 (match_operand:QI 2 "register_operand" "c")))]
4663 rtx xops[4], low[1], high[1];
4664 static HOST_WIDE_INT ashldi_label_number;
4668 split_di (operands, 1, low, high);
4669 xops[0] = operands[2];
4670 xops[1] = GEN_INT (32);
4674 output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
4675 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
4676 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
4677 asm_fprintf (asm_out_file, \"\\tje %LLASHLDI%d\\n\", ashldi_label_number);
4678 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
4679 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4680 asm_fprintf (asm_out_file, \"%LLASHLDI%d:\\n\", ashldi_label_number++);
4685 ;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
4686 ;; On i486, movl/sall appears slightly faster than leal, but the leal
4687 ;; is smaller - use leal for now unless the shift count is 1.
4689 (define_insn "ashlsi3"
4690 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4691 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,0")
4692 (match_operand:SI 2 "nonmemory_operand" "M,cI")))]
4696 if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
4698 if (TARGET_DOUBLE_WITH_ADD && INTVAL (operands[2]) == 1)
4700 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
4701 return AS2 (add%L0,%1,%0);
4707 if (operands[1] == stack_pointer_rtx)
4709 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
4710 operands[1] = operands[0];
4712 operands[1] = gen_rtx_MULT (SImode, operands[1],
4713 GEN_INT (1 << INTVAL (operands[2])));
4714 return AS2 (lea%L0,%a1,%0);
4718 if (REG_P (operands[2]))
4719 return AS2 (sal%L0,%b2,%0);
4721 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4722 return AS2 (add%L0,%0,%0);
4724 return AS2 (sal%L0,%2,%0);
4727 (define_insn "ashlhi3"
4728 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4729 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4730 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4734 if (REG_P (operands[2]))
4735 return AS2 (sal%W0,%b2,%0);
4737 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4738 return AS2 (add%W0,%0,%0);
4740 return AS2 (sal%W0,%2,%0);
4743 (define_insn "ashlqi3"
4744 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4745 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4746 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4750 if (REG_P (operands[2]))
4751 return AS2 (sal%B0,%b2,%0);
4753 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4754 return AS2 (add%B0,%0,%0);
4756 return AS2 (sal%B0,%2,%0);
4759 ;; See comment above `ashldi3' about how this works.
4761 (define_expand "ashrdi3"
4762 [(set (match_operand:DI 0 "register_operand" "")
4763 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4764 (match_operand:QI 2 "nonmemory_operand" "")))]
4768 if (GET_CODE (operands[2]) != CONST_INT
4769 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4771 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4772 emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1],
4776 emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2]));
4781 (define_insn "ashldi3_32"
4782 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
4783 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
4788 rtx low[2], high[2], xops[4];
4790 split_di (operands, 2, low, high);
4794 xops[3] = const0_rtx;
4795 if (!rtx_equal_p (xops[0], xops[1]))
4796 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
4798 if (GET_CODE (low[0]) == MEM)
4799 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4801 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4806 (define_insn "ashrdi3_const_int"
4807 [(set (match_operand:DI 0 "register_operand" "=&r")
4808 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
4809 (match_operand:QI 2 "const_int_operand" "J")))]
4810 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
4813 rtx xops[4], low[1], high[1];
4817 split_di (operands, 1, low, high);
4818 xops[0] = operands[2];
4819 xops[1] = const1_rtx;
4823 if (INTVAL (xops[0]) > 31)
4825 xops[1] = GEN_INT (31);
4826 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4827 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */
4829 if (INTVAL (xops[0]) > 32)
4831 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
4832 output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */
4837 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
4838 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
4844 (define_insn "ashrdi3_non_const_int"
4845 [(set (match_operand:DI 0 "register_operand" "=&r")
4846 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
4847 (match_operand:QI 2 "register_operand" "c")))]
4851 rtx xops[4], low[1], high[1];
4852 static HOST_WIDE_INT ashrdi_label_number;
4856 split_di (operands, 1, low, high);
4857 xops[0] = operands[2];
4858 xops[1] = GEN_INT (32);
4862 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
4863 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
4864 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
4865 asm_fprintf (asm_out_file, \"\\tje %LLASHRDI%d\\n\", ashrdi_label_number);
4866 xops[1] = GEN_INT (31);
4867 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4868 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */
4869 asm_fprintf (asm_out_file, \"%LLASHRDI%d:\\n\", ashrdi_label_number++);
4874 (define_insn "ashrsi3"
4875 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4876 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
4877 (match_operand:SI 2 "nonmemory_operand" "cI")))]
4881 if (REG_P (operands[2]))
4882 return AS2 (sar%L0,%b2,%0);
4884 return AS2 (sar%L0,%2,%0);
4887 (define_insn "ashrhi3"
4888 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4889 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4890 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4894 if (REG_P (operands[2]))
4895 return AS2 (sar%W0,%b2,%0);
4897 return AS2 (sar%W0,%2,%0);
4900 (define_insn "ashrqi3"
4901 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4902 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4903 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4907 if (REG_P (operands[2]))
4908 return AS2 (sar%B0,%b2,%0);
4910 return AS2 (sar%B0,%2,%0);
4913 ;;- logical shift instructions
4915 ;; See comment above `ashldi3' about how this works.
4917 (define_expand "lshrdi3"
4918 [(set (match_operand:DI 0 "register_operand" "")
4919 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4920 (match_operand:QI 2 "nonmemory_operand" "")))]
4924 if (GET_CODE (operands[2]) != CONST_INT
4925 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4927 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4928 emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
4932 emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
4937 (define_insn "lshrdi3_32"
4938 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
4939 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
4944 rtx low[2], high[2], xops[4];
4946 split_di (operands, 2, low, high);
4950 xops[3] = const0_rtx;
4951 if (!rtx_equal_p (xops[0], xops[1]))
4952 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
4954 if (GET_CODE (low[0]) == MEM)
4955 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4957 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4962 (define_insn "lshrdi3_const_int"
4963 [(set (match_operand:DI 0 "register_operand" "=&r")
4964 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
4965 (match_operand:QI 2 "const_int_operand" "J")))]
4966 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
4969 rtx xops[4], low[1], high[1];
4973 split_di (operands, 1, low, high);
4974 xops[0] = operands[2];
4975 xops[1] = const1_rtx;
4979 if (INTVAL (xops[0]) > 31)
4981 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
4982 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
4984 if (INTVAL (xops[0]) > 32)
4986 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
4987 output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
4992 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
4993 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
4999 (define_insn "lshrdi3_non_const_int"
5000 [(set (match_operand:DI 0 "register_operand" "=&r")
5001 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5002 (match_operand:QI 2 "register_operand" "c")))]
5006 rtx xops[4], low[1], high[1];
5007 static HOST_WIDE_INT lshrdi_label_number;
5011 split_di (operands, 1, low, high);
5012 xops[0] = operands[2];
5013 xops[1] = GEN_INT (32);
5017 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
5018 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
5019 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5020 asm_fprintf (asm_out_file, \"\\tje %LLLSHRDI%d\\n\", lshrdi_label_number);
5021 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
5022 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
5023 asm_fprintf (asm_out_file, \"%LLLSHRDI%d:\\n\", lshrdi_label_number++);
5028 (define_insn "lshrsi3"
5029 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5030 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5031 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5035 if (REG_P (operands[2]))
5036 return AS2 (shr%L0,%b2,%0);
5038 return AS2 (shr%L0,%2,%1);
5041 (define_insn "lshrhi3"
5042 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5043 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5044 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5048 if (REG_P (operands[2]))
5049 return AS2 (shr%W0,%b2,%0);
5051 return AS2 (shr%W0,%2,%0);
5054 (define_insn "lshrqi3"
5055 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5056 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5057 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5061 if (REG_P (operands[2]))
5062 return AS2 (shr%B0,%b2,%0);
5064 return AS2 (shr%B0,%2,%0);
5067 ;;- rotate instructions
5069 (define_insn "rotlsi3"
5070 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5071 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5072 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5076 if (REG_P (operands[2]))
5077 return AS2 (rol%L0,%b2,%0);
5079 return AS2 (rol%L0,%2,%0);
5082 (define_insn "rotlhi3"
5083 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5084 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5085 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5089 if (REG_P (operands[2]))
5090 return AS2 (rol%W0,%b2,%0);
5092 return AS2 (rol%W0,%2,%0);
5095 (define_insn "rotlqi3"
5096 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5097 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5098 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5102 if (REG_P (operands[2]))
5103 return AS2 (rol%B0,%b2,%0);
5105 return AS2 (rol%B0,%2,%0);
5108 (define_insn "rotrsi3"
5109 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5110 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5111 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5115 if (REG_P (operands[2]))
5116 return AS2 (ror%L0,%b2,%0);
5118 return AS2 (ror%L0,%2,%0);
5121 (define_insn "rotrhi3"
5122 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5123 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5124 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5128 if (REG_P (operands[2]))
5129 return AS2 (ror%W0,%b2,%0);
5131 return AS2 (ror%W0,%2,%0);
5134 (define_insn "rotrqi3"
5135 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5136 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5137 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5141 if (REG_P (operands[2]))
5142 return AS2 (ror%B0,%b2,%0);
5144 return AS2 (ror%B0,%2,%0);
5148 ;; This usually looses. But try a define_expand to recognize a few case
5149 ;; we can do efficiently, such as accessing the "high" QImode registers,
5150 ;; %ah, %bh, %ch, %dh.
5151 ;; ??? Note this has a botch on the mode of operand 0, which needs to be
5152 ;; fixed if this is ever enabled.
5154 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
5155 (match_operand:SI 1 "immediate_operand" "i")
5156 (match_operand:SI 2 "immediate_operand" "i"))
5157 (match_operand:SI 3 "nonmemory_operand" "ri"))]
5161 if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
5163 if (GET_CODE (operands[3]) == CONST_INT)
5165 unsigned int mask = (1 << INTVAL (operands[1])) - 1;
5166 operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
5167 output_asm_insn (AS2 (and%L0,%1,%0), operands);
5168 operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
5169 output_asm_insn (AS2 (or%L0,%3,%0), operands);
5173 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
5174 if (INTVAL (operands[2]))
5175 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5176 output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
5177 operands[2] = GEN_INT (BITS_PER_WORD
5178 - INTVAL (operands[1]) - INTVAL (operands[2]));
5179 if (INTVAL (operands[2]))
5180 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5186 ;; ??? There are problems with the mode of operand[3]. The point of this
5187 ;; is to represent an HImode move to a "high byte" register.
5189 (define_expand "insv"
5190 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
5191 (match_operand:SI 1 "immediate_operand" "")
5192 (match_operand:SI 2 "immediate_operand" ""))
5193 (match_operand:QI 3 "nonmemory_operand" "ri"))]
5197 if (GET_CODE (operands[1]) != CONST_INT
5198 || GET_CODE (operands[2]) != CONST_INT)
5201 if (! (INTVAL (operands[1]) == 8
5202 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
5203 && ! INTVAL (operands[1]) == 1)
5208 ;; On i386, the register count for a bit operation is *not* truncated,
5209 ;; so SHIFT_COUNT_TRUNCATED must not be defined.
5211 ;; On i486, the shift & or/and code is faster than bts or btr. If
5212 ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
5214 ;; On i386, bts is a little faster if operands[0] is a reg, and a
5215 ;; little slower if operands[0] is a MEM, than the shift & or/and code.
5216 ;; Use bts & btr, since they reload better.
5218 ;; General bit set and clear.
5220 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm")
5222 (match_operand:SI 2 "register_operand" "r"))
5223 (match_operand:SI 3 "const_int_operand" "n"))]
5224 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5229 if (INTVAL (operands[3]) == 1)
5230 return AS2 (bts%L0,%2,%0);
5232 return AS2 (btr%L0,%2,%0);
5235 ;; Bit complement. See comments on previous pattern.
5236 ;; ??? Is this really worthwhile?
5238 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5239 (xor:SI (ashift:SI (const_int 1)
5240 (match_operand:SI 1 "register_operand" "r"))
5241 (match_operand:SI 2 "nonimmediate_operand" "0")))]
5242 "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT"
5247 return AS2 (btc%L0,%1,%0);
5251 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5252 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5253 (ashift:SI (const_int 1)
5254 (match_operand:SI 2 "register_operand" "r"))))]
5255 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5260 return AS2 (btc%L0,%2,%0);
5263 ;; Recognizers for bit-test instructions.
5265 ;; The bt opcode allows a MEM in operands[0]. But on both i386 and
5266 ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
5267 ;; bt on the MEM directly.
5269 ;; ??? The first argument of a zero_extract must not be reloaded, so
5270 ;; don't allow a MEM in the operand predicate without allowing it in the
5274 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5276 (match_operand:SI 1 "register_operand" "r")))]
5277 "GET_CODE (operands[1]) != CONST_INT"
5280 cc_status.flags |= CC_Z_IN_NOT_C;
5281 return AS2 (bt%L0,%1,%0);
5285 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5286 (match_operand:SI 1 "const_int_operand" "n")
5287 (match_operand:SI 2 "const_int_operand" "n")))]
5293 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5294 operands[1] = GEN_INT (mask);
5296 if (QI_REG_P (operands[0]))
5298 if ((mask & ~0xff) == 0)
5300 cc_status.flags |= CC_NOT_NEGATIVE;
5301 return AS2 (test%B0,%1,%b0);
5304 if ((mask & ~0xff00) == 0)
5306 cc_status.flags |= CC_NOT_NEGATIVE;
5307 operands[1] = GEN_INT (mask >> 8);
5308 return AS2 (test%B0,%1,%h0);
5312 return AS2 (test%L0,%1,%0);
5315 ;; ??? All bets are off if operand 0 is a volatile MEM reference.
5316 ;; The CPU may access unspecified bytes around the actual target byte.
5319 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
5320 (match_operand:SI 1 "const_int_operand" "n")
5321 (match_operand:SI 2 "const_int_operand" "n")))]
5322 "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
5327 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5328 operands[1] = GEN_INT (mask);
5330 if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
5332 if ((mask & ~0xff) == 0)
5334 cc_status.flags |= CC_NOT_NEGATIVE;
5335 return AS2 (test%B0,%1,%b0);
5338 if ((mask & ~0xff00) == 0)
5340 cc_status.flags |= CC_NOT_NEGATIVE;
5341 operands[1] = GEN_INT (mask >> 8);
5343 if (QI_REG_P (operands[0]))
5344 return AS2 (test%B0,%1,%h0);
5347 operands[0] = adj_offsettable_operand (operands[0], 1);
5348 return AS2 (test%B0,%1,%b0);
5352 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
5354 cc_status.flags |= CC_NOT_NEGATIVE;
5355 operands[1] = GEN_INT (mask >> 16);
5356 operands[0] = adj_offsettable_operand (operands[0], 2);
5357 return AS2 (test%B0,%1,%b0);
5360 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
5362 cc_status.flags |= CC_NOT_NEGATIVE;
5363 operands[1] = GEN_INT (mask >> 24);
5364 operands[0] = adj_offsettable_operand (operands[0], 3);
5365 return AS2 (test%B0,%1,%b0);
5369 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
5370 return AS2 (test%L0,%1,%0);
5372 return AS2 (test%L1,%0,%1);
5375 ;; Store-flag instructions.
5377 ;; For all sCOND expanders, also expand the compare or test insn that
5378 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
5380 ;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may
5381 ;; not have any input reloads. A MEM write might need an input reload
5382 ;; for the address of the MEM. So don't allow MEM as the SET_DEST.
5384 (define_expand "seq"
5386 (set (match_operand:QI 0 "register_operand" "")
5387 (eq:QI (cc0) (const_int 0)))]
5392 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5393 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5395 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5399 [(set (match_operand:QI 0 "register_operand" "=q")
5400 (eq:QI (cc0) (const_int 0)))]
5404 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5405 return AS1 (setnb,%0);
5407 return AS1 (sete,%0);
5410 (define_expand "sne"
5412 (set (match_operand:QI 0 "register_operand" "")
5413 (ne:QI (cc0) (const_int 0)))]
5418 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5419 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5421 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5425 [(set (match_operand:QI 0 "register_operand" "=q")
5426 (ne:QI (cc0) (const_int 0)))]
5430 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5431 return AS1 (setb,%0);
5433 return AS1 (setne,%0);
5437 (define_expand "sgt"
5439 (set (match_operand:QI 0 "register_operand" "")
5440 (gt:QI (cc0) (const_int 0)))]
5442 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5445 [(set (match_operand:QI 0 "register_operand" "=q")
5446 (gt:QI (cc0) (const_int 0)))]
5450 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5451 && ! (cc_prev_status.flags & CC_FCOMI))
5452 return AS1 (sete,%0);
5454 OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR);
5457 (define_expand "sgtu"
5459 (set (match_operand:QI 0 "register_operand" "")
5460 (gtu:QI (cc0) (const_int 0)))]
5462 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5465 [(set (match_operand:QI 0 "register_operand" "=q")
5466 (gtu:QI (cc0) (const_int 0)))]
5468 "* return \"seta %0\"; ")
5470 (define_expand "slt"
5472 (set (match_operand:QI 0 "register_operand" "")
5473 (lt:QI (cc0) (const_int 0)))]
5475 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5478 [(set (match_operand:QI 0 "register_operand" "=q")
5479 (lt:QI (cc0) (const_int 0)))]
5483 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5484 && ! (cc_prev_status.flags & CC_FCOMI))
5485 return AS1 (sete,%0);
5487 OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\");
5490 (define_expand "sltu"
5492 (set (match_operand:QI 0 "register_operand" "")
5493 (ltu:QI (cc0) (const_int 0)))]
5495 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5498 [(set (match_operand:QI 0 "register_operand" "=q")
5499 (ltu:QI (cc0) (const_int 0)))]
5501 "* return \"setb %0\"; ")
5503 (define_expand "sge"
5505 (set (match_operand:QI 0 "register_operand" "")
5506 (ge:QI (cc0) (const_int 0)))]
5508 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5511 [(set (match_operand:QI 0 "register_operand" "=q")
5512 (ge:QI (cc0) (const_int 0)))]
5516 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5517 && ! (cc_prev_status.flags & CC_FCOMI))
5518 return AS1 (sete,%0);
5520 OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\");
5523 (define_expand "sgeu"
5525 (set (match_operand:QI 0 "register_operand" "")
5526 (geu:QI (cc0) (const_int 0)))]
5528 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5531 [(set (match_operand:QI 0 "register_operand" "=q")
5532 (geu:QI (cc0) (const_int 0)))]
5534 "* return \"setae %0\"; ")
5536 (define_expand "sle"
5538 (set (match_operand:QI 0 "register_operand" "")
5539 (le:QI (cc0) (const_int 0)))]
5541 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5544 [(set (match_operand:QI 0 "register_operand" "=q")
5545 (le:QI (cc0) (const_int 0)))]
5549 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5550 && ! (cc_prev_status.flags & CC_FCOMI))
5551 return AS1 (setb,%0);
5553 OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR);
5556 (define_expand "sleu"
5558 (set (match_operand:QI 0 "register_operand" "")
5559 (leu:QI (cc0) (const_int 0)))]
5561 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5564 [(set (match_operand:QI 0 "register_operand" "=q")
5565 (leu:QI (cc0) (const_int 0)))]
5567 "* return \"setbe %0\"; ")
5569 ;; Basic conditional jump instructions.
5570 ;; We ignore the overflow flag for signed branch instructions.
5572 ;; For all bCOND expanders, also expand the compare or test insn that
5573 ;; generates cc0. Generate an equality comparison if `beq' or `bne'.
5575 (define_expand "beq"
5578 (if_then_else (eq (cc0)
5580 (label_ref (match_operand 0 "" ""))
5586 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5587 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5589 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5594 (if_then_else (eq (cc0)
5596 (label_ref (match_operand 0 "" ""))
5601 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5604 if (cc_prev_status.flags & CC_TEST_AX)
5606 operands[1] = gen_rtx_REG (SImode, 0);
5607 operands[2] = GEN_INT (0x4000);
5608 output_asm_insn (AS2 (testl,%2,%1), operands);
5609 return AS1 (jne,%l0);
5615 (define_expand "bne"
5618 (if_then_else (ne (cc0)
5620 (label_ref (match_operand 0 "" ""))
5626 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5627 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5629 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5634 (if_then_else (ne (cc0)
5636 (label_ref (match_operand 0 "" ""))
5641 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5644 if (cc_prev_status.flags & CC_TEST_AX)
5646 operands[1] = gen_rtx_REG (SImode, 0);
5647 operands[2] = GEN_INT (0x4000);
5648 output_asm_insn (AS2 (testl,%2,%1), operands);
5649 return AS1 (je,%l0);
5655 (define_expand "bgt"
5658 (if_then_else (gt (cc0)
5660 (label_ref (match_operand 0 "" ""))
5663 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5667 (if_then_else (gt (cc0)
5669 (label_ref (match_operand 0 "" ""))
5674 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5675 && ! (cc_prev_status.flags & CC_FCOMI))
5676 return AS1 (je,%l0);
5678 if (cc_prev_status.flags & CC_TEST_AX)
5680 operands[1] = gen_rtx_REG (SImode, 0);
5681 operands[2] = GEN_INT (0x4100);
5682 output_asm_insn (AS2 (testl,%2,%1), operands);
5683 return AS1 (je,%l0);
5685 OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
5688 (define_expand "bgtu"
5691 (if_then_else (gtu (cc0)
5693 (label_ref (match_operand 0 "" ""))
5696 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5700 (if_then_else (gtu (cc0)
5702 (label_ref (match_operand 0 "" ""))
5707 (define_expand "blt"
5710 (if_then_else (lt (cc0)
5712 (label_ref (match_operand 0 "" ""))
5715 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5719 (if_then_else (lt (cc0)
5721 (label_ref (match_operand 0 "" ""))
5726 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5727 && ! (cc_prev_status.flags & CC_FCOMI))
5728 return AS1 (je,%l0);
5730 if (cc_prev_status.flags & CC_TEST_AX)
5732 operands[1] = gen_rtx_REG (SImode, 0);
5733 operands[2] = GEN_INT (0x100);
5734 output_asm_insn (AS2 (testl,%2,%1), operands);
5735 return AS1 (jne,%l0);
5737 OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
5740 (define_expand "bltu"
5743 (if_then_else (ltu (cc0)
5745 (label_ref (match_operand 0 "" ""))
5748 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5752 (if_then_else (ltu (cc0)
5754 (label_ref (match_operand 0 "" ""))
5759 (define_expand "bge"
5762 (if_then_else (ge (cc0)
5764 (label_ref (match_operand 0 "" ""))
5767 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5771 (if_then_else (ge (cc0)
5773 (label_ref (match_operand 0 "" ""))
5778 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5779 && ! (cc_prev_status.flags & CC_FCOMI))
5780 return AS1 (je,%l0);
5781 if (cc_prev_status.flags & CC_TEST_AX)
5783 operands[1] = gen_rtx_REG (SImode, 0);
5784 operands[2] = GEN_INT (0x100);
5785 output_asm_insn (AS2 (testl,%2,%1), operands);
5786 return AS1 (je,%l0);
5788 OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
5791 (define_expand "bgeu"
5794 (if_then_else (geu (cc0)
5796 (label_ref (match_operand 0 "" ""))
5799 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5803 (if_then_else (geu (cc0)
5805 (label_ref (match_operand 0 "" ""))
5810 (define_expand "ble"
5813 (if_then_else (le (cc0)
5815 (label_ref (match_operand 0 "" ""))
5818 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5822 (if_then_else (le (cc0)
5824 (label_ref (match_operand 0 "" ""))
5829 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5830 && ! (cc_prev_status.flags & CC_FCOMI))
5831 return AS1 (jb,%l0);
5832 if (cc_prev_status.flags & CC_TEST_AX)
5834 operands[1] = gen_rtx_REG (SImode, 0);
5835 operands[2] = GEN_INT (0x4100);
5836 output_asm_insn (AS2 (testl,%2,%1), operands);
5837 return AS1 (jne,%l0);
5840 OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
5843 (define_expand "bleu"
5846 (if_then_else (leu (cc0)
5848 (label_ref (match_operand 0 "" ""))
5851 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5855 (if_then_else (leu (cc0)
5857 (label_ref (match_operand 0 "" ""))
5862 ;; Negated conditional jump instructions.
5866 (if_then_else (eq (cc0)
5869 (label_ref (match_operand 0 "" ""))))]
5873 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5876 if (cc_prev_status.flags & CC_TEST_AX)
5878 operands[1] = gen_rtx_REG (SImode, 0);
5879 operands[2] = GEN_INT (0x4000);
5880 output_asm_insn (AS2 (testl,%2,%1), operands);
5881 return AS1 (je,%l0);
5888 (if_then_else (ne (cc0)
5891 (label_ref (match_operand 0 "" ""))))]
5895 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5898 if (cc_prev_status.flags & CC_TEST_AX)
5900 operands[1] = gen_rtx_REG (SImode, 0);
5901 operands[2] = GEN_INT (0x4000);
5902 output_asm_insn (AS2 (testl,%2,%1), operands);
5903 return AS1 (jne,%l0);
5910 (if_then_else (gt (cc0)
5913 (label_ref (match_operand 0 "" ""))))]
5917 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5918 && ! (cc_prev_status.flags & CC_FCOMI))
5919 return AS1 (jne,%l0);
5920 if (cc_prev_status.flags & CC_TEST_AX)
5922 operands[1] = gen_rtx_REG (SImode, 0);
5923 operands[2] = GEN_INT (0x4100);
5924 output_asm_insn (AS2 (testl,%2,%1), operands);
5925 return AS1 (jne,%l0);
5927 OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
5932 (if_then_else (gtu (cc0)
5935 (label_ref (match_operand 0 "" ""))))]
5941 (if_then_else (lt (cc0)
5944 (label_ref (match_operand 0 "" ""))))]
5948 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5949 && ! (cc_prev_status.flags & CC_FCOMI))
5950 return AS1 (jne,%l0);
5951 if (cc_prev_status.flags & CC_TEST_AX)
5953 operands[1] = gen_rtx_REG (SImode, 0);
5954 operands[2] = GEN_INT (0x100);
5955 output_asm_insn (AS2 (testl,%2,%1), operands);
5956 return AS1 (je,%l0);
5959 OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
5964 (if_then_else (ltu (cc0)
5967 (label_ref (match_operand 0 "" ""))))]
5973 (if_then_else (ge (cc0)
5976 (label_ref (match_operand 0 "" ""))))]
5980 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5981 && ! (cc_prev_status.flags & CC_FCOMI))
5982 return AS1 (jne,%l0);
5983 if (cc_prev_status.flags & CC_TEST_AX)
5985 operands[1] = gen_rtx_REG (SImode, 0);
5986 operands[2] = GEN_INT (0x100);
5987 output_asm_insn (AS2 (testl,%2,%1), operands);
5988 return AS1 (jne,%l0);
5990 OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
5995 (if_then_else (geu (cc0)
5998 (label_ref (match_operand 0 "" ""))))]
6004 (if_then_else (le (cc0)
6007 (label_ref (match_operand 0 "" ""))))]
6011 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
6012 && ! (cc_prev_status.flags & CC_FCOMI))
6013 return AS1 (jae,%l0);
6015 if (cc_prev_status.flags & CC_TEST_AX)
6017 operands[1] = gen_rtx_REG (SImode, 0);
6018 operands[2] = GEN_INT (0x4100);
6019 output_asm_insn (AS2 (testl,%2,%1), operands);
6020 return AS1 (je,%l0);
6022 OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
6027 (if_then_else (leu (cc0)
6030 (label_ref (match_operand 0 "" ""))))]
6034 ;; Unconditional and other jump instructions
6038 (label_ref (match_operand 0 "" "")))]
6042 (define_insn "indirect_jump"
6043 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
6049 return AS1 (jmp,%*%0);
6052 ;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
6053 ;; if S does not change i
6055 (define_expand "decrement_and_branch_until_zero"
6056 [(parallel [(set (pc)
6057 (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "")
6060 (label_ref (match_operand 1 "" ""))
6063 (plus:SI (match_dup 0)
6070 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
6071 [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
6072 (match_operand:SI 2 "general_operand" "rmi,ri"))
6074 (label_ref (match_operand 3 "" ""))
6077 (plus:SI (match_dup 1)
6083 if (operands[2] == constm1_rtx)
6084 output_asm_insn (AS1 (dec%L1,%1), operands);
6086 else if (operands[2] == const1_rtx)
6087 output_asm_insn (AS1 (inc%L1,%1), operands);
6090 output_asm_insn (AS2 (add%L1,%2,%1), operands);
6092 return AS1 (%J0,%l3);
6097 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
6098 [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
6099 (match_operand:SI 2 "general_operand" "rmi,ri"))
6101 (label_ref (match_operand 3 "" ""))
6104 (minus:SI (match_dup 1)
6110 if (operands[2] == const1_rtx)
6111 output_asm_insn (AS1 (dec%L1,%1), operands);
6113 else if (operands[1] == constm1_rtx)
6114 output_asm_insn (AS1 (inc%L1,%1), operands);
6117 output_asm_insn (AS2 (sub%L1,%2,%1), operands);
6119 return AS1 (%J0,%l3);
6124 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6126 (label_ref (match_operand 1 "" ""))
6129 (plus:SI (match_dup 0)
6135 operands[2] = const1_rtx;
6136 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6142 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6144 (label_ref (match_operand 1 "" ""))
6147 (plus:SI (match_dup 0)
6153 operands[2] = const1_rtx;
6154 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6160 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6162 (label_ref (match_operand 1 "" ""))
6165 (plus:SI (match_dup 0)
6171 output_asm_insn (AS1 (dec%L0,%0), operands);
6177 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6179 (label_ref (match_operand 1 "" ""))
6182 (plus:SI (match_dup 0)
6188 output_asm_insn (AS1 (dec%L0,%0), operands);
6194 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6196 (label_ref (match_operand 1 "" ""))
6199 (plus:SI (match_dup 0)
6205 output_asm_insn (AS1 (inc%L0,%0), operands);
6211 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6213 (label_ref (match_operand 1 "" ""))
6216 (plus:SI (match_dup 0)
6222 output_asm_insn (AS1 (inc%L0,%0), operands);
6226 ;; Implement switch statements when generating PIC code. Switches are
6227 ;; implemented by `tablejump' when not using -fpic.
6229 ;; Emit code here to do the range checking and make the index zero based.
6231 (define_expand "casesi"
6233 (match_operand:SI 0 "general_operand" ""))
6235 (minus:SI (match_dup 5)
6236 (match_operand:SI 1 "general_operand" "")))
6238 (compare:CC (match_dup 6)
6239 (match_operand:SI 2 "general_operand" "")))
6241 (if_then_else (gtu (cc0)
6243 (label_ref (match_operand 4 "" ""))
6247 (minus:SI (reg:SI 3)
6248 (mem:SI (plus:SI (mult:SI (match_dup 6)
6250 (label_ref (match_operand 3 "" ""))))))
6251 (clobber (match_scratch:SI 7 ""))])]
6255 operands[5] = gen_reg_rtx (SImode);
6256 operands[6] = gen_reg_rtx (SImode);
6257 current_function_uses_pic_offset_table = 1;
6260 ;; Implement a casesi insn.
6262 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
6265 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
6267 ;; 1. An expression involving an external reference may only use the
6268 ;; addition operator, and only with an assembly-time constant.
6269 ;; The example above satisfies this because ".-.L2" is a constant.
6271 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
6272 ;; given the value of "GOT - .", where GOT is the actual address of
6273 ;; the Global Offset Table. Therefore, the .long above actually
6274 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
6275 ;; expression "GOT - .L2" by itself would generate an error from as(1).
6277 ;; The pattern below emits code that looks like this:
6280 ;; subl TABLE@GOTOFF(%ebx,index,4),reg
6283 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
6284 ;; the addr_diff_vec is known to be part of this module.
6286 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
6287 ;; evaluates to just ".L2".
6291 (minus:SI (reg:SI 3)
6293 (mult:SI (match_operand:SI 0 "register_operand" "r")
6295 (label_ref (match_operand 1 "" ""))))))
6296 (clobber (match_scratch:SI 2 "=&r"))]
6302 xops[0] = operands[0];
6303 xops[1] = operands[1];
6304 xops[2] = operands[2];
6305 xops[3] = pic_offset_table_rtx;
6307 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
6308 output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
6309 output_asm_insn (AS1 (jmp,%*%2), xops);
6310 ASM_OUTPUT_ALIGN (asm_out_file, i386_align_jumps);
6314 (define_insn "tablejump"
6315 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
6316 (use (label_ref (match_operand 1 "" "")))]
6322 return AS1 (jmp,%*%0);
6327 ;; If generating PIC code, the predicate indirect_operand will fail
6328 ;; for operands[0] containing symbolic references on all of the named
6329 ;; call* patterns. Each named pattern is followed by an unnamed pattern
6330 ;; that matches any call to a symbolic CONST (ie, a symbol_ref). The
6331 ;; unnamed patterns are only used while generating PIC code, because
6332 ;; otherwise the named patterns match.
6334 ;; Call subroutine returning no value.
6336 (define_expand "call_pop"
6337 [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
6338 (match_operand:SI 1 "general_operand" ""))
6341 (match_operand:SI 3 "immediate_operand" "")))])]
6348 current_function_uses_pic_offset_table = 1;
6350 /* With half-pic, force the address into a register. */
6351 addr = XEXP (operands[0], 0);
6352 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6353 XEXP (operands[0], 0) = force_reg (Pmode, addr);
6355 if (! expander_call_insn_operand (operands[0], QImode))
6357 = change_address (operands[0], VOIDmode,
6358 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
6362 [(call (match_operand:QI 0 "call_insn_operand" "m")
6363 (match_operand:SI 1 "general_operand" "g"))
6364 (set (reg:SI 7) (plus:SI (reg:SI 7)
6365 (match_operand:SI 3 "immediate_operand" "i")))]
6369 if (GET_CODE (operands[0]) == MEM
6370 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6372 operands[0] = XEXP (operands[0], 0);
6373 return AS1 (call,%*%0);
6376 return AS1 (call,%P0);
6380 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6381 (match_operand:SI 1 "general_operand" "g"))
6382 (set (reg:SI 7) (plus:SI (reg:SI 7)
6383 (match_operand:SI 3 "immediate_operand" "i")))]
6387 (define_expand "call"
6388 [(call (match_operand:QI 0 "indirect_operand" "")
6389 (match_operand:SI 1 "general_operand" ""))]
6390 ;; Operand 1 not used on the i386.
6397 current_function_uses_pic_offset_table = 1;
6399 /* With half-pic, force the address into a register. */
6400 addr = XEXP (operands[0], 0);
6401 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6402 XEXP (operands[0], 0) = force_reg (Pmode, addr);
6404 if (! expander_call_insn_operand (operands[0], QImode))
6406 = change_address (operands[0], VOIDmode,
6407 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
6411 [(call (match_operand:QI 0 "call_insn_operand" "m")
6412 (match_operand:SI 1 "general_operand" "g"))]
6413 ;; Operand 1 not used on the i386.
6417 if (GET_CODE (operands[0]) == MEM
6418 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6420 operands[0] = XEXP (operands[0], 0);
6421 return AS1 (call,%*%0);
6424 return AS1 (call,%P0);
6428 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6429 (match_operand:SI 1 "general_operand" "g"))]
6430 ;; Operand 1 not used on the i386.
6434 ;; Call subroutine, returning value in operand 0
6435 ;; (which must be a hard register).
6437 (define_expand "call_value_pop"
6438 [(parallel [(set (match_operand 0 "" "")
6439 (call (match_operand:QI 1 "indirect_operand" "")
6440 (match_operand:SI 2 "general_operand" "")))
6443 (match_operand:SI 4 "immediate_operand" "")))])]
6450 current_function_uses_pic_offset_table = 1;
6452 /* With half-pic, force the address into a register. */
6453 addr = XEXP (operands[1], 0);
6454 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6455 XEXP (operands[1], 0) = force_reg (Pmode, addr);
6457 if (! expander_call_insn_operand (operands[1], QImode))
6459 = change_address (operands[1], VOIDmode,
6460 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
6464 [(set (match_operand 0 "" "=rf")
6465 (call (match_operand:QI 1 "call_insn_operand" "m")
6466 (match_operand:SI 2 "general_operand" "g")))
6467 (set (reg:SI 7) (plus:SI (reg:SI 7)
6468 (match_operand:SI 4 "immediate_operand" "i")))]
6472 if (GET_CODE (operands[1]) == MEM
6473 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6475 operands[1] = XEXP (operands[1], 0);
6476 output_asm_insn (AS1 (call,%*%1), operands);
6479 output_asm_insn (AS1 (call,%P1), operands);
6485 [(set (match_operand 0 "" "=rf")
6486 (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6487 (match_operand:SI 2 "general_operand" "g")))
6488 (set (reg:SI 7) (plus:SI (reg:SI 7)
6489 (match_operand:SI 4 "immediate_operand" "i")))]
6493 (define_expand "call_value"
6494 [(set (match_operand 0 "" "")
6495 (call (match_operand:QI 1 "indirect_operand" "")
6496 (match_operand:SI 2 "general_operand" "")))]
6497 ;; Operand 2 not used on the i386.
6504 current_function_uses_pic_offset_table = 1;
6506 /* With half-pic, force the address into a register. */
6507 addr = XEXP (operands[1], 0);
6508 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6509 XEXP (operands[1], 0) = force_reg (Pmode, addr);
6511 if (! expander_call_insn_operand (operands[1], QImode))
6513 = change_address (operands[1], VOIDmode,
6514 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
6518 [(set (match_operand 0 "" "=rf")
6519 (call (match_operand:QI 1 "call_insn_operand" "m")
6520 (match_operand:SI 2 "general_operand" "g")))]
6521 ;; Operand 2 not used on the i386.
6525 if (GET_CODE (operands[1]) == MEM
6526 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6528 operands[1] = XEXP (operands[1], 0);
6529 output_asm_insn (AS1 (call,%*%1), operands);
6532 output_asm_insn (AS1 (call,%P1), operands);
6538 [(set (match_operand 0 "" "=rf")
6539 (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6540 (match_operand:SI 2 "general_operand" "g")))]
6541 ;; Operand 2 not used on the i386.
6545 ;; Call subroutine returning any type.
6547 (define_expand "untyped_call"
6548 [(parallel [(call (match_operand 0 "" "")
6550 (match_operand 1 "" "")
6551 (match_operand 2 "" "")])]
6557 /* In order to give reg-stack an easier job in validating two
6558 coprocessor registers as containing a possible return value,
6559 simply pretend the untyped call returns a complex long double
6562 emit_call_insn (TARGET_80387
6563 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
6564 operands[0], const0_rtx)
6565 : gen_call (operands[0], const0_rtx));
6567 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6569 rtx set = XVECEXP (operands[2], 0, i);
6570 emit_move_insn (SET_DEST (set), SET_SRC (set));
6573 /* The optimizer does not know that the call sets the function value
6574 registers we stored in the result block. We avoid problems by
6575 claiming that all hard registers are used and clobbered at this
6577 emit_insn (gen_blockage ());
6582 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6583 ;; all of memory. This blocks insns from being moved across this point.
6585 (define_insn "blockage"
6586 [(unspec_volatile [(const_int 0)] 0)]
6590 ;; Insn emitted into the body of a function to return from a function.
6591 ;; This is only done if the function's epilogue is known to be simple.
6592 ;; See comments for simple_386_epilogue in i386.c.
6594 (define_expand "return"
6596 "ix86_can_use_return_insn_p ()"
6599 (define_insn "return_internal"
6604 (define_insn "return_pop_internal"
6606 (use (match_operand:SI 0 "const_int_operand" ""))]
6615 (define_expand "prologue"
6620 ix86_expand_prologue ();
6624 ;; The use of UNSPEC here is currently not necessary - a simple SET of ebp
6625 ;; to itself would be enough. But this way we are safe even if some optimizer
6626 ;; becomes too clever in the future.
6627 (define_insn "prologue_set_stack_ptr"
6629 (minus:SI (reg:SI 7) (match_operand:SI 0 "immediate_operand" "i")))
6630 (set (reg:SI 6) (unspec:SI [(reg:SI 6)] 4))]
6636 xops[0] = operands[0];
6637 xops[1] = stack_pointer_rtx;
6638 output_asm_insn (AS2 (sub%L1,%0,%1), xops);
6642 (define_insn "prologue_set_got"
6643 [(set (match_operand:SI 0 "" "")
6645 [(plus:SI (match_dup 0)
6646 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
6647 (minus:SI (pc) (match_operand 2 "" ""))))] 1))]
6653 if (TARGET_DEEP_BRANCH_PREDICTION)
6655 sprintf (buffer, \"addl %s,%%0\", XSTR (operands[1], 0));
6656 output_asm_insn (buffer, operands);
6660 sprintf (buffer, \"addl %s+[.-%%P2],%%0\", XSTR (operands[1], 0));
6661 output_asm_insn (buffer, operands);
6666 (define_insn "prologue_get_pc"
6667 [(set (match_operand:SI 0 "" "")
6668 (unspec_volatile [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
6674 output_asm_insn (AS1 (call,%P1), operands);
6675 if (! TARGET_DEEP_BRANCH_PREDICTION)
6677 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1]));
6682 (define_insn "prologue_get_pc_and_set_got"
6683 [(unspec_volatile [(match_operand:SI 0 "" "")] 3)]
6687 operands[1] = gen_label_rtx ();
6688 output_asm_insn (AS1 (call,%P1), operands);
6689 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
6690 CODE_LABEL_NUMBER (operands[1]));
6691 output_asm_insn (AS1 (pop%L0,%0), operands);
6692 output_asm_insn (\"addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0\", operands);
6696 (define_expand "epilogue"
6701 ix86_expand_epilogue ();
6705 (define_insn "epilogue_set_stack_ptr"
6706 [(set (reg:SI 7) (reg:SI 6))
6707 (clobber (reg:SI 6))]
6713 xops[0] = frame_pointer_rtx;
6714 xops[1] = stack_pointer_rtx;
6715 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
6719 (define_insn "leave"
6721 (clobber (reg:SI 6))
6722 (clobber (reg:SI 7))]
6727 [(set (match_operand:SI 0 "register_operand" "r")
6728 (mem:SI (reg:SI 7)))
6729 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))]
6733 output_asm_insn (AS1 (pop%L0,%P0), operands);
6737 (define_expand "movstrsi"
6738 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
6739 (match_operand:BLK 1 "memory_operand" ""))
6740 (use (match_operand:SI 2 "const_int_operand" ""))
6741 (use (match_operand:SI 3 "const_int_operand" ""))
6742 (clobber (match_scratch:SI 4 ""))
6743 (clobber (match_dup 5))
6744 (clobber (match_dup 6))])]
6750 if (GET_CODE (operands[2]) != CONST_INT)
6753 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
6754 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
6756 operands[5] = addr0;
6757 operands[6] = addr1;
6759 operands[0] = change_address (operands[0], VOIDmode, addr0);
6760 operands[1] = change_address (operands[1], VOIDmode, addr1);
6763 ;; It might seem that operands 0 & 1 could use predicate register_operand.
6764 ;; But strength reduction might offset the MEM expression. So we let
6765 ;; reload put the address into %edi & %esi.
6768 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
6769 (mem:BLK (match_operand:SI 1 "address_operand" "S")))
6770 (use (match_operand:SI 2 "const_int_operand" "n"))
6771 (use (match_operand:SI 3 "immediate_operand" "i"))
6772 (clobber (match_scratch:SI 4 "=&c"))
6773 (clobber (match_dup 0))
6774 (clobber (match_dup 1))]
6780 output_asm_insn (\"cld\", operands);
6781 if (GET_CODE (operands[2]) == CONST_INT)
6783 if (INTVAL (operands[2]) & ~0x03)
6785 xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
6786 xops[1] = operands[4];
6788 output_asm_insn (AS2 (mov%L1,%0,%1), xops);
6790 output_asm_insn (\"rep movsd\", xops);
6792 output_asm_insn (\"rep\;movsl\", xops);
6795 if (INTVAL (operands[2]) & 0x02)
6796 output_asm_insn (\"movsw\", operands);
6797 if (INTVAL (operands[2]) & 0x01)
6798 output_asm_insn (\"movsb\", operands);
6805 (define_expand "clrstrsi"
6806 [(set (match_dup 3) (const_int 0))
6807 (parallel [(set (match_operand:BLK 0 "memory_operand" "")
6809 (use (match_operand:SI 1 "const_int_operand" ""))
6810 (use (match_operand:SI 2 "const_int_operand" ""))
6812 (clobber (match_scratch:SI 4 ""))
6813 (clobber (match_dup 5))])]
6819 if (GET_CODE (operands[1]) != CONST_INT)
6822 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
6824 operands[3] = gen_reg_rtx (SImode);
6825 operands[5] = addr0;
6827 operands[0] = gen_rtx_MEM (BLKmode, addr0);
6830 ;; It might seem that operand 0 could use predicate register_operand.
6831 ;; But strength reduction might offset the MEM expression. So we let
6832 ;; reload put the address into %edi.
6835 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
6837 (use (match_operand:SI 1 "const_int_operand" "n"))
6838 (use (match_operand:SI 2 "immediate_operand" "i"))
6839 (use (match_operand:SI 3 "register_operand" "a"))
6840 (clobber (match_scratch:SI 4 "=&c"))
6841 (clobber (match_dup 0))]
6847 output_asm_insn (\"cld\", operands);
6848 if (GET_CODE (operands[1]) == CONST_INT)
6850 if (INTVAL (operands[1]) & ~0x03)
6852 xops[0] = GEN_INT ((INTVAL (operands[1]) >> 2) & 0x3fffffff);
6853 xops[1] = operands[4];
6855 output_asm_insn (AS2 (mov%L1,%0,%1), xops);
6857 output_asm_insn (\"rep stosd\", xops);
6859 output_asm_insn (\"rep\;stosl\", xops);
6862 if (INTVAL (operands[1]) & 0x02)
6863 output_asm_insn (\"stosw\", operands);
6864 if (INTVAL (operands[1]) & 0x01)
6865 output_asm_insn (\"stosb\", operands);
6872 (define_expand "cmpstrsi"
6873 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6874 (compare:SI (match_operand:BLK 1 "general_operand" "")
6875 (match_operand:BLK 2 "general_operand" "")))
6876 (use (match_operand:SI 3 "general_operand" ""))
6877 (use (match_operand:SI 4 "immediate_operand" ""))
6878 (clobber (match_dup 5))
6879 (clobber (match_dup 6))
6880 (clobber (match_dup 3))])]
6886 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
6887 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
6888 operands[3] = copy_to_mode_reg (SImode, operands[3]);
6890 operands[5] = addr1;
6891 operands[6] = addr2;
6893 operands[1] = gen_rtx_MEM (BLKmode, addr1);
6894 operands[2] = gen_rtx_MEM (BLKmode, addr2);
6898 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
6899 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
6901 ;; It might seem that operands 0 & 1 could use predicate register_operand.
6902 ;; But strength reduction might offset the MEM expression. So we let
6903 ;; reload put the address into %edi & %esi.
6905 ;; ??? Most comparisons have a constant length, and it's therefore
6906 ;; possible to know that the length is non-zero, and to avoid the extra
6907 ;; code to handle zero-length compares.
6910 [(set (match_operand:SI 0 "register_operand" "=&r")
6911 (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
6912 (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
6913 (use (match_operand:SI 3 "register_operand" "c"))
6914 (use (match_operand:SI 4 "immediate_operand" "i"))
6915 (clobber (match_dup 1))
6916 (clobber (match_dup 2))
6917 (clobber (match_dup 3))]
6923 label = gen_label_rtx ();
6925 output_asm_insn (\"cld\", operands);
6926 output_asm_insn (AS2 (xor%L0,%0,%0), operands);
6927 output_asm_insn (\"repz\;cmps%B2\", operands);
6928 output_asm_insn (\"je %l0\", &label);
6930 xops[0] = operands[0];
6931 xops[1] = const1_rtx;
6932 output_asm_insn (AS2 (sbb%L0,%0,%0), xops);
6933 if (QI_REG_P (xops[0]))
6934 output_asm_insn (AS2 (or%B0,%1,%b0), xops);
6936 output_asm_insn (AS2 (or%L0,%1,%0), xops);
6938 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
6944 (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
6945 (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
6946 (use (match_operand:SI 2 "register_operand" "c"))
6947 (use (match_operand:SI 3 "immediate_operand" "i"))
6948 (clobber (match_dup 0))
6949 (clobber (match_dup 1))
6950 (clobber (match_dup 2))]
6956 cc_status.flags |= CC_NOT_SIGNED;
6958 xops[0] = gen_rtx_REG (QImode, 0);
6959 xops[1] = CONST0_RTX (QImode);
6961 output_asm_insn (\"cld\", operands);
6962 output_asm_insn (AS2 (test%B0,%1,%0), xops);
6963 return \"repz\;cmps%B2\";
6967 ;; Note, you cannot optimize away the branch following the bsfl by assuming
6968 ;; that the destination is not modified if the input is 0, since not all
6969 ;; x86 implementations do this.
6971 (define_expand "ffssi2"
6972 [(set (match_operand:SI 0 "general_operand" "")
6973 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
6977 rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode);
6979 emit_insn (gen_ffssi_1 (temp, operands[1]));
6980 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0);
6981 emit_jump_insn (gen_bne (label));
6982 emit_move_insn (temp, constm1_rtx);
6984 temp = expand_binop (SImode, add_optab, temp, const1_rtx,
6985 operands[0], 0, OPTAB_WIDEN);
6987 if (temp != operands[0])
6988 emit_move_insn (operands[0], temp);
6992 (define_insn "ffssi_1"
6993 [(set (match_operand:SI 0 "register_operand" "=r")
6994 (unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
6996 "* return AS2 (bsf%L0,%1,%0);")
6998 (define_expand "ffshi2"
6999 [(set (match_operand:SI 0 "general_operand" "")
7000 (ffs:HI (match_operand:HI 1 "general_operand" "")))]
7004 rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode);
7006 emit_insn (gen_ffshi_1 (temp, operands[1]));
7007 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0);
7008 emit_jump_insn (gen_bne (label));
7009 emit_move_insn (temp, constm1_rtx);
7011 temp = expand_binop (HImode, add_optab, temp, const1_rtx,
7012 operands[0], 0, OPTAB_WIDEN);
7014 if (temp != operands[0])
7015 emit_move_insn (operands[0], temp);
7019 (define_insn "ffshi_1"
7020 [(set (match_operand:HI 0 "register_operand" "=r")
7021 (unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
7023 "* return AS2 (bsf%W0,%1,%0);")
7025 ;; These patterns match the binary 387 instructions for addM3, subM3,
7026 ;; mulM3 and divM3. There are three patterns for each of DFmode and
7027 ;; SFmode. The first is the normal insn, the second the same insn but
7028 ;; with one operand a conversion, and the third the same insn but with
7029 ;; the other operand a conversion. The conversion may be SFmode or
7030 ;; SImode if the target mode DFmode, but only SImode if the target mode
7034 [(set (match_operand:DF 0 "register_operand" "=f,f")
7035 (match_operator:DF 3 "binary_387_op"
7036 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
7037 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
7039 "* return output_387_binary_op (insn, operands);"
7041 (cond [(match_operand:DF 3 "is_mul" "")
7042 (const_string "fpmul")
7043 (match_operand:DF 3 "is_div" "")
7044 (const_string "fpdiv")
7046 (const_string "fpop")
7051 [(set (match_operand:DF 0 "register_operand" "=f")
7052 (match_operator:DF 3 "binary_387_op"
7053 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "rm"))
7054 (match_operand:DF 2 "register_operand" "0")]))]
7056 "* return output_387_binary_op (insn, operands);"
7058 (cond [(match_operand:DF 3 "is_mul" "")
7059 (const_string "fpmul")
7060 (match_operand:DF 3 "is_div" "")
7061 (const_string "fpdiv")
7063 (const_string "fpop")
7068 [(set (match_operand:XF 0 "register_operand" "=f,f")
7069 (match_operator:XF 3 "binary_387_op"
7070 [(match_operand:XF 1 "register_operand" "0,f")
7071 (match_operand:XF 2 "register_operand" "f,0")]))]
7073 "* return output_387_binary_op (insn, operands);"
7075 (cond [(match_operand:DF 3 "is_mul" "")
7076 (const_string "fpmul")
7077 (match_operand:DF 3 "is_div" "")
7078 (const_string "fpdiv")
7080 (const_string "fpop")
7085 [(set (match_operand:XF 0 "register_operand" "=f")
7086 (match_operator:XF 3 "binary_387_op"
7087 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "rm"))
7088 (match_operand:XF 2 "register_operand" "0")]))]
7090 "* return output_387_binary_op (insn, operands);"
7092 (cond [(match_operand:DF 3 "is_mul" "")
7093 (const_string "fpmul")
7094 (match_operand:DF 3 "is_div" "")
7095 (const_string "fpdiv")
7097 (const_string "fpop")
7102 [(set (match_operand:XF 0 "register_operand" "=f,f")
7103 (match_operator:XF 3 "binary_387_op"
7104 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7105 (match_operand:XF 2 "register_operand" "0,f")]))]
7107 "* return output_387_binary_op (insn, operands);"
7109 (cond [(match_operand:DF 3 "is_mul" "")
7110 (const_string "fpmul")
7111 (match_operand:DF 3 "is_div" "")
7112 (const_string "fpdiv")
7114 (const_string "fpop")
7119 [(set (match_operand:XF 0 "register_operand" "=f")
7120 (match_operator:XF 3 "binary_387_op"
7121 [(match_operand:XF 1 "register_operand" "0")
7122 (float:XF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
7124 "* return output_387_binary_op (insn, operands);"
7126 (cond [(match_operand:DF 3 "is_mul" "")
7127 (const_string "fpmul")
7128 (match_operand:DF 3 "is_div" "")
7129 (const_string "fpdiv")
7131 (const_string "fpop")
7136 [(set (match_operand:XF 0 "register_operand" "=f,f")
7137 (match_operator:XF 3 "binary_387_op"
7138 [(match_operand:XF 1 "register_operand" "0,f")
7140 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7142 "* return output_387_binary_op (insn, operands);"
7144 (cond [(match_operand:DF 3 "is_mul" "")
7145 (const_string "fpmul")
7146 (match_operand:DF 3 "is_div" "")
7147 (const_string "fpdiv")
7149 (const_string "fpop")
7154 [(set (match_operand:DF 0 "register_operand" "=f,f")
7155 (match_operator:DF 3 "binary_387_op"
7156 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7157 (match_operand:DF 2 "register_operand" "0,f")]))]
7159 "* return output_387_binary_op (insn, operands);"
7161 (cond [(match_operand:DF 3 "is_mul" "")
7162 (const_string "fpmul")
7163 (match_operand:DF 3 "is_div" "")
7164 (const_string "fpdiv")
7166 (const_string "fpop")
7171 [(set (match_operand:DF 0 "register_operand" "=f")
7172 (match_operator:DF 3 "binary_387_op"
7173 [(match_operand:DF 1 "register_operand" "0")
7174 (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
7176 "* return output_387_binary_op (insn, operands);"
7178 (cond [(match_operand:DF 3 "is_mul" "")
7179 (const_string "fpmul")
7180 (match_operand:DF 3 "is_div" "")
7181 (const_string "fpdiv")
7183 (const_string "fpop")
7188 [(set (match_operand:DF 0 "register_operand" "=f,f")
7189 (match_operator:DF 3 "binary_387_op"
7190 [(match_operand:DF 1 "register_operand" "0,f")
7192 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7194 "* return output_387_binary_op (insn, operands);"
7196 (cond [(match_operand:DF 3 "is_mul" "")
7197 (const_string "fpmul")
7198 (match_operand:DF 3 "is_div" "")
7199 (const_string "fpdiv")
7201 (const_string "fpop")
7206 [(set (match_operand:SF 0 "register_operand" "=f,f")
7207 (match_operator:SF 3 "binary_387_op"
7208 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
7209 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
7211 "* return output_387_binary_op (insn, operands);"
7213 (cond [(match_operand:DF 3 "is_mul" "")
7214 (const_string "fpmul")
7215 (match_operand:DF 3 "is_div" "")
7216 (const_string "fpdiv")
7218 (const_string "fpop")
7223 [(set (match_operand:SF 0 "register_operand" "=f")
7224 (match_operator:SF 3 "binary_387_op"
7225 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "rm"))
7226 (match_operand:SF 2 "register_operand" "0")]))]
7228 "* return output_387_binary_op (insn, operands);"
7230 (cond [(match_operand:DF 3 "is_mul" "")
7231 (const_string "fpmul")
7232 (match_operand:DF 3 "is_div" "")
7233 (const_string "fpdiv")
7235 (const_string "fpop")
7240 [(set (match_operand:SF 0 "register_operand" "=f")
7241 (match_operator:SF 3 "binary_387_op"
7242 [(match_operand:SF 1 "register_operand" "0")
7243 (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
7245 "* return output_387_binary_op (insn, operands);"
7247 (cond [(match_operand:DF 3 "is_mul" "")
7248 (const_string "fpmul")
7249 (match_operand:DF 3 "is_div" "")
7250 (const_string "fpdiv")
7252 (const_string "fpop")
7256 (define_expand "strlensi"
7257 [(parallel [(set (match_dup 4)
7258 (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
7259 (match_operand:QI 2 "immediate_operand" "")
7260 (match_operand:SI 3 "immediate_operand" "")] 0))
7261 (clobber (match_dup 1))])
7263 (not:SI (match_dup 4)))
7264 (set (match_operand:SI 0 "register_operand" "")
7265 (plus:SI (match_dup 5)
7270 if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1)
7275 /* well it seems that some optimizer does not combine a call like
7276 foo(strlen(bar), strlen(bar));
7277 when the move and the subtraction is done here. It does calculate
7278 the length just once when these instructions are done inside of
7279 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
7280 often used and I use one fewer register for the lifetime of
7281 output_strlen_unroll() this is better. */
7282 scratch = gen_reg_rtx (SImode);
7283 address = force_reg (SImode, XEXP (operands[1], 0));
7285 /* move address to scratch-register
7286 this is done here because the i586 can do the following and
7287 in the same cycle with the following move. */
7288 if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4)
7289 emit_insn (gen_movsi (scratch, address));
7291 emit_insn (gen_movsi (operands[0], address));
7293 if(TARGET_USE_Q_REG)
7294 emit_insn (gen_strlensi_unroll5 (operands[0],
7299 emit_insn (gen_strlensi_unroll4 (operands[0],
7304 /* gen_strlensi_unroll[45] returns the address of the zero
7305 at the end of the string, like memchr(), so compute the
7306 length by subtracting the startaddress. */
7307 emit_insn (gen_subsi3 (operands[0], operands[0], address));
7311 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7312 operands[4] = gen_reg_rtx (SImode);
7313 operands[5] = gen_reg_rtx (SImode);
7316 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7317 ;; But strength reduction might offset the MEM expression. So we let
7318 ;; reload put the address into %edi.
7321 [(set (match_operand:SI 0 "register_operand" "=&c")
7322 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
7323 (match_operand:QI 2 "immediate_operand" "a")
7324 (match_operand:SI 3 "immediate_operand" "i")] 0))
7325 (clobber (match_dup 1))]
7331 xops[0] = operands[0];
7332 xops[1] = constm1_rtx;
7333 output_asm_insn (\"cld\", operands);
7334 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
7335 return \"repnz\;scas%B2\";
7338 /* Conditional move define_insns. */
7340 (define_expand "movsicc"
7342 (set (match_operand 0 "register_operand" "")
7343 (if_then_else:SI (match_operand 1 "comparison_operator" "")
7344 (match_operand:SI 2 "nonimmediate_operand" "")
7345 (match_operand:SI 3 "nonimmediate_operand" "")))]
7349 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7352 (define_expand "movhicc"
7354 (set (match_operand 0 "register_operand" "")
7355 (if_then_else:HI (match_operand 1 "comparison_operator" "")
7356 (match_operand:HI 2 "nonimmediate_operand" "")
7357 (match_operand:HI 3 "nonimmediate_operand" "")))]
7361 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7364 (define_insn "movsicc_1"
7365 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,&r")
7366 (if_then_else:SI (match_operator 1 "comparison_operator"
7367 [(cc0) (const_int 0)])
7368 (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm")
7369 (match_operand:SI 3 "nonimmediate_operand" "0,rm,rm")))]
7373 switch (which_alternative)
7376 /* r <- cond ? arg : r */
7377 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7381 /* r <- cond ? r : arg */
7382 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7386 /* r <- cond ? arg1 : arg2 */
7387 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7388 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7395 (define_insn "movhicc_1"
7396 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,&r")
7397 (if_then_else:HI (match_operator 1 "comparison_operator"
7398 [(cc0) (const_int 0)])
7399 (match_operand:HI 2 "nonimmediate_operand" "rm,0,rm")
7400 (match_operand:HI 3 "nonimmediate_operand" "0,rm,rm")))]
7404 switch (which_alternative)
7407 /* r <- cond ? arg : r */
7408 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7412 /* r <- cond ? r : arg */
7413 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7417 /* r <- cond ? arg1 : arg2 */
7418 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7419 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7426 ;; We need to disable the FP forms of these since they do not support
7427 ;; memory as written, but no input reloads are permitted for insns
7428 ;; that use cc0. Also, movxfcc is not present.
7430 (define_expand "movsfcc"
7432 (set (match_operand 0 "register_operand" "")
7433 (if_then_else:SF (match_operand 1 "comparison_operator" "")
7434 (match_operand:SF 2 "register_operand" "")
7435 (match_operand:SF 3 "register_operand" "")))]
7439 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7442 (define_expand "movdfcc"
7444 (set (match_operand 0 "register_operand" "t")
7445 (if_then_else:DF (match_operand 1 "comparison_operator" "")
7446 (match_operand:DF 2 "register_operand" "")
7447 (match_operand:DF 3 "register_operand" "")))]
7451 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7454 (define_expand "movxfcc"
7456 (set (match_operand 0 "register_operand" "")
7457 (if_then_else:XF (match_operand 1 "comparison_operator" "")
7458 (match_operand:XF 2 "register_operand" "")
7459 (match_operand:XF 3 "register_operand" "")))]
7463 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7466 (define_insn "movsfcc_1"
7467 [(set (match_operand:SF 0 "general_operand" "=f,f,&f")
7468 (if_then_else:SF (match_operator 1 "comparison_operator"
7469 [(cc0) (const_int 0)])
7470 (match_operand:SF 2 "register_operand" "0,f,f")
7471 (match_operand:SF 3 "register_operand" "f,0,f")))]
7475 switch (which_alternative)
7478 /* r <- cond ? arg : r */
7479 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7483 /* r <- cond ? r : arg */
7484 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7488 /* r <- cond ? r : arg */
7489 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7490 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7497 (define_insn "movdfcc_1"
7498 [(set (match_operand:DF 0 "general_operand" "=f,f,&f")
7499 (if_then_else:DF (match_operator 1 "comparison_operator"
7500 [(cc0) (const_int 0)])
7501 (match_operand:DF 2 "register_operand" "0,f,f")
7502 (match_operand:DF 3 "register_operand" "f,0,f")))]
7506 switch (which_alternative)
7509 /* r <- cond ? arg : r */
7510 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7514 /* r <- cond ? r : arg */
7515 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7519 /* r <- cond ? r : arg */
7520 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7521 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7528 (define_insn "strlensi_unroll"
7529 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
7530 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r"))
7531 (match_operand:SI 2 "immediate_operand" "i,i")] 0))
7532 (clobber (match_scratch:SI 3 "=&q,&r"))]
7534 "* return output_strlen_unroll (operands);")
7536 ;; the only difference between the following patterns is the register preference
7537 ;; on a pentium using a q-register saves one clock cycle per 4 characters
7539 (define_insn "strlensi_unroll4"
7540 [(set (match_operand:SI 0 "register_operand" "=r,r")
7541 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0"))
7542 (match_operand:SI 1 "immediate_operand" "i,i")
7543 (match_operand:SI 2 "register_operand" "+q,!r")] 0))
7544 (clobber (match_dup 2))]
7545 "(TARGET_USE_ANY_REG && optimize > 1)"
7546 "* return output_strlen_unroll (operands);")
7548 (define_insn "strlensi_unroll5"
7549 [(set (match_operand:SI 0 "register_operand" "=r")
7550 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0"))
7551 (match_operand:SI 1 "immediate_operand" "i")
7552 (match_operand:SI 2 "register_operand" "+q")] 0))
7553 (clobber (match_dup 2))]
7554 "(TARGET_USE_Q_REG && optimize > 1)"
7555 "* return output_strlen_unroll (operands);"
7558 (define_insn "allocate_stack_worker"
7559 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
7560 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
7561 (clobber (match_dup 0))]
7562 "TARGET_STACK_PROBE"
7563 "* return AS1(call,__alloca);")
7565 (define_expand "allocate_stack"
7566 [(set (match_operand:SI 0 "register_operand" "=r")
7567 (minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" "")))
7568 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))]
7569 "TARGET_STACK_PROBE"
7572 #ifdef CHECK_STACK_LIMIT
7573 if (GET_CODE (operands[1]) == CONST_INT
7574 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
7575 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
7579 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
7582 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
7586 (define_expand "nonlocal_goto_receiver"
7591 load_pic_register (1);