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))
1117 /* Fastest way to change a
0 to a
1.
1118 If inc%B0 isn't allowed, use inc%L0. */
1119 if (NON_QI_REG_P (operands[
0]))
1120 return AS1 (inc%L0,%
0);
1122 return AS1 (inc%B0,%
0);
1125 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1126 if (NON_QI_REG_P (operands[
0]) || NON_QI_REG_P (operands[
1]))
1127 return (AS2 (mov%L0,%k1,%k0));
1129 return (AS2 (mov%B0,%
1,%
0));
1132 ;; If it becomes necessary to support movstrictqi into %esi or %edi,
1133 ;; use the insn sequence:
1135 ;; shrdl $
8,srcreg,dstreg
1138 ;; If operands[
1] is a constant, then an andl/orl sequence would be
1141 (define_expand "movstrictqi"
1142 [(set (strict_low_part (match_operand:QI
0 "general_operand" ""))
1143 (match_operand:QI
1 "general_operand" ""))]
1147 /* Don't generate memory->memory moves, go through a register */
1149 && (reload_in_progress | reload_completed) ==
0
1150 && GET_CODE (operands[
0]) == MEM
1151 && GET_CODE (operands[
1]) == MEM)
1153 operands[
1] = force_reg (QImode, operands[
1]);
1158 [(set (strict_low_part (match_operand:QI
0 "nonimmediate_operand" "+qm,q"))
1159 (match_operand:QI
1 "general_operand" "*qn,m"))]
1160 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM) || (GET_CODE (operands[
1]) != MEM)"
1164 if (operands[
1] == const0_rtx && REG_P (operands[
0]))
1165 return AS2 (xor%B0,%
0,%
0);
1167 if (operands[
1] == const1_rtx
1168 && ! NON_QI_REG_P (operands[
0])
1169 && (link = find_reg_note (insn, REG_WAS_0,
0))
1170 /* Make sure the insn that stored the
0 is still present. */
1171 && ! INSN_DELETED_P (XEXP (link,
0))
1172 && GET_CODE (XEXP (link,
0)) != NOTE
1173 /* Make sure cross jumping didn't happen here. */
1174 && no_labels_between_p (XEXP (link,
0), insn)
1175 /* Make sure the reg hasn't been clobbered. */
1176 && ! reg_set_between_p (operands[
0], XEXP (link,
0), insn))
1177 /* Fastest way to change a
0 to a
1. */
1178 return AS1 (inc%B0,%
0);
1180 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1181 if (NON_QI_REG_P (operands[
0]) || NON_QI_REG_P (operands[
1]))
1184 return (AS2 (mov%L0,%k1,%k0));
1187 return AS2 (mov%B0,%
1,%
0);
1190 (define_insn "movsf_push"
1191 [(set (match_operand:SF
0 "push_operand" "=<,<")
1192 (match_operand:SF
1 "general_operand" "*rfF,m"))]
1193 "GET_CODE (operands[
1]) != MEM || reload_in_progress || reload_completed"
1196 if (STACK_REG_P (operands[
1]))
1200 if (! STACK_TOP_P (operands[
1]))
1203 xops[
0] = AT_SP (SFmode);
1204 xops[
1] = GEN_INT (
4);
1205 xops[
2] = stack_pointer_rtx;
1207 output_asm_insn (AS2 (sub%L2,%
1,%
2), xops);
1209 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1210 output_asm_insn (AS1 (fstp%S0,%
0), xops);
1212 output_asm_insn (AS1 (fst%S0,%
0), xops);
1217 return AS1 (push%L0,%
1);
1220 (define_insn "movsf_push_memory"
1221 [(set (match_operand:SF
0 "push_operand" "=<")
1222 (match_operand:SF
1 "memory_operand" "m"))]
1223 "TARGET_PUSH_MEMORY"
1224 "* return AS1 (push%L0,%
1);")
1226 (define_expand "movsf"
1227 [(set (match_operand:SF
0 "general_operand" "")
1228 (match_operand:SF
1 "general_operand" ""))]
1232 /* Don't generate memory->memory moves, go through a register */
1234 && (reload_in_progress | reload_completed) ==
0
1235 && GET_CODE (operands[
0]) == MEM
1236 && GET_CODE (operands[
1]) == MEM)
1238 operands[
1] = force_reg (SFmode, operands[
1]);
1241 /* If we are loading a floating point constant that isn't
0 or
1
1242 into a register, indicate we need the pic register loaded. This could
1243 be optimized into stores of constants if the target eventually moves
1244 to memory, but better safe than sorry. */
1245 else if ((reload_in_progress | reload_completed) ==
0
1246 && GET_CODE (operands[
0]) != MEM
1247 && GET_CODE (operands[
1]) == CONST_DOUBLE
1248 && !standard_80387_constant_p (operands[
1]))
1250 rtx insn, note, fp_const;
1252 fp_const = force_const_mem (SFmode, operands[
1]);
1254 current_function_uses_pic_offset_table =
1;
1256 insn = emit_insn (gen_rtx_SET (SFmode, operands[
0], fp_const));
1257 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
1260 XEXP (note,
0) = operands[
1];
1262 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[
1], REG_NOTES (insn));
1266 ;; For the purposes of regclass, prefer FLOAT_REGS.
1268 [(set (match_operand:SF
0 "nonimmediate_operand" "=*rfm,*rf,f,!*rm")
1269 (match_operand:SF
1 "general_operand" "*rf,*rfm,fG,fF"))]
1270 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM) || (GET_CODE (operands[
1]) != MEM)"
1273 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) !=
0;
1275 /* First handle a
`pop' insn or a `fld %st(
0)' */
1277 if (STACK_TOP_P (operands[
0]) && STACK_TOP_P (operands[
1]))
1280 return AS1 (fstp,%y0);
1282 return AS1 (fld,%y0);
1285 /* Handle a transfer between the
387 and a
386 register */
1287 if (STACK_TOP_P (operands[
0]) && NON_STACK_REG_P (operands[
1]))
1289 output_op_from_reg (operands[
1], AS1 (fld%z0,%y1));
1293 if (STACK_TOP_P (operands[
1]) && NON_STACK_REG_P (operands[
0]))
1295 output_to_reg (operands[
0], stack_top_dies,
0);
1299 /* Handle other kinds of writes from the
387 */
1301 if (STACK_TOP_P (operands[
1]))
1304 return AS1 (fstp%z0,%y0);
1306 return AS1 (fst%z0,%y0);
1309 /* Handle other kinds of reads to the
387 */
1311 if (STACK_TOP_P (operands[
0]) && GET_CODE (operands[
1]) == CONST_DOUBLE)
1312 return output_move_const_single (operands);
1314 if (STACK_TOP_P (operands[
0]))
1315 return AS1 (fld%z1,%y1);
1317 /* Handle all SFmode moves not involving the
387 */
1319 return singlemove_string (operands);
1321 [(set_attr "type" "fld")])
1324 (define_insn "swapsf"
1325 [(set (match_operand:SF
0 "register_operand" "f")
1326 (match_operand:SF
1 "register_operand" "f"))
1332 if (STACK_TOP_P (operands[
0]))
1333 return AS1 (fxch,%
1);
1335 return AS1 (fxch,%
0);
1338 (define_insn "movdf_push"
1339 [(set (match_operand:DF
0 "push_operand" "=<,<")
1340 (match_operand:DF
1 "general_operand" "*rfF,o"))]
1341 "GET_CODE (operands[
1]) != MEM || reload_in_progress || reload_completed"
1344 if (STACK_REG_P (operands[
1]))
1348 xops[
0] = AT_SP (DFmode);
1349 xops[
1] = GEN_INT (
8);
1350 xops[
2] = stack_pointer_rtx;
1352 output_asm_insn (AS2 (sub%L2,%
1,%
2), xops);
1354 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1355 output_asm_insn (AS1 (fstp%Q0,%
0), xops);
1357 output_asm_insn (AS1 (fst%Q0,%
0), xops);
1362 if (which_alternative ==
1)
1363 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode),
0,
0);
1365 return output_move_double (operands);
1368 (define_insn "movdf_push_memory"
1369 [(set (match_operand:DF
0 "push_operand" "=<")
1370 (match_operand:DF
1 "memory_operand" "o"))]
1371 "TARGET_PUSH_MEMORY"
1372 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode),
0,
0);")
1374 (define_expand "movdf"
1375 [(set (match_operand:DF
0 "general_operand" "")
1376 (match_operand:DF
1 "general_operand" ""))]
1380 /* Don't generate memory->memory moves, go through a register */
1382 && (reload_in_progress | reload_completed) ==
0
1383 && GET_CODE (operands[
0]) == MEM
1384 && GET_CODE (operands[
1]) == MEM)
1386 operands[
1] = force_reg (DFmode, operands[
1]);
1389 /* If we are loading a floating point constant that isn't
0 or
1 into a
1390 register, indicate we need the pic register loaded. This could be
1391 optimized into stores of constants if the target eventually moves to
1392 memory, but better safe than sorry. */
1393 else if ((reload_in_progress | reload_completed) ==
0
1394 && GET_CODE (operands[
0]) != MEM
1395 && GET_CODE (operands[
1]) == CONST_DOUBLE
1396 && !standard_80387_constant_p (operands[
1]))
1398 rtx insn, note, fp_const;
1400 fp_const = force_const_mem (DFmode, operands[
1]);
1402 current_function_uses_pic_offset_table =
1;
1404 insn = emit_insn (gen_rtx_SET (DFmode, operands[
0], fp_const));
1405 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
1408 XEXP (note,
0) = operands[
1];
1410 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[
1], REG_NOTES (insn));
1414 ;; For the purposes of regclass, prefer FLOAT_REGS.
1416 [(set (match_operand:DF
0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
1417 (match_operand:DF
1 "general_operand" "fmG,f,*rfm,*rfF"))]
1418 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM)
1419 || (GET_CODE (operands[
1]) != MEM)"
1422 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) !=
0;
1424 /* First handle a
`pop' insn or a `fld %st(
0)' */
1426 if (STACK_TOP_P (operands[
0]) && STACK_TOP_P (operands[
1]))
1429 return AS1 (fstp,%y0);
1431 return AS1 (fld,%y0);
1434 /* Handle a transfer between the
387 and a
386 register */
1436 if (STACK_TOP_P (operands[
0]) && NON_STACK_REG_P (operands[
1]))
1438 output_op_from_reg (operands[
1], AS1 (fld%z0,%y1));
1442 if (STACK_TOP_P (operands[
1]) && NON_STACK_REG_P (operands[
0]))
1444 output_to_reg (operands[
0], stack_top_dies,
0);
1448 /* Handle other kinds of writes from the
387 */
1450 if (STACK_TOP_P (operands[
1]))
1453 return AS1 (fstp%z0,%y0);
1455 return AS1 (fst%z0,%y0);
1458 /* Handle other kinds of reads to the
387 */
1460 if (STACK_TOP_P (operands[
0]) && GET_CODE (operands[
1]) == CONST_DOUBLE)
1461 return output_move_const_single (operands);
1463 if (STACK_TOP_P (operands[
0]))
1464 return AS1 (fld%z1,%y1);
1466 /* Handle all DFmode moves not involving the
387 */
1468 return output_move_double (operands);
1470 [(set_attr "type" "fld")])
1474 (define_insn "swapdf"
1475 [(set (match_operand:DF
0 "register_operand" "f")
1476 (match_operand:DF
1 "register_operand" "f"))
1482 if (STACK_TOP_P (operands[
0]))
1483 return AS1 (fxch,%
1);
1485 return AS1 (fxch,%
0);
1488 (define_insn "movxf_push"
1489 [(set (match_operand:XF
0 "push_operand" "=<,<")
1490 (match_operand:XF
1 "general_operand" "*rfF,o"))]
1491 "GET_CODE (operands[
1]) != MEM || reload_in_progress || reload_completed"
1494 if (STACK_REG_P (operands[
1]))
1498 xops[
0] = AT_SP (XFmode);
1499 xops[
1] = GEN_INT (
12);
1500 xops[
2] = stack_pointer_rtx;
1502 output_asm_insn (AS2 (sub%L2,%
1,%
2), xops);
1504 output_asm_insn (AS1 (fstp%T0,%
0), xops);
1505 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1506 output_asm_insn (AS1 (fld%T0,%
0), xops);
1511 if (which_alternative ==
1)
1512 return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode),
0,
0);
1514 return output_move_double (operands);
1517 (define_insn "movxf_push_memory"
1518 [(set (match_operand:XF
0 "push_operand" "=<")
1519 (match_operand:XF
1 "memory_operand" "o"))]
1520 "TARGET_PUSH_MEMORY"
1521 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode),
0,
0);")
1523 (define_expand "movxf"
1524 [(set (match_operand:XF
0 "general_operand" "")
1525 (match_operand:XF
1 "general_operand" ""))]
1529 /* Don't generate memory->memory moves, go through a register */
1531 && (reload_in_progress | reload_completed) ==
0
1532 && GET_CODE (operands[
0]) == MEM
1533 && GET_CODE (operands[
1]) == MEM)
1535 operands[
1] = force_reg (XFmode, operands[
1]);
1538 /* If we are loading a floating point constant that isn't
0 or
1
1539 into a register, indicate we need the pic register loaded. This could
1540 be optimized into stores of constants if the target eventually moves
1541 to memory, but better safe than sorry. */
1542 else if ((reload_in_progress | reload_completed) ==
0
1543 && GET_CODE (operands[
0]) != MEM
1544 && GET_CODE (operands[
1]) == CONST_DOUBLE
1545 && !standard_80387_constant_p (operands[
1]))
1547 rtx insn, note, fp_const;
1549 fp_const = force_const_mem (XFmode, operands[
1]);
1551 current_function_uses_pic_offset_table =
1;
1553 insn = emit_insn (gen_rtx_SET (XFmode, operands[
0], fp_const));
1554 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
1557 XEXP (note,
0) = operands[
1];
1559 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[
1], REG_NOTES (insn));
1565 [(set (match_operand:XF
0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
1566 (match_operand:XF
1 "general_operand" "fmG,f,*rfm,*rfF"))]
1567 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM)
1568 || (GET_CODE (operands[
1]) != MEM)"
1571 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) !=
0;
1573 /* First handle a
`pop' insn or a `fld %st(
0)' */
1575 if (STACK_TOP_P (operands[
0]) && STACK_TOP_P (operands[
1]))
1578 return AS1 (fstp,%y0);
1580 return AS1 (fld,%y0);
1583 /* Handle a transfer between the
387 and a
386 register */
1585 if (STACK_TOP_P (operands[
0]) && NON_STACK_REG_P (operands[
1]))
1587 output_op_from_reg (operands[
1], AS1 (fld%z0,%y1));
1591 if (STACK_TOP_P (operands[
1]) && NON_STACK_REG_P (operands[
0]))
1593 output_to_reg (operands[
0], stack_top_dies,
0);
1597 /* Handle other kinds of writes from the
387 */
1599 if (STACK_TOP_P (operands[
1]))
1601 output_asm_insn (AS1 (fstp%z0,%y0), operands);
1602 if (! stack_top_dies)
1603 return AS1 (fld%z0,%y0);
1608 /* Handle other kinds of reads to the
387 */
1610 if (STACK_TOP_P (operands[
0]) && GET_CODE (operands[
1]) == CONST_DOUBLE)
1611 return output_move_const_single (operands);
1613 if (STACK_TOP_P (operands[
0]))
1614 return AS1 (fld%z1,%y1);
1616 /* Handle all XFmode moves not involving the
387 */
1618 return output_move_double (operands);
1621 (define_insn "swapxf"
1622 [(set (match_operand:XF
0 "register_operand" "f")
1623 (match_operand:XF
1 "register_operand" "f"))
1629 if (STACK_TOP_P (operands[
0]))
1630 return AS1 (fxch,%
1);
1632 return AS1 (fxch,%
0);
1636 [(set (match_operand:DI
0 "push_operand" "=<,<,<,<")
1637 (match_operand:DI
1 "general_operand" "riF,o,o,o"))
1638 (clobber (match_scratch:SI
2 "=X,&r,&r,X"))
1639 (clobber (match_scratch:SI
3 "=X,&r,X,X"))]
1643 if (GET_CODE (operands[
1]) != MEM)
1644 return output_move_double (operands);
1647 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode),
2,
4);
1650 (define_insn "movdi"
1651 [(set (match_operand:DI
0 "general_operand" "=o,o,r,rm")
1652 (match_operand:DI
1 "general_operand" "o,o,m,riF"))
1653 (clobber (match_scratch:SI
2 "=&r,&r,X,X"))
1654 (clobber (match_scratch:SI
3 "=&r,X,X,X"))]
1658 rtx low[
2], high[
2], xop[
6];
1660 if (GET_CODE (operands[
0]) != MEM || GET_CODE (operands[
1]) != MEM)
1661 return output_move_double (operands);
1663 return output_move_memory (operands, insn, GET_MODE_SIZE (DImode),
2,
4);
1667 ;;- conversion instructions
1670 ;;- zero extension instructions
1671 ;; See comments by
`andsi' for when andl is faster than movzx.
1673 (define_insn "zero_extendhisi2"
1674 [(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
1675 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
1681 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1682 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1684 xops[0] = operands[0];
1685 xops[1] = GEN_INT (0xffff);
1686 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1689 if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1]))
1691 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1692 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1696 if (TARGET_ZERO_EXTEND_WITH_AND)
1698 xops[0] = operands[0];
1699 xops[1] = GEN_INT (0xffff);
1700 if (i386_aligned_p (operands[1]))
1701 output_asm_insn (AS2 (mov%L0,%k1,%k0),operands);
1703 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1704 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1709 return AS2 (movzx,%1,%0);
1711 return AS2 (movz%W0%L0,%1,%0);
1716 [(set (match_operand:SI 0 "register_operand" "")
1717 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1718 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])"
1721 (set (strict_low_part (match_dup 2))
1723 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1727 [(set (match_operand:SI 0 "register_operand" "")
1728 (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))]
1729 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])"
1730 [(set (strict_low_part (match_dup 2))
1733 (and:SI (match_dup 0)
1734 (const_int 65535)))]
1735 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1737 (define_insn "zero_extendqihi2"
1738 [(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
1739 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1745 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1746 && REG_P (operands[1])
1747 && REGNO (operands[0]) == REGNO (operands[1]))
1749 xops[0] = operands[0];
1750 xops[1] = GEN_INT (0xff);
1751 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1754 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1756 if(!reg_overlap_mentioned_p(operands[0],operands[1]))
1758 output_asm_insn (AS2 (xor%L0,%k0,%k0), operands);
1759 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1763 xops[0] = operands[0];
1764 xops[1] = GEN_INT (0xff);
1765 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1766 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1772 return AS2 (movzx,%1,%0);
1774 return AS2 (movz%B0%W0,%1,%0);
1779 [(set (match_operand:HI 0 "register_operand" "")
1780 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1781 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1782 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1785 (set (strict_low_part (match_dup 2))
1787 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1791 [(set (match_operand:HI 0 "register_operand" "")
1792 (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))]
1793 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1794 && reg_overlap_mentioned_p (operands[0], operands[1])"
1795 [(set (strict_low_part (match_dup 2))
1798 (and:HI (match_dup 0)
1800 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1803 [(set (match_operand:HI 0 "register_operand" "")
1804 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1805 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND"
1809 (and:HI (match_dup 0)
1811 "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0)
1812 operands[1] = SUBREG_REG (operands[1]);
1813 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG
1814 || REGNO (operands[0]) == REGNO (operands[1]))
1816 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));")
1818 (define_insn "zero_extendqisi2"
1819 [(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
1820 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1826 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1827 && REG_P (operands[1])
1828 && REGNO (operands[0]) == REGNO (operands[1]))
1830 xops[0] = operands[0];
1831 xops[1] = GEN_INT (0xff);
1832 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1835 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1837 if(!reg_overlap_mentioned_p (operands[0], operands[1]))
1839 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1840 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1844 xops[0] = operands[0];
1845 xops[1] = GEN_INT (0xff);
1846 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1847 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1852 if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG)
1854 xops[0] = operands[0];
1855 xops[1] = GEN_INT (0xff);
1856 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
1857 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
1858 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1863 return AS2 (movzx,%1,%0);
1865 return AS2 (movz%B0%L0,%1,%0);
1870 [(set (match_operand:SI 0 "register_operand" "")
1871 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1872 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1873 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1876 (set (strict_low_part (match_dup 2))
1878 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1882 [(set (match_operand:SI 0 "register_operand" "")
1883 (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))]
1884 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1885 && reg_overlap_mentioned_p (operands[0], operands[1])"
1886 [(set (strict_low_part (match_dup 2))
1889 (and:SI (match_dup 0)
1891 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1894 [(set (match_operand:SI 0 "register_operand" "")
1895 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1896 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
1897 && ! reg_overlap_mentioned_p (operands[0], operands[1])"
1901 (and:SI (match_dup 0)
1903 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
1905 (define_insn "zero_extendsidi2"
1906 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m")
1907 (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))]
1911 rtx high[2], low[2], xops[4];
1913 if (REG_P (operands[0]) && REG_P (operands[1])
1914 && REGNO (operands[0]) == REGNO (operands[1]))
1916 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1917 return AS2 (xor%L0,%0,%0);
1920 split_di (operands, 1, low, high);
1922 xops[1] = operands[1];
1924 xops[3] = const0_rtx;
1926 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
1927 if (GET_CODE (low[0]) == MEM)
1928 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
1930 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
1935 ;;- sign extension instructions
1937 (define_insn "extendsidi2"
1938 [(set (match_operand:DI 0 "register_operand" "=r")
1939 (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))]
1943 if (REGNO (operands[0]) == 0)
1945 /* This used to be cwtl, but that extends HI to SI somehow. */
1953 operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1954 output_asm_insn (AS2 (mov%L0,%0,%1), operands);
1956 operands[0] = GEN_INT (31);
1957 return AS2 (sar%L1,%0,%1);
1960 ;; Note that the i386 programmers' manual says that the opcodes
1961 ;; are named movsx..., but the assembler on Unix does not accept that.
1962 ;; We use what the Unix assembler expects.
1964 (define_insn "extendhisi2"
1965 [(set (match_operand:SI 0 "register_operand" "=r")
1966 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
1970 if (REGNO (operands[0]) == 0
1971 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
1979 return AS2 (movsx,%1,%0);
1981 return AS2 (movs%W0%L0,%1,%0);
1985 (define_insn "extendqihi2"
1986 [(set (match_operand:HI 0 "register_operand" "=r")
1987 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1991 if (REGNO (operands[0]) == 0
1992 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
1996 return AS2 (movsx,%1,%0);
1998 return AS2 (movs%B0%W0,%1,%0);
2002 (define_insn "extendqisi2"
2003 [(set (match_operand:SI 0 "register_operand" "=r")
2004 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2009 return AS2 (movsx,%1,%0);
2011 return AS2 (movs%B0%L0,%1,%0);
2016 ;; Truncation of long long -> 32 bit
2018 (define_expand "truncdisi2"
2019 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2020 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2024 /* Don't generate memory->memory moves, go through a register */
2026 && (reload_in_progress | reload_completed) == 0
2027 && GET_CODE (operands[0]) == MEM
2028 && GET_CODE (operands[1]) == MEM)
2030 rtx target = gen_reg_rtx (SImode);
2031 emit_insn (gen_truncdisi2 (target, operands[1]));
2032 emit_move_insn (operands[0], target);
2038 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2039 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2040 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2043 rtx low[2], high[2], xops[2];
2045 split_di (&operands[1], 1, low, high);
2046 xops[0] = operands[0];
2048 if (!rtx_equal_p (xops[0], xops[1]))
2049 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2055 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2056 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
2058 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2061 rtx low[2], high[2], xops[2];
2063 split_di (&operands[1], 1, low, high);
2064 xops[0] = operands[0];
2066 if (!rtx_equal_p (xops[0], xops[1]))
2067 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2074 ;; Conversions between float and double.
2076 (define_insn "extendsfdf2"
2077 [(set (match_operand:DF 0 "nonimmediate_operand" "=fm,f")
2079 (match_operand:SF 1 "nonimmediate_operand" "f,fm")))]
2083 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2085 if (NON_STACK_REG_P (operands[1]))
2087 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2091 if (NON_STACK_REG_P (operands[0]))
2093 output_to_reg (operands[0], stack_top_dies, 0);
2097 if (STACK_TOP_P (operands[0]))
2098 return AS1 (fld%z1,%y1);
2100 if (GET_CODE (operands[0]) == MEM)
2103 return AS1 (fstp%z0,%y0);
2105 return AS1 (fst%z0,%y0);
2111 (define_insn "extenddfxf2"
2112 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
2114 (match_operand:DF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
2118 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2120 if (NON_STACK_REG_P (operands[1]))
2122 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2126 if (NON_STACK_REG_P (operands[0]))
2128 output_to_reg (operands[0], stack_top_dies, 0);
2132 if (STACK_TOP_P (operands[0]))
2133 return AS1 (fld%z1,%y1);
2135 if (GET_CODE (operands[0]) == MEM)
2137 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2138 if (! stack_top_dies)
2139 return AS1 (fld%z0,%y0);
2146 (define_insn "extendsfxf2"
2147 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
2149 (match_operand:SF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
2153 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2155 if (NON_STACK_REG_P (operands[1]))
2157 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2161 if (NON_STACK_REG_P (operands[0]))
2163 output_to_reg (operands[0], stack_top_dies, 0);
2167 if (STACK_TOP_P (operands[0]))
2168 return AS1 (fld%z1,%y1);
2170 if (GET_CODE (operands[0]) == MEM)
2172 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2173 if (! stack_top_dies)
2174 return AS1 (fld%z0,%y0);
2181 (define_expand "truncdfsf2"
2182 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2184 (match_operand:DF 1 "register_operand" "")))
2185 (clobber (match_dup 2))])]
2189 operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2192 ;; This cannot output into an f-reg because there is no way to be sure
2193 ;; of truncating in that case. Otherwise this is just like a simple move
2194 ;; insn. So we pretend we can output to a reg in order to get better
2195 ;; register preferencing, but we really use a stack slot.
2198 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
2200 (match_operand:DF 1 "register_operand" "0,f")))
2201 (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
2205 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2207 if (GET_CODE (operands[0]) == MEM)
2210 return AS1 (fstp%z0,%0);
2212 return AS1 (fst%z0,%0);
2214 else if (STACK_TOP_P (operands[0]))
2216 output_asm_insn (AS1 (fstp%z2,%y2), operands);
2217 return AS1 (fld%z2,%y2);
2223 (define_insn "truncxfsf2"
2224 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r")
2226 (match_operand:XF 1 "register_operand" "f,f")))]
2230 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2232 if (NON_STACK_REG_P (operands[0]))
2234 if (stack_top_dies == 0)
2236 output_asm_insn (AS1 (fld,%y1), operands);
2239 output_to_reg (operands[0], stack_top_dies, 0);
2242 else if (GET_CODE (operands[0]) == MEM)
2245 return AS1 (fstp%z0,%0);
2248 output_asm_insn (AS1 (fld,%y1), operands);
2249 return AS1 (fstp%z0,%0);
2256 (define_insn "truncxfdf2"
2257 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!*r")
2259 (match_operand:XF 1 "register_operand" "f,f")))]
2263 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2265 if (NON_STACK_REG_P (operands[0]))
2267 if (stack_top_dies == 0)
2269 output_asm_insn (AS1 (fld,%y1), operands);
2272 output_to_reg (operands[0], stack_top_dies, 0);
2275 else if (GET_CODE (operands[0]) == MEM)
2278 return AS1 (fstp%z0,%0);
2281 output_asm_insn (AS1 (fld,%y1), operands);
2282 return AS1 (fstp%z0,%0);
2290 ;; The 387 requires that the stack top dies after converting to DImode.
2292 ;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
2293 ;; doing a signed conversion to DImode, and then taking just the low
2296 (define_expand "fixuns_truncxfsi2"
2298 (match_operand:XF 1 "register_operand" ""))
2299 (parallel [(set (match_dup 2)
2300 (fix:DI (fix:XF (match_dup 4))))
2301 (clobber (match_dup 4))
2302 (clobber (match_dup 5))
2303 (clobber (match_dup 6))
2304 (clobber (match_scratch:SI 7 ""))])
2305 (set (match_operand:SI 0 "general_operand" "")
2310 operands[2] = gen_reg_rtx (DImode);
2311 operands[3] = gen_lowpart (SImode, operands[2]);
2312 operands[4] = gen_reg_rtx (XFmode);
2313 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2314 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2317 (define_expand "fixuns_truncdfsi2"
2319 (match_operand:DF 1 "register_operand" ""))
2320 (parallel [(set (match_dup 2)
2321 (fix:DI (fix:DF (match_dup 4))))
2322 (clobber (match_dup 4))
2323 (clobber (match_dup 5))
2324 (clobber (match_dup 6))
2325 (clobber (match_scratch:SI 7 ""))])
2326 (set (match_operand:SI 0 "general_operand" "")
2331 operands[2] = gen_reg_rtx (DImode);
2332 operands[3] = gen_lowpart (SImode, operands[2]);
2333 operands[4] = gen_reg_rtx (DFmode);
2334 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2335 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2338 (define_expand "fixuns_truncsfsi2"
2340 (match_operand:SF 1 "register_operand" ""))
2341 (parallel [(set (match_dup 2)
2342 (fix:DI (fix:SF (match_dup 4))))
2343 (clobber (match_dup 4))
2344 (clobber (match_dup 5))
2345 (clobber (match_dup 6))
2346 (clobber (match_scratch:SI 7 ""))])
2347 (set (match_operand:SI 0 "general_operand" "")
2352 operands[2] = gen_reg_rtx (DImode);
2353 operands[3] = gen_lowpart (SImode, operands[2]);
2354 operands[4] = gen_reg_rtx (SFmode);
2355 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2356 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2359 ;; Signed conversion to DImode.
2361 (define_expand "fix_truncxfdi2"
2363 (match_operand:XF 1 "register_operand" ""))
2364 (parallel [(set (match_operand:DI 0 "general_operand" "")
2365 (fix:DI (fix:XF (match_dup 2))))
2366 (clobber (match_dup 2))
2367 (clobber (match_dup 3))
2368 (clobber (match_dup 4))
2369 (clobber (match_scratch:SI 5 ""))])]
2373 operands[1] = copy_to_mode_reg (XFmode, operands[1]);
2374 operands[2] = gen_reg_rtx (XFmode);
2375 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2376 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2379 (define_expand "fix_truncdfdi2"
2381 (match_operand:DF 1 "register_operand" ""))
2382 (parallel [(set (match_operand:DI 0 "general_operand" "")
2383 (fix:DI (fix:DF (match_dup 2))))
2384 (clobber (match_dup 2))
2385 (clobber (match_dup 3))
2386 (clobber (match_dup 4))
2387 (clobber (match_scratch:SI 5 ""))])]
2391 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
2392 operands[2] = gen_reg_rtx (DFmode);
2393 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2394 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2397 (define_expand "fix_truncsfdi2"
2399 (match_operand:SF 1 "register_operand" ""))
2400 (parallel [(set (match_operand:DI 0 "general_operand" "")
2401 (fix:DI (fix:SF (match_dup 2))))
2402 (clobber (match_dup 2))
2403 (clobber (match_dup 3))
2404 (clobber (match_dup 4))
2405 (clobber (match_scratch:SI 5 ""))])]
2409 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
2410 operands[2] = gen_reg_rtx (SFmode);
2411 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2412 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2415 ;; These match a signed conversion of either DFmode or SFmode to DImode.
2418 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2419 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "+f"))))
2420 (clobber (match_dup 1))
2421 (clobber (match_operand:SI 2 "memory_operand" "m"))
2422 (clobber (match_operand:DI 3 "memory_operand" "m"))
2423 (clobber (match_scratch:SI 4 "=&q"))]
2425 "* return output_fix_trunc (insn, operands);")
2428 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2429 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "+f"))))
2430 (clobber (match_dup 1))
2431 (clobber (match_operand:SI 2 "memory_operand" "m"))
2432 (clobber (match_operand:DI 3 "memory_operand" "m"))
2433 (clobber (match_scratch:SI 4 "=&q"))]
2435 "* return output_fix_trunc (insn, operands);")
2438 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2439 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "+f"))))
2440 (clobber (match_dup 1))
2441 (clobber (match_operand:SI 2 "memory_operand" "m"))
2442 (clobber (match_operand:DI 3 "memory_operand" "m"))
2443 (clobber (match_scratch:SI 4 "=&q"))]
2445 "* return output_fix_trunc (insn, operands);")
2447 ;; Signed MODE_FLOAT conversion to SImode.
2449 (define_expand "fix_truncxfsi2"
2450 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2452 (fix:XF (match_operand:XF 1 "register_operand" ""))))
2453 (clobber (match_dup 2))
2454 (clobber (match_dup 3))
2455 (clobber (match_scratch:SI 4 ""))])]
2459 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2460 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2463 (define_expand "fix_truncdfsi2"
2464 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2466 (fix:DF (match_operand:DF 1 "register_operand" ""))))
2467 (clobber (match_dup 2))
2468 (clobber (match_dup 3))
2469 (clobber (match_scratch:SI 4 ""))])]
2473 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2474 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2477 (define_expand "fix_truncsfsi2"
2478 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2480 (fix:SF (match_operand:SF 1 "register_operand" ""))))
2481 (clobber (match_dup 2))
2482 (clobber (match_dup 3))
2483 (clobber (match_scratch:SI 4 ""))])]
2487 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2488 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2492 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2493 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
2494 (clobber (match_operand:SI 2 "memory_operand" "m"))
2495 (clobber (match_operand:DI 3 "memory_operand" "m"))
2496 (clobber (match_scratch:SI 4 "=&q"))]
2498 "* return output_fix_trunc (insn, operands);")
2501 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2502 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2503 (clobber (match_operand:SI 2 "memory_operand" "m"))
2504 (clobber (match_operand:DI 3 "memory_operand" "m"))
2505 (clobber (match_scratch:SI 4 "=&q"))]
2507 "* return output_fix_trunc (insn, operands);")
2510 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2511 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
2512 (clobber (match_operand:SI 2 "memory_operand" "m"))
2513 (clobber (match_operand:DI 3 "memory_operand" "m"))
2514 (clobber (match_scratch:SI 4 "=&q"))]
2516 "* return output_fix_trunc (insn, operands);")
2518 ;; Conversion between fixed point and floating point.
2519 ;; The actual pattern that matches these is at the end of this file.
2521 ;; ??? Possibly represent floatunssidf2 here in gcc2.
2523 (define_expand "floatsisf2"
2524 [(set (match_operand:SF 0 "register_operand" "")
2525 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
2529 (define_expand "floatdisf2"
2530 [(set (match_operand:SF 0 "register_operand" "")
2531 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
2535 (define_expand "floatsidf2"
2536 [(set (match_operand:DF 0 "register_operand" "")
2537 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
2541 (define_expand "floatdidf2"
2542 [(set (match_operand:DF 0 "register_operand" "")
2543 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
2547 (define_expand "floatsixf2"
2548 [(set (match_operand:XF 0 "register_operand" "")
2549 (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
2553 (define_expand "floatdixf2"
2554 [(set (match_operand:XF 0 "register_operand" "")
2555 (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
2556 "TARGET_80387 && LONG_DOUBLE_TYPE_SIZE == 96"
2559 ;; This will convert from SImode or DImode to MODE_FLOAT.
2562 [(set (match_operand:XF 0 "register_operand" "=f")
2563 (float:XF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2567 if (NON_STACK_REG_P (operands[1]))
2569 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2572 else if (GET_CODE (operands[1]) == MEM)
2573 return AS1 (fild%z1,%1);
2579 [(set (match_operand:DF 0 "register_operand" "=f")
2580 (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2584 if (NON_STACK_REG_P (operands[1]))
2586 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2589 else if (GET_CODE (operands[1]) == MEM)
2590 return AS1 (fild%z1,%1);
2596 [(set (match_operand:SF 0 "register_operand" "=f")
2597 (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2601 if (NON_STACK_REG_P (operands[1]))
2603 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2606 else if (GET_CODE (operands[1]) == MEM)
2607 return AS1 (fild%z1,%1);
2613 [(set (match_operand:DF 0 "register_operand" "=f")
2614 (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
2618 if (NON_STACK_REG_P (operands[1]))
2620 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2623 else if (GET_CODE (operands[1]) == MEM)
2624 return AS1 (fild%z1,%1);
2630 [(set (match_operand:XF 0 "register_operand" "=f,f")
2631 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!*r")))]
2635 if (NON_STACK_REG_P (operands[1]))
2637 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2640 else if (GET_CODE (operands[1]) == MEM)
2641 return AS1 (fild%z1,%1);
2647 [(set (match_operand:SF 0 "register_operand" "=f")
2648 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
2652 if (NON_STACK_REG_P (operands[1]))
2654 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2657 else if (GET_CODE (operands[1]) == MEM)
2658 return AS1 (fild%z1,%1);
2663 ;;- add instructions
2665 (define_insn "addsidi3_1"
2666 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o")
2667 (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o")
2668 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri"))))
2669 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))]
2673 rtx low[3], high[3], xops[7], temp;
2677 split_di (operands, 2, low, high);
2678 high[2] = const0_rtx;
2679 low[2] = operands[2];
2681 if (!rtx_equal_p (operands[0], operands[1]))
2688 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2690 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2691 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2697 xops[6] = operands[3];
2698 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2699 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2700 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2701 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2702 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2703 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2708 output_asm_insn (AS2 (add%L0,%2,%0), low);
2709 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2713 (define_insn "addsidi3_2"
2714 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o")
2715 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r"))
2716 (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o")))
2717 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))]
2721 rtx low[3], high[3], xops[7], temp;
2725 split_di (operands, 2, low, high);
2726 high[2] = const0_rtx;
2727 low[2] = operands[2];
2729 if (!rtx_equal_p (operands[0], operands[1]))
2736 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2738 if (rtx_equal_p (low[0], operands[2]))
2740 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2741 output_asm_insn (AS2 (add%L0,%1,%0), low);
2742 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2745 if (rtx_equal_p (high[0], operands[2]))
2747 if (GET_CODE (operands[0]) != MEM)
2749 output_asm_insn (AS2 (mov%L0,%2,%0), low);
2750 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2751 output_asm_insn (AS2 (add%L0,%1,%0), low);
2752 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2756 /* It's too late to ask for a scratch now - but this
2757 will probably not happen too often. */
2758 output_asm_insn (AS2 (add%L1,%2,%1), low);
2759 output_asm_insn (AS2 (mov%L0,%1,%0), low);
2760 output_asm_insn (AS2 (mov%L1,%2,%1), low);
2761 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2762 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2763 output_asm_insn (AS2 (sub%L1,%0,%1), low);
2764 output_asm_insn (AS1 (neg%L1,%1), low);
2768 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2769 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2775 xops[6] = operands[3];
2776 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2777 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2778 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2779 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2780 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2781 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2786 output_asm_insn (AS2 (add%L0,%2,%0), low);
2787 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2791 (define_insn "adddi3"
2792 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
2793 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
2794 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
2795 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
2799 rtx low[3], high[3], xops[7], temp;
2803 if (rtx_equal_p (operands[0], operands[2]))
2806 operands[1] = operands[2];
2810 split_di (operands, 3, low, high);
2811 if (!rtx_equal_p (operands[0], operands[1]))
2818 if (GET_CODE (operands[0]) != MEM)
2820 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2821 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2827 xops[6] = operands[3];
2828 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2829 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2830 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2831 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2832 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2833 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2838 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
2844 xops[4] = operands[3];
2846 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
2847 output_asm_insn (AS2 (add%L1,%4,%1), xops);
2848 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
2849 output_asm_insn (AS2 (adc%L0,%4,%0), xops);
2852 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
2854 output_asm_insn (AS2 (add%L0,%2,%0), low);
2855 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2859 output_asm_insn (AS2 (add%L0,%2,%0), high);
2864 ;; On a 486, it is faster to do movl/addl than to do a single leal if
2865 ;; operands[1] and operands[2] are both registers.
2867 (define_expand "addsi3"
2868 [(set (match_operand:SI 0 "nonimmediate_operand" "")
2869 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
2870 (match_operand:SI 2 "general_operand" "")))]
2872 "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);")
2875 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
2876 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
2877 (match_operand:SI 2 "general_operand" "rmi,ri,ri")))]
2878 "ix86_binary_operator_ok (PLUS, SImode, operands)"
2881 if (REG_P (operands[0]) && REG_P (operands[1])
2882 && (REG_P (operands[2]) || GET_CODE (operands[2]) == CONST_INT)
2883 && REGNO (operands[0]) != REGNO (operands[1]))
2885 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
2886 return AS2 (add%L0,%1,%0);
2888 if (operands[2] == stack_pointer_rtx)
2893 operands[1] = operands[2];
2897 if (operands[2] != stack_pointer_rtx)
2900 operands[1] = SET_SRC (PATTERN (insn));
2901 return AS2 (lea%L0,%a1,%0);
2905 if (!rtx_equal_p (operands[0], operands[1]))
2906 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
2908 if (operands[2] == const1_rtx)
2909 return AS1 (inc%L0,%0);
2911 if (operands[2] == constm1_rtx)
2912 return AS1 (dec%L0,%0);
2914 /* subl $-128,%ebx is smaller than addl $128,%ebx. */
2915 if (GET_CODE (operands[2]) == CONST_INT
2916 && INTVAL (operands[2]) == 128)
2918 /* This doesn't compute the carry bit in the same way
2919 * as add%L0, but we use inc and dec above and they
2920 * don't set the carry bit at all. If inc/dec don't need
2921 * a CC_STATUS_INIT, this doesn't either... */
2922 operands[2] = GEN_INT (-128);
2923 return AS2 (sub%L0,%2,%0);
2926 return AS2 (add%L0,%2,%0);
2929 ;; addsi3 is faster, so put this after.
2931 (define_insn "movsi_lea"
2932 [(set (match_operand:SI 0 "register_operand" "=r")
2933 (match_operand:QI 1 "address_operand" "p"))]
2937 /* Adding a constant to a register is faster with an add. */
2938 /* ??? can this ever happen? */
2939 if (GET_CODE (operands[1]) == PLUS
2940 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
2941 && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
2943 operands[1] = XEXP (operands[1], 1);
2945 if (operands[1] == const1_rtx)
2946 return AS1 (inc%L0,%0);
2948 if (operands[1] == constm1_rtx)
2949 return AS1 (dec%L0,%0);
2951 return AS2 (add%L0,%1,%0);
2955 return AS2 (lea%L0,%a1,%0);
2958 ;; ??? `lea' here, for three operand add? If leaw is used, only %bx,
2959 ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
2960 ;; able to handle the operand. But leal always works?
2962 (define_expand "addhi3"
2963 [(set (match_operand:HI
0 "general_operand" "")
2964 (plus:HI (match_operand:HI
1 "nonimmediate_operand" "")
2965 (match_operand:HI
2 "general_operand" "")))]
2967 "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);")
2970 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
2971 (plus:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,
0")
2972 (match_operand:HI
2 "general_operand" "ri,rm")))]
2973 "ix86_binary_operator_ok (PLUS, HImode, operands)"
2976 /* ??? what about offsettable memory references? */
2977 if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */
2978 && QI_REG_P (operands[
0])
2979 && GET_CODE (operands[
2]) == CONST_INT
2980 && (INTVAL (operands[
2]) &
0xff) ==
0
2981 && i386_cc_probably_useless_p (insn))
2983 int byteval = (INTVAL (operands[
2]) >>
8) &
0xff;
2987 return AS1 (inc%B0,%h0);
2988 else if (byteval ==
255)
2989 return AS1 (dec%B0,%h0);
2991 operands[
2] = GEN_INT (byteval);
2992 return AS2 (add%B0,%
2,%h0);
2995 /* Use a
32-bit operation when possible, to avoid the prefix penalty. */
2996 if (REG_P (operands[
0])
2997 && i386_aligned_p (operands[
2])
2998 && i386_cc_probably_useless_p (insn))
3002 if (GET_CODE (operands[
2]) == CONST_INT)
3004 HOST_WIDE_INT intval =
0xffff & INTVAL (operands[
2]);
3007 return AS1 (inc%L0,%k0);
3009 if (intval ==
0xffff)
3010 return AS1 (dec%L0,%k0);
3012 operands[
2] = i386_sext16_if_const (operands[
2]);
3014 return AS2 (add%L0,%k2,%k0);
3017 if (operands[
2] == const1_rtx)
3018 return AS1 (inc%W0,%
0);
3020 if (operands[
2] == constm1_rtx
3021 || (GET_CODE (operands[
2]) == CONST_INT
3022 && INTVAL (operands[
2]) ==
65535))
3023 return AS1 (dec%W0,%
0);
3025 return AS2 (add%W0,%
2,%
0);
3028 (define_expand "addqi3"
3029 [(set (match_operand:QI
0 "general_operand" "")
3030 (plus:QI (match_operand:QI
1 "general_operand" "")
3031 (match_operand:QI
2 "general_operand" "")))]
3033 "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);")
3036 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
3037 (plus:QI (match_operand:QI
1 "nonimmediate_operand" "%
0,
0")
3038 (match_operand:QI
2 "general_operand" "qn,qmn")))]
3039 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3042 if (operands[
2] == const1_rtx)
3043 return AS1 (inc%B0,%
0);
3045 if (operands[
2] == constm1_rtx
3046 || (GET_CODE (operands[
2]) == CONST_INT
3047 && INTVAL (operands[
2]) ==
255))
3048 return AS1 (dec%B0,%
0);
3050 return AS2 (add%B0,%
2,%
0);
3053 ;Lennart Augustsson <augustss@cs.chalmers.se>
3054 ;says this pattern just makes slower code:
3058 ; leal -
80(%ebp),%eax
3062 ; [(set (match_operand:SI
0 "push_operand" "=<")
3063 ; (plus:SI (match_operand:SI
1 "register_operand" "%r")
3064 ; (match_operand:SI
2 "nonmemory_operand" "ri")))]
3069 ; xops[
0] = operands[
0];
3070 ; xops[
1] = operands[
1];
3071 ; xops[
2] = operands[
2];
3072 ; xops[
3] = gen_rtx_MEM (SImode, stack_pointer_rtx);
3073 ; output_asm_insn (
\"push%z1 %
1\", xops);
3074 ; output_asm_insn (AS2 (add%z3,%
2,%
3), xops);
3078 ;; The patterns that match these are at the end of this file.
3080 (define_expand "addxf3"
3081 [(set (match_operand:XF
0 "register_operand" "")
3082 (plus:XF (match_operand:XF
1 "register_operand" "")
3083 (match_operand:XF
2 "register_operand" "")))]
3087 (define_expand "adddf3"
3088 [(set (match_operand:DF
0 "register_operand" "")
3089 (plus:DF (match_operand:DF
1 "nonimmediate_operand" "")
3090 (match_operand:DF
2 "nonimmediate_operand" "")))]
3094 (define_expand "addsf3"
3095 [(set (match_operand:SF
0 "register_operand" "")
3096 (plus:SF (match_operand:SF
1 "nonimmediate_operand" "")
3097 (match_operand:SF
2 "nonimmediate_operand" "")))]
3101 ;;- subtract instructions
3103 (define_insn "subsidi3"
3104 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o")
3105 (minus:DI (match_operand:DI
1 "general_operand" "
0iF,
0,roiF,roiF,riF,o,o")
3106 (zero_extend:DI (match_operand:SI
2 "general_operand" "o,ri,ri,o,ri,i,r"))))
3107 (clobber (match_scratch:SI
3 "=X,X,X,X,X,&r,&r"))]
3111 rtx low[
3], high[
3], xops[
7];
3115 split_di (operands,
2, low, high);
3116 high[
2] = const0_rtx;
3117 low[
2] = operands[
2];
3119 if (!rtx_equal_p (operands[
0], operands[
1]))
3126 if (GET_CODE (operands[
0]) != MEM || GET_CODE (operands[
1]) != MEM)
3128 output_asm_insn (AS2 (mov%L1,%
3,%
1), xops);
3129 output_asm_insn (AS2 (mov%L0,%
2,%
0), xops);
3135 xops[
6] = operands[
3];
3136 output_asm_insn (AS2 (mov%L6,%
3,%
6), xops);
3137 output_asm_insn (AS2 (sub%L6,%
5,%
6), xops);
3138 output_asm_insn (AS2 (mov%L1,%
6,%
1), xops);
3139 output_asm_insn (AS2 (mov%L6,%
2,%
6), xops);
3140 output_asm_insn (AS2 (sbb%L6,%
4,%
6), xops);
3141 output_asm_insn (AS2 (mov%L0,%
6,%
0), xops);
3146 output_asm_insn (AS2 (sub%L0,%
2,%
0), low);
3147 output_asm_insn (AS2 (sbb%L0,%
2,%
0), high);
3151 (define_insn "subdi3"
3152 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,o,o,!&r,!o")
3153 (minus:DI (match_operand:DI
1 "general_operand" "
0,
0,
0iF,or,roiF,roiF")
3154 (match_operand:DI
2 "general_operand" "or,riF,or,iF,roiF,roiF")))
3155 (clobber (match_scratch:SI
3 "=X,X,&r,&r,X,&r"))]
3159 rtx low[
3], high[
3], xops[
7];
3163 split_di (operands,
3, low, high);
3165 if (!rtx_equal_p (operands[
0], operands[
1]))
3172 if (GET_CODE (operands[
0]) != MEM)
3174 output_asm_insn (AS2 (mov%L1,%
3,%
1), xops);
3175 output_asm_insn (AS2 (mov%L0,%
2,%
0), xops);
3181 xops[
6] = operands[
3];
3182 output_asm_insn (AS2 (mov%L6,%
3,%
6), xops);
3183 output_asm_insn (AS2 (sub%L6,%
5,%
6), xops);
3184 output_asm_insn (AS2 (mov%L1,%
6,%
1), xops);
3185 output_asm_insn (AS2 (mov%L6,%
2,%
6), xops);
3186 output_asm_insn (AS2 (sbb%L6,%
4,%
6), xops);
3187 output_asm_insn (AS2 (mov%L0,%
6,%
0), xops);
3192 if (GET_CODE (operands[
3]) == REG)
3198 xops[
4] = operands[
3];
3200 output_asm_insn (AS2 (mov%L4,%
3,%
4), xops);
3201 output_asm_insn (AS2 (sub%L1,%
4,%
1), xops);
3202 output_asm_insn (AS2 (mov%L4,%
2,%
4), xops);
3203 output_asm_insn (AS2 (sbb%L0,%
4,%
0), xops);
3206 else if (GET_CODE (low[
2]) != CONST_INT || INTVAL (low[
2]) !=
0)
3208 output_asm_insn (AS2 (sub%L0,%
2,%
0), low);
3209 output_asm_insn (AS2 (sbb%L0,%
2,%
0), high);
3213 output_asm_insn (AS2 (sub%L0,%
2,%
0), high);
3218 (define_expand "subsi3"
3219 [(set (match_operand:SI
0 "nonimmediate_operand" "")
3220 (minus:SI (match_operand:SI
1 "nonimmediate_operand" "")
3221 (match_operand:SI
2 "general_operand" "")))]
3223 "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);")
3226 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm,r")
3227 (minus:SI (match_operand:SI
1 "nonimmediate_operand" "
0,
0")
3228 (match_operand:SI
2 "general_operand" "ri,rm")))]
3229 "ix86_binary_operator_ok (MINUS, SImode, operands)"
3230 "* return AS2 (sub%L0,%
2,%
0);")
3232 (define_expand "subhi3"
3233 [(set (match_operand:HI
0 "general_operand" "")
3234 (minus:HI (match_operand:HI
1 "nonimmediate_operand" "")
3235 (match_operand:HI
2 "general_operand" "")))]
3237 "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);")
3240 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
3241 (minus:HI (match_operand:HI
1 "nonimmediate_operand" "
0,
0")
3242 (match_operand:HI
2 "general_operand" "ri,rm")))]
3243 "ix86_binary_operator_ok (MINUS, HImode, operands)"
3246 if (REG_P (operands[
0])
3247 && i386_aligned_p (operands[
2])
3248 && i386_cc_probably_useless_p (insn))
3251 operands[
2] = i386_sext16_if_const (operands[
2]);
3252 return AS2 (sub%L0,%k2,%k0);
3254 return AS2 (sub%W0,%
2,%
0);
3257 (define_expand "subqi3"
3258 [(set (match_operand:QI
0 "general_operand" "")
3259 (minus:QI (match_operand:QI
1 "general_operand" "")
3260 (match_operand:QI
2 "general_operand" "")))]
3262 "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);")
3265 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
3266 (minus:QI (match_operand:QI
1 "nonimmediate_operand" "
0,
0")
3267 (match_operand:QI
2 "general_operand" "qn,qmn")))]
3268 "ix86_binary_operator_ok (MINUS, QImode, operands)"
3269 "* return AS2 (sub%B0,%
2,%
0);")
3271 ;; The patterns that match these are at the end of this file.
3273 (define_expand "subxf3"
3274 [(set (match_operand:XF
0 "register_operand" "")
3275 (minus:XF (match_operand:XF
1 "register_operand" "")
3276 (match_operand:XF
2 "register_operand" "")))]
3280 (define_expand "subdf3"
3281 [(set (match_operand:DF
0 "register_operand" "")
3282 (minus:DF (match_operand:DF
1 "nonimmediate_operand" "")
3283 (match_operand:DF
2 "nonimmediate_operand" "")))]
3287 (define_expand "subsf3"
3288 [(set (match_operand:SF
0 "register_operand" "")
3289 (minus:SF (match_operand:SF
1 "nonimmediate_operand" "")
3290 (match_operand:SF
2 "nonimmediate_operand" "")))]
3294 ;;- multiply instructions
3296 ;(define_insn "mulqi3"
3297 ; [(set (match_operand:QI
0 "register_operand" "=a")
3298 ; (mult:QI (match_operand:QI
1 "register_operand" "%
0")
3299 ; (match_operand:QI
2 "nonimmediate_operand" "qm")))]
3303 (define_insn "mulhi3"
3304 [(set (match_operand:HI
0 "register_operand" "=r,r")
3305 (mult:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,rm")
3306 (match_operand:HI
2 "general_operand" "g,i")))]
3310 if (GET_CODE (operands[
1]) == REG
3311 && REGNO (operands[
1]) == REGNO (operands[
0])
3312 && (GET_CODE (operands[
2]) == MEM || GET_CODE (operands[
2]) == REG))
3313 /* Assembler has weird restrictions. */
3314 return AS2 (imul%W0,%
2,%
0);
3315 return AS3 (imul%W0,%
2,%
1,%
0);
3317 [(set_attr "type" "imul")])
3319 (define_insn "mulsi3"
3320 [(set (match_operand:SI
0 "register_operand" "=r,r")
3321 (mult:SI (match_operand:SI
1 "nonimmediate_operand" "%
0,rm")
3322 (match_operand:SI
2 "general_operand" "g,i")))]
3326 if (GET_CODE (operands[
1]) == REG
3327 && REGNO (operands[
1]) == REGNO (operands[
0])
3328 && (GET_CODE (operands[
2]) == MEM || GET_CODE (operands[
2]) == REG))
3329 /* Assembler has weird restrictions. */
3330 return AS2 (imul%L0,%
2,%
0);
3331 return AS3 (imul%L0,%
2,%
1,%
0);
3333 [(set_attr "type" "imul")])
3335 (define_insn "umulqihi3"
3336 [(set (match_operand:HI
0 "register_operand" "=a")
3337 (mult:HI (zero_extend:HI (match_operand:QI
1 "register_operand" "%
0"))
3338 (zero_extend:HI (match_operand:QI
2 "nonimmediate_operand" "qm"))))]
3341 [(set_attr "type" "imul")])
3343 (define_insn "mulqihi3"
3344 [(set (match_operand:HI
0 "register_operand" "=a")
3345 (mult:HI (sign_extend:HI (match_operand:QI
1 "register_operand" "%
0"))
3346 (sign_extend:HI (match_operand:QI
2 "nonimmediate_operand" "qm"))))]
3349 [(set_attr "type" "imul")])
3351 (define_insn "umulsidi3"
3352 [(set (match_operand:DI
0 "register_operand" "=A")
3353 (mult:DI (zero_extend:DI (match_operand:SI
1 "register_operand" "%
0"))
3354 (zero_extend:DI (match_operand:SI
2 "nonimmediate_operand" "rm"))))]
3355 "TARGET_WIDE_MULTIPLY"
3357 [(set_attr "type" "imul")])
3359 (define_insn "mulsidi3"
3360 [(set (match_operand:DI
0 "register_operand" "=A")
3361 (mult:DI (sign_extend:DI (match_operand:SI
1 "register_operand" "%
0"))
3362 (sign_extend:DI (match_operand:SI
2 "nonimmediate_operand" "rm"))))]
3363 "TARGET_WIDE_MULTIPLY"
3365 [(set_attr "type" "imul")])
3367 (define_insn "umulsi3_highpart"
3368 [(set (match_operand:SI
0 "register_operand" "=d")
3369 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI
1 "register_operand" "%a"))
3370 (zero_extend:DI (match_operand:SI
2 "nonimmediate_operand" "rm")))
3372 (clobber (match_scratch:SI
3 "=a"))]
3373 "TARGET_WIDE_MULTIPLY"
3375 [(set_attr "type" "imul")])
3377 (define_insn "smulsi3_highpart"
3378 [(set (match_operand:SI
0 "register_operand" "=d")
3379 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI
1 "register_operand" "%a"))
3380 (sign_extend:DI (match_operand:SI
2 "nonimmediate_operand" "rm")))
3382 (clobber (match_scratch:SI
3 "=a"))]
3383 "TARGET_WIDE_MULTIPLY"
3385 [(set_attr "type" "imul")])
3387 ;; The patterns that match these are at the end of this file.
3389 (define_expand "mulxf3"
3390 [(set (match_operand:XF
0 "register_operand" "")
3391 (mult:XF (match_operand:XF
1 "register_operand" "")
3392 (match_operand:XF
2 "register_operand" "")))]
3396 (define_expand "muldf3"
3397 [(set (match_operand:DF
0 "register_operand" "")
3398 (mult:DF (match_operand:DF
1 "register_operand" "")
3399 (match_operand:DF
2 "nonimmediate_operand" "")))]
3403 (define_expand "mulsf3"
3404 [(set (match_operand:SF
0 "register_operand" "")
3405 (mult:SF (match_operand:SF
1 "register_operand" "")
3406 (match_operand:SF
2 "nonimmediate_operand" "")))]
3410 ;;- divide instructions
3412 (define_insn "divqi3"
3413 [(set (match_operand:QI
0 "register_operand" "=a")
3414 (div:QI (match_operand:HI
1 "register_operand" "
0")
3415 (match_operand:QI
2 "nonimmediate_operand" "qm")))]
3419 (define_insn "udivqi3"
3420 [(set (match_operand:QI
0 "register_operand" "=a")
3421 (udiv:QI (match_operand:HI
1 "register_operand" "
0")
3422 (match_operand:QI
2 "nonimmediate_operand" "qm")))]
3425 [(set_attr "type" "idiv")])
3427 ;; The patterns that match these are at the end of this file.
3429 (define_expand "divxf3"
3430 [(set (match_operand:XF
0 "register_operand" "")
3431 (div:XF (match_operand:XF
1 "register_operand" "")
3432 (match_operand:XF
2 "register_operand" "")))]
3436 (define_expand "divdf3"
3437 [(set (match_operand:DF
0 "register_operand" "")
3438 (div:DF (match_operand:DF
1 "register_operand" "")
3439 (match_operand:DF
2 "nonimmediate_operand" "")))]
3443 (define_expand "divsf3"
3444 [(set (match_operand:SF
0 "register_operand" "")
3445 (div:SF (match_operand:SF
1 "register_operand" "")
3446 (match_operand:SF
2 "nonimmediate_operand" "")))]
3450 ;; Remainder instructions.
3452 (define_insn "divmodsi4"
3453 [(set (match_operand:SI
0 "register_operand" "=a")
3454 (div:SI (match_operand:SI
1 "register_operand" "
0")
3455 (match_operand:SI
2 "nonimmediate_operand" "rm")))
3456 (set (match_operand:SI
3 "register_operand" "=&d")
3457 (mod:SI (match_dup
1) (match_dup
2)))]
3462 output_asm_insn (
\"cdq
\", operands);
3464 output_asm_insn (
\"cltd
\", operands);
3466 return AS1 (idiv%L0,%
2);
3468 [(set_attr "type" "idiv")])
3470 (define_insn "divmodhi4"
3471 [(set (match_operand:HI
0 "register_operand" "=a")
3472 (div:HI (match_operand:HI
1 "register_operand" "
0")
3473 (match_operand:HI
2 "nonimmediate_operand" "rm")))
3474 (set (match_operand:HI
3 "register_operand" "=&d")
3475 (mod:HI (match_dup
1) (match_dup
2)))]
3478 [(set_attr "type" "idiv")])
3480 ;; ??? Can we make gcc zero extend operand[
0]?
3481 (define_insn "udivmodsi4"
3482 [(set (match_operand:SI
0 "register_operand" "=a")
3483 (udiv:SI (match_operand:SI
1 "register_operand" "
0")
3484 (match_operand:SI
2 "nonimmediate_operand" "rm")))
3485 (set (match_operand:SI
3 "register_operand" "=&d")
3486 (umod:SI (match_dup
1) (match_dup
2)))]
3490 output_asm_insn (AS2 (xor%L3,%
3,%
3), operands);
3491 return AS1 (div%L0,%
2);
3493 [(set_attr "type" "idiv")])
3495 ;; ??? Can we make gcc zero extend operand[
0]?
3496 (define_insn "udivmodhi4"
3497 [(set (match_operand:HI
0 "register_operand" "=a")
3498 (udiv:HI (match_operand:HI
1 "register_operand" "
0")
3499 (match_operand:HI
2 "nonimmediate_operand" "rm")))
3500 (set (match_operand:HI
3 "register_operand" "=&d")
3501 (umod:HI (match_dup
1) (match_dup
2)))]
3505 output_asm_insn (AS2 (xor%W0,%
3,%
3), operands);
3506 return AS1 (div%W0,%
2);
3508 [(set_attr "type" "idiv")])
3511 ;;this should be a valid double division which we may want to add
3514 [(set (match_operand:SI
0 "register_operand" "=a")
3515 (udiv:DI (match_operand:DI
1 "register_operand" "a")
3516 (match_operand:SI
2 "nonimmediate_operand" "rm")))
3517 (set (match_operand:SI
3 "register_operand" "=d")
3518 (umod:SI (match_dup
1) (match_dup
2)))]
3521 [(set_attr "type" "idiv")])
3524 ;;- and instructions
3531 ;; but if the reg is %eax, then the "andl" is faster.
3533 ;; On i486, the "andl" is always faster than the "movzbl".
3535 ;; On both i386 and i486, a three operand AND is as fast with movzbl or
3536 ;; movzwl as with andl, if operands[
0] != operands[
1].
3538 ;; The
`r' in `rm' for operand
3 looks redundant, but it causes
3539 ;; optional reloads to be generated if op
3 is a pseudo in a stack slot.
3541 (define_insn "andsi3"
3542 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm,r")
3543 (and:SI (match_operand:SI
1 "nonimmediate_operand" "%
0,
0")
3544 (match_operand:SI
2 "general_operand" "ri,rm")))]
3548 HOST_WIDE_INT intval;
3549 if (!rtx_equal_p (operands[
0], operands[
1])
3550 && rtx_equal_p (operands[
0], operands[
2]))
3554 operands[
1] = operands[
2];
3557 switch (GET_CODE (operands[
2]))
3560 if (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
3562 intval = INTVAL (operands[
2]);
3563 /* zero-extend
16->
32? */
3564 if (intval ==
0xffff && REG_P (operands[
0])
3565 && (! REG_P (operands[
1])
3566 || REGNO (operands[
0]) !=
0 || REGNO (operands[
1]) !=
0)
3567 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[
0], operands[
1])))
3569 /* ??? tege: Should forget CC_STATUS only if we clobber a
3570 remembered operand. Fix that later. */
3573 return AS2 (movzx,%w1,%
0);
3575 return AS2 (movz%W0%L0,%w1,%
0);
3579 /* zero extend
8->
32? */
3580 if (intval ==
0xff && REG_P (operands[
0])
3581 && !(REG_P (operands[
1]) && NON_QI_REG_P (operands[
1]))
3582 && (! REG_P (operands[
1])
3583 || REGNO (operands[
0]) !=
0 || REGNO (operands[
1]) !=
0)
3584 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[
0], operands[
1])))
3586 /* ??? tege: Should forget CC_STATUS only if we clobber a
3587 remembered operand. Fix that later. */
3590 return AS2 (movzx,%b1,%
0);
3592 return AS2 (movz%B0%L0,%b1,%
0);
3596 /* Check partial bytes.. non-QI-regs are not available */
3597 if (REG_P (operands[
0]) && ! QI_REG_P (operands[
0]))
3600 /* only low byte has zero bits? */
3601 if (~(intval |
0xff) ==
0)
3604 if (REG_P (operands[
0]))
3609 return AS2 (xor%B0,%b0,%b0);
3612 /* we're better off with the
32-bit version if reg != EAX */
3613 /* the value is sign-extended in
8 bits */
3614 if (REGNO (operands[
0]) !=
0 && (intval &
0x80))
3620 operands[
2] = GEN_INT (intval);
3623 return AS2 (mov%B0,%
2,%b0);
3625 return AS2 (and%B0,%
2,%b0);
3628 /* only second byte has zero? */
3629 if (~(intval |
0xff00) ==
0)
3633 intval = (intval >>
8) &
0xff;
3634 operands[
2] = GEN_INT (intval);
3637 if (REG_P (operands[
0]))
3638 return AS2 (xor%B0,%h0,%h0);
3639 operands[
0] = adj_offsettable_operand (operands[
0],
1);
3640 return AS2 (mov%B0,%
2,%b0);
3643 if (REG_P (operands[
0]))
3644 return AS2 (and%B0,%
2,%h0);
3646 operands[
0] = adj_offsettable_operand (operands[
0],
1);
3647 return AS2 (and%B0,%
2,%b0);
3650 if (REG_P (operands[
0]))
3653 /* third byte has zero bits? */
3654 if (~(intval |
0xff0000) ==
0)
3656 intval = (intval >>
16) &
0xff;
3657 operands[
0] = adj_offsettable_operand (operands[
0],
2);
3660 operands[
2] = GEN_INT (intval);
3662 return AS2 (mov%B0,%
2,%b0);
3663 return AS2 (and%B0,%
2,%b0);
3666 /* fourth byte has zero bits? */
3667 if (~(intval |
0xff000000) ==
0)
3669 intval = (intval >>
24) &
0xff;
3670 operands[
0] = adj_offsettable_operand (operands[
0],
3);
3671 goto byte_and_operation;
3674 /* Low word is zero? */
3675 if (intval ==
0xffff0000)
3677 word_zero_and_operation:
3679 operands[
2] = const0_rtx;
3680 return AS2 (mov%W0,%
2,%w0);
3683 /* High word is zero? */
3684 if (intval ==
0x0000ffff)
3686 operands[
0] = adj_offsettable_operand (operands[
0],
2);
3687 goto word_zero_and_operation;
3694 return AS2 (and%L0,%
2,%
0);
3697 (define_insn "andhi3"
3698 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
3699 (and:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,
0")
3700 (match_operand:HI
2 "general_operand" "ri,rm")))]
3704 if (GET_CODE (operands[
2]) == CONST_INT
3705 && ! (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0])))
3707 /* Can we ignore the upper byte? */
3708 if ((! REG_P (operands[
0]) || QI_REG_P (operands[
0]))
3709 && (INTVAL (operands[
2]) &
0xff00) ==
0xff00)
3713 if ((INTVAL (operands[
2]) &
0xff) ==
0)
3715 operands[
2] = const0_rtx;
3716 return AS2 (mov%B0,%
2,%b0);
3719 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0xff);
3720 return AS2 (and%B0,%
2,%b0);
3723 /* Can we ignore the lower byte? */
3724 /* ??? what about offsettable memory references? */
3725 if (QI_REG_P (operands[
0]) && (INTVAL (operands[
2]) &
0xff) ==
0xff)
3729 if ((INTVAL (operands[
2]) &
0xff00) ==
0)
3731 operands[
2] = const0_rtx;
3732 return AS2 (mov%B0,%
2,%h0);
3735 operands[
2] = GEN_INT ((INTVAL (operands[
2]) >>
8) &
0xff);
3736 return AS2 (and%B0,%
2,%h0);
3739 /* use
32-bit ops on registers when there are no sign issues.. */
3740 if (REG_P (operands[
0]))
3742 if (!(INTVAL (operands[
2]) & ~
0x7fff))
3743 return AS2 (and%L0,%
2,%k0);
3747 if (REG_P (operands[
0])
3748 && i386_aligned_p (operands[
2]))
3751 /* If op[
2] is constant, we should zero-extend it and */
3752 /* make a note that op[
0] has been zero-extended, so */
3753 /* that we could use
32-bit ops on it forthwith, but */
3754 /* there is no such reg-note available. Instead we do */
3755 /* a sign extension as that can result in shorter asm */
3756 operands[
2] = i386_sext16_if_const (operands[
2]);
3757 return AS2 (and%L0,%k2,%k0);
3760 /* Use a
32-bit word with the upper bits set, invalidate CC */
3761 if (GET_CODE (operands[
2]) == CONST_INT
3762 && i386_aligned_p (operands[
0]))
3764 HOST_WIDE_INT val = INTVAL (operands[
2]);
3767 if (val != INTVAL (operands[
2]))
3768 operands[
2] = GEN_INT (val);
3769 return AS2 (and%L0,%k2,%k0);
3772 return AS2 (and%W0,%
2,%
0);
3775 (define_insn "andqi3"
3776 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
3777 (and:QI (match_operand:QI
1 "nonimmediate_operand" "%
0,
0")
3778 (match_operand:QI
2 "general_operand" "qn,qmn")))]
3780 "* return AS2 (and%B0,%
2,%
0);")
3782 /* I am nervous about these two.. add them later..
3783 ;I presume this means that we have something in say op0= eax which is small
3784 ;and we want to and it with memory so we can do this by just an
3785 ;andb m,%al and have success.
3787 [(set (match_operand:SI
0 "general_operand" "=r")
3788 (and:SI (zero_extend:SI
3789 (match_operand:HI
1 "nonimmediate_operand" "rm"))
3790 (match_operand:SI
2 "general_operand" "
0")))]
3791 "GET_CODE (operands[
2]) == CONST_INT
3792 && (unsigned int) INTVAL (operands[
2]) < (
1 << GET_MODE_BITSIZE (HImode))"
3796 [(set (match_operand:SI
0 "register_operand" "=q")
3798 (zero_extend:SI (match_operand:QI
1 "nonimmediate_operand" "qm"))
3799 (match_operand:SI
2 "register_operand" "
0")))]
3800 "GET_CODE (operands[
2]) == CONST_INT
3801 && (unsigned int) INTVAL (operands[
2]) < (
1 << GET_MODE_BITSIZE (QImode))"
3806 ;;- Bit set (inclusive or) instructions
3808 ;; This optimizes known byte-wide operations to memory, and in some cases
3809 ;; to QI registers.. Note that we don't want to use the QI registers too
3810 ;; aggressively, because often the
32-bit register instruction is the same
3811 ;; size, and likely to be faster on PentiumPro.
3812 (define_insn "iorsi3"
3813 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm,r")
3814 (ior:SI (match_operand:SI
1 "nonimmediate_operand" "%
0,
0")
3815 (match_operand:SI
2 "general_operand" "ri,rm")))]
3819 HOST_WIDE_INT intval;
3820 switch (GET_CODE (operands[
2]))
3824 if (REG_P (operands[
0]) && ! QI_REG_P (operands[
0]))
3827 /* don't try to optimize volatile accesses */
3828 if (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
3831 intval = INTVAL (operands[
2]);
3832 if ((intval & ~
0xff) ==
0)
3834 if (REG_P (operands[
0]))
3836 /* Do low byte access only for %eax or when high bit is set */
3837 if (REGNO (operands[
0]) !=
0 && !(intval &
0x80))
3844 if (intval != INTVAL (operands[
2]))
3845 operands[
2] = GEN_INT (intval);
3848 return AS2 (mov%B0,%
2,%b0);
3850 return AS2 (or%B0,%
2,%b0);
3854 if ((intval & ~
0xff00) ==
0)
3858 if (REG_P (operands[
0]))
3861 operands[
2] = GEN_INT (intval);
3863 return AS2 (mov%B0,%
2,%h0);
3865 return AS2 (or%B0,%
2,%h0);
3868 operands[
0] = adj_offsettable_operand (operands[
0],
1);
3869 goto byte_or_operation;
3872 if (REG_P (operands[
0]))
3876 if ((intval & ~
0xff0000) ==
0)
3879 operands[
0] = adj_offsettable_operand (operands[
0],
2);
3880 goto byte_or_operation;
3884 if ((intval & ~
0xff000000) ==
0)
3886 intval = (intval >>
24) &
0xff;
3887 operands[
0] = adj_offsettable_operand (operands[
0],
3);
3888 goto byte_or_operation;
3895 return AS2 (or%L0,%
2,%
0);
3898 (define_insn "iorhi3"
3899 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
3900 (ior:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,
0")
3901 (match_operand:HI
2 "general_operand" "ri,rm")))]
3905 HOST_WIDE_INT intval;
3906 switch (GET_CODE (operands[
2]))
3910 if (REG_P (operands[
0]) && ! QI_REG_P (operands[
0]))
3913 /* don't try to optimize volatile accesses */
3914 if (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
3917 intval =
0xffff & INTVAL (operands[
2]);
3919 if ((intval &
0xff00) ==
0)
3921 if (REG_P (operands[
0]))
3923 /* Do low byte access only for %eax or when high bit is set */
3924 if (REGNO (operands[
0]) !=
0 && !(intval &
0x80))
3932 return AS2 (mov%B0,%
2,%b0);
3934 return AS2 (or%B0,%
2,%b0);
3938 if ((intval &
0xff) ==
0)
3941 operands[
2] = GEN_INT (intval);
3943 if (REG_P (operands[
0]))
3947 return AS2 (mov%B0,%
2,%h0);
3949 return AS2 (or%B0,%
2,%h0);
3952 operands[
0] = adj_offsettable_operand (operands[
0],
1);
3954 goto byte_or_operation;
3961 if (REG_P (operands[
0])
3962 && i386_aligned_p (operands[
2]))
3965 operands[
2] = i386_sext16_if_const (operands[
2]);
3966 return AS2 (or%L0,%k2,%k0);
3969 if (GET_CODE (operands[
2]) == CONST_INT
3970 && i386_aligned_p (operands[
0]))
3973 intval =
0xffff & INTVAL (operands[
2]);
3974 if (intval != INTVAL (operands[
2]))
3975 operands[
2] = GEN_INT (intval);
3976 return AS2 (or%L0,%
2,%k0);
3979 return AS2 (or%W0,%
2,%
0);
3982 (define_insn "iorqi3"
3983 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
3984 (ior:QI (match_operand:QI
1 "nonimmediate_operand" "%
0,
0")
3985 (match_operand:QI
2 "general_operand" "qn,qmn")))]
3987 "* return AS2 (or%B0,%
2,%
0);")
3989 ;;- xor instructions
3991 (define_insn "xorsi3"
3992 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm,r")
3993 (xor:SI (match_operand:SI
1 "nonimmediate_operand" "%
0,
0")
3994 (match_operand:SI
2 "general_operand" "ri,rm")))]
3998 HOST_WIDE_INT intval;
3999 switch (GET_CODE (operands[
2]))
4003 if (REG_P (operands[
0]) && ! QI_REG_P (operands[
0]))
4006 /* don't try to optimize volatile accesses */
4007 if (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
4010 intval = INTVAL (operands[
2]);
4011 if ((intval & ~
0xff) ==
0)
4013 if (REG_P (operands[
0]))
4015 /* Do low byte access only for %eax or when high bit is set */
4016 if (REGNO (operands[
0]) !=
0 && !(intval &
0x80))
4024 return AS1 (not%B0,%b0);
4026 if (intval != INTVAL (operands[
2]))
4027 operands[
2] = GEN_INT (intval);
4028 return AS2 (xor%B0,%
2,%b0);
4032 if ((intval & ~
0xff00) ==
0)
4036 if (REG_P (operands[
0]))
4040 return AS1 (not%B0,%h0);
4042 operands[
2] = GEN_INT (intval);
4043 return AS2 (xor%B0,%
2,%h0);
4046 operands[
0] = adj_offsettable_operand (operands[
0],
1);
4048 goto byte_xor_operation;
4051 if (REG_P (operands[
0]))
4055 if ((intval & ~
0xff0000) ==
0)
4058 operands[
0] = adj_offsettable_operand (operands[
0],
2);
4059 goto byte_xor_operation;
4063 if ((intval & ~
0xff000000) ==
0)
4065 intval = (intval >>
24) &
0xff;
4066 operands[
0] = adj_offsettable_operand (operands[
0],
3);
4067 goto byte_xor_operation;
4074 return AS2 (xor%L0,%
2,%
0);
4077 (define_insn "xorhi3"
4078 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
4079 (xor:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,
0")
4080 (match_operand:HI
2 "general_operand" "ri,rm")))]
4084 if (GET_CODE (operands[
2]) == CONST_INT
4085 && ! (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0])))
4087 /* Can we ignore the upper byte? */
4088 if ((! REG_P (operands[
0]) || QI_REG_P (operands[
0]))
4089 && (INTVAL (operands[
2]) &
0xff00) ==
0)
4092 if (INTVAL (operands[
2]) &
0xffff0000)
4093 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0xffff);
4095 if (INTVAL (operands[
2]) ==
0xff)
4096 return AS1 (not%B0,%b0);
4098 return AS2 (xor%B0,%
2,%b0);
4101 /* Can we ignore the lower byte? */
4102 /* ??? what about offsettable memory references? */
4103 if (QI_REG_P (operands[
0])
4104 && (INTVAL (operands[
2]) &
0xff) ==
0)
4107 operands[
2] = GEN_INT ((INTVAL (operands[
2]) >>
8) &
0xff);
4109 if (INTVAL (operands[
2]) ==
0xff)
4110 return AS1 (not%B0,%h0);
4112 return AS2 (xor%B0,%
2,%h0);
4116 if (REG_P (operands[
0])
4117 && i386_aligned_p (operands[
2]))
4120 operands[
2] = i386_sext16_if_const (operands[
2]);
4121 return AS2 (xor%L0,%k2,%k0);
4124 if (GET_CODE (operands[
2]) == CONST_INT
4125 && i386_aligned_p (operands[
0]))
4127 HOST_WIDE_INT intval;
4129 intval =
0xffff & INTVAL (operands[
2]);
4130 if (intval != INTVAL (operands[
2]))
4131 operands[
2] = GEN_INT (intval);
4132 return AS2 (xor%L0,%
2,%k0);
4135 return AS2 (xor%W0,%
2,%
0);
4138 (define_insn "xorqi3"
4139 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
4140 (xor:QI (match_operand:QI
1 "nonimmediate_operand" "%
0,
0")
4141 (match_operand:QI
2 "general_operand" "qn,qm")))]
4143 "* return AS2 (xor%B0,%
2,%
0);")
4145 ;; logical operations for DImode
4148 (define_insn "anddi3"
4149 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4150 (and:DI (match_operand:DI
1 "general_operand" "%
0,
0,
0,
0iF,or,riF,o")
4151 (match_operand:DI
2 "general_operand" "o,riF,
0,or,or,oriF,o")))
4152 (clobber (match_scratch:SI
3 "=X,X,X,&r,X,&r,&r"))]
4156 (define_insn "iordi3"
4157 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4158 (ior:DI (match_operand:DI
1 "general_operand" "%
0,
0,
0,
0iF,or,riF,o")
4159 (match_operand:DI
2 "general_operand" "o,riF,
0,or,or,oriF,o")))
4160 (clobber (match_scratch:SI
3 "=X,X,X,&r,X,&r,&r"))]
4164 (define_insn "xordi3"
4165 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4166 (xor:DI (match_operand:DI
1 "general_operand" "%
0,
0,
0,
0iF,or,riF,o")
4167 (match_operand:DI
2 "general_operand" "o,riF,
0,or,or,oriF,o")))
4168 (clobber (match_scratch:SI
3 "=X,X,X,&r,X,&r,&r"))]
4173 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4174 (match_operator:DI
4 "ix86_logical_operator"
4175 [(match_operand:DI
1 "general_operand" "%
0,
0,
0,
0iF,or,riF,o")
4176 (match_operand:DI
2 "general_operand" "o,riF,
0,or,or,oriF,o")]))
4177 (clobber (match_scratch:SI
3 "=X,X,X,&r,X,&r,&r"))]
4182 rtx low[
3], high[
3], xops[
7], temp;
4183 rtx (*genfunc)() = (GET_CODE (operands[
4]) == AND ? gen_andsi3
4184 : GET_CODE (operands[
4]) == IOR ? gen_iorsi3
4185 : GET_CODE (operands[
4]) == XOR ? gen_xorsi3
4188 if (rtx_equal_p (operands[
0], operands[
2]))
4191 operands[
1] = operands[
2];
4195 split_di (operands,
3, low, high);
4196 if (!rtx_equal_p (operands[
0], operands[
1]))
4203 if (GET_CODE (operands[
0]) != MEM)
4205 emit_insn (gen_movsi (xops[
1], xops[
3]));
4206 emit_insn (gen_movsi (xops[
0], xops[
2]));
4212 xops[
6] = operands[
3];
4213 emit_insn (gen_movsi (xops[
6], xops[
3]));
4214 emit_insn ((*genfunc) (xops[
6], xops[
6], xops[
5]));
4215 emit_insn (gen_movsi (xops[
1], xops[
6]));
4216 emit_insn (gen_movsi (xops[
6], xops[
2]));
4217 emit_insn ((*genfunc) (xops[
6], xops[
6], xops[
4]));
4218 emit_insn (gen_movsi (xops[
0], xops[
6]));
4223 if (GET_CODE (operands[
3]) == REG && GET_CODE (operands[
2]) != REG)
4229 xops[
4] = operands[
3];
4231 emit_insn (gen_movsi (xops[
4], xops[
3]));
4232 emit_insn ((*genfunc) (xops[
1], xops[
1], xops[
4]));
4233 emit_insn (gen_movsi (xops[
4], xops[
2]));
4234 emit_insn ((*genfunc) (xops[
0], xops[
0], xops[
4]));
4239 emit_insn ((*genfunc) (low[
0], low[
0], low[
2]));
4240 emit_insn ((*genfunc) (high[
0], high[
0], high[
2]));
4246 ;;- negation instructions
4248 (define_insn "negdi2"
4249 [(set (match_operand:DI
0 "general_operand" "=&ro")
4250 (neg:DI (match_operand:DI
1 "general_operand" "
0")))]
4254 rtx xops[
2], low[
1], high[
1];
4258 split_di (operands,
1, low, high);
4259 xops[
0] = const0_rtx;
4262 output_asm_insn (AS1 (neg%L0,%
0), low);
4263 output_asm_insn (AS2 (adc%L1,%
0,%
1), xops);
4264 output_asm_insn (AS1 (neg%L0,%
0), high);
4268 (define_insn "negsi2"
4269 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm")
4270 (neg:SI (match_operand:SI
1 "nonimmediate_operand" "
0")))]
4274 (define_insn "neghi2"
4275 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm")
4276 (neg:HI (match_operand:HI
1 "nonimmediate_operand" "
0")))]
4280 (define_insn "negqi2"
4281 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm")
4282 (neg:QI (match_operand:QI
1 "nonimmediate_operand" "
0")))]
4286 (define_insn "negsf2"
4287 [(set (match_operand:SF
0 "register_operand" "=f")
4288 (neg:SF (match_operand:SF
1 "register_operand" "
0")))]
4292 (define_insn "negdf2"
4293 [(set (match_operand:DF
0 "register_operand" "=f")
4294 (neg:DF (match_operand:DF
1 "register_operand" "
0")))]
4299 [(set (match_operand:DF
0 "register_operand" "=f")
4300 (neg:DF (float_extend:DF (match_operand:SF
1 "register_operand" "
0"))))]
4304 (define_insn "negxf2"
4305 [(set (match_operand:XF
0 "register_operand" "=f")
4306 (neg:XF (match_operand:XF
1 "register_operand" "
0")))]
4311 [(set (match_operand:XF
0 "register_operand" "=f")
4312 (neg:XF (float_extend:XF (match_operand:DF
1 "register_operand" "
0"))))]
4316 ;; Absolute value instructions
4318 (define_insn "abssf2"
4319 [(set (match_operand:SF
0 "register_operand" "=f")
4320 (abs:SF (match_operand:SF
1 "register_operand" "
0")))]
4323 [(set_attr "type" "fpop")])
4325 (define_insn "absdf2"
4326 [(set (match_operand:DF
0 "register_operand" "=f")
4327 (abs:DF (match_operand:DF
1 "register_operand" "
0")))]
4330 [(set_attr "type" "fpop")])
4333 [(set (match_operand:DF
0 "register_operand" "=f")
4334 (abs:DF (float_extend:DF (match_operand:SF
1 "register_operand" "
0"))))]
4337 [(set_attr "type" "fpop")])
4339 (define_insn "absxf2"
4340 [(set (match_operand:XF
0 "register_operand" "=f")
4341 (abs:XF (match_operand:XF
1 "register_operand" "
0")))]
4344 [(set_attr "type" "fpop")])
4347 [(set (match_operand:XF
0 "register_operand" "=f")
4348 (abs:XF (float_extend:XF (match_operand:DF
1 "register_operand" "
0"))))]
4351 [(set_attr "type" "fpop")])
4353 (define_insn "sqrtsf2"
4354 [(set (match_operand:SF
0 "register_operand" "=f")
4355 (sqrt:SF (match_operand:SF
1 "register_operand" "
0")))]
4356 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4359 (define_insn "sqrtdf2"
4360 [(set (match_operand:DF
0 "register_operand" "=f")
4361 (sqrt:DF (match_operand:DF
1 "register_operand" "
0")))]
4362 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4363 && (TARGET_IEEE_FP || flag_fast_math) "
4367 [(set (match_operand:DF
0 "register_operand" "=f")
4368 (sqrt:DF (float_extend:DF
4369 (match_operand:SF
1 "register_operand" "
0"))))]
4370 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4373 (define_insn "sqrtxf2"
4374 [(set (match_operand:XF
0 "register_operand" "=f")
4375 (sqrt:XF (match_operand:XF
1 "register_operand" "
0")))]
4376 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4377 && (TARGET_IEEE_FP || flag_fast_math) "
4381 [(set (match_operand:XF
0 "register_operand" "=f")
4382 (sqrt:XF (float_extend:XF
4383 (match_operand:DF
1 "register_operand" "
0"))))]
4384 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4388 [(set (match_operand:XF
0 "register_operand" "=f")
4389 (sqrt:XF (float_extend:XF
4390 (match_operand:SF
1 "register_operand" "
0"))))]
4391 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4394 (define_insn "sindf2"
4395 [(set (match_operand:DF
0 "register_operand" "=f")
4396 (unspec:DF [(match_operand:DF
1 "register_operand" "
0")]
1))]
4397 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4400 (define_insn "sinsf2"
4401 [(set (match_operand:SF
0 "register_operand" "=f")
4402 (unspec:SF [(match_operand:SF
1 "register_operand" "
0")]
1))]
4403 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4407 [(set (match_operand:DF
0 "register_operand" "=f")
4408 (unspec:DF [(float_extend:DF
4409 (match_operand:SF
1 "register_operand" "
0"))]
1))]
4410 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4413 (define_insn "sinxf2"
4414 [(set (match_operand:XF
0 "register_operand" "=f")
4415 (unspec:XF [(match_operand:XF
1 "register_operand" "
0")]
1))]
4416 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4419 (define_insn "cosdf2"
4420 [(set (match_operand:DF
0 "register_operand" "=f")
4421 (unspec:DF [(match_operand:DF
1 "register_operand" "
0")]
2))]
4422 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4425 (define_insn "cossf2"
4426 [(set (match_operand:SF
0 "register_operand" "=f")
4427 (unspec:SF [(match_operand:SF
1 "register_operand" "
0")]
2))]
4428 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4432 [(set (match_operand:DF
0 "register_operand" "=f")
4433 (unspec:DF [(float_extend:DF
4434 (match_operand:SF
1 "register_operand" "
0"))]
2))]
4435 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4438 (define_insn "cosxf2"
4439 [(set (match_operand:XF
0 "register_operand" "=f")
4440 (unspec:XF [(match_operand:XF
1 "register_operand" "
0")]
2))]
4441 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4444 ;;- one complement instructions
4446 (define_insn "one_cmplsi2"
4447 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm")
4448 (not:SI (match_operand:SI
1 "nonimmediate_operand" "
0")))]
4452 (define_insn "one_cmplhi2"
4453 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm")
4454 (not:HI (match_operand:HI
1 "nonimmediate_operand" "
0")))]
4458 (define_insn "one_cmplqi2"
4459 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm")
4460 (not:QI (match_operand:QI
1 "nonimmediate_operand" "
0")))]
4464 ;;- arithmetic shift instructions
4466 ;; DImode shifts are implemented using the i386 "shift double" opcode,
4467 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
4468 ;; is variable, then the count is in %cl and the "imm" operand is dropped
4469 ;; from the assembler input.
4471 ;; This instruction shifts the target reg/mem as usual, but instead of
4472 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
4473 ;; is a left shift double, bits are taken from the high order bits of
4474 ;; reg, else if the insn is a shift right double, bits are taken from the
4475 ;; low order bits of reg. So if %eax is "
1234" and %edx is "
5678",
4476 ;; "shldl $
8,%edx,%eax" leaves %edx unchanged and sets %eax to "
2345".
4478 ;; Since sh[lr]d does not change the
`reg' operand, that is done
4479 ;; separately, making all shifts emit pairs of shift double and normal
4480 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
4481 ;; support a 63 bit shift, each shift where the count is in a reg expands
4482 ;; to a pair of shifts, a branch, a shift by 32 and a label.
4484 ;; If the shift count is a constant, we need never emit more than one
4485 ;; shift pair, instead using moves and sign extension for counts greater
4488 (define_expand "ashldi3"
4489 [(set (match_operand:DI 0 "register_operand" "")
4490 (ashift:DI (match_operand:DI 1 "register_operand" "")
4491 (match_operand:QI 2 "nonmemory_operand" "")))]
4495 if (GET_CODE (operands[2]) != CONST_INT
4496 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4498 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4499 emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
4503 emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
4508 (define_insn "ashldi3_const_int"
4509 [(set (match_operand:DI 0 "register_operand" "=&r")
4510 (ashift:DI (match_operand:DI 1 "register_operand" "0")
4511 (match_operand:QI 2 "const_int_operand" "J")))]
4512 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
4515 rtx xops[4], low[1], high[1];
4519 split_di (operands, 1, low, high);
4520 xops[0] = operands[2];
4521 xops[1] = const1_rtx;
4525 if (INTVAL (xops[0]) > 31)
4527 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
4528 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4530 if (INTVAL (xops[0]) > 32)
4532 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
4533 output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
4538 output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
4539 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
4544 (define_insn "ashldi3_non_const_int"
4545 [(set (match_operand:DI 0 "register_operand" "=&r")
4546 (ashift:DI (match_operand:DI 1 "register_operand" "0")
4547 (match_operand:QI 2 "register_operand" "c")))]
4551 rtx xops[4], low[1], high[1];
4552 static HOST_WIDE_INT ashldi_label_number;
4556 split_di (operands, 1, low, high);
4557 xops[0] = operands[2];
4558 xops[1] = GEN_INT (32);
4562 output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
4563 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
4564 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
4565 asm_fprintf (asm_out_file, \"\\tje %LLASHLDI%d\\n\", ashldi_label_number);
4566 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
4567 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4568 asm_fprintf (asm_out_file, \"%LLASHLDI%d:\\n\", ashldi_label_number++);
4573 ;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
4574 ;; On i486, movl/sall appears slightly faster than leal, but the leal
4575 ;; is smaller - use leal for now unless the shift count is 1.
4577 (define_insn "ashlsi3"
4578 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4579 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,0")
4580 (match_operand:SI 2 "nonmemory_operand" "M,cI")))]
4584 if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
4586 if (TARGET_DOUBLE_WITH_ADD && INTVAL (operands[2]) == 1)
4588 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
4589 return AS2 (add%L0,%1,%0);
4595 if (operands[1] == stack_pointer_rtx)
4597 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
4598 operands[1] = operands[0];
4600 operands[1] = gen_rtx_MULT (SImode, operands[1],
4601 GEN_INT (1 << INTVAL (operands[2])));
4602 return AS2 (lea%L0,%a1,%0);
4606 if (REG_P (operands[2]))
4607 return AS2 (sal%L0,%b2,%0);
4609 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4610 return AS2 (add%L0,%0,%0);
4612 return AS2 (sal%L0,%2,%0);
4615 (define_insn "ashlhi3"
4616 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4617 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4618 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4622 if (REG_P (operands[2]))
4623 return AS2 (sal%W0,%b2,%0);
4625 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4626 return AS2 (add%W0,%0,%0);
4628 return AS2 (sal%W0,%2,%0);
4631 (define_insn "ashlqi3"
4632 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4633 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4634 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4638 if (REG_P (operands[2]))
4639 return AS2 (sal%B0,%b2,%0);
4641 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4642 return AS2 (add%B0,%0,%0);
4644 return AS2 (sal%B0,%2,%0);
4647 ;; See comment above `ashldi3' about how this works.
4649 (define_expand "ashrdi3"
4650 [(set (match_operand:DI
0 "register_operand" "")
4651 (ashiftrt:DI (match_operand:DI
1 "register_operand" "")
4652 (match_operand:QI
2 "nonmemory_operand" "")))]
4656 if (GET_CODE (operands[
2]) != CONST_INT
4657 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[
2]), 'J'))
4659 operands[
2] = copy_to_mode_reg (QImode, operands[
2]);
4660 emit_insn (gen_ashrdi3_non_const_int (operands[
0], operands[
1],
4664 emit_insn (gen_ashrdi3_const_int (operands[
0], operands[
1], operands[
2]));
4669 (define_insn "ashldi3_32"
4670 [(set (match_operand:DI
0 "nonimmediate_operand" "=r,m")
4671 (ashift:DI (match_operand:DI
1 "nonimmediate_operand" "ro,r")
4676 rtx low[
2], high[
2], xops[
4];
4678 split_di (operands,
2, low, high);
4682 xops[
3] = const0_rtx;
4683 if (!rtx_equal_p (xops[
0], xops[
1]))
4684 output_asm_insn (AS2 (mov%L0,%
1,%
0), xops);
4686 if (GET_CODE (low[
0]) == MEM)
4687 output_asm_insn (AS2 (mov%L2,%
3,%
2), xops);
4689 output_asm_insn (AS2 (xor%L2,%
2,%
2), xops);
4694 (define_insn "ashrdi3_const_int"
4695 [(set (match_operand:DI
0 "register_operand" "=&r")
4696 (ashiftrt:DI (match_operand:DI
1 "register_operand" "
0")
4697 (match_operand:QI
2 "const_int_operand" "J")))]
4698 "CONST_OK_FOR_LETTER_P (INTVAL (operands[
2]), 'J')"
4701 rtx xops[
4], low[
1], high[
1];
4705 split_di (operands,
1, low, high);
4706 xops[
0] = operands[
2];
4707 xops[
1] = const1_rtx;
4711 if (INTVAL (xops[
0]) >
31)
4713 xops[
1] = GEN_INT (
31);
4714 output_asm_insn (AS2 (mov%L2,%
3,%
2), xops);
4715 output_asm_insn (AS2 (sar%L3,%
1,%
3), xops); /* shift by
32 */
4717 if (INTVAL (xops[
0]) >
32)
4719 xops[
0] = GEN_INT (INTVAL (xops[
0]) -
32);
4720 output_asm_insn (AS2 (sar%L2,%
0,%
2), xops); /* Remaining shift */
4725 output_asm_insn (AS3 (shrd%L2,%
0,%
3,%
2), xops);
4726 output_asm_insn (AS2 (sar%L3,%
0,%
3), xops);
4732 (define_insn "ashrdi3_non_const_int"
4733 [(set (match_operand:DI
0 "register_operand" "=&r")
4734 (ashiftrt:DI (match_operand:DI
1 "register_operand" "
0")
4735 (match_operand:QI
2 "register_operand" "c")))]
4739 rtx xops[
4], low[
1], high[
1];
4740 static HOST_WIDE_INT ashrdi_label_number;
4744 split_di (operands,
1, low, high);
4745 xops[
0] = operands[
2];
4746 xops[
1] = GEN_INT (
32);
4750 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%
0,%
3,%
2), xops);
4751 output_asm_insn (AS2 (sar%L3,%
0,%
3), xops);
4752 output_asm_insn (AS2 (test%B0,%
1,%b0), xops);
4753 asm_fprintf (asm_out_file,
\"\\tje %LLASHRDI%d
\\n
\", ashrdi_label_number);
4754 xops[
1] = GEN_INT (
31);
4755 output_asm_insn (AS2 (mov%L2,%
3,%
2), xops);
4756 output_asm_insn (AS2 (sar%L3,%
1,%
3), xops); /* shift by
32 */
4757 asm_fprintf (asm_out_file,
\"%LLASHRDI%d:
\\n
\", ashrdi_label_number++);
4762 (define_insn "ashrsi3"
4763 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm")
4764 (ashiftrt:SI (match_operand:SI
1 "nonimmediate_operand" "
0")
4765 (match_operand:SI
2 "nonmemory_operand" "cI")))]
4769 if (REG_P (operands[
2]))
4770 return AS2 (sar%L0,%b2,%
0);
4772 return AS2 (sar%L0,%
2,%
0);
4775 (define_insn "ashrhi3"
4776 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm")
4777 (ashiftrt:HI (match_operand:HI
1 "nonimmediate_operand" "
0")
4778 (match_operand:HI
2 "nonmemory_operand" "cI")))]
4782 if (REG_P (operands[
2]))
4783 return AS2 (sar%W0,%b2,%
0);
4785 return AS2 (sar%W0,%
2,%
0);
4788 (define_insn "ashrqi3"
4789 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm")
4790 (ashiftrt:QI (match_operand:QI
1 "nonimmediate_operand" "
0")
4791 (match_operand:QI
2 "nonmemory_operand" "cI")))]
4795 if (REG_P (operands[
2]))
4796 return AS2 (sar%B0,%b2,%
0);
4798 return AS2 (sar%B0,%
2,%
0);
4801 ;;- logical shift instructions
4803 ;; See comment above
`ashldi3' about how this works.
4805 (define_expand "lshrdi3"
4806 [(set (match_operand:DI 0 "register_operand" "")
4807 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4808 (match_operand:QI 2 "nonmemory_operand" "")))]
4812 if (GET_CODE (operands[2]) != CONST_INT
4813 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4815 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4816 emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
4820 emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
4825 (define_insn "lshrdi3_32"
4826 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
4827 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
4832 rtx low[2], high[2], xops[4];
4834 split_di (operands, 2, low, high);
4838 xops[3] = const0_rtx;
4839 if (!rtx_equal_p (xops[0], xops[1]))
4840 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
4842 if (GET_CODE (low[0]) == MEM)
4843 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4845 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4850 (define_insn "lshrdi3_const_int"
4851 [(set (match_operand:DI 0 "register_operand" "=&r")
4852 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
4853 (match_operand:QI 2 "const_int_operand" "J")))]
4854 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
4857 rtx xops[4], low[1], high[1];
4861 split_di (operands, 1, low, high);
4862 xops[0] = operands[2];
4863 xops[1] = const1_rtx;
4867 if (INTVAL (xops[0]) > 31)
4869 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
4870 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
4872 if (INTVAL (xops[0]) > 32)
4874 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
4875 output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
4880 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
4881 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
4887 (define_insn "lshrdi3_non_const_int"
4888 [(set (match_operand:DI 0 "register_operand" "=&r")
4889 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
4890 (match_operand:QI 2 "register_operand" "c")))]
4894 rtx xops[4], low[1], high[1];
4895 static HOST_WIDE_INT lshrdi_label_number;
4899 split_di (operands, 1, low, high);
4900 xops[0] = operands[2];
4901 xops[1] = GEN_INT (32);
4905 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
4906 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
4907 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
4908 asm_fprintf (asm_out_file, \"\\tje %LLLSHRDI%d\\n\", lshrdi_label_number);
4909 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
4910 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
4911 asm_fprintf (asm_out_file, \"%LLLSHRDI%d:\\n\", lshrdi_label_number++);
4916 (define_insn "lshrsi3"
4917 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4918 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
4919 (match_operand:SI 2 "nonmemory_operand" "cI")))]
4923 if (REG_P (operands[2]))
4924 return AS2 (shr%L0,%b2,%0);
4926 return AS2 (shr%L0,%2,%1);
4929 (define_insn "lshrhi3"
4930 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4931 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4932 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4936 if (REG_P (operands[2]))
4937 return AS2 (shr%W0,%b2,%0);
4939 return AS2 (shr%W0,%2,%0);
4942 (define_insn "lshrqi3"
4943 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4944 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4945 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4949 if (REG_P (operands[2]))
4950 return AS2 (shr%B0,%b2,%0);
4952 return AS2 (shr%B0,%2,%0);
4955 ;;- rotate instructions
4957 (define_insn "rotlsi3"
4958 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4959 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
4960 (match_operand:SI 2 "nonmemory_operand" "cI")))]
4964 if (REG_P (operands[2]))
4965 return AS2 (rol%L0,%b2,%0);
4967 return AS2 (rol%L0,%2,%0);
4970 (define_insn "rotlhi3"
4971 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4972 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4973 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4977 if (REG_P (operands[2]))
4978 return AS2 (rol%W0,%b2,%0);
4980 return AS2 (rol%W0,%2,%0);
4983 (define_insn "rotlqi3"
4984 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4985 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4986 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4990 if (REG_P (operands[2]))
4991 return AS2 (rol%B0,%b2,%0);
4993 return AS2 (rol%B0,%2,%0);
4996 (define_insn "rotrsi3"
4997 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4998 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
4999 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5003 if (REG_P (operands[2]))
5004 return AS2 (ror%L0,%b2,%0);
5006 return AS2 (ror%L0,%2,%0);
5009 (define_insn "rotrhi3"
5010 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5011 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5012 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5016 if (REG_P (operands[2]))
5017 return AS2 (ror%W0,%b2,%0);
5019 return AS2 (ror%W0,%2,%0);
5022 (define_insn "rotrqi3"
5023 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5024 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5025 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5029 if (REG_P (operands[2]))
5030 return AS2 (ror%B0,%b2,%0);
5032 return AS2 (ror%B0,%2,%0);
5036 ;; This usually looses. But try a define_expand to recognize a few case
5037 ;; we can do efficiently, such as accessing the "high" QImode registers,
5038 ;; %ah, %bh, %ch, %dh.
5039 ;; ??? Note this has a botch on the mode of operand 0, which needs to be
5040 ;; fixed if this is ever enabled.
5042 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
5043 (match_operand:SI 1 "immediate_operand" "i")
5044 (match_operand:SI 2 "immediate_operand" "i"))
5045 (match_operand:SI 3 "nonmemory_operand" "ri"))]
5049 if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
5051 if (GET_CODE (operands[3]) == CONST_INT)
5053 unsigned int mask = (1 << INTVAL (operands[1])) - 1;
5054 operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
5055 output_asm_insn (AS2 (and%L0,%1,%0), operands);
5056 operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
5057 output_asm_insn (AS2 (or%L0,%3,%0), operands);
5061 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
5062 if (INTVAL (operands[2]))
5063 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5064 output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
5065 operands[2] = GEN_INT (BITS_PER_WORD
5066 - INTVAL (operands[1]) - INTVAL (operands[2]));
5067 if (INTVAL (operands[2]))
5068 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5074 ;; ??? There are problems with the mode of operand[3]. The point of this
5075 ;; is to represent an HImode move to a "high byte" register.
5077 (define_expand "insv"
5078 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
5079 (match_operand:SI 1 "immediate_operand" "")
5080 (match_operand:SI 2 "immediate_operand" ""))
5081 (match_operand:QI 3 "nonmemory_operand" "ri"))]
5085 if (GET_CODE (operands[1]) != CONST_INT
5086 || GET_CODE (operands[2]) != CONST_INT)
5089 if (! (INTVAL (operands[1]) == 8
5090 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
5091 && ! INTVAL (operands[1]) == 1)
5096 ;; On i386, the register count for a bit operation is *not* truncated,
5097 ;; so SHIFT_COUNT_TRUNCATED must not be defined.
5099 ;; On i486, the shift & or/and code is faster than bts or btr. If
5100 ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
5102 ;; On i386, bts is a little faster if operands[0] is a reg, and a
5103 ;; little slower if operands[0] is a MEM, than the shift & or/and code.
5104 ;; Use bts & btr, since they reload better.
5106 ;; General bit set and clear.
5108 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm")
5110 (match_operand:SI 2 "register_operand" "r"))
5111 (match_operand:SI 3 "const_int_operand" "n"))]
5112 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5117 if (INTVAL (operands[3]) == 1)
5118 return AS2 (bts%L0,%2,%0);
5120 return AS2 (btr%L0,%2,%0);
5123 ;; Bit complement. See comments on previous pattern.
5124 ;; ??? Is this really worthwhile?
5126 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5127 (xor:SI (ashift:SI (const_int 1)
5128 (match_operand:SI 1 "register_operand" "r"))
5129 (match_operand:SI 2 "nonimmediate_operand" "0")))]
5130 "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT"
5135 return AS2 (btc%L0,%1,%0);
5139 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5140 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5141 (ashift:SI (const_int 1)
5142 (match_operand:SI 2 "register_operand" "r"))))]
5143 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5148 return AS2 (btc%L0,%2,%0);
5151 ;; Recognizers for bit-test instructions.
5153 ;; The bt opcode allows a MEM in operands[0]. But on both i386 and
5154 ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
5155 ;; bt on the MEM directly.
5157 ;; ??? The first argument of a zero_extract must not be reloaded, so
5158 ;; don't allow a MEM in the operand predicate without allowing it in the
5162 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5164 (match_operand:SI 1 "register_operand" "r")))]
5165 "GET_CODE (operands[1]) != CONST_INT"
5168 cc_status.flags |= CC_Z_IN_NOT_C;
5169 return AS2 (bt%L0,%1,%0);
5173 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5174 (match_operand:SI 1 "const_int_operand" "n")
5175 (match_operand:SI 2 "const_int_operand" "n")))]
5181 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5182 operands[1] = GEN_INT (mask);
5184 if (QI_REG_P (operands[0]))
5186 if ((mask & ~0xff) == 0)
5188 cc_status.flags |= CC_NOT_NEGATIVE;
5189 return AS2 (test%B0,%1,%b0);
5192 if ((mask & ~0xff00) == 0)
5194 cc_status.flags |= CC_NOT_NEGATIVE;
5195 operands[1] = GEN_INT (mask >> 8);
5196 return AS2 (test%B0,%1,%h0);
5200 return AS2 (test%L0,%1,%0);
5203 ;; ??? All bets are off if operand 0 is a volatile MEM reference.
5204 ;; The CPU may access unspecified bytes around the actual target byte.
5207 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
5208 (match_operand:SI 1 "const_int_operand" "n")
5209 (match_operand:SI 2 "const_int_operand" "n")))]
5210 "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
5215 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5216 operands[1] = GEN_INT (mask);
5218 if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
5220 if ((mask & ~0xff) == 0)
5222 cc_status.flags |= CC_NOT_NEGATIVE;
5223 return AS2 (test%B0,%1,%b0);
5226 if ((mask & ~0xff00) == 0)
5228 cc_status.flags |= CC_NOT_NEGATIVE;
5229 operands[1] = GEN_INT (mask >> 8);
5231 if (QI_REG_P (operands[0]))
5232 return AS2 (test%B0,%1,%h0);
5235 operands[0] = adj_offsettable_operand (operands[0], 1);
5236 return AS2 (test%B0,%1,%b0);
5240 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
5242 cc_status.flags |= CC_NOT_NEGATIVE;
5243 operands[1] = GEN_INT (mask >> 16);
5244 operands[0] = adj_offsettable_operand (operands[0], 2);
5245 return AS2 (test%B0,%1,%b0);
5248 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
5250 cc_status.flags |= CC_NOT_NEGATIVE;
5251 operands[1] = GEN_INT (mask >> 24);
5252 operands[0] = adj_offsettable_operand (operands[0], 3);
5253 return AS2 (test%B0,%1,%b0);
5257 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
5258 return AS2 (test%L0,%1,%0);
5260 return AS2 (test%L1,%0,%1);
5263 ;; Store-flag instructions.
5265 ;; For all sCOND expanders, also expand the compare or test insn that
5266 ;; generates cc0. Generate an equality comparison if `seq' or
`sne'.
5268 ;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may
5269 ;; not have any input reloads. A MEM write might need an input reload
5270 ;; for the address of the MEM. So don't allow MEM as the SET_DEST.
5272 (define_expand "seq"
5274 (set (match_operand:QI 0 "register_operand" "")
5275 (eq:QI (cc0) (const_int 0)))]
5280 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5281 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5283 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5287 [(set (match_operand:QI 0 "register_operand" "=q")
5288 (eq:QI (cc0) (const_int 0)))]
5292 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5293 return AS1 (setnb,%0);
5295 return AS1 (sete,%0);
5298 (define_expand "sne"
5300 (set (match_operand:QI 0 "register_operand" "")
5301 (ne:QI (cc0) (const_int 0)))]
5306 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5307 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5309 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5313 [(set (match_operand:QI 0 "register_operand" "=q")
5314 (ne:QI (cc0) (const_int 0)))]
5318 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5319 return AS1 (setb,%0);
5321 return AS1 (setne,%0);
5325 (define_expand "sgt"
5327 (set (match_operand:QI 0 "register_operand" "")
5328 (gt:QI (cc0) (const_int 0)))]
5330 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5333 [(set (match_operand:QI 0 "register_operand" "=q")
5334 (gt:QI (cc0) (const_int 0)))]
5338 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5339 && ! (cc_prev_status.flags & CC_FCOMI))
5340 return AS1 (sete,%0);
5342 OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR);
5345 (define_expand "sgtu"
5347 (set (match_operand:QI 0 "register_operand" "")
5348 (gtu:QI (cc0) (const_int 0)))]
5350 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5353 [(set (match_operand:QI 0 "register_operand" "=q")
5354 (gtu:QI (cc0) (const_int 0)))]
5356 "* return \"seta %0\"; ")
5358 (define_expand "slt"
5360 (set (match_operand:QI 0 "register_operand" "")
5361 (lt:QI (cc0) (const_int 0)))]
5363 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5366 [(set (match_operand:QI 0 "register_operand" "=q")
5367 (lt:QI (cc0) (const_int 0)))]
5371 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5372 && ! (cc_prev_status.flags & CC_FCOMI))
5373 return AS1 (sete,%0);
5375 OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\");
5378 (define_expand "sltu"
5380 (set (match_operand:QI 0 "register_operand" "")
5381 (ltu:QI (cc0) (const_int 0)))]
5383 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5386 [(set (match_operand:QI 0 "register_operand" "=q")
5387 (ltu:QI (cc0) (const_int 0)))]
5389 "* return \"setb %0\"; ")
5391 (define_expand "sge"
5393 (set (match_operand:QI 0 "register_operand" "")
5394 (ge:QI (cc0) (const_int 0)))]
5396 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5399 [(set (match_operand:QI 0 "register_operand" "=q")
5400 (ge:QI (cc0) (const_int 0)))]
5404 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5405 && ! (cc_prev_status.flags & CC_FCOMI))
5406 return AS1 (sete,%0);
5408 OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\");
5411 (define_expand "sgeu"
5413 (set (match_operand:QI 0 "register_operand" "")
5414 (geu:QI (cc0) (const_int 0)))]
5416 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5419 [(set (match_operand:QI 0 "register_operand" "=q")
5420 (geu:QI (cc0) (const_int 0)))]
5422 "* return \"setae %0\"; ")
5424 (define_expand "sle"
5426 (set (match_operand:QI 0 "register_operand" "")
5427 (le:QI (cc0) (const_int 0)))]
5429 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5432 [(set (match_operand:QI 0 "register_operand" "=q")
5433 (le:QI (cc0) (const_int 0)))]
5437 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5438 && ! (cc_prev_status.flags & CC_FCOMI))
5439 return AS1 (setb,%0);
5441 OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR);
5444 (define_expand "sleu"
5446 (set (match_operand:QI 0 "register_operand" "")
5447 (leu:QI (cc0) (const_int 0)))]
5449 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5452 [(set (match_operand:QI 0 "register_operand" "=q")
5453 (leu:QI (cc0) (const_int 0)))]
5455 "* return \"setbe %0\"; ")
5457 ;; Basic conditional jump instructions.
5458 ;; We ignore the overflow flag for signed branch instructions.
5460 ;; For all bCOND expanders, also expand the compare or test insn that
5461 ;; generates cc0. Generate an equality comparison if `beq' or
`bne'.
5463 (define_expand "beq"
5466 (if_then_else (eq (cc0)
5468 (label_ref (match_operand 0 "" ""))
5474 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5475 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5477 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5482 (if_then_else (eq (cc0)
5484 (label_ref (match_operand 0 "" ""))
5489 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5492 if (cc_prev_status.flags & CC_TEST_AX)
5494 operands[1] = gen_rtx_REG (SImode, 0);
5495 operands[2] = GEN_INT (0x4000);
5496 output_asm_insn (AS2 (testl,%2,%1), operands);
5497 return AS1 (jne,%l0);
5503 (define_expand "bne"
5506 (if_then_else (ne (cc0)
5508 (label_ref (match_operand 0 "" ""))
5514 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5515 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5517 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5522 (if_then_else (ne (cc0)
5524 (label_ref (match_operand 0 "" ""))
5529 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5532 if (cc_prev_status.flags & CC_TEST_AX)
5534 operands[1] = gen_rtx_REG (SImode, 0);
5535 operands[2] = GEN_INT (0x4000);
5536 output_asm_insn (AS2 (testl,%2,%1), operands);
5537 return AS1 (je,%l0);
5543 (define_expand "bgt"
5546 (if_then_else (gt (cc0)
5548 (label_ref (match_operand 0 "" ""))
5551 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5555 (if_then_else (gt (cc0)
5557 (label_ref (match_operand 0 "" ""))
5562 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5563 && ! (cc_prev_status.flags & CC_FCOMI))
5564 return AS1 (je,%l0);
5566 if (cc_prev_status.flags & CC_TEST_AX)
5568 operands[1] = gen_rtx_REG (SImode, 0);
5569 operands[2] = GEN_INT (0x4100);
5570 output_asm_insn (AS2 (testl,%2,%1), operands);
5571 return AS1 (je,%l0);
5573 OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
5576 (define_expand "bgtu"
5579 (if_then_else (gtu (cc0)
5581 (label_ref (match_operand 0 "" ""))
5584 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5588 (if_then_else (gtu (cc0)
5590 (label_ref (match_operand 0 "" ""))
5595 (define_expand "blt"
5598 (if_then_else (lt (cc0)
5600 (label_ref (match_operand 0 "" ""))
5603 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5607 (if_then_else (lt (cc0)
5609 (label_ref (match_operand 0 "" ""))
5614 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5615 && ! (cc_prev_status.flags & CC_FCOMI))
5616 return AS1 (je,%l0);
5618 if (cc_prev_status.flags & CC_TEST_AX)
5620 operands[1] = gen_rtx_REG (SImode, 0);
5621 operands[2] = GEN_INT (0x100);
5622 output_asm_insn (AS2 (testl,%2,%1), operands);
5623 return AS1 (jne,%l0);
5625 OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
5628 (define_expand "bltu"
5631 (if_then_else (ltu (cc0)
5633 (label_ref (match_operand 0 "" ""))
5636 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5640 (if_then_else (ltu (cc0)
5642 (label_ref (match_operand 0 "" ""))
5647 (define_expand "bge"
5650 (if_then_else (ge (cc0)
5652 (label_ref (match_operand 0 "" ""))
5655 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5659 (if_then_else (ge (cc0)
5661 (label_ref (match_operand 0 "" ""))
5666 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5667 && ! (cc_prev_status.flags & CC_FCOMI))
5668 return AS1 (je,%l0);
5669 if (cc_prev_status.flags & CC_TEST_AX)
5671 operands[1] = gen_rtx_REG (SImode, 0);
5672 operands[2] = GEN_INT (0x100);
5673 output_asm_insn (AS2 (testl,%2,%1), operands);
5674 return AS1 (je,%l0);
5676 OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
5679 (define_expand "bgeu"
5682 (if_then_else (geu (cc0)
5684 (label_ref (match_operand 0 "" ""))
5687 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5691 (if_then_else (geu (cc0)
5693 (label_ref (match_operand 0 "" ""))
5698 (define_expand "ble"
5701 (if_then_else (le (cc0)
5703 (label_ref (match_operand 0 "" ""))
5706 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5710 (if_then_else (le (cc0)
5712 (label_ref (match_operand 0 "" ""))
5717 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5718 && ! (cc_prev_status.flags & CC_FCOMI))
5719 return AS1 (jb,%l0);
5720 if (cc_prev_status.flags & CC_TEST_AX)
5722 operands[1] = gen_rtx_REG (SImode, 0);
5723 operands[2] = GEN_INT (0x4100);
5724 output_asm_insn (AS2 (testl,%2,%1), operands);
5725 return AS1 (jne,%l0);
5728 OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
5731 (define_expand "bleu"
5734 (if_then_else (leu (cc0)
5736 (label_ref (match_operand 0 "" ""))
5739 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5743 (if_then_else (leu (cc0)
5745 (label_ref (match_operand 0 "" ""))
5750 ;; Negated conditional jump instructions.
5754 (if_then_else (eq (cc0)
5757 (label_ref (match_operand 0 "" ""))))]
5761 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5764 if (cc_prev_status.flags & CC_TEST_AX)
5766 operands[1] = gen_rtx_REG (SImode, 0);
5767 operands[2] = GEN_INT (0x4000);
5768 output_asm_insn (AS2 (testl,%2,%1), operands);
5769 return AS1 (je,%l0);
5776 (if_then_else (ne (cc0)
5779 (label_ref (match_operand 0 "" ""))))]
5783 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5786 if (cc_prev_status.flags & CC_TEST_AX)
5788 operands[1] = gen_rtx_REG (SImode, 0);
5789 operands[2] = GEN_INT (0x4000);
5790 output_asm_insn (AS2 (testl,%2,%1), operands);
5791 return AS1 (jne,%l0);
5798 (if_then_else (gt (cc0)
5801 (label_ref (match_operand 0 "" ""))))]
5805 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5806 && ! (cc_prev_status.flags & CC_FCOMI))
5807 return AS1 (jne,%l0);
5808 if (cc_prev_status.flags & CC_TEST_AX)
5810 operands[1] = gen_rtx_REG (SImode, 0);
5811 operands[2] = GEN_INT (0x4100);
5812 output_asm_insn (AS2 (testl,%2,%1), operands);
5813 return AS1 (jne,%l0);
5815 OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
5820 (if_then_else (gtu (cc0)
5823 (label_ref (match_operand 0 "" ""))))]
5829 (if_then_else (lt (cc0)
5832 (label_ref (match_operand 0 "" ""))))]
5836 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5837 && ! (cc_prev_status.flags & CC_FCOMI))
5838 return AS1 (jne,%l0);
5839 if (cc_prev_status.flags & CC_TEST_AX)
5841 operands[1] = gen_rtx_REG (SImode, 0);
5842 operands[2] = GEN_INT (0x100);
5843 output_asm_insn (AS2 (testl,%2,%1), operands);
5844 return AS1 (je,%l0);
5847 OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
5852 (if_then_else (ltu (cc0)
5855 (label_ref (match_operand 0 "" ""))))]
5861 (if_then_else (ge (cc0)
5864 (label_ref (match_operand 0 "" ""))))]
5868 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5869 && ! (cc_prev_status.flags & CC_FCOMI))
5870 return AS1 (jne,%l0);
5871 if (cc_prev_status.flags & CC_TEST_AX)
5873 operands[1] = gen_rtx_REG (SImode, 0);
5874 operands[2] = GEN_INT (0x100);
5875 output_asm_insn (AS2 (testl,%2,%1), operands);
5876 return AS1 (jne,%l0);
5878 OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
5883 (if_then_else (geu (cc0)
5886 (label_ref (match_operand 0 "" ""))))]
5892 (if_then_else (le (cc0)
5895 (label_ref (match_operand 0 "" ""))))]
5899 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5900 && ! (cc_prev_status.flags & CC_FCOMI))
5901 return AS1 (jae,%l0);
5903 if (cc_prev_status.flags & CC_TEST_AX)
5905 operands[1] = gen_rtx_REG (SImode, 0);
5906 operands[2] = GEN_INT (0x4100);
5907 output_asm_insn (AS2 (testl,%2,%1), operands);
5908 return AS1 (je,%l0);
5910 OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
5915 (if_then_else (leu (cc0)
5918 (label_ref (match_operand 0 "" ""))))]
5922 ;; Unconditional and other jump instructions
5926 (label_ref (match_operand 0 "" "")))]
5930 (define_insn "indirect_jump"
5931 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
5937 return AS1 (jmp,%*%0);
5940 ;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
5941 ;; if S does not change i
5943 (define_expand "decrement_and_branch_until_zero"
5944 [(parallel [(set (pc)
5945 (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "")
5948 (label_ref (match_operand 1 "" ""))
5951 (plus:SI (match_dup 0)
5958 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
5959 [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
5960 (match_operand:SI 2 "general_operand" "rmi,ri"))
5962 (label_ref (match_operand 3 "" ""))
5965 (plus:SI (match_dup 1)
5971 if (operands[2] == constm1_rtx)
5972 output_asm_insn (AS1 (dec%L1,%1), operands);
5974 else if (operands[2] == const1_rtx)
5975 output_asm_insn (AS1 (inc%L1,%1), operands);
5978 output_asm_insn (AS2 (add%L1,%2,%1), operands);
5980 return AS1 (%J0,%l3);
5985 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
5986 [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
5987 (match_operand:SI 2 "general_operand" "rmi,ri"))
5989 (label_ref (match_operand 3 "" ""))
5992 (minus:SI (match_dup 1)
5998 if (operands[2] == const1_rtx)
5999 output_asm_insn (AS1 (dec%L1,%1), operands);
6001 else if (operands[1] == constm1_rtx)
6002 output_asm_insn (AS1 (inc%L1,%1), operands);
6005 output_asm_insn (AS2 (sub%L1,%2,%1), operands);
6007 return AS1 (%J0,%l3);
6012 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6014 (label_ref (match_operand 1 "" ""))
6017 (plus:SI (match_dup 0)
6023 operands[2] = const1_rtx;
6024 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6030 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6032 (label_ref (match_operand 1 "" ""))
6035 (plus:SI (match_dup 0)
6041 operands[2] = const1_rtx;
6042 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6048 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6050 (label_ref (match_operand 1 "" ""))
6053 (plus:SI (match_dup 0)
6059 output_asm_insn (AS1 (dec%L0,%0), operands);
6065 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6067 (label_ref (match_operand 1 "" ""))
6070 (plus:SI (match_dup 0)
6076 output_asm_insn (AS1 (dec%L0,%0), operands);
6082 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6084 (label_ref (match_operand 1 "" ""))
6087 (plus:SI (match_dup 0)
6093 output_asm_insn (AS1 (inc%L0,%0), operands);
6099 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6101 (label_ref (match_operand 1 "" ""))
6104 (plus:SI (match_dup 0)
6110 output_asm_insn (AS1 (inc%L0,%0), operands);
6114 ;; Implement switch statements when generating PIC code. Switches are
6115 ;; implemented by `tablejump' when not using -fpic.
6117 ;; Emit code here to do the range checking and make the index zero based.
6119 (define_expand "casesi"
6121 (match_operand:SI
0 "general_operand" ""))
6123 (minus:SI (match_dup
5)
6124 (match_operand:SI
1 "general_operand" "")))
6126 (compare:CC (match_dup
6)
6127 (match_operand:SI
2 "general_operand" "")))
6129 (if_then_else (gtu (cc0)
6131 (label_ref (match_operand
4 "" ""))
6135 (minus:SI (reg:SI
3)
6136 (mem:SI (plus:SI (mult:SI (match_dup
6)
6138 (label_ref (match_operand
3 "" ""))))))
6139 (clobber (match_scratch:SI
7 ""))])]
6143 operands[
5] = gen_reg_rtx (SImode);
6144 operands[
6] = gen_reg_rtx (SImode);
6145 current_function_uses_pic_offset_table =
1;
6148 ;; Implement a casesi insn.
6150 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
6153 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
6155 ;;
1. An expression involving an external reference may only use the
6156 ;; addition operator, and only with an assembly-time constant.
6157 ;; The example above satisfies this because ".-.L2" is a constant.
6159 ;;
2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
6160 ;; given the value of "GOT - .", where GOT is the actual address of
6161 ;; the Global Offset Table. Therefore, the .long above actually
6162 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
6163 ;; expression "GOT - .L2" by itself would generate an error from as(
1).
6165 ;; The pattern below emits code that looks like this:
6168 ;; subl TABLE@GOTOFF(%ebx,index,
4),reg
6171 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
6172 ;; the addr_diff_vec is known to be part of this module.
6174 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
6175 ;; evaluates to just ".L2".
6179 (minus:SI (reg:SI
3)
6181 (mult:SI (match_operand:SI
0 "register_operand" "r")
6183 (label_ref (match_operand
1 "" ""))))))
6184 (clobber (match_scratch:SI
2 "=&r"))]
6190 xops[
0] = operands[
0];
6191 xops[
1] = operands[
1];
6192 xops[
2] = operands[
2];
6193 xops[
3] = pic_offset_table_rtx;
6195 output_asm_insn (AS2 (mov%L2,%
3,%
2), xops);
6196 output_asm_insn (
\"sub%L2 %l1@GOTOFF(%
3,%
0,
4),%
2\", xops);
6197 output_asm_insn (AS1 (jmp,%*%
2), xops);
6198 ASM_OUTPUT_ALIGN (asm_out_file, i386_align_jumps);
6202 (define_insn "tablejump"
6203 [(set (pc) (match_operand:SI
0 "nonimmediate_operand" "rm"))
6204 (use (label_ref (match_operand
1 "" "")))]
6210 return AS1 (jmp,%*%
0);
6215 ;; If generating PIC code, the predicate indirect_operand will fail
6216 ;; for operands[
0] containing symbolic references on all of the named
6217 ;; call* patterns. Each named pattern is followed by an unnamed pattern
6218 ;; that matches any call to a symbolic CONST (ie, a symbol_ref). The
6219 ;; unnamed patterns are only used while generating PIC code, because
6220 ;; otherwise the named patterns match.
6222 ;; Call subroutine returning no value.
6224 (define_expand "call_pop"
6225 [(parallel [(call (match_operand:QI
0 "indirect_operand" "")
6226 (match_operand:SI
1 "general_operand" ""))
6229 (match_operand:SI
3 "immediate_operand" "")))])]
6236 current_function_uses_pic_offset_table =
1;
6238 /* With half-pic, force the address into a register. */
6239 addr = XEXP (operands[
0],
0);
6240 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6241 XEXP (operands[
0],
0) = force_reg (Pmode, addr);
6243 if (! expander_call_insn_operand (operands[
0], QImode))
6245 = change_address (operands[
0], VOIDmode,
6246 copy_to_mode_reg (Pmode, XEXP (operands[
0],
0)));
6250 [(call (match_operand:QI
0 "call_insn_operand" "m")
6251 (match_operand:SI
1 "general_operand" "g"))
6252 (set (reg:SI
7) (plus:SI (reg:SI
7)
6253 (match_operand:SI
3 "immediate_operand" "i")))]
6257 if (GET_CODE (operands[
0]) == MEM
6258 && ! CONSTANT_ADDRESS_P (XEXP (operands[
0],
0)))
6260 operands[
0] = XEXP (operands[
0],
0);
6261 return AS1 (call,%*%
0);
6264 return AS1 (call,%P0);
6268 [(call (mem:QI (match_operand:SI
0 "symbolic_operand" ""))
6269 (match_operand:SI
1 "general_operand" "g"))
6270 (set (reg:SI
7) (plus:SI (reg:SI
7)
6271 (match_operand:SI
3 "immediate_operand" "i")))]
6275 (define_expand "call"
6276 [(call (match_operand:QI
0 "indirect_operand" "")
6277 (match_operand:SI
1 "general_operand" ""))]
6278 ;; Operand
1 not used on the i386.
6285 current_function_uses_pic_offset_table =
1;
6287 /* With half-pic, force the address into a register. */
6288 addr = XEXP (operands[
0],
0);
6289 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6290 XEXP (operands[
0],
0) = force_reg (Pmode, addr);
6292 if (! expander_call_insn_operand (operands[
0], QImode))
6294 = change_address (operands[
0], VOIDmode,
6295 copy_to_mode_reg (Pmode, XEXP (operands[
0],
0)));
6299 [(call (match_operand:QI
0 "call_insn_operand" "m")
6300 (match_operand:SI
1 "general_operand" "g"))]
6301 ;; Operand
1 not used on the i386.
6305 if (GET_CODE (operands[
0]) == MEM
6306 && ! CONSTANT_ADDRESS_P (XEXP (operands[
0],
0)))
6308 operands[
0] = XEXP (operands[
0],
0);
6309 return AS1 (call,%*%
0);
6312 return AS1 (call,%P0);
6316 [(call (mem:QI (match_operand:SI
0 "symbolic_operand" ""))
6317 (match_operand:SI
1 "general_operand" "g"))]
6318 ;; Operand
1 not used on the i386.
6322 ;; Call subroutine, returning value in operand
0
6323 ;; (which must be a hard register).
6325 (define_expand "call_value_pop"
6326 [(parallel [(set (match_operand
0 "" "")
6327 (call (match_operand:QI
1 "indirect_operand" "")
6328 (match_operand:SI
2 "general_operand" "")))
6331 (match_operand:SI
4 "immediate_operand" "")))])]
6338 current_function_uses_pic_offset_table =
1;
6340 /* With half-pic, force the address into a register. */
6341 addr = XEXP (operands[
1],
0);
6342 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6343 XEXP (operands[
1],
0) = force_reg (Pmode, addr);
6345 if (! expander_call_insn_operand (operands[
1], QImode))
6347 = change_address (operands[
1], VOIDmode,
6348 copy_to_mode_reg (Pmode, XEXP (operands[
1],
0)));
6352 [(set (match_operand
0 "" "=rf")
6353 (call (match_operand:QI
1 "call_insn_operand" "m")
6354 (match_operand:SI
2 "general_operand" "g")))
6355 (set (reg:SI
7) (plus:SI (reg:SI
7)
6356 (match_operand:SI
4 "immediate_operand" "i")))]
6360 if (GET_CODE (operands[
1]) == MEM
6361 && ! CONSTANT_ADDRESS_P (XEXP (operands[
1],
0)))
6363 operands[
1] = XEXP (operands[
1],
0);
6364 output_asm_insn (AS1 (call,%*%
1), operands);
6367 output_asm_insn (AS1 (call,%P1), operands);
6373 [(set (match_operand
0 "" "=rf")
6374 (call (mem:QI (match_operand:SI
1 "symbolic_operand" ""))
6375 (match_operand:SI
2 "general_operand" "g")))
6376 (set (reg:SI
7) (plus:SI (reg:SI
7)
6377 (match_operand:SI
4 "immediate_operand" "i")))]
6381 (define_expand "call_value"
6382 [(set (match_operand
0 "" "")
6383 (call (match_operand:QI
1 "indirect_operand" "")
6384 (match_operand:SI
2 "general_operand" "")))]
6385 ;; Operand
2 not used on the i386.
6392 current_function_uses_pic_offset_table =
1;
6394 /* With half-pic, force the address into a register. */
6395 addr = XEXP (operands[
1],
0);
6396 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6397 XEXP (operands[
1],
0) = force_reg (Pmode, addr);
6399 if (! expander_call_insn_operand (operands[
1], QImode))
6401 = change_address (operands[
1], VOIDmode,
6402 copy_to_mode_reg (Pmode, XEXP (operands[
1],
0)));
6406 [(set (match_operand
0 "" "=rf")
6407 (call (match_operand:QI
1 "call_insn_operand" "m")
6408 (match_operand:SI
2 "general_operand" "g")))]
6409 ;; Operand
2 not used on the i386.
6413 if (GET_CODE (operands[
1]) == MEM
6414 && ! CONSTANT_ADDRESS_P (XEXP (operands[
1],
0)))
6416 operands[
1] = XEXP (operands[
1],
0);
6417 output_asm_insn (AS1 (call,%*%
1), operands);
6420 output_asm_insn (AS1 (call,%P1), operands);
6426 [(set (match_operand
0 "" "=rf")
6427 (call (mem:QI (match_operand:SI
1 "symbolic_operand" ""))
6428 (match_operand:SI
2 "general_operand" "g")))]
6429 ;; Operand
2 not used on the i386.
6433 ;; Call subroutine returning any type.
6435 (define_expand "untyped_call"
6436 [(parallel [(call (match_operand
0 "" "")
6438 (match_operand
1 "" "")
6439 (match_operand
2 "" "")])]
6445 /* In order to give reg-stack an easier job in validating two
6446 coprocessor registers as containing a possible return value,
6447 simply pretend the untyped call returns a complex long double
6450 emit_call_insn (TARGET_80387
6451 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
6452 operands[
0], const0_rtx)
6453 : gen_call (operands[
0], const0_rtx));
6455 for (i =
0; i < XVECLEN (operands[
2],
0); i++)
6457 rtx set = XVECEXP (operands[
2],
0, i);
6458 emit_move_insn (SET_DEST (set), SET_SRC (set));
6461 /* The optimizer does not know that the call sets the function value
6462 registers we stored in the result block. We avoid problems by
6463 claiming that all hard registers are used and clobbered at this
6465 emit_insn (gen_blockage ());
6470 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6471 ;; all of memory. This blocks insns from being moved across this point.
6473 (define_insn "blockage"
6474 [(unspec_volatile [(const_int
0)]
0)]
6478 ;; Insn emitted into the body of a function to return from a function.
6479 ;; This is only done if the function's epilogue is known to be simple.
6480 ;; See comments for simple_386_epilogue in i386.c.
6482 (define_expand "return"
6484 "ix86_can_use_return_insn_p ()"
6487 (define_insn "return_internal"
6492 (define_insn "return_pop_internal"
6494 (use (match_operand:SI
0 "const_int_operand" ""))]
6503 (define_expand "prologue"
6508 ix86_expand_prologue ();
6512 ;; The use of UNSPEC here is currently not necessary - a simple SET of ebp
6513 ;; to itself would be enough. But this way we are safe even if some optimizer
6514 ;; becomes too clever in the future.
6515 (define_insn "prologue_set_stack_ptr"
6517 (minus:SI (reg:SI
7) (match_operand:SI
0 "immediate_operand" "i")))
6518 (set (reg:SI
6) (unspec:SI [(reg:SI
6)]
4))]
6524 xops[
0] = operands[
0];
6525 xops[
1] = stack_pointer_rtx;
6526 output_asm_insn (AS2 (sub%L1,%
0,%
1), xops);
6530 (define_insn "prologue_set_got"
6531 [(set (match_operand:SI
0 "" "")
6533 [(plus:SI (match_dup
0)
6534 (plus:SI (match_operand:SI
1 "symbolic_operand" "")
6535 (minus:SI (pc) (match_operand
2 "" ""))))]
1))]
6541 if (TARGET_DEEP_BRANCH_PREDICTION)
6543 sprintf (buffer,
\"addl %s,%%
0\", XSTR (operands[
1],
0));
6544 output_asm_insn (buffer, operands);
6548 sprintf (buffer,
\"addl %s+[.-%%X2],%%
0\", XSTR (operands[
1],
0));
6549 output_asm_insn (buffer, operands);
6554 (define_insn "prologue_get_pc"
6555 [(set (match_operand:SI
0 "" "")
6556 (unspec_volatile [(plus:SI (pc) (match_operand
1 "" ""))]
2))]
6562 output_asm_insn (AS1 (call,%X1), operands);
6563 if (! TARGET_DEEP_BRANCH_PREDICTION)
6565 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file,
\"L
\", CODE_LABEL_NUMBER (operands[
1]));
6570 (define_insn "prologue_get_pc_and_set_got"
6571 [(unspec_volatile [(match_operand:SI
0 "" "")]
3)]
6575 operands[
1] = gen_label_rtx ();
6576 output_asm_insn (AS1 (call,%X1), operands);
6577 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file,
\"L
\",
6578 CODE_LABEL_NUMBER (operands[
1]));
6579 output_asm_insn (AS1 (pop%L0,%
0), operands);
6580 output_asm_insn (
\"addl $_GLOBAL_OFFSET_TABLE_+[.-%X1],%
0\", operands);
6584 (define_expand "epilogue"
6589 ix86_expand_epilogue ();
6593 (define_insn "epilogue_set_stack_ptr"
6594 [(set (reg:SI
7) (reg:SI
6))
6595 (clobber (reg:SI
6))]
6601 xops[
0] = frame_pointer_rtx;
6602 xops[
1] = stack_pointer_rtx;
6603 output_asm_insn (AS2 (mov%L0,%
0,%
1), xops);
6607 (define_insn "leave"
6609 (clobber (reg:SI
6))
6610 (clobber (reg:SI
7))]
6615 [(set (match_operand:SI
0 "register_operand" "r")
6616 (mem:SI (reg:SI
7)))
6617 (set (reg:SI
7) (plus:SI (reg:SI
7) (const_int
4)))]
6621 output_asm_insn (AS1 (pop%L0,%P0), operands);
6625 (define_expand "movstrsi"
6626 [(parallel [(set (match_operand:BLK
0 "memory_operand" "")
6627 (match_operand:BLK
1 "memory_operand" ""))
6628 (use (match_operand:SI
2 "const_int_operand" ""))
6629 (use (match_operand:SI
3 "const_int_operand" ""))
6630 (clobber (match_scratch:SI
4 ""))
6631 (clobber (match_dup
5))
6632 (clobber (match_dup
6))])]
6638 if (GET_CODE (operands[
2]) != CONST_INT)
6641 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[
0],
0));
6642 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[
1],
0));
6644 operands[
5] = addr0;
6645 operands[
6] = addr1;
6647 operands[
0] = change_address (operands[
0], VOIDmode, addr0);
6648 operands[
1] = change_address (operands[
1], VOIDmode, addr1);
6651 ;; It might seem that operands
0 &
1 could use predicate register_operand.
6652 ;; But strength reduction might offset the MEM expression. So we let
6653 ;; reload put the address into %edi & %esi.
6656 [(set (mem:BLK (match_operand:SI
0 "address_operand" "D"))
6657 (mem:BLK (match_operand:SI
1 "address_operand" "S")))
6658 (use (match_operand:SI
2 "const_int_operand" "n"))
6659 (use (match_operand:SI
3 "immediate_operand" "i"))
6660 (clobber (match_scratch:SI
4 "=&c"))
6661 (clobber (match_dup
0))
6662 (clobber (match_dup
1))]
6668 output_asm_insn (
\"cld
\", operands);
6669 if (GET_CODE (operands[
2]) == CONST_INT)
6671 if (INTVAL (operands[
2]) & ~
0x03)
6673 xops[
0] = GEN_INT ((INTVAL (operands[
2]) >>
2) &
0x3fffffff);
6674 xops[
1] = operands[
4];
6676 output_asm_insn (AS2 (mov%L1,%
0,%
1), xops);
6678 output_asm_insn (
\"rep movsd
\", xops);
6680 output_asm_insn (
\"rep\;movsl
\", xops);
6683 if (INTVAL (operands[
2]) &
0x02)
6684 output_asm_insn (
\"movsw
\", operands);
6685 if (INTVAL (operands[
2]) &
0x01)
6686 output_asm_insn (
\"movsb
\", operands);
6693 (define_expand "clrstrsi"
6694 [(set (match_dup
3) (const_int
0))
6695 (parallel [(set (match_operand:BLK
0 "memory_operand" "")
6697 (use (match_operand:SI
1 "const_int_operand" ""))
6698 (use (match_operand:SI
2 "const_int_operand" ""))
6700 (clobber (match_scratch:SI
4 ""))
6701 (clobber (match_dup
5))])]
6707 if (GET_CODE (operands[
1]) != CONST_INT)
6710 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[
0],
0));
6712 operands[
3] = gen_reg_rtx (SImode);
6713 operands[
5] = addr0;
6715 operands[
0] = gen_rtx_MEM (BLKmode, addr0);
6718 ;; It might seem that operand
0 could use predicate register_operand.
6719 ;; But strength reduction might offset the MEM expression. So we let
6720 ;; reload put the address into %edi.
6723 [(set (mem:BLK (match_operand:SI
0 "address_operand" "D"))
6725 (use (match_operand:SI
1 "const_int_operand" "n"))
6726 (use (match_operand:SI
2 "immediate_operand" "i"))
6727 (use (match_operand:SI
3 "register_operand" "a"))
6728 (clobber (match_scratch:SI
4 "=&c"))
6729 (clobber (match_dup
0))]
6735 output_asm_insn (
\"cld
\", operands);
6736 if (GET_CODE (operands[
1]) == CONST_INT)
6738 if (INTVAL (operands[
1]) & ~
0x03)
6740 xops[
0] = GEN_INT ((INTVAL (operands[
1]) >>
2) &
0x3fffffff);
6741 xops[
1] = operands[
4];
6743 output_asm_insn (AS2 (mov%L1,%
0,%
1), xops);
6745 output_asm_insn (
\"rep stosd
\", xops);
6747 output_asm_insn (
\"rep\;stosl
\", xops);
6750 if (INTVAL (operands[
1]) &
0x02)
6751 output_asm_insn (
\"stosw
\", operands);
6752 if (INTVAL (operands[
1]) &
0x01)
6753 output_asm_insn (
\"stosb
\", operands);
6760 (define_expand "cmpstrsi"
6761 [(parallel [(set (match_operand:SI
0 "general_operand" "")
6762 (compare:SI (match_operand:BLK
1 "general_operand" "")
6763 (match_operand:BLK
2 "general_operand" "")))
6764 (use (match_operand:SI
3 "general_operand" ""))
6765 (use (match_operand:SI
4 "immediate_operand" ""))
6766 (clobber (match_dup
5))
6767 (clobber (match_dup
6))
6768 (clobber (match_dup
3))])]
6774 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[
1],
0));
6775 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[
2],
0));
6776 operands[
3] = copy_to_mode_reg (SImode, operands[
3]);
6778 operands[
5] = addr1;
6779 operands[
6] = addr2;
6781 operands[
1] = gen_rtx_MEM (BLKmode, addr1);
6782 operands[
2] = gen_rtx_MEM (BLKmode, addr2);
6786 ;; memcmp recognizers. The
`cmpsb' opcode does nothing if the count is
6787 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
6789 ;; It might seem that operands 0 & 1 could use predicate register_operand.
6790 ;; But strength reduction might offset the MEM expression. So we let
6791 ;; reload put the address into %edi & %esi.
6793 ;; ??? Most comparisons have a constant length, and it's therefore
6794 ;; possible to know that the length is non-zero, and to avoid the extra
6795 ;; code to handle zero-length compares.
6798 [(set (match_operand:SI 0 "register_operand" "=&r")
6799 (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
6800 (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
6801 (use (match_operand:SI 3 "register_operand" "c"))
6802 (use (match_operand:SI 4 "immediate_operand" "i"))
6803 (clobber (match_dup 1))
6804 (clobber (match_dup 2))
6805 (clobber (match_dup 3))]
6811 label = gen_label_rtx ();
6813 output_asm_insn (\"cld\", operands);
6814 output_asm_insn (AS2 (xor%L0,%0,%0), operands);
6815 output_asm_insn (\"repz\;cmps%B2\", operands);
6816 output_asm_insn (\"je %l0\", &label);
6818 xops[0] = operands[0];
6819 xops[1] = const1_rtx;
6820 output_asm_insn (AS2 (sbb%L0,%0,%0), xops);
6821 if (QI_REG_P (xops[0]))
6822 output_asm_insn (AS2 (or%B0,%1,%b0), xops);
6824 output_asm_insn (AS2 (or%L0,%1,%0), xops);
6826 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
6832 (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
6833 (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
6834 (use (match_operand:SI 2 "register_operand" "c"))
6835 (use (match_operand:SI 3 "immediate_operand" "i"))
6836 (clobber (match_dup 0))
6837 (clobber (match_dup 1))
6838 (clobber (match_dup 2))]
6844 cc_status.flags |= CC_NOT_SIGNED;
6846 xops[0] = gen_rtx_REG (QImode, 0);
6847 xops[1] = CONST0_RTX (QImode);
6849 output_asm_insn (\"cld\", operands);
6850 output_asm_insn (AS2 (test%B0,%1,%0), xops);
6851 return \"repz\;cmps%B2\";
6855 ;; Note, you cannot optimize away the branch following the bsfl by assuming
6856 ;; that the destination is not modified if the input is 0, since not all
6857 ;; x86 implementations do this.
6859 (define_expand "ffssi2"
6860 [(set (match_operand:SI 0 "general_operand" "")
6861 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
6865 rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode);
6867 emit_insn (gen_ffssi_1 (temp, operands[1]));
6868 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0);
6869 emit_jump_insn (gen_bne (label));
6870 emit_move_insn (temp, constm1_rtx);
6872 temp = expand_binop (SImode, add_optab, temp, const1_rtx,
6873 operands[0], 0, OPTAB_WIDEN);
6875 if (temp != operands[0])
6876 emit_move_insn (operands[0], temp);
6880 (define_insn "ffssi_1"
6881 [(set (match_operand:SI 0 "register_operand" "=r")
6882 (unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
6884 "* return AS2 (bsf%L0,%1,%0);")
6886 (define_expand "ffshi2"
6887 [(set (match_operand:SI 0 "general_operand" "")
6888 (ffs:HI (match_operand:HI 1 "general_operand" "")))]
6892 rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode);
6894 emit_insn (gen_ffshi_1 (temp, operands[1]));
6895 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0);
6896 emit_jump_insn (gen_bne (label));
6897 emit_move_insn (temp, constm1_rtx);
6899 temp = expand_binop (HImode, add_optab, temp, const1_rtx,
6900 operands[0], 0, OPTAB_WIDEN);
6902 if (temp != operands[0])
6903 emit_move_insn (operands[0], temp);
6907 (define_insn "ffshi_1"
6908 [(set (match_operand:HI 0 "register_operand" "=r")
6909 (unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
6911 "* return AS2 (bsf%W0,%1,%0);")
6913 ;; These patterns match the binary 387 instructions for addM3, subM3,
6914 ;; mulM3 and divM3. There are three patterns for each of DFmode and
6915 ;; SFmode. The first is the normal insn, the second the same insn but
6916 ;; with one operand a conversion, and the third the same insn but with
6917 ;; the other operand a conversion. The conversion may be SFmode or
6918 ;; SImode if the target mode DFmode, but only SImode if the target mode
6922 [(set (match_operand:DF 0 "register_operand" "=f,f")
6923 (match_operator:DF 3 "binary_387_op"
6924 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
6925 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
6927 "* return output_387_binary_op (insn, operands);"
6929 (cond [(match_operand:DF 3 "is_mul" "")
6930 (const_string "fpmul")
6931 (match_operand:DF 3 "is_div" "")
6932 (const_string "fpdiv")
6934 (const_string "fpop")
6939 [(set (match_operand:DF 0 "register_operand" "=f")
6940 (match_operator:DF 3 "binary_387_op"
6941 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "rm"))
6942 (match_operand:DF 2 "register_operand" "0")]))]
6944 "* return output_387_binary_op (insn, operands);"
6946 (cond [(match_operand:DF 3 "is_mul" "")
6947 (const_string "fpmul")
6948 (match_operand:DF 3 "is_div" "")
6949 (const_string "fpdiv")
6951 (const_string "fpop")
6956 [(set (match_operand:XF 0 "register_operand" "=f,f")
6957 (match_operator:XF 3 "binary_387_op"
6958 [(match_operand:XF 1 "register_operand" "0,f")
6959 (match_operand:XF 2 "register_operand" "f,0")]))]
6961 "* return output_387_binary_op (insn, operands);"
6963 (cond [(match_operand:DF 3 "is_mul" "")
6964 (const_string "fpmul")
6965 (match_operand:DF 3 "is_div" "")
6966 (const_string "fpdiv")
6968 (const_string "fpop")
6973 [(set (match_operand:XF 0 "register_operand" "=f")
6974 (match_operator:XF 3 "binary_387_op"
6975 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "rm"))
6976 (match_operand:XF 2 "register_operand" "0")]))]
6978 "* return output_387_binary_op (insn, operands);"
6980 (cond [(match_operand:DF 3 "is_mul" "")
6981 (const_string "fpmul")
6982 (match_operand:DF 3 "is_div" "")
6983 (const_string "fpdiv")
6985 (const_string "fpop")
6990 [(set (match_operand:XF 0 "register_operand" "=f,f")
6991 (match_operator:XF 3 "binary_387_op"
6992 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
6993 (match_operand:XF 2 "register_operand" "0,f")]))]
6995 "* return output_387_binary_op (insn, operands);"
6997 (cond [(match_operand:DF 3 "is_mul" "")
6998 (const_string "fpmul")
6999 (match_operand:DF 3 "is_div" "")
7000 (const_string "fpdiv")
7002 (const_string "fpop")
7007 [(set (match_operand:XF 0 "register_operand" "=f")
7008 (match_operator:XF 3 "binary_387_op"
7009 [(match_operand:XF 1 "register_operand" "0")
7010 (float:XF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
7012 "* return output_387_binary_op (insn, operands);"
7014 (cond [(match_operand:DF 3 "is_mul" "")
7015 (const_string "fpmul")
7016 (match_operand:DF 3 "is_div" "")
7017 (const_string "fpdiv")
7019 (const_string "fpop")
7024 [(set (match_operand:XF 0 "register_operand" "=f,f")
7025 (match_operator:XF 3 "binary_387_op"
7026 [(match_operand:XF 1 "register_operand" "0,f")
7028 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7030 "* return output_387_binary_op (insn, operands);"
7032 (cond [(match_operand:DF 3 "is_mul" "")
7033 (const_string "fpmul")
7034 (match_operand:DF 3 "is_div" "")
7035 (const_string "fpdiv")
7037 (const_string "fpop")
7042 [(set (match_operand:DF 0 "register_operand" "=f,f")
7043 (match_operator:DF 3 "binary_387_op"
7044 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7045 (match_operand:DF 2 "register_operand" "0,f")]))]
7047 "* return output_387_binary_op (insn, operands);"
7049 (cond [(match_operand:DF 3 "is_mul" "")
7050 (const_string "fpmul")
7051 (match_operand:DF 3 "is_div" "")
7052 (const_string "fpdiv")
7054 (const_string "fpop")
7059 [(set (match_operand:DF 0 "register_operand" "=f")
7060 (match_operator:DF 3 "binary_387_op"
7061 [(match_operand:DF 1 "register_operand" "0")
7062 (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
7064 "* return output_387_binary_op (insn, operands);"
7066 (cond [(match_operand:DF 3 "is_mul" "")
7067 (const_string "fpmul")
7068 (match_operand:DF 3 "is_div" "")
7069 (const_string "fpdiv")
7071 (const_string "fpop")
7076 [(set (match_operand:DF 0 "register_operand" "=f,f")
7077 (match_operator:DF 3 "binary_387_op"
7078 [(match_operand:DF 1 "register_operand" "0,f")
7080 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7082 "* return output_387_binary_op (insn, operands);"
7084 (cond [(match_operand:DF 3 "is_mul" "")
7085 (const_string "fpmul")
7086 (match_operand:DF 3 "is_div" "")
7087 (const_string "fpdiv")
7089 (const_string "fpop")
7094 [(set (match_operand:SF 0 "register_operand" "=f,f")
7095 (match_operator:SF 3 "binary_387_op"
7096 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
7097 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
7099 "* return output_387_binary_op (insn, operands);"
7101 (cond [(match_operand:DF 3 "is_mul" "")
7102 (const_string "fpmul")
7103 (match_operand:DF 3 "is_div" "")
7104 (const_string "fpdiv")
7106 (const_string "fpop")
7111 [(set (match_operand:SF 0 "register_operand" "=f")
7112 (match_operator:SF 3 "binary_387_op"
7113 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "rm"))
7114 (match_operand:SF 2 "register_operand" "0")]))]
7116 "* return output_387_binary_op (insn, operands);"
7118 (cond [(match_operand:DF 3 "is_mul" "")
7119 (const_string "fpmul")
7120 (match_operand:DF 3 "is_div" "")
7121 (const_string "fpdiv")
7123 (const_string "fpop")
7128 [(set (match_operand:SF 0 "register_operand" "=f")
7129 (match_operator:SF 3 "binary_387_op"
7130 [(match_operand:SF 1 "register_operand" "0")
7131 (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
7133 "* return output_387_binary_op (insn, operands);"
7135 (cond [(match_operand:DF 3 "is_mul" "")
7136 (const_string "fpmul")
7137 (match_operand:DF 3 "is_div" "")
7138 (const_string "fpdiv")
7140 (const_string "fpop")
7144 (define_expand "strlensi"
7145 [(parallel [(set (match_dup 4)
7146 (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
7147 (match_operand:QI 2 "immediate_operand" "")
7148 (match_operand:SI 3 "immediate_operand" "")] 0))
7149 (clobber (match_dup 1))])
7151 (not:SI (match_dup 4)))
7152 (set (match_operand:SI 0 "register_operand" "")
7153 (plus:SI (match_dup 5)
7158 if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1)
7163 /* well it seems that some optimizer does not combine a call like
7164 foo(strlen(bar), strlen(bar));
7165 when the move and the subtraction is done here. It does calculate
7166 the length just once when these instructions are done inside of
7167 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
7168 often used and I use one fewer register for the lifetime of
7169 output_strlen_unroll() this is better. */
7170 scratch = gen_reg_rtx (SImode);
7171 address = force_reg (SImode, XEXP (operands[1], 0));
7173 /* move address to scratch-register
7174 this is done here because the i586 can do the following and
7175 in the same cycle with the following move. */
7176 if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4)
7177 emit_insn (gen_movsi (scratch, address));
7179 emit_insn (gen_movsi (operands[0], address));
7181 if(TARGET_USE_Q_REG)
7182 emit_insn (gen_strlensi_unroll5 (operands[0],
7187 emit_insn (gen_strlensi_unroll4 (operands[0],
7192 /* gen_strlensi_unroll[45] returns the address of the zero
7193 at the end of the string, like memchr(), so compute the
7194 length by subtracting the startaddress. */
7195 emit_insn (gen_subsi3 (operands[0], operands[0], address));
7199 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7200 operands[4] = gen_reg_rtx (SImode);
7201 operands[5] = gen_reg_rtx (SImode);
7204 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7205 ;; But strength reduction might offset the MEM expression. So we let
7206 ;; reload put the address into %edi.
7209 [(set (match_operand:SI 0 "register_operand" "=&c")
7210 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
7211 (match_operand:QI 2 "immediate_operand" "a")
7212 (match_operand:SI 3 "immediate_operand" "i")] 0))
7213 (clobber (match_dup 1))]
7219 xops[0] = operands[0];
7220 xops[1] = constm1_rtx;
7221 output_asm_insn (\"cld\", operands);
7222 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
7223 return \"repnz\;scas%B2\";
7226 /* Conditional move define_insns. */
7228 ;; These are all disabled, because they are buggy. They are all susceptible
7229 ;; to problems with input reloads clobbering the condition code registers.
7230 ;; It appears the only safe way to write a integer/FP conditional move pattern
7231 ;; is to write one which emits both the compare and the cmov, and which can be
7232 ;; split only after reload.
7234 (define_expand "movsicc"
7236 (parallel [(set (match_operand 0 "register_operand" "")
7237 (if_then_else:SI (match_operand 1 "comparison_operator" "")
7238 (match_operand:SI 2 "general_operand" "")
7239 (match_operand:SI 3 "general_operand" "")))
7240 (clobber (match_scratch:SI 4 "=&r"))])]
7244 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7247 (define_expand "movhicc"
7249 (parallel [(set (match_operand 0 "register_operand" "")
7250 (if_then_else:HI (match_operand 1 "comparison_operator" "")
7251 (match_operand:HI 2 "general_operand" "")
7252 (match_operand:HI 3 "general_operand" "")))
7253 (clobber (match_scratch:SI 4 "=&r"))])]
7257 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7260 (define_insn "movsicc_1"
7261 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,&r,rm")
7262 (if_then_else:SI (match_operator 1 "comparison_operator"
7263 [(cc0) (const_int 0)])
7264 (match_operand:SI 2 "general_operand" "rm,0,rm,g")
7265 (match_operand:SI 3 "general_operand" "0,rm,rm,g")))
7266 (clobber (match_scratch:SI 4 "X,X,X,=&r"))]
7270 if (which_alternative == 0)
7272 /* r <- cond ? arg : r */
7273 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7275 else if (which_alternative == 1)
7277 /* r <- cond ? r : arg */
7278 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7280 else if (which_alternative == 2)
7282 /* r <- cond ? arg1 : arg2 */
7283 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7284 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7286 else if (which_alternative == 3)
7288 /* r <- cond ? arg1 : arg2 */
7291 xops[0] = gen_label_rtx ();
7292 xops[1] = gen_label_rtx ();
7293 xops[2] = operands[1];
7295 output_asm_insn (\"j%c2 %l0\", xops);
7296 if (! rtx_equal_p (operands[0], operands[2]))
7297 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[2]) == MEM)
7299 output_asm_insn (AS2 (mov%z2,%2,%4), operands);
7300 output_asm_insn (AS2 (mov%z2,%4,%0), operands);
7303 output_asm_insn (AS2 (mov%z0,%2,%0), operands);
7304 output_asm_insn (\"jmp %l1\", xops);
7305 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
7306 if (! rtx_equal_p (operands[0], operands[3]))
7308 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[3]) == MEM)
7310 output_asm_insn (AS2 (mov%z3,%3,%4), operands);
7311 output_asm_insn (AS2 (mov%z3,%4,%0), operands);
7314 output_asm_insn (AS2 (mov%z0,%3,%0), operands);
7316 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
7321 (define_insn "movhicc_1"
7322 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,&r,rm")
7323 (if_then_else:HI (match_operator 1 "comparison_operator"
7324 [(cc0) (const_int 0)])
7325 (match_operand:HI 2 "general_operand" "rm,0,rm,g")
7326 (match_operand:HI 3 "general_operand" "0,rm,rm,g")))
7327 (clobber (match_scratch:SI 4 "X,X,X,=&r"))]
7331 if (which_alternative == 0)
7333 /* r <- cond ? arg : r */
7334 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7336 else if (which_alternative == 1)
7338 /* r <- cond ? r : arg */
7339 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7341 else if (which_alternative == 2)
7343 /* r <- cond ? arg1 : arg2 */
7344 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7345 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7347 else if (which_alternative == 3)
7349 /* r <- cond ? arg1 : arg2 */
7352 xops[0] = gen_label_rtx ();
7353 xops[1] = gen_label_rtx ();
7354 xops[2] = operands[1];
7356 output_asm_insn (\"j%c2 %l0\", xops);
7357 if (! rtx_equal_p (operands[0], operands[2]))
7358 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[2]) == MEM)
7360 output_asm_insn (AS2 (mov%z2,%2,%4), operands);
7361 output_asm_insn (AS2 (mov%z2,%4,%0), operands);
7364 output_asm_insn (AS2 (mov%z0,%2,%0), operands);
7365 output_asm_insn (\"jmp %l1\", xops);
7366 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
7367 if (! rtx_equal_p (operands[0], operands[3]))
7369 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[3]) == MEM)
7371 output_asm_insn (AS2 (mov%z3,%3,%4), operands);
7372 output_asm_insn (AS2 (mov%z3,%4,%0), operands);
7375 output_asm_insn (AS2 (mov%z0,%3,%0), operands);
7377 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
7381 ;; We need to disable the FP forms of these since they do not support
7382 ;; memory as written, but no input reloads are permitted for insns
7383 ;; that use cc0. Also, movxfcc is not present.
7385 (define_expand "movsfcc"
7387 (set (match_operand 0 "register_operand" "")
7388 (if_then_else:SF (match_operand 1 "comparison_operator" "")
7389 (match_operand:SF 2 "register_operand" "")
7390 (match_operand:SF 3 "register_operand" "")))]
7394 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7397 (define_expand "movdfcc"
7399 (set (match_operand 0 "register_operand" "t")
7400 (if_then_else:DF (match_operand 1 "comparison_operator" "")
7401 (match_operand:DF 2 "register_operand" "")
7402 (match_operand:DF 3 "register_operand" "")))]
7406 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7409 (define_expand "movxfcc"
7411 (set (match_operand 0 "register_operand" "")
7412 (if_then_else:XF (match_operand 1 "comparison_operator" "")
7413 (match_operand:XF 2 "register_operand" "")
7414 (match_operand:XF 3 "register_operand" "")))]
7418 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7421 (define_insn "movsfcc_1"
7422 [(set (match_operand:SF 0 "general_operand" "=f,f,&f")
7423 (if_then_else:SF (match_operator 1 "comparison_operator"
7424 [(cc0) (const_int 0)])
7425 (match_operand:SF 2 "register_operand" "0,f,f")
7426 (match_operand:SF 3 "register_operand" "f,0,f")))]
7430 switch (which_alternative)
7433 /* r <- cond ? arg : r */
7434 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7438 /* r <- cond ? r : arg */
7439 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7443 /* r <- cond ? r : arg */
7444 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7445 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7452 (define_insn "movdfcc_1"
7453 [(set (match_operand:DF 0 "general_operand" "=f,f,&f")
7454 (if_then_else:DF (match_operator 1 "comparison_operator"
7455 [(cc0) (const_int 0)])
7456 (match_operand:DF 2 "register_operand" "0,f,f")
7457 (match_operand:DF 3 "register_operand" "f,0,f")))]
7461 switch (which_alternative)
7464 /* r <- cond ? arg : r */
7465 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7469 /* r <- cond ? r : arg */
7470 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7474 /* r <- cond ? r : arg */
7475 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7476 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7483 (define_insn "strlensi_unroll"
7484 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
7485 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r"))
7486 (match_operand:SI 2 "immediate_operand" "i,i")] 0))
7487 (clobber (match_scratch:SI 3 "=&q,&r"))]
7489 "* return output_strlen_unroll (operands);")
7491 ;; the only difference between the following patterns is the register preference
7492 ;; on a pentium using a q-register saves one clock cycle per 4 characters
7494 (define_insn "strlensi_unroll4"
7495 [(set (match_operand:SI 0 "register_operand" "=r,r")
7496 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0"))
7497 (match_operand:SI 1 "immediate_operand" "i,i")
7498 (match_operand:SI 2 "register_operand" "+q,!r")] 0))
7499 (clobber (match_dup 2))]
7500 "(TARGET_USE_ANY_REG && optimize > 1)"
7501 "* return output_strlen_unroll (operands);")
7503 (define_insn "strlensi_unroll5"
7504 [(set (match_operand:SI 0 "register_operand" "=r")
7505 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0"))
7506 (match_operand:SI 1 "immediate_operand" "i")
7507 (match_operand:SI 2 "register_operand" "+q")] 0))
7508 (clobber (match_dup 2))]
7509 "(TARGET_USE_Q_REG && optimize > 1)"
7510 "* return output_strlen_unroll (operands);"
7513 (define_insn "allocate_stack_worker"
7514 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
7515 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
7516 (clobber (match_dup 0))]
7517 "TARGET_STACK_PROBE"
7518 "* return AS1(call,__alloca);")
7520 (define_expand "allocate_stack"
7521 [(set (match_operand:SI 0 "register_operand" "=r")
7522 (minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" "")))
7523 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))]
7524 "TARGET_STACK_PROBE"
7527 #ifdef CHECK_STACK_LIMIT
7528 if (GET_CODE (operands[1]) == CONST_INT
7529 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
7530 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
7534 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
7537 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
7541 (define_expand "nonlocal_goto_receiver"
7546 load_pic_register (1);