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"))]
1639 "* return output_move_double (operands);")
1642 [(set (match_operand:DI
0 "push_operand" "=<")
1643 (match_operand:DI
1 "memory_operand" "o"))]
1644 "TARGET_PUSH_MEMORY"
1645 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode),
0,
0);")
1647 (define_expand "movdi"
1648 [(set (match_operand:DI
0 "general_operand" "")
1649 (match_operand:DI
1 "general_operand" ""))]
1653 /* Don't generate memory->memory moves, go through a register */
1655 && (reload_in_progress | reload_completed) ==
0
1656 && GET_CODE (operands[
0]) == MEM
1657 && GET_CODE (operands[
1]) == MEM)
1659 operands[
1] = force_reg (DImode, operands[
1]);
1664 [(set (match_operand:DI
0 "general_operand" "=g,r")
1665 (match_operand:DI
1 "general_operand" "riF,m"))]
1666 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM)
1667 || (GET_CODE (operands[
1]) != MEM)"
1668 "* return output_move_double (operands);")
1671 ;;- conversion instructions
1674 ;;- zero extension instructions
1675 ;; See comments by
`andsi' for when andl is faster than movzx.
1677 (define_insn "zero_extendhisi2"
1678 [(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
1679 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
1685 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1686 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1688 xops[0] = operands[0];
1689 xops[1] = GEN_INT (0xffff);
1690 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1693 if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1]))
1695 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1696 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1700 if (TARGET_ZERO_EXTEND_WITH_AND)
1702 xops[0] = operands[0];
1703 xops[1] = GEN_INT (0xffff);
1704 if (i386_aligned_p (operands[1]))
1705 output_asm_insn (AS2 (mov%L0,%k1,%k0),operands);
1707 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1708 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1713 return AS2 (movzx,%1,%0);
1715 return AS2 (movz%W0%L0,%1,%0);
1720 [(set (match_operand:SI 0 "register_operand" "")
1721 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1722 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])"
1725 (set (strict_low_part (match_dup 2))
1727 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1731 [(set (match_operand:SI 0 "register_operand" "")
1732 (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))]
1733 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])"
1734 [(set (strict_low_part (match_dup 2))
1737 (and:SI (match_dup 0)
1738 (const_int 65535)))]
1739 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1741 (define_insn "zero_extendqihi2"
1742 [(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
1743 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1749 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1750 && REG_P (operands[1])
1751 && REGNO (operands[0]) == REGNO (operands[1]))
1753 xops[0] = operands[0];
1754 xops[1] = GEN_INT (0xff);
1755 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1758 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1760 if(!reg_overlap_mentioned_p(operands[0],operands[1]))
1762 output_asm_insn (AS2 (xor%L0,%k0,%k0), operands);
1763 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1767 xops[0] = operands[0];
1768 xops[1] = GEN_INT (0xff);
1769 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1770 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1776 return AS2 (movzx,%1,%0);
1778 return AS2 (movz%B0%W0,%1,%0);
1783 [(set (match_operand:HI 0 "register_operand" "")
1784 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1785 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1786 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1789 (set (strict_low_part (match_dup 2))
1791 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1795 [(set (match_operand:HI 0 "register_operand" "")
1796 (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))]
1797 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1798 && reg_overlap_mentioned_p (operands[0], operands[1])"
1799 [(set (strict_low_part (match_dup 2))
1802 (and:HI (match_dup 0)
1804 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1807 [(set (match_operand:HI 0 "register_operand" "")
1808 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1809 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND"
1813 (and:HI (match_dup 0)
1815 "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0)
1816 operands[1] = SUBREG_REG (operands[1]);
1817 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG
1818 || REGNO (operands[0]) == REGNO (operands[1]))
1820 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));")
1822 (define_insn "zero_extendqisi2"
1823 [(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
1824 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1830 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1831 && REG_P (operands[1])
1832 && REGNO (operands[0]) == REGNO (operands[1]))
1834 xops[0] = operands[0];
1835 xops[1] = GEN_INT (0xff);
1836 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1839 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1841 if(!reg_overlap_mentioned_p (operands[0], operands[1]))
1843 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1844 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1848 xops[0] = operands[0];
1849 xops[1] = GEN_INT (0xff);
1850 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1851 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1856 if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG)
1858 xops[0] = operands[0];
1859 xops[1] = GEN_INT (0xff);
1860 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
1861 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
1862 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1867 return AS2 (movzx,%1,%0);
1869 return AS2 (movz%B0%L0,%1,%0);
1874 [(set (match_operand:SI 0 "register_operand" "")
1875 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1876 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1877 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1880 (set (strict_low_part (match_dup 2))
1882 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1886 [(set (match_operand:SI 0 "register_operand" "")
1887 (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))]
1888 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1889 && reg_overlap_mentioned_p (operands[0], operands[1])"
1890 [(set (strict_low_part (match_dup 2))
1893 (and:SI (match_dup 0)
1895 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1898 [(set (match_operand:SI 0 "register_operand" "")
1899 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1900 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
1901 && ! reg_overlap_mentioned_p (operands[0], operands[1])"
1905 (and:SI (match_dup 0)
1907 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
1909 (define_insn "zero_extendsidi2"
1910 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m")
1911 (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))]
1915 rtx high[2], low[2], xops[4];
1917 if (REG_P (operands[0]) && REG_P (operands[1])
1918 && REGNO (operands[0]) == REGNO (operands[1]))
1920 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1921 return AS2 (xor%L0,%0,%0);
1924 split_di (operands, 1, low, high);
1926 xops[1] = operands[1];
1928 xops[3] = const0_rtx;
1930 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
1931 if (GET_CODE (low[0]) == MEM)
1932 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
1934 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
1939 ;;- sign extension instructions
1941 (define_insn "extendsidi2"
1942 [(set (match_operand:DI 0 "register_operand" "=r")
1943 (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))]
1947 if (REGNO (operands[0]) == 0)
1949 /* This used to be cwtl, but that extends HI to SI somehow. */
1957 operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1958 output_asm_insn (AS2 (mov%L0,%0,%1), operands);
1960 operands[0] = GEN_INT (31);
1961 return AS2 (sar%L1,%0,%1);
1964 ;; Note that the i386 programmers' manual says that the opcodes
1965 ;; are named movsx..., but the assembler on Unix does not accept that.
1966 ;; We use what the Unix assembler expects.
1968 (define_insn "extendhisi2"
1969 [(set (match_operand:SI 0 "register_operand" "=r")
1970 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
1974 if (REGNO (operands[0]) == 0
1975 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
1983 return AS2 (movsx,%1,%0);
1985 return AS2 (movs%W0%L0,%1,%0);
1989 (define_insn "extendqihi2"
1990 [(set (match_operand:HI 0 "register_operand" "=r")
1991 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1995 if (REGNO (operands[0]) == 0
1996 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
2000 return AS2 (movsx,%1,%0);
2002 return AS2 (movs%B0%W0,%1,%0);
2006 (define_insn "extendqisi2"
2007 [(set (match_operand:SI 0 "register_operand" "=r")
2008 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2013 return AS2 (movsx,%1,%0);
2015 return AS2 (movs%B0%L0,%1,%0);
2020 ;; Truncation of long long -> 32 bit
2022 (define_expand "truncdisi2"
2023 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2024 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2028 /* Don't generate memory->memory moves, go through a register */
2030 && (reload_in_progress | reload_completed) == 0
2031 && GET_CODE (operands[0]) == MEM
2032 && GET_CODE (operands[1]) == MEM)
2034 rtx target = gen_reg_rtx (SImode);
2035 emit_insn (gen_truncdisi2 (target, operands[1]));
2036 emit_move_insn (operands[0], target);
2042 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2043 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2044 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2047 rtx low[2], high[2], xops[2];
2049 split_di (&operands[1], 1, low, high);
2050 xops[0] = operands[0];
2052 if (!rtx_equal_p (xops[0], xops[1]))
2053 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2059 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2060 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
2062 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2065 rtx low[2], high[2], xops[2];
2067 split_di (&operands[1], 1, low, high);
2068 xops[0] = operands[0];
2070 if (!rtx_equal_p (xops[0], xops[1]))
2071 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2078 ;; Conversions between float and double.
2080 (define_insn "extendsfdf2"
2081 [(set (match_operand:DF 0 "nonimmediate_operand" "=fm,f")
2083 (match_operand:SF 1 "nonimmediate_operand" "f,fm")))]
2087 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2089 if (NON_STACK_REG_P (operands[1]))
2091 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2095 if (NON_STACK_REG_P (operands[0]))
2097 output_to_reg (operands[0], stack_top_dies, 0);
2101 if (STACK_TOP_P (operands[0]))
2102 return AS1 (fld%z1,%y1);
2104 if (GET_CODE (operands[0]) == MEM)
2107 return AS1 (fstp%z0,%y0);
2109 return AS1 (fst%z0,%y0);
2115 (define_insn "extenddfxf2"
2116 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
2118 (match_operand:DF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
2122 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2124 if (NON_STACK_REG_P (operands[1]))
2126 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2130 if (NON_STACK_REG_P (operands[0]))
2132 output_to_reg (operands[0], stack_top_dies, 0);
2136 if (STACK_TOP_P (operands[0]))
2137 return AS1 (fld%z1,%y1);
2139 if (GET_CODE (operands[0]) == MEM)
2141 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2142 if (! stack_top_dies)
2143 return AS1 (fld%z0,%y0);
2150 (define_insn "extendsfxf2"
2151 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
2153 (match_operand:SF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
2157 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2159 if (NON_STACK_REG_P (operands[1]))
2161 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2165 if (NON_STACK_REG_P (operands[0]))
2167 output_to_reg (operands[0], stack_top_dies, 0);
2171 if (STACK_TOP_P (operands[0]))
2172 return AS1 (fld%z1,%y1);
2174 if (GET_CODE (operands[0]) == MEM)
2176 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2177 if (! stack_top_dies)
2178 return AS1 (fld%z0,%y0);
2185 (define_expand "truncdfsf2"
2186 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2188 (match_operand:DF 1 "register_operand" "")))
2189 (clobber (match_dup 2))])]
2193 operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2196 ;; This cannot output into an f-reg because there is no way to be sure
2197 ;; of truncating in that case. Otherwise this is just like a simple move
2198 ;; insn. So we pretend we can output to a reg in order to get better
2199 ;; register preferencing, but we really use a stack slot.
2202 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
2204 (match_operand:DF 1 "register_operand" "0,f")))
2205 (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
2209 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2211 if (GET_CODE (operands[0]) == MEM)
2214 return AS1 (fstp%z0,%0);
2216 return AS1 (fst%z0,%0);
2218 else if (STACK_TOP_P (operands[0]))
2220 output_asm_insn (AS1 (fstp%z2,%y2), operands);
2221 return AS1 (fld%z2,%y2);
2227 (define_insn "truncxfsf2"
2228 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r")
2230 (match_operand:XF 1 "register_operand" "f,f")))]
2234 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2236 if (NON_STACK_REG_P (operands[0]))
2238 if (stack_top_dies == 0)
2240 output_asm_insn (AS1 (fld,%y1), operands);
2243 output_to_reg (operands[0], stack_top_dies, 0);
2246 else if (GET_CODE (operands[0]) == MEM)
2249 return AS1 (fstp%z0,%0);
2252 output_asm_insn (AS1 (fld,%y1), operands);
2253 return AS1 (fstp%z0,%0);
2260 (define_insn "truncxfdf2"
2261 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!*r")
2263 (match_operand:XF 1 "register_operand" "f,f")))]
2267 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2269 if (NON_STACK_REG_P (operands[0]))
2271 if (stack_top_dies == 0)
2273 output_asm_insn (AS1 (fld,%y1), operands);
2276 output_to_reg (operands[0], stack_top_dies, 0);
2279 else if (GET_CODE (operands[0]) == MEM)
2282 return AS1 (fstp%z0,%0);
2285 output_asm_insn (AS1 (fld,%y1), operands);
2286 return AS1 (fstp%z0,%0);
2294 ;; The 387 requires that the stack top dies after converting to DImode.
2296 ;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
2297 ;; doing a signed conversion to DImode, and then taking just the low
2300 (define_expand "fixuns_truncxfsi2"
2302 (match_operand:XF 1 "register_operand" ""))
2303 (parallel [(set (match_dup 2)
2304 (fix:DI (fix:XF (match_dup 4))))
2305 (clobber (match_dup 4))
2306 (clobber (match_dup 5))
2307 (clobber (match_dup 6))
2308 (clobber (match_scratch:SI 7 ""))])
2309 (set (match_operand:SI 0 "general_operand" "")
2314 operands[2] = gen_reg_rtx (DImode);
2315 operands[3] = gen_lowpart (SImode, operands[2]);
2316 operands[4] = gen_reg_rtx (XFmode);
2317 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2318 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2321 (define_expand "fixuns_truncdfsi2"
2323 (match_operand:DF 1 "register_operand" ""))
2324 (parallel [(set (match_dup 2)
2325 (fix:DI (fix:DF (match_dup 4))))
2326 (clobber (match_dup 4))
2327 (clobber (match_dup 5))
2328 (clobber (match_dup 6))
2329 (clobber (match_scratch:SI 7 ""))])
2330 (set (match_operand:SI 0 "general_operand" "")
2335 operands[2] = gen_reg_rtx (DImode);
2336 operands[3] = gen_lowpart (SImode, operands[2]);
2337 operands[4] = gen_reg_rtx (DFmode);
2338 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2339 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2342 (define_expand "fixuns_truncsfsi2"
2344 (match_operand:SF 1 "register_operand" ""))
2345 (parallel [(set (match_dup 2)
2346 (fix:DI (fix:SF (match_dup 4))))
2347 (clobber (match_dup 4))
2348 (clobber (match_dup 5))
2349 (clobber (match_dup 6))
2350 (clobber (match_scratch:SI 7 ""))])
2351 (set (match_operand:SI 0 "general_operand" "")
2356 operands[2] = gen_reg_rtx (DImode);
2357 operands[3] = gen_lowpart (SImode, operands[2]);
2358 operands[4] = gen_reg_rtx (SFmode);
2359 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2360 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2363 ;; Signed conversion to DImode.
2365 (define_expand "fix_truncxfdi2"
2367 (match_operand:XF 1 "register_operand" ""))
2368 (parallel [(set (match_operand:DI 0 "general_operand" "")
2369 (fix:DI (fix:XF (match_dup 2))))
2370 (clobber (match_dup 2))
2371 (clobber (match_dup 3))
2372 (clobber (match_dup 4))
2373 (clobber (match_scratch:SI 5 ""))])]
2377 operands[1] = copy_to_mode_reg (XFmode, operands[1]);
2378 operands[2] = gen_reg_rtx (XFmode);
2379 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2380 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2383 (define_expand "fix_truncdfdi2"
2385 (match_operand:DF 1 "register_operand" ""))
2386 (parallel [(set (match_operand:DI 0 "general_operand" "")
2387 (fix:DI (fix:DF (match_dup 2))))
2388 (clobber (match_dup 2))
2389 (clobber (match_dup 3))
2390 (clobber (match_dup 4))
2391 (clobber (match_scratch:SI 5 ""))])]
2395 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
2396 operands[2] = gen_reg_rtx (DFmode);
2397 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2398 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2401 (define_expand "fix_truncsfdi2"
2403 (match_operand:SF 1 "register_operand" ""))
2404 (parallel [(set (match_operand:DI 0 "general_operand" "")
2405 (fix:DI (fix:SF (match_dup 2))))
2406 (clobber (match_dup 2))
2407 (clobber (match_dup 3))
2408 (clobber (match_dup 4))
2409 (clobber (match_scratch:SI 5 ""))])]
2413 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
2414 operands[2] = gen_reg_rtx (SFmode);
2415 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2416 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2419 ;; These match a signed conversion of either DFmode or SFmode to DImode.
2422 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2423 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "+f"))))
2424 (clobber (match_dup 1))
2425 (clobber (match_operand:SI 2 "memory_operand" "m"))
2426 (clobber (match_operand:DI 3 "memory_operand" "m"))
2427 (clobber (match_scratch:SI 4 "=&q"))]
2429 "* return output_fix_trunc (insn, operands);")
2432 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2433 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "+f"))))
2434 (clobber (match_dup 1))
2435 (clobber (match_operand:SI 2 "memory_operand" "m"))
2436 (clobber (match_operand:DI 3 "memory_operand" "m"))
2437 (clobber (match_scratch:SI 4 "=&q"))]
2439 "* return output_fix_trunc (insn, operands);")
2442 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2443 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "+f"))))
2444 (clobber (match_dup 1))
2445 (clobber (match_operand:SI 2 "memory_operand" "m"))
2446 (clobber (match_operand:DI 3 "memory_operand" "m"))
2447 (clobber (match_scratch:SI 4 "=&q"))]
2449 "* return output_fix_trunc (insn, operands);")
2451 ;; Signed MODE_FLOAT conversion to SImode.
2453 (define_expand "fix_truncxfsi2"
2454 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2456 (fix:XF (match_operand:XF 1 "register_operand" ""))))
2457 (clobber (match_dup 2))
2458 (clobber (match_dup 3))
2459 (clobber (match_scratch:SI 4 ""))])]
2463 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2464 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2467 (define_expand "fix_truncdfsi2"
2468 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2470 (fix:DF (match_operand:DF 1 "register_operand" ""))))
2471 (clobber (match_dup 2))
2472 (clobber (match_dup 3))
2473 (clobber (match_scratch:SI 4 ""))])]
2477 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2478 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2481 (define_expand "fix_truncsfsi2"
2482 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2484 (fix:SF (match_operand:SF 1 "register_operand" ""))))
2485 (clobber (match_dup 2))
2486 (clobber (match_dup 3))
2487 (clobber (match_scratch:SI 4 ""))])]
2491 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2492 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2496 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2497 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
2498 (clobber (match_operand:SI 2 "memory_operand" "m"))
2499 (clobber (match_operand:DI 3 "memory_operand" "m"))
2500 (clobber (match_scratch:SI 4 "=&q"))]
2502 "* return output_fix_trunc (insn, operands);")
2505 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2506 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2507 (clobber (match_operand:SI 2 "memory_operand" "m"))
2508 (clobber (match_operand:DI 3 "memory_operand" "m"))
2509 (clobber (match_scratch:SI 4 "=&q"))]
2511 "* return output_fix_trunc (insn, operands);")
2514 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2515 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
2516 (clobber (match_operand:SI 2 "memory_operand" "m"))
2517 (clobber (match_operand:DI 3 "memory_operand" "m"))
2518 (clobber (match_scratch:SI 4 "=&q"))]
2520 "* return output_fix_trunc (insn, operands);")
2522 ;; Conversion between fixed point and floating point.
2523 ;; The actual pattern that matches these is at the end of this file.
2525 ;; ??? Possibly represent floatunssidf2 here in gcc2.
2527 (define_expand "floatsisf2"
2528 [(set (match_operand:SF 0 "register_operand" "")
2529 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
2533 (define_expand "floatdisf2"
2534 [(set (match_operand:SF 0 "register_operand" "")
2535 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
2539 (define_expand "floatsidf2"
2540 [(set (match_operand:DF 0 "register_operand" "")
2541 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
2545 (define_expand "floatdidf2"
2546 [(set (match_operand:DF 0 "register_operand" "")
2547 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
2551 (define_expand "floatsixf2"
2552 [(set (match_operand:XF 0 "register_operand" "")
2553 (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
2557 (define_expand "floatdixf2"
2558 [(set (match_operand:XF 0 "register_operand" "")
2559 (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
2560 "TARGET_80387 && LONG_DOUBLE_TYPE_SIZE == 96"
2563 ;; This will convert from SImode or DImode to MODE_FLOAT.
2566 [(set (match_operand:XF 0 "register_operand" "=f")
2567 (float:XF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2571 if (NON_STACK_REG_P (operands[1]))
2573 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2576 else if (GET_CODE (operands[1]) == MEM)
2577 return AS1 (fild%z1,%1);
2583 [(set (match_operand:DF 0 "register_operand" "=f")
2584 (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2588 if (NON_STACK_REG_P (operands[1]))
2590 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2593 else if (GET_CODE (operands[1]) == MEM)
2594 return AS1 (fild%z1,%1);
2600 [(set (match_operand:SF 0 "register_operand" "=f")
2601 (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2605 if (NON_STACK_REG_P (operands[1]))
2607 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2610 else if (GET_CODE (operands[1]) == MEM)
2611 return AS1 (fild%z1,%1);
2617 [(set (match_operand:DF 0 "register_operand" "=f")
2618 (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
2622 if (NON_STACK_REG_P (operands[1]))
2624 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2627 else if (GET_CODE (operands[1]) == MEM)
2628 return AS1 (fild%z1,%1);
2634 [(set (match_operand:XF 0 "register_operand" "=f,f")
2635 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!*r")))]
2639 if (NON_STACK_REG_P (operands[1]))
2641 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2644 else if (GET_CODE (operands[1]) == MEM)
2645 return AS1 (fild%z1,%1);
2651 [(set (match_operand:SF 0 "register_operand" "=f")
2652 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
2656 if (NON_STACK_REG_P (operands[1]))
2658 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2661 else if (GET_CODE (operands[1]) == MEM)
2662 return AS1 (fild%z1,%1);
2667 ;;- add instructions
2669 (define_insn "addsidi3_1"
2670 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o")
2671 (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o")
2672 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri"))))
2673 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))]
2677 rtx low[3], high[3], xops[7], temp;
2681 split_di (operands, 2, low, high);
2682 high[2] = const0_rtx;
2683 low[2] = operands[2];
2685 if (!rtx_equal_p (operands[0], operands[1]))
2692 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2694 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2695 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2701 xops[6] = operands[3];
2702 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2703 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2704 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2705 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2706 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2707 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2712 output_asm_insn (AS2 (add%L0,%2,%0), low);
2713 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2717 (define_insn "addsidi3_2"
2718 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o")
2719 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r"))
2720 (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o")))
2721 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))]
2725 rtx low[3], high[3], xops[7], temp;
2729 split_di (operands, 2, low, high);
2730 high[2] = const0_rtx;
2731 low[2] = operands[2];
2733 if (!rtx_equal_p (operands[0], operands[1]))
2740 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2742 if (rtx_equal_p (low[0], operands[2]))
2744 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2745 output_asm_insn (AS2 (add%L0,%1,%0), low);
2746 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2749 if (rtx_equal_p (high[0], operands[2]))
2751 if (GET_CODE (operands[0]) != MEM)
2753 output_asm_insn (AS2 (mov%L0,%2,%0), low);
2754 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2755 output_asm_insn (AS2 (add%L0,%1,%0), low);
2756 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2760 /* It's too late to ask for a scratch now - but this
2761 will probably not happen too often. */
2762 output_asm_insn (AS2 (add%L1,%2,%1), low);
2763 output_asm_insn (AS2 (mov%L0,%1,%0), low);
2764 output_asm_insn (AS2 (mov%L1,%2,%1), low);
2765 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2766 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2767 output_asm_insn (AS2 (sub%L1,%0,%1), low);
2768 output_asm_insn (AS1 (neg%L1,%1), low);
2772 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2773 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2779 xops[6] = operands[3];
2780 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2781 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2782 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2783 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2784 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2785 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2790 output_asm_insn (AS2 (add%L0,%2,%0), low);
2791 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2795 (define_insn "adddi3"
2796 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
2797 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
2798 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
2799 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
2803 rtx low[3], high[3], xops[7], temp;
2807 if (rtx_equal_p (operands[0], operands[2]))
2810 operands[1] = operands[2];
2814 split_di (operands, 3, low, high);
2815 if (!rtx_equal_p (operands[0], operands[1]))
2822 if (GET_CODE (operands[0]) != MEM)
2824 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2825 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2831 xops[6] = operands[3];
2832 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2833 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2834 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2835 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2836 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2837 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2842 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
2848 xops[4] = operands[3];
2850 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
2851 output_asm_insn (AS2 (add%L1,%4,%1), xops);
2852 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
2853 output_asm_insn (AS2 (adc%L0,%4,%0), xops);
2856 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
2858 output_asm_insn (AS2 (add%L0,%2,%0), low);
2859 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2863 output_asm_insn (AS2 (add%L0,%2,%0), high);
2868 ;; On a 486, it is faster to do movl/addl than to do a single leal if
2869 ;; operands[1] and operands[2] are both registers.
2871 (define_expand "addsi3"
2872 [(set (match_operand:SI 0 "nonimmediate_operand" "")
2873 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
2874 (match_operand:SI 2 "general_operand" "")))]
2876 "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);")
2879 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
2880 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
2881 (match_operand:SI 2 "general_operand" "rmi,ri,ri")))]
2882 "ix86_binary_operator_ok (PLUS, SImode, operands)"
2885 if (REG_P (operands[0]) && REG_P (operands[1])
2886 && (REG_P (operands[2]) || GET_CODE (operands[2]) == CONST_INT)
2887 && REGNO (operands[0]) != REGNO (operands[1]))
2889 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
2890 return AS2 (add%L0,%1,%0);
2892 if (operands[2] == stack_pointer_rtx)
2897 operands[1] = operands[2];
2901 if (operands[2] != stack_pointer_rtx)
2904 operands[1] = SET_SRC (PATTERN (insn));
2905 return AS2 (lea%L0,%a1,%0);
2909 if (!rtx_equal_p (operands[0], operands[1]))
2910 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
2912 if (operands[2] == const1_rtx)
2913 return AS1 (inc%L0,%0);
2915 if (operands[2] == constm1_rtx)
2916 return AS1 (dec%L0,%0);
2918 /* subl $-128,%ebx is smaller than addl $128,%ebx. */
2919 if (GET_CODE (operands[2]) == CONST_INT
2920 && INTVAL (operands[2]) == 128)
2922 /* This doesn't compute the carry bit in the same way
2923 * as add%L0, but we use inc and dec above and they
2924 * don't set the carry bit at all. If inc/dec don't need
2925 * a CC_STATUS_INIT, this doesn't either... */
2926 operands[2] = GEN_INT (-128);
2927 return AS2 (sub%L0,%2,%0);
2930 return AS2 (add%L0,%2,%0);
2933 ;; addsi3 is faster, so put this after.
2935 (define_insn "movsi_lea"
2936 [(set (match_operand:SI 0 "register_operand" "=r")
2937 (match_operand:QI 1 "address_operand" "p"))]
2941 /* Adding a constant to a register is faster with an add. */
2942 /* ??? can this ever happen? */
2943 if (GET_CODE (operands[1]) == PLUS
2944 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
2945 && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
2947 operands[1] = XEXP (operands[1], 1);
2949 if (operands[1] == const1_rtx)
2950 return AS1 (inc%L0,%0);
2952 if (operands[1] == constm1_rtx)
2953 return AS1 (dec%L0,%0);
2955 return AS2 (add%L0,%1,%0);
2959 return AS2 (lea%L0,%a1,%0);
2962 ;; ??? `lea' here, for three operand add? If leaw is used, only %bx,
2963 ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
2964 ;; able to handle the operand. But leal always works?
2966 (define_expand "addhi3"
2967 [(set (match_operand:HI
0 "general_operand" "")
2968 (plus:HI (match_operand:HI
1 "nonimmediate_operand" "")
2969 (match_operand:HI
2 "general_operand" "")))]
2971 "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);")
2974 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
2975 (plus:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,
0")
2976 (match_operand:HI
2 "general_operand" "ri,rm")))]
2977 "ix86_binary_operator_ok (PLUS, HImode, operands)"
2980 /* ??? what about offsettable memory references? */
2981 if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */
2982 && QI_REG_P (operands[
0])
2983 && GET_CODE (operands[
2]) == CONST_INT
2984 && (INTVAL (operands[
2]) &
0xff) ==
0
2985 && i386_cc_probably_useless_p (insn))
2987 int byteval = (INTVAL (operands[
2]) >>
8) &
0xff;
2991 return AS1 (inc%B0,%h0);
2992 else if (byteval ==
255)
2993 return AS1 (dec%B0,%h0);
2995 operands[
2] = GEN_INT (byteval);
2996 return AS2 (add%B0,%
2,%h0);
2999 /* Use a
32-bit operation when possible, to avoid the prefix penalty. */
3000 if (REG_P (operands[
0])
3001 && i386_aligned_p (operands[
2])
3002 && i386_cc_probably_useless_p (insn))
3006 if (GET_CODE (operands[
2]) == CONST_INT)
3008 HOST_WIDE_INT intval =
0xffff & INTVAL (operands[
2]);
3011 return AS1 (inc%L0,%k0);
3013 if (intval ==
0xffff)
3014 return AS1 (dec%L0,%k0);
3016 operands[
2] = i386_sext16_if_const (operands[
2]);
3018 return AS2 (add%L0,%k2,%k0);
3021 if (operands[
2] == const1_rtx)
3022 return AS1 (inc%W0,%
0);
3024 if (operands[
2] == constm1_rtx
3025 || (GET_CODE (operands[
2]) == CONST_INT
3026 && INTVAL (operands[
2]) ==
65535))
3027 return AS1 (dec%W0,%
0);
3029 return AS2 (add%W0,%
2,%
0);
3032 (define_expand "addqi3"
3033 [(set (match_operand:QI
0 "general_operand" "")
3034 (plus:QI (match_operand:QI
1 "general_operand" "")
3035 (match_operand:QI
2 "general_operand" "")))]
3037 "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);")
3040 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
3041 (plus:QI (match_operand:QI
1 "nonimmediate_operand" "%
0,
0")
3042 (match_operand:QI
2 "general_operand" "qn,qmn")))]
3043 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3046 if (operands[
2] == const1_rtx)
3047 return AS1 (inc%B0,%
0);
3049 if (operands[
2] == constm1_rtx
3050 || (GET_CODE (operands[
2]) == CONST_INT
3051 && INTVAL (operands[
2]) ==
255))
3052 return AS1 (dec%B0,%
0);
3054 return AS2 (add%B0,%
2,%
0);
3057 ;Lennart Augustsson <augustss@cs.chalmers.se>
3058 ;says this pattern just makes slower code:
3062 ; leal -
80(%ebp),%eax
3066 ; [(set (match_operand:SI
0 "push_operand" "=<")
3067 ; (plus:SI (match_operand:SI
1 "register_operand" "%r")
3068 ; (match_operand:SI
2 "nonmemory_operand" "ri")))]
3073 ; xops[
0] = operands[
0];
3074 ; xops[
1] = operands[
1];
3075 ; xops[
2] = operands[
2];
3076 ; xops[
3] = gen_rtx_MEM (SImode, stack_pointer_rtx);
3077 ; output_asm_insn (
\"push%z1 %
1\", xops);
3078 ; output_asm_insn (AS2 (add%z3,%
2,%
3), xops);
3082 ;; The patterns that match these are at the end of this file.
3084 (define_expand "addxf3"
3085 [(set (match_operand:XF
0 "register_operand" "")
3086 (plus:XF (match_operand:XF
1 "register_operand" "")
3087 (match_operand:XF
2 "register_operand" "")))]
3091 (define_expand "adddf3"
3092 [(set (match_operand:DF
0 "register_operand" "")
3093 (plus:DF (match_operand:DF
1 "nonimmediate_operand" "")
3094 (match_operand:DF
2 "nonimmediate_operand" "")))]
3098 (define_expand "addsf3"
3099 [(set (match_operand:SF
0 "register_operand" "")
3100 (plus:SF (match_operand:SF
1 "nonimmediate_operand" "")
3101 (match_operand:SF
2 "nonimmediate_operand" "")))]
3105 ;;- subtract instructions
3107 (define_insn "subsidi3"
3108 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o")
3109 (minus:DI (match_operand:DI
1 "general_operand" "
0iF,
0,roiF,roiF,riF,o,o")
3110 (zero_extend:DI (match_operand:SI
2 "general_operand" "o,ri,ri,o,ri,i,r"))))
3111 (clobber (match_scratch:SI
3 "=X,X,X,X,X,&r,&r"))]
3115 rtx low[
3], high[
3], xops[
7];
3119 split_di (operands,
2, low, high);
3120 high[
2] = const0_rtx;
3121 low[
2] = operands[
2];
3123 if (!rtx_equal_p (operands[
0], operands[
1]))
3130 if (GET_CODE (operands[
0]) != MEM || GET_CODE (operands[
1]) != MEM)
3132 output_asm_insn (AS2 (mov%L1,%
3,%
1), xops);
3133 output_asm_insn (AS2 (mov%L0,%
2,%
0), xops);
3139 xops[
6] = operands[
3];
3140 output_asm_insn (AS2 (mov%L6,%
3,%
6), xops);
3141 output_asm_insn (AS2 (sub%L6,%
5,%
6), xops);
3142 output_asm_insn (AS2 (mov%L1,%
6,%
1), xops);
3143 output_asm_insn (AS2 (mov%L6,%
2,%
6), xops);
3144 output_asm_insn (AS2 (sbb%L6,%
4,%
6), xops);
3145 output_asm_insn (AS2 (mov%L0,%
6,%
0), xops);
3150 output_asm_insn (AS2 (sub%L0,%
2,%
0), low);
3151 output_asm_insn (AS2 (sbb%L0,%
2,%
0), high);
3155 (define_insn "subdi3"
3156 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,o,o,!&r,!o")
3157 (minus:DI (match_operand:DI
1 "general_operand" "
0,
0,
0iF,or,roiF,roiF")
3158 (match_operand:DI
2 "general_operand" "or,riF,or,iF,roiF,roiF")))
3159 (clobber (match_scratch:SI
3 "=X,X,&r,&r,X,&r"))]
3163 rtx low[
3], high[
3], xops[
7];
3167 split_di (operands,
3, low, high);
3169 if (!rtx_equal_p (operands[
0], operands[
1]))
3176 if (GET_CODE (operands[
0]) != MEM)
3178 output_asm_insn (AS2 (mov%L1,%
3,%
1), xops);
3179 output_asm_insn (AS2 (mov%L0,%
2,%
0), xops);
3185 xops[
6] = operands[
3];
3186 output_asm_insn (AS2 (mov%L6,%
3,%
6), xops);
3187 output_asm_insn (AS2 (sub%L6,%
5,%
6), xops);
3188 output_asm_insn (AS2 (mov%L1,%
6,%
1), xops);
3189 output_asm_insn (AS2 (mov%L6,%
2,%
6), xops);
3190 output_asm_insn (AS2 (sbb%L6,%
4,%
6), xops);
3191 output_asm_insn (AS2 (mov%L0,%
6,%
0), xops);
3196 if (GET_CODE (operands[
3]) == REG)
3202 xops[
4] = operands[
3];
3204 output_asm_insn (AS2 (mov%L4,%
3,%
4), xops);
3205 output_asm_insn (AS2 (sub%L1,%
4,%
1), xops);
3206 output_asm_insn (AS2 (mov%L4,%
2,%
4), xops);
3207 output_asm_insn (AS2 (sbb%L0,%
4,%
0), xops);
3210 else if (GET_CODE (low[
2]) != CONST_INT || INTVAL (low[
2]) !=
0)
3212 output_asm_insn (AS2 (sub%L0,%
2,%
0), low);
3213 output_asm_insn (AS2 (sbb%L0,%
2,%
0), high);
3217 output_asm_insn (AS2 (sub%L0,%
2,%
0), high);
3222 (define_expand "subsi3"
3223 [(set (match_operand:SI
0 "nonimmediate_operand" "")
3224 (minus:SI (match_operand:SI
1 "nonimmediate_operand" "")
3225 (match_operand:SI
2 "general_operand" "")))]
3227 "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);")
3230 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm,r")
3231 (minus:SI (match_operand:SI
1 "nonimmediate_operand" "
0,
0")
3232 (match_operand:SI
2 "general_operand" "ri,rm")))]
3233 "ix86_binary_operator_ok (MINUS, SImode, operands)"
3234 "* return AS2 (sub%L0,%
2,%
0);")
3236 (define_expand "subhi3"
3237 [(set (match_operand:HI
0 "general_operand" "")
3238 (minus:HI (match_operand:HI
1 "nonimmediate_operand" "")
3239 (match_operand:HI
2 "general_operand" "")))]
3241 "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);")
3244 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
3245 (minus:HI (match_operand:HI
1 "nonimmediate_operand" "
0,
0")
3246 (match_operand:HI
2 "general_operand" "ri,rm")))]
3247 "ix86_binary_operator_ok (MINUS, HImode, operands)"
3250 if (REG_P (operands[
0])
3251 && i386_aligned_p (operands[
2])
3252 && i386_cc_probably_useless_p (insn))
3255 operands[
2] = i386_sext16_if_const (operands[
2]);
3256 return AS2 (sub%L0,%k2,%k0);
3258 return AS2 (sub%W0,%
2,%
0);
3261 (define_expand "subqi3"
3262 [(set (match_operand:QI
0 "general_operand" "")
3263 (minus:QI (match_operand:QI
1 "general_operand" "")
3264 (match_operand:QI
2 "general_operand" "")))]
3266 "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);")
3269 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
3270 (minus:QI (match_operand:QI
1 "nonimmediate_operand" "
0,
0")
3271 (match_operand:QI
2 "general_operand" "qn,qmn")))]
3272 "ix86_binary_operator_ok (MINUS, QImode, operands)"
3273 "* return AS2 (sub%B0,%
2,%
0);")
3275 ;; The patterns that match these are at the end of this file.
3277 (define_expand "subxf3"
3278 [(set (match_operand:XF
0 "register_operand" "")
3279 (minus:XF (match_operand:XF
1 "register_operand" "")
3280 (match_operand:XF
2 "register_operand" "")))]
3284 (define_expand "subdf3"
3285 [(set (match_operand:DF
0 "register_operand" "")
3286 (minus:DF (match_operand:DF
1 "nonimmediate_operand" "")
3287 (match_operand:DF
2 "nonimmediate_operand" "")))]
3291 (define_expand "subsf3"
3292 [(set (match_operand:SF
0 "register_operand" "")
3293 (minus:SF (match_operand:SF
1 "nonimmediate_operand" "")
3294 (match_operand:SF
2 "nonimmediate_operand" "")))]
3298 ;;- multiply instructions
3300 ;(define_insn "mulqi3"
3301 ; [(set (match_operand:QI
0 "register_operand" "=a")
3302 ; (mult:QI (match_operand:QI
1 "register_operand" "%
0")
3303 ; (match_operand:QI
2 "nonimmediate_operand" "qm")))]
3307 (define_insn "mulhi3"
3308 [(set (match_operand:HI
0 "register_operand" "=r,r")
3309 (mult:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,rm")
3310 (match_operand:HI
2 "general_operand" "g,i")))]
3314 if (GET_CODE (operands[
1]) == REG
3315 && REGNO (operands[
1]) == REGNO (operands[
0])
3316 && (GET_CODE (operands[
2]) == MEM || GET_CODE (operands[
2]) == REG))
3317 /* Assembler has weird restrictions. */
3318 return AS2 (imul%W0,%
2,%
0);
3319 return AS3 (imul%W0,%
2,%
1,%
0);
3321 [(set_attr "type" "imul")])
3323 (define_insn "mulsi3"
3324 [(set (match_operand:SI
0 "register_operand" "=r,r")
3325 (mult:SI (match_operand:SI
1 "nonimmediate_operand" "%
0,rm")
3326 (match_operand:SI
2 "general_operand" "g,i")))]
3330 if (GET_CODE (operands[
1]) == REG
3331 && REGNO (operands[
1]) == REGNO (operands[
0])
3332 && (GET_CODE (operands[
2]) == MEM || GET_CODE (operands[
2]) == REG))
3333 /* Assembler has weird restrictions. */
3334 return AS2 (imul%L0,%
2,%
0);
3335 return AS3 (imul%L0,%
2,%
1,%
0);
3337 [(set_attr "type" "imul")])
3339 (define_insn "umulqihi3"
3340 [(set (match_operand:HI
0 "register_operand" "=a")
3341 (mult:HI (zero_extend:HI (match_operand:QI
1 "register_operand" "%
0"))
3342 (zero_extend:HI (match_operand:QI
2 "nonimmediate_operand" "qm"))))]
3345 [(set_attr "type" "imul")])
3347 (define_insn "mulqihi3"
3348 [(set (match_operand:HI
0 "register_operand" "=a")
3349 (mult:HI (sign_extend:HI (match_operand:QI
1 "register_operand" "%
0"))
3350 (sign_extend:HI (match_operand:QI
2 "nonimmediate_operand" "qm"))))]
3353 [(set_attr "type" "imul")])
3355 (define_insn "umulsidi3"
3356 [(set (match_operand:DI
0 "register_operand" "=A")
3357 (mult:DI (zero_extend:DI (match_operand:SI
1 "register_operand" "%
0"))
3358 (zero_extend:DI (match_operand:SI
2 "nonimmediate_operand" "rm"))))]
3359 "TARGET_WIDE_MULTIPLY"
3361 [(set_attr "type" "imul")])
3363 (define_insn "mulsidi3"
3364 [(set (match_operand:DI
0 "register_operand" "=A")
3365 (mult:DI (sign_extend:DI (match_operand:SI
1 "register_operand" "%
0"))
3366 (sign_extend:DI (match_operand:SI
2 "nonimmediate_operand" "rm"))))]
3367 "TARGET_WIDE_MULTIPLY"
3369 [(set_attr "type" "imul")])
3371 (define_insn "umulsi3_highpart"
3372 [(set (match_operand:SI
0 "register_operand" "=d")
3373 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI
1 "register_operand" "%a"))
3374 (zero_extend:DI (match_operand:SI
2 "nonimmediate_operand" "rm")))
3376 (clobber (match_scratch:SI
3 "=a"))]
3377 "TARGET_WIDE_MULTIPLY"
3379 [(set_attr "type" "imul")])
3381 (define_insn "smulsi3_highpart"
3382 [(set (match_operand:SI
0 "register_operand" "=d")
3383 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI
1 "register_operand" "%a"))
3384 (sign_extend:DI (match_operand:SI
2 "nonimmediate_operand" "rm")))
3386 (clobber (match_scratch:SI
3 "=a"))]
3387 "TARGET_WIDE_MULTIPLY"
3389 [(set_attr "type" "imul")])
3391 ;; The patterns that match these are at the end of this file.
3393 (define_expand "mulxf3"
3394 [(set (match_operand:XF
0 "register_operand" "")
3395 (mult:XF (match_operand:XF
1 "register_operand" "")
3396 (match_operand:XF
2 "register_operand" "")))]
3400 (define_expand "muldf3"
3401 [(set (match_operand:DF
0 "register_operand" "")
3402 (mult:DF (match_operand:DF
1 "register_operand" "")
3403 (match_operand:DF
2 "nonimmediate_operand" "")))]
3407 (define_expand "mulsf3"
3408 [(set (match_operand:SF
0 "register_operand" "")
3409 (mult:SF (match_operand:SF
1 "register_operand" "")
3410 (match_operand:SF
2 "nonimmediate_operand" "")))]
3414 ;;- divide instructions
3416 (define_insn "divqi3"
3417 [(set (match_operand:QI
0 "register_operand" "=a")
3418 (div:QI (match_operand:HI
1 "register_operand" "
0")
3419 (match_operand:QI
2 "nonimmediate_operand" "qm")))]
3423 (define_insn "udivqi3"
3424 [(set (match_operand:QI
0 "register_operand" "=a")
3425 (udiv:QI (match_operand:HI
1 "register_operand" "
0")
3426 (match_operand:QI
2 "nonimmediate_operand" "qm")))]
3429 [(set_attr "type" "idiv")])
3431 ;; The patterns that match these are at the end of this file.
3433 (define_expand "divxf3"
3434 [(set (match_operand:XF
0 "register_operand" "")
3435 (div:XF (match_operand:XF
1 "register_operand" "")
3436 (match_operand:XF
2 "register_operand" "")))]
3440 (define_expand "divdf3"
3441 [(set (match_operand:DF
0 "register_operand" "")
3442 (div:DF (match_operand:DF
1 "register_operand" "")
3443 (match_operand:DF
2 "nonimmediate_operand" "")))]
3447 (define_expand "divsf3"
3448 [(set (match_operand:SF
0 "register_operand" "")
3449 (div:SF (match_operand:SF
1 "register_operand" "")
3450 (match_operand:SF
2 "nonimmediate_operand" "")))]
3454 ;; Remainder instructions.
3456 (define_insn "divmodsi4"
3457 [(set (match_operand:SI
0 "register_operand" "=a")
3458 (div:SI (match_operand:SI
1 "register_operand" "
0")
3459 (match_operand:SI
2 "nonimmediate_operand" "rm")))
3460 (set (match_operand:SI
3 "register_operand" "=&d")
3461 (mod:SI (match_dup
1) (match_dup
2)))]
3466 output_asm_insn (
\"cdq
\", operands);
3468 output_asm_insn (
\"cltd
\", operands);
3470 return AS1 (idiv%L0,%
2);
3472 [(set_attr "type" "idiv")])
3474 (define_insn "divmodhi4"
3475 [(set (match_operand:HI
0 "register_operand" "=a")
3476 (div:HI (match_operand:HI
1 "register_operand" "
0")
3477 (match_operand:HI
2 "nonimmediate_operand" "rm")))
3478 (set (match_operand:HI
3 "register_operand" "=&d")
3479 (mod:HI (match_dup
1) (match_dup
2)))]
3482 [(set_attr "type" "idiv")])
3484 ;; ??? Can we make gcc zero extend operand[
0]?
3485 (define_insn "udivmodsi4"
3486 [(set (match_operand:SI
0 "register_operand" "=a")
3487 (udiv:SI (match_operand:SI
1 "register_operand" "
0")
3488 (match_operand:SI
2 "nonimmediate_operand" "rm")))
3489 (set (match_operand:SI
3 "register_operand" "=&d")
3490 (umod:SI (match_dup
1) (match_dup
2)))]
3494 output_asm_insn (AS2 (xor%L3,%
3,%
3), operands);
3495 return AS1 (div%L0,%
2);
3497 [(set_attr "type" "idiv")])
3499 ;; ??? Can we make gcc zero extend operand[
0]?
3500 (define_insn "udivmodhi4"
3501 [(set (match_operand:HI
0 "register_operand" "=a")
3502 (udiv:HI (match_operand:HI
1 "register_operand" "
0")
3503 (match_operand:HI
2 "nonimmediate_operand" "rm")))
3504 (set (match_operand:HI
3 "register_operand" "=&d")
3505 (umod:HI (match_dup
1) (match_dup
2)))]
3509 output_asm_insn (AS2 (xor%W0,%
3,%
3), operands);
3510 return AS1 (div%W0,%
2);
3512 [(set_attr "type" "idiv")])
3515 ;;this should be a valid double division which we may want to add
3518 [(set (match_operand:SI
0 "register_operand" "=a")
3519 (udiv:DI (match_operand:DI
1 "register_operand" "a")
3520 (match_operand:SI
2 "nonimmediate_operand" "rm")))
3521 (set (match_operand:SI
3 "register_operand" "=d")
3522 (umod:SI (match_dup
1) (match_dup
2)))]
3525 [(set_attr "type" "idiv")])
3528 ;;- and instructions
3535 ;; but if the reg is %eax, then the "andl" is faster.
3537 ;; On i486, the "andl" is always faster than the "movzbl".
3539 ;; On both i386 and i486, a three operand AND is as fast with movzbl or
3540 ;; movzwl as with andl, if operands[
0] != operands[
1].
3542 ;; The
`r' in `rm' for operand
3 looks redundant, but it causes
3543 ;; optional reloads to be generated if op
3 is a pseudo in a stack slot.
3545 (define_insn "andsi3"
3546 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm,r")
3547 (and:SI (match_operand:SI
1 "nonimmediate_operand" "%
0,
0")
3548 (match_operand:SI
2 "general_operand" "ri,rm")))]
3552 HOST_WIDE_INT intval;
3553 if (!rtx_equal_p (operands[
0], operands[
1])
3554 && rtx_equal_p (operands[
0], operands[
2]))
3558 operands[
1] = operands[
2];
3561 switch (GET_CODE (operands[
2]))
3564 if (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
3566 intval = INTVAL (operands[
2]);
3567 /* zero-extend
16->
32? */
3568 if (intval ==
0xffff && REG_P (operands[
0])
3569 && (! REG_P (operands[
1])
3570 || REGNO (operands[
0]) !=
0 || REGNO (operands[
1]) !=
0)
3571 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[
0], operands[
1])))
3573 /* ??? tege: Should forget CC_STATUS only if we clobber a
3574 remembered operand. Fix that later. */
3577 return AS2 (movzx,%w1,%
0);
3579 return AS2 (movz%W0%L0,%w1,%
0);
3583 /* zero extend
8->
32? */
3584 if (intval ==
0xff && REG_P (operands[
0])
3585 && !(REG_P (operands[
1]) && NON_QI_REG_P (operands[
1]))
3586 && (! REG_P (operands[
1])
3587 || REGNO (operands[
0]) !=
0 || REGNO (operands[
1]) !=
0)
3588 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[
0], operands[
1])))
3590 /* ??? tege: Should forget CC_STATUS only if we clobber a
3591 remembered operand. Fix that later. */
3594 return AS2 (movzx,%b1,%
0);
3596 return AS2 (movz%B0%L0,%b1,%
0);
3600 /* Check partial bytes.. non-QI-regs are not available */
3601 if (REG_P (operands[
0]) && ! QI_REG_P (operands[
0]))
3604 /* only low byte has zero bits? */
3605 if (~(intval |
0xff) ==
0)
3608 if (REG_P (operands[
0]))
3613 return AS2 (xor%B0,%b0,%b0);
3616 /* we're better off with the
32-bit version if reg != EAX */
3617 /* the value is sign-extended in
8 bits */
3618 if (REGNO (operands[
0]) !=
0 && (intval &
0x80))
3624 operands[
2] = GEN_INT (intval);
3627 return AS2 (mov%B0,%
2,%b0);
3629 return AS2 (and%B0,%
2,%b0);
3632 /* only second byte has zero? */
3633 if (~(intval |
0xff00) ==
0)
3637 intval = (intval >>
8) &
0xff;
3638 operands[
2] = GEN_INT (intval);
3641 if (REG_P (operands[
0]))
3642 return AS2 (xor%B0,%h0,%h0);
3643 operands[
0] = adj_offsettable_operand (operands[
0],
1);
3644 return AS2 (mov%B0,%
2,%b0);
3647 if (REG_P (operands[
0]))
3648 return AS2 (and%B0,%
2,%h0);
3650 operands[
0] = adj_offsettable_operand (operands[
0],
1);
3651 return AS2 (and%B0,%
2,%b0);
3654 if (REG_P (operands[
0]))
3657 /* third byte has zero bits? */
3658 if (~(intval |
0xff0000) ==
0)
3660 intval = (intval >>
16) &
0xff;
3661 operands[
0] = adj_offsettable_operand (operands[
0],
2);
3664 operands[
2] = GEN_INT (intval);
3666 return AS2 (mov%B0,%
2,%b0);
3667 return AS2 (and%B0,%
2,%b0);
3670 /* fourth byte has zero bits? */
3671 if (~(intval |
0xff000000) ==
0)
3673 intval = (intval >>
24) &
0xff;
3674 operands[
0] = adj_offsettable_operand (operands[
0],
3);
3675 goto byte_and_operation;
3678 /* Low word is zero? */
3679 if (intval ==
0xffff0000)
3681 word_zero_and_operation:
3683 operands[
2] = const0_rtx;
3684 return AS2 (mov%W0,%
2,%w0);
3687 /* High word is zero? */
3688 if (intval ==
0x0000ffff)
3690 operands[
0] = adj_offsettable_operand (operands[
0],
2);
3691 goto word_zero_and_operation;
3698 return AS2 (and%L0,%
2,%
0);
3701 (define_insn "andhi3"
3702 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
3703 (and:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,
0")
3704 (match_operand:HI
2 "general_operand" "ri,rm")))]
3708 if (GET_CODE (operands[
2]) == CONST_INT
3709 && ! (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0])))
3711 /* Can we ignore the upper byte? */
3712 if ((! REG_P (operands[
0]) || QI_REG_P (operands[
0]))
3713 && (INTVAL (operands[
2]) &
0xff00) ==
0xff00)
3717 if ((INTVAL (operands[
2]) &
0xff) ==
0)
3719 operands[
2] = const0_rtx;
3720 return AS2 (mov%B0,%
2,%b0);
3723 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0xff);
3724 return AS2 (and%B0,%
2,%b0);
3727 /* Can we ignore the lower byte? */
3728 /* ??? what about offsettable memory references? */
3729 if (QI_REG_P (operands[
0]) && (INTVAL (operands[
2]) &
0xff) ==
0xff)
3733 if ((INTVAL (operands[
2]) &
0xff00) ==
0)
3735 operands[
2] = const0_rtx;
3736 return AS2 (mov%B0,%
2,%h0);
3739 operands[
2] = GEN_INT ((INTVAL (operands[
2]) >>
8) &
0xff);
3740 return AS2 (and%B0,%
2,%h0);
3743 /* use
32-bit ops on registers when there are no sign issues.. */
3744 if (REG_P (operands[
0]))
3746 if (!(INTVAL (operands[
2]) & ~
0x7fff))
3747 return AS2 (and%L0,%
2,%k0);
3751 if (REG_P (operands[
0])
3752 && i386_aligned_p (operands[
2]))
3755 /* If op[
2] is constant, we should zero-extend it and */
3756 /* make a note that op[
0] has been zero-extended, so */
3757 /* that we could use
32-bit ops on it forthwith, but */
3758 /* there is no such reg-note available. Instead we do */
3759 /* a sign extension as that can result in shorter asm */
3760 operands[
2] = i386_sext16_if_const (operands[
2]);
3761 return AS2 (and%L0,%k2,%k0);
3764 /* Use a
32-bit word with the upper bits set, invalidate CC */
3765 if (GET_CODE (operands[
2]) == CONST_INT
3766 && i386_aligned_p (operands[
0]))
3768 HOST_WIDE_INT val = INTVAL (operands[
2]);
3771 if (val != INTVAL (operands[
2]))
3772 operands[
2] = GEN_INT (val);
3773 return AS2 (and%L0,%k2,%k0);
3776 return AS2 (and%W0,%
2,%
0);
3779 (define_insn "andqi3"
3780 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
3781 (and:QI (match_operand:QI
1 "nonimmediate_operand" "%
0,
0")
3782 (match_operand:QI
2 "general_operand" "qn,qmn")))]
3784 "* return AS2 (and%B0,%
2,%
0);")
3786 /* I am nervous about these two.. add them later..
3787 ;I presume this means that we have something in say op0= eax which is small
3788 ;and we want to and it with memory so we can do this by just an
3789 ;andb m,%al and have success.
3791 [(set (match_operand:SI
0 "general_operand" "=r")
3792 (and:SI (zero_extend:SI
3793 (match_operand:HI
1 "nonimmediate_operand" "rm"))
3794 (match_operand:SI
2 "general_operand" "
0")))]
3795 "GET_CODE (operands[
2]) == CONST_INT
3796 && (unsigned int) INTVAL (operands[
2]) < (
1 << GET_MODE_BITSIZE (HImode))"
3800 [(set (match_operand:SI
0 "register_operand" "=q")
3802 (zero_extend:SI (match_operand:QI
1 "nonimmediate_operand" "qm"))
3803 (match_operand:SI
2 "register_operand" "
0")))]
3804 "GET_CODE (operands[
2]) == CONST_INT
3805 && (unsigned int) INTVAL (operands[
2]) < (
1 << GET_MODE_BITSIZE (QImode))"
3810 ;;- Bit set (inclusive or) instructions
3812 ;; This optimizes known byte-wide operations to memory, and in some cases
3813 ;; to QI registers.. Note that we don't want to use the QI registers too
3814 ;; aggressively, because often the
32-bit register instruction is the same
3815 ;; size, and likely to be faster on PentiumPro.
3816 (define_insn "iorsi3"
3817 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm,r")
3818 (ior:SI (match_operand:SI
1 "nonimmediate_operand" "%
0,
0")
3819 (match_operand:SI
2 "general_operand" "ri,rm")))]
3823 HOST_WIDE_INT intval;
3824 switch (GET_CODE (operands[
2]))
3828 if (REG_P (operands[
0]) && ! QI_REG_P (operands[
0]))
3831 /* don't try to optimize volatile accesses */
3832 if (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
3835 intval = INTVAL (operands[
2]);
3836 if ((intval & ~
0xff) ==
0)
3838 if (REG_P (operands[
0]))
3840 /* Do low byte access only for %eax or when high bit is set */
3841 if (REGNO (operands[
0]) !=
0 && !(intval &
0x80))
3848 if (intval != INTVAL (operands[
2]))
3849 operands[
2] = GEN_INT (intval);
3852 return AS2 (mov%B0,%
2,%b0);
3854 return AS2 (or%B0,%
2,%b0);
3858 if ((intval & ~
0xff00) ==
0)
3862 if (REG_P (operands[
0]))
3865 operands[
2] = GEN_INT (intval);
3867 return AS2 (mov%B0,%
2,%h0);
3869 return AS2 (or%B0,%
2,%h0);
3872 operands[
0] = adj_offsettable_operand (operands[
0],
1);
3873 goto byte_or_operation;
3876 if (REG_P (operands[
0]))
3880 if ((intval & ~
0xff0000) ==
0)
3883 operands[
0] = adj_offsettable_operand (operands[
0],
2);
3884 goto byte_or_operation;
3888 if ((intval & ~
0xff000000) ==
0)
3890 intval = (intval >>
24) &
0xff;
3891 operands[
0] = adj_offsettable_operand (operands[
0],
3);
3892 goto byte_or_operation;
3899 return AS2 (or%L0,%
2,%
0);
3902 (define_insn "iorhi3"
3903 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
3904 (ior:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,
0")
3905 (match_operand:HI
2 "general_operand" "ri,rm")))]
3909 HOST_WIDE_INT intval;
3910 switch (GET_CODE (operands[
2]))
3914 if (REG_P (operands[
0]) && ! QI_REG_P (operands[
0]))
3917 /* don't try to optimize volatile accesses */
3918 if (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
3921 intval =
0xffff & INTVAL (operands[
2]);
3923 if ((intval &
0xff00) ==
0)
3925 if (REG_P (operands[
0]))
3927 /* Do low byte access only for %eax or when high bit is set */
3928 if (REGNO (operands[
0]) !=
0 && !(intval &
0x80))
3936 return AS2 (mov%B0,%
2,%b0);
3938 return AS2 (or%B0,%
2,%b0);
3942 if ((intval &
0xff) ==
0)
3945 operands[
2] = GEN_INT (intval);
3947 if (REG_P (operands[
0]))
3951 return AS2 (mov%B0,%
2,%h0);
3953 return AS2 (or%B0,%
2,%h0);
3956 operands[
0] = adj_offsettable_operand (operands[
0],
1);
3958 goto byte_or_operation;
3965 if (REG_P (operands[
0])
3966 && i386_aligned_p (operands[
2]))
3969 operands[
2] = i386_sext16_if_const (operands[
2]);
3970 return AS2 (or%L0,%k2,%k0);
3973 if (GET_CODE (operands[
2]) == CONST_INT
3974 && i386_aligned_p (operands[
0]))
3977 intval =
0xffff & INTVAL (operands[
2]);
3978 if (intval != INTVAL (operands[
2]))
3979 operands[
2] = GEN_INT (intval);
3980 return AS2 (or%L0,%
2,%k0);
3983 return AS2 (or%W0,%
2,%
0);
3986 (define_insn "iorqi3"
3987 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
3988 (ior:QI (match_operand:QI
1 "nonimmediate_operand" "%
0,
0")
3989 (match_operand:QI
2 "general_operand" "qn,qmn")))]
3991 "* return AS2 (or%B0,%
2,%
0);")
3993 ;;- xor instructions
3995 (define_insn "xorsi3"
3996 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm,r")
3997 (xor:SI (match_operand:SI
1 "nonimmediate_operand" "%
0,
0")
3998 (match_operand:SI
2 "general_operand" "ri,rm")))]
4002 HOST_WIDE_INT intval;
4003 switch (GET_CODE (operands[
2]))
4007 if (REG_P (operands[
0]) && ! QI_REG_P (operands[
0]))
4010 /* don't try to optimize volatile accesses */
4011 if (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
4014 intval = INTVAL (operands[
2]);
4015 if ((intval & ~
0xff) ==
0)
4017 if (REG_P (operands[
0]))
4019 /* Do low byte access only for %eax or when high bit is set */
4020 if (REGNO (operands[
0]) !=
0 && !(intval &
0x80))
4028 return AS1 (not%B0,%b0);
4030 if (intval != INTVAL (operands[
2]))
4031 operands[
2] = GEN_INT (intval);
4032 return AS2 (xor%B0,%
2,%b0);
4036 if ((intval & ~
0xff00) ==
0)
4040 if (REG_P (operands[
0]))
4044 return AS1 (not%B0,%h0);
4046 operands[
2] = GEN_INT (intval);
4047 return AS2 (xor%B0,%
2,%h0);
4050 operands[
0] = adj_offsettable_operand (operands[
0],
1);
4052 goto byte_xor_operation;
4055 if (REG_P (operands[
0]))
4059 if ((intval & ~
0xff0000) ==
0)
4062 operands[
0] = adj_offsettable_operand (operands[
0],
2);
4063 goto byte_xor_operation;
4067 if ((intval & ~
0xff000000) ==
0)
4069 intval = (intval >>
24) &
0xff;
4070 operands[
0] = adj_offsettable_operand (operands[
0],
3);
4071 goto byte_xor_operation;
4078 return AS2 (xor%L0,%
2,%
0);
4081 (define_insn "xorhi3"
4082 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
4083 (xor:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,
0")
4084 (match_operand:HI
2 "general_operand" "ri,rm")))]
4088 if (GET_CODE (operands[
2]) == CONST_INT
4089 && ! (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0])))
4091 /* Can we ignore the upper byte? */
4092 if ((! REG_P (operands[
0]) || QI_REG_P (operands[
0]))
4093 && (INTVAL (operands[
2]) &
0xff00) ==
0)
4096 if (INTVAL (operands[
2]) &
0xffff0000)
4097 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0xffff);
4099 if (INTVAL (operands[
2]) ==
0xff)
4100 return AS1 (not%B0,%b0);
4102 return AS2 (xor%B0,%
2,%b0);
4105 /* Can we ignore the lower byte? */
4106 /* ??? what about offsettable memory references? */
4107 if (QI_REG_P (operands[
0])
4108 && (INTVAL (operands[
2]) &
0xff) ==
0)
4111 operands[
2] = GEN_INT ((INTVAL (operands[
2]) >>
8) &
0xff);
4113 if (INTVAL (operands[
2]) ==
0xff)
4114 return AS1 (not%B0,%h0);
4116 return AS2 (xor%B0,%
2,%h0);
4120 if (REG_P (operands[
0])
4121 && i386_aligned_p (operands[
2]))
4124 operands[
2] = i386_sext16_if_const (operands[
2]);
4125 return AS2 (xor%L0,%k2,%k0);
4128 if (GET_CODE (operands[
2]) == CONST_INT
4129 && i386_aligned_p (operands[
0]))
4131 HOST_WIDE_INT intval;
4133 intval =
0xffff & INTVAL (operands[
2]);
4134 if (intval != INTVAL (operands[
2]))
4135 operands[
2] = GEN_INT (intval);
4136 return AS2 (xor%L0,%
2,%k0);
4139 return AS2 (xor%W0,%
2,%
0);
4142 (define_insn "xorqi3"
4143 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
4144 (xor:QI (match_operand:QI
1 "nonimmediate_operand" "%
0,
0")
4145 (match_operand:QI
2 "general_operand" "qn,qm")))]
4147 "* return AS2 (xor%B0,%
2,%
0);")
4149 ;; logical operations for DImode
4152 (define_insn "anddi3"
4153 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4154 (and:DI (match_operand:DI
1 "general_operand" "%
0,
0,
0,
0iF,or,riF,o")
4155 (match_operand:DI
2 "general_operand" "o,riF,
0,or,or,oriF,o")))
4156 (clobber (match_scratch:SI
3 "=X,X,X,&r,X,&r,&r"))]
4160 (define_insn "iordi3"
4161 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4162 (ior:DI (match_operand:DI
1 "general_operand" "%
0,
0,
0,
0iF,or,riF,o")
4163 (match_operand:DI
2 "general_operand" "o,riF,
0,or,or,oriF,o")))
4164 (clobber (match_scratch:SI
3 "=X,X,X,&r,X,&r,&r"))]
4168 (define_insn "xordi3"
4169 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4170 (xor:DI (match_operand:DI
1 "general_operand" "%
0,
0,
0,
0iF,or,riF,o")
4171 (match_operand:DI
2 "general_operand" "o,riF,
0,or,or,oriF,o")))
4172 (clobber (match_scratch:SI
3 "=X,X,X,&r,X,&r,&r"))]
4177 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4178 (match_operator:DI
4 "ix86_logical_operator"
4179 [(match_operand:DI
1 "general_operand" "%
0,
0,
0,
0iF,or,riF,o")
4180 (match_operand:DI
2 "general_operand" "o,riF,
0,or,or,oriF,o")]))
4181 (clobber (match_scratch:SI
3 "=X,X,X,&r,X,&r,&r"))]
4186 rtx low[
3], high[
3], xops[
7], temp;
4187 rtx (*genfunc)() = (GET_CODE (operands[
4]) == AND ? gen_andsi3
4188 : GET_CODE (operands[
4]) == IOR ? gen_iorsi3
4189 : GET_CODE (operands[
4]) == XOR ? gen_xorsi3
4192 if (rtx_equal_p (operands[
0], operands[
2]))
4195 operands[
1] = operands[
2];
4199 split_di (operands,
3, low, high);
4200 if (!rtx_equal_p (operands[
0], operands[
1]))
4207 if (GET_CODE (operands[
0]) != MEM)
4209 emit_insn (gen_movsi (xops[
1], xops[
3]));
4210 emit_insn (gen_movsi (xops[
0], xops[
2]));
4216 xops[
6] = operands[
3];
4217 emit_insn (gen_movsi (xops[
6], xops[
3]));
4218 emit_insn ((*genfunc) (xops[
6], xops[
6], xops[
5]));
4219 emit_insn (gen_movsi (xops[
1], xops[
6]));
4220 emit_insn (gen_movsi (xops[
6], xops[
2]));
4221 emit_insn ((*genfunc) (xops[
6], xops[
6], xops[
4]));
4222 emit_insn (gen_movsi (xops[
0], xops[
6]));
4227 if (GET_CODE (operands[
3]) == REG && GET_CODE (operands[
2]) != REG)
4233 xops[
4] = operands[
3];
4235 emit_insn (gen_movsi (xops[
4], xops[
3]));
4236 emit_insn ((*genfunc) (xops[
1], xops[
1], xops[
4]));
4237 emit_insn (gen_movsi (xops[
4], xops[
2]));
4238 emit_insn ((*genfunc) (xops[
0], xops[
0], xops[
4]));
4243 emit_insn ((*genfunc) (low[
0], low[
0], low[
2]));
4244 emit_insn ((*genfunc) (high[
0], high[
0], high[
2]));
4250 ;;- negation instructions
4252 (define_insn "negdi2"
4253 [(set (match_operand:DI
0 "general_operand" "=&ro")
4254 (neg:DI (match_operand:DI
1 "general_operand" "
0")))]
4258 rtx xops[
2], low[
1], high[
1];
4262 split_di (operands,
1, low, high);
4263 xops[
0] = const0_rtx;
4266 output_asm_insn (AS1 (neg%L0,%
0), low);
4267 output_asm_insn (AS2 (adc%L1,%
0,%
1), xops);
4268 output_asm_insn (AS1 (neg%L0,%
0), high);
4272 (define_insn "negsi2"
4273 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm")
4274 (neg:SI (match_operand:SI
1 "nonimmediate_operand" "
0")))]
4278 (define_insn "neghi2"
4279 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm")
4280 (neg:HI (match_operand:HI
1 "nonimmediate_operand" "
0")))]
4284 (define_insn "negqi2"
4285 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm")
4286 (neg:QI (match_operand:QI
1 "nonimmediate_operand" "
0")))]
4290 (define_insn "negsf2"
4291 [(set (match_operand:SF
0 "register_operand" "=f")
4292 (neg:SF (match_operand:SF
1 "register_operand" "
0")))]
4296 (define_insn "negdf2"
4297 [(set (match_operand:DF
0 "register_operand" "=f")
4298 (neg:DF (match_operand:DF
1 "register_operand" "
0")))]
4303 [(set (match_operand:DF
0 "register_operand" "=f")
4304 (neg:DF (float_extend:DF (match_operand:SF
1 "register_operand" "
0"))))]
4308 (define_insn "negxf2"
4309 [(set (match_operand:XF
0 "register_operand" "=f")
4310 (neg:XF (match_operand:XF
1 "register_operand" "
0")))]
4315 [(set (match_operand:XF
0 "register_operand" "=f")
4316 (neg:XF (float_extend:XF (match_operand:DF
1 "register_operand" "
0"))))]
4320 ;; Absolute value instructions
4322 (define_insn "abssf2"
4323 [(set (match_operand:SF
0 "register_operand" "=f")
4324 (abs:SF (match_operand:SF
1 "register_operand" "
0")))]
4327 [(set_attr "type" "fpop")])
4329 (define_insn "absdf2"
4330 [(set (match_operand:DF
0 "register_operand" "=f")
4331 (abs:DF (match_operand:DF
1 "register_operand" "
0")))]
4334 [(set_attr "type" "fpop")])
4337 [(set (match_operand:DF
0 "register_operand" "=f")
4338 (abs:DF (float_extend:DF (match_operand:SF
1 "register_operand" "
0"))))]
4341 [(set_attr "type" "fpop")])
4343 (define_insn "absxf2"
4344 [(set (match_operand:XF
0 "register_operand" "=f")
4345 (abs:XF (match_operand:XF
1 "register_operand" "
0")))]
4348 [(set_attr "type" "fpop")])
4351 [(set (match_operand:XF
0 "register_operand" "=f")
4352 (abs:XF (float_extend:XF (match_operand:DF
1 "register_operand" "
0"))))]
4355 [(set_attr "type" "fpop")])
4357 (define_insn "sqrtsf2"
4358 [(set (match_operand:SF
0 "register_operand" "=f")
4359 (sqrt:SF (match_operand:SF
1 "register_operand" "
0")))]
4360 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4363 (define_insn "sqrtdf2"
4364 [(set (match_operand:DF
0 "register_operand" "=f")
4365 (sqrt:DF (match_operand:DF
1 "register_operand" "
0")))]
4366 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4367 && (TARGET_IEEE_FP || flag_fast_math) "
4371 [(set (match_operand:DF
0 "register_operand" "=f")
4372 (sqrt:DF (float_extend:DF
4373 (match_operand:SF
1 "register_operand" "
0"))))]
4374 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4377 (define_insn "sqrtxf2"
4378 [(set (match_operand:XF
0 "register_operand" "=f")
4379 (sqrt:XF (match_operand:XF
1 "register_operand" "
0")))]
4380 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4381 && (TARGET_IEEE_FP || flag_fast_math) "
4385 [(set (match_operand:XF
0 "register_operand" "=f")
4386 (sqrt:XF (float_extend:XF
4387 (match_operand:DF
1 "register_operand" "
0"))))]
4388 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4392 [(set (match_operand:XF
0 "register_operand" "=f")
4393 (sqrt:XF (float_extend:XF
4394 (match_operand:SF
1 "register_operand" "
0"))))]
4395 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4398 (define_insn "sindf2"
4399 [(set (match_operand:DF
0 "register_operand" "=f")
4400 (unspec:DF [(match_operand:DF
1 "register_operand" "
0")]
1))]
4401 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4404 (define_insn "sinsf2"
4405 [(set (match_operand:SF
0 "register_operand" "=f")
4406 (unspec:SF [(match_operand:SF
1 "register_operand" "
0")]
1))]
4407 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4411 [(set (match_operand:DF
0 "register_operand" "=f")
4412 (unspec:DF [(float_extend:DF
4413 (match_operand:SF
1 "register_operand" "
0"))]
1))]
4414 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4417 (define_insn "sinxf2"
4418 [(set (match_operand:XF
0 "register_operand" "=f")
4419 (unspec:XF [(match_operand:XF
1 "register_operand" "
0")]
1))]
4420 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4423 (define_insn "cosdf2"
4424 [(set (match_operand:DF
0 "register_operand" "=f")
4425 (unspec:DF [(match_operand:DF
1 "register_operand" "
0")]
2))]
4426 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4429 (define_insn "cossf2"
4430 [(set (match_operand:SF
0 "register_operand" "=f")
4431 (unspec:SF [(match_operand:SF
1 "register_operand" "
0")]
2))]
4432 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4436 [(set (match_operand:DF
0 "register_operand" "=f")
4437 (unspec:DF [(float_extend:DF
4438 (match_operand:SF
1 "register_operand" "
0"))]
2))]
4439 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4442 (define_insn "cosxf2"
4443 [(set (match_operand:XF
0 "register_operand" "=f")
4444 (unspec:XF [(match_operand:XF
1 "register_operand" "
0")]
2))]
4445 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4448 ;;- one complement instructions
4450 (define_insn "one_cmplsi2"
4451 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm")
4452 (not:SI (match_operand:SI
1 "nonimmediate_operand" "
0")))]
4456 (define_insn "one_cmplhi2"
4457 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm")
4458 (not:HI (match_operand:HI
1 "nonimmediate_operand" "
0")))]
4462 (define_insn "one_cmplqi2"
4463 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm")
4464 (not:QI (match_operand:QI
1 "nonimmediate_operand" "
0")))]
4468 ;;- arithmetic shift instructions
4470 ;; DImode shifts are implemented using the i386 "shift double" opcode,
4471 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
4472 ;; is variable, then the count is in %cl and the "imm" operand is dropped
4473 ;; from the assembler input.
4475 ;; This instruction shifts the target reg/mem as usual, but instead of
4476 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
4477 ;; is a left shift double, bits are taken from the high order bits of
4478 ;; reg, else if the insn is a shift right double, bits are taken from the
4479 ;; low order bits of reg. So if %eax is "
1234" and %edx is "
5678",
4480 ;; "shldl $
8,%edx,%eax" leaves %edx unchanged and sets %eax to "
2345".
4482 ;; Since sh[lr]d does not change the
`reg' operand, that is done
4483 ;; separately, making all shifts emit pairs of shift double and normal
4484 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
4485 ;; support a 63 bit shift, each shift where the count is in a reg expands
4486 ;; to a pair of shifts, a branch, a shift by 32 and a label.
4488 ;; If the shift count is a constant, we need never emit more than one
4489 ;; shift pair, instead using moves and sign extension for counts greater
4492 (define_expand "ashldi3"
4493 [(set (match_operand:DI 0 "register_operand" "")
4494 (ashift:DI (match_operand:DI 1 "register_operand" "")
4495 (match_operand:QI 2 "nonmemory_operand" "")))]
4499 if (GET_CODE (operands[2]) != CONST_INT
4500 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4502 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4503 emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
4507 emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
4512 (define_insn "ashldi3_const_int"
4513 [(set (match_operand:DI 0 "register_operand" "=&r")
4514 (ashift:DI (match_operand:DI 1 "register_operand" "0")
4515 (match_operand:QI 2 "const_int_operand" "J")))]
4516 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
4519 rtx xops[4], low[1], high[1];
4523 split_di (operands, 1, low, high);
4524 xops[0] = operands[2];
4525 xops[1] = const1_rtx;
4529 if (INTVAL (xops[0]) > 31)
4531 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
4532 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4534 if (INTVAL (xops[0]) > 32)
4536 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
4537 output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
4542 output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
4543 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
4548 (define_insn "ashldi3_non_const_int"
4549 [(set (match_operand:DI 0 "register_operand" "=&r")
4550 (ashift:DI (match_operand:DI 1 "register_operand" "0")
4551 (match_operand:QI 2 "register_operand" "c")))]
4555 rtx xops[4], low[1], high[1];
4556 static HOST_WIDE_INT ashldi_label_number;
4560 split_di (operands, 1, low, high);
4561 xops[0] = operands[2];
4562 xops[1] = GEN_INT (32);
4566 output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
4567 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
4568 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
4569 asm_fprintf (asm_out_file, \"\\tje %LLASHLDI%d\\n\", ashldi_label_number);
4570 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
4571 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4572 asm_fprintf (asm_out_file, \"%LLASHLDI%d:\\n\", ashldi_label_number++);
4577 ;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
4578 ;; On i486, movl/sall appears slightly faster than leal, but the leal
4579 ;; is smaller - use leal for now unless the shift count is 1.
4581 (define_insn "ashlsi3"
4582 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4583 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,0")
4584 (match_operand:SI 2 "nonmemory_operand" "M,cI")))]
4588 if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
4590 if (TARGET_DOUBLE_WITH_ADD && INTVAL (operands[2]) == 1)
4592 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
4593 return AS2 (add%L0,%1,%0);
4599 if (operands[1] == stack_pointer_rtx)
4601 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
4602 operands[1] = operands[0];
4604 operands[1] = gen_rtx_MULT (SImode, operands[1],
4605 GEN_INT (1 << INTVAL (operands[2])));
4606 return AS2 (lea%L0,%a1,%0);
4610 if (REG_P (operands[2]))
4611 return AS2 (sal%L0,%b2,%0);
4613 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4614 return AS2 (add%L0,%0,%0);
4616 return AS2 (sal%L0,%2,%0);
4619 (define_insn "ashlhi3"
4620 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4621 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4622 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4626 if (REG_P (operands[2]))
4627 return AS2 (sal%W0,%b2,%0);
4629 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4630 return AS2 (add%W0,%0,%0);
4632 return AS2 (sal%W0,%2,%0);
4635 (define_insn "ashlqi3"
4636 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4637 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4638 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4642 if (REG_P (operands[2]))
4643 return AS2 (sal%B0,%b2,%0);
4645 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4646 return AS2 (add%B0,%0,%0);
4648 return AS2 (sal%B0,%2,%0);
4651 ;; See comment above `ashldi3' about how this works.
4653 (define_expand "ashrdi3"
4654 [(set (match_operand:DI
0 "register_operand" "")
4655 (ashiftrt:DI (match_operand:DI
1 "register_operand" "")
4656 (match_operand:QI
2 "nonmemory_operand" "")))]
4660 if (GET_CODE (operands[
2]) != CONST_INT
4661 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[
2]), 'J'))
4663 operands[
2] = copy_to_mode_reg (QImode, operands[
2]);
4664 emit_insn (gen_ashrdi3_non_const_int (operands[
0], operands[
1],
4668 emit_insn (gen_ashrdi3_const_int (operands[
0], operands[
1], operands[
2]));
4673 (define_insn "ashldi3_32"
4674 [(set (match_operand:DI
0 "nonimmediate_operand" "=r,m")
4675 (ashift:DI (match_operand:DI
1 "nonimmediate_operand" "ro,r")
4680 rtx low[
2], high[
2], xops[
4];
4682 split_di (operands,
2, low, high);
4686 xops[
3] = const0_rtx;
4687 if (!rtx_equal_p (xops[
0], xops[
1]))
4688 output_asm_insn (AS2 (mov%L0,%
1,%
0), xops);
4690 if (GET_CODE (low[
0]) == MEM)
4691 output_asm_insn (AS2 (mov%L2,%
3,%
2), xops);
4693 output_asm_insn (AS2 (xor%L2,%
2,%
2), xops);
4698 (define_insn "ashrdi3_const_int"
4699 [(set (match_operand:DI
0 "register_operand" "=&r")
4700 (ashiftrt:DI (match_operand:DI
1 "register_operand" "
0")
4701 (match_operand:QI
2 "const_int_operand" "J")))]
4702 "CONST_OK_FOR_LETTER_P (INTVAL (operands[
2]), 'J')"
4705 rtx xops[
4], low[
1], high[
1];
4709 split_di (operands,
1, low, high);
4710 xops[
0] = operands[
2];
4711 xops[
1] = const1_rtx;
4715 if (INTVAL (xops[
0]) >
31)
4717 xops[
1] = GEN_INT (
31);
4718 output_asm_insn (AS2 (mov%L2,%
3,%
2), xops);
4719 output_asm_insn (AS2 (sar%L3,%
1,%
3), xops); /* shift by
32 */
4721 if (INTVAL (xops[
0]) >
32)
4723 xops[
0] = GEN_INT (INTVAL (xops[
0]) -
32);
4724 output_asm_insn (AS2 (sar%L2,%
0,%
2), xops); /* Remaining shift */
4729 output_asm_insn (AS3 (shrd%L2,%
0,%
3,%
2), xops);
4730 output_asm_insn (AS2 (sar%L3,%
0,%
3), xops);
4736 (define_insn "ashrdi3_non_const_int"
4737 [(set (match_operand:DI
0 "register_operand" "=&r")
4738 (ashiftrt:DI (match_operand:DI
1 "register_operand" "
0")
4739 (match_operand:QI
2 "register_operand" "c")))]
4743 rtx xops[
4], low[
1], high[
1];
4744 static HOST_WIDE_INT ashrdi_label_number;
4748 split_di (operands,
1, low, high);
4749 xops[
0] = operands[
2];
4750 xops[
1] = GEN_INT (
32);
4754 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%
0,%
3,%
2), xops);
4755 output_asm_insn (AS2 (sar%L3,%
0,%
3), xops);
4756 output_asm_insn (AS2 (test%B0,%
1,%b0), xops);
4757 asm_fprintf (asm_out_file,
\"\\tje %LLASHRDI%d
\\n
\", ashrdi_label_number);
4758 xops[
1] = GEN_INT (
31);
4759 output_asm_insn (AS2 (mov%L2,%
3,%
2), xops);
4760 output_asm_insn (AS2 (sar%L3,%
1,%
3), xops); /* shift by
32 */
4761 asm_fprintf (asm_out_file,
\"%LLASHRDI%d:
\\n
\", ashrdi_label_number++);
4766 (define_insn "ashrsi3"
4767 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm")
4768 (ashiftrt:SI (match_operand:SI
1 "nonimmediate_operand" "
0")
4769 (match_operand:SI
2 "nonmemory_operand" "cI")))]
4773 if (REG_P (operands[
2]))
4774 return AS2 (sar%L0,%b2,%
0);
4776 return AS2 (sar%L0,%
2,%
0);
4779 (define_insn "ashrhi3"
4780 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm")
4781 (ashiftrt:HI (match_operand:HI
1 "nonimmediate_operand" "
0")
4782 (match_operand:HI
2 "nonmemory_operand" "cI")))]
4786 if (REG_P (operands[
2]))
4787 return AS2 (sar%W0,%b2,%
0);
4789 return AS2 (sar%W0,%
2,%
0);
4792 (define_insn "ashrqi3"
4793 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm")
4794 (ashiftrt:QI (match_operand:QI
1 "nonimmediate_operand" "
0")
4795 (match_operand:QI
2 "nonmemory_operand" "cI")))]
4799 if (REG_P (operands[
2]))
4800 return AS2 (sar%B0,%b2,%
0);
4802 return AS2 (sar%B0,%
2,%
0);
4805 ;;- logical shift instructions
4807 ;; See comment above
`ashldi3' about how this works.
4809 (define_expand "lshrdi3"
4810 [(set (match_operand:DI 0 "register_operand" "")
4811 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4812 (match_operand:QI 2 "nonmemory_operand" "")))]
4816 if (GET_CODE (operands[2]) != CONST_INT
4817 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4819 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4820 emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
4824 emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
4829 (define_insn "lshrdi3_32"
4830 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
4831 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
4836 rtx low[2], high[2], xops[4];
4838 split_di (operands, 2, low, high);
4842 xops[3] = const0_rtx;
4843 if (!rtx_equal_p (xops[0], xops[1]))
4844 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
4846 if (GET_CODE (low[0]) == MEM)
4847 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4849 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4854 (define_insn "lshrdi3_const_int"
4855 [(set (match_operand:DI 0 "register_operand" "=&r")
4856 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
4857 (match_operand:QI 2 "const_int_operand" "J")))]
4858 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
4861 rtx xops[4], low[1], high[1];
4865 split_di (operands, 1, low, high);
4866 xops[0] = operands[2];
4867 xops[1] = const1_rtx;
4871 if (INTVAL (xops[0]) > 31)
4873 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
4874 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
4876 if (INTVAL (xops[0]) > 32)
4878 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
4879 output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
4884 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
4885 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
4891 (define_insn "lshrdi3_non_const_int"
4892 [(set (match_operand:DI 0 "register_operand" "=&r")
4893 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
4894 (match_operand:QI 2 "register_operand" "c")))]
4898 rtx xops[4], low[1], high[1];
4899 static HOST_WIDE_INT lshrdi_label_number;
4903 split_di (operands, 1, low, high);
4904 xops[0] = operands[2];
4905 xops[1] = GEN_INT (32);
4909 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
4910 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
4911 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
4912 asm_fprintf (asm_out_file, \"\\tje %LLLSHRDI%d\\n\", lshrdi_label_number);
4913 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
4914 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
4915 asm_fprintf (asm_out_file, \"%LLLSHRDI%d:\\n\", lshrdi_label_number++);
4920 (define_insn "lshrsi3"
4921 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4922 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
4923 (match_operand:SI 2 "nonmemory_operand" "cI")))]
4927 if (REG_P (operands[2]))
4928 return AS2 (shr%L0,%b2,%0);
4930 return AS2 (shr%L0,%2,%1);
4933 (define_insn "lshrhi3"
4934 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4935 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4936 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4940 if (REG_P (operands[2]))
4941 return AS2 (shr%W0,%b2,%0);
4943 return AS2 (shr%W0,%2,%0);
4946 (define_insn "lshrqi3"
4947 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4948 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4949 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4953 if (REG_P (operands[2]))
4954 return AS2 (shr%B0,%b2,%0);
4956 return AS2 (shr%B0,%2,%0);
4959 ;;- rotate instructions
4961 (define_insn "rotlsi3"
4962 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4963 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
4964 (match_operand:SI 2 "nonmemory_operand" "cI")))]
4968 if (REG_P (operands[2]))
4969 return AS2 (rol%L0,%b2,%0);
4971 return AS2 (rol%L0,%2,%0);
4974 (define_insn "rotlhi3"
4975 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4976 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4977 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4981 if (REG_P (operands[2]))
4982 return AS2 (rol%W0,%b2,%0);
4984 return AS2 (rol%W0,%2,%0);
4987 (define_insn "rotlqi3"
4988 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4989 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4990 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4994 if (REG_P (operands[2]))
4995 return AS2 (rol%B0,%b2,%0);
4997 return AS2 (rol%B0,%2,%0);
5000 (define_insn "rotrsi3"
5001 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5002 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5003 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5007 if (REG_P (operands[2]))
5008 return AS2 (ror%L0,%b2,%0);
5010 return AS2 (ror%L0,%2,%0);
5013 (define_insn "rotrhi3"
5014 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5015 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5016 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5020 if (REG_P (operands[2]))
5021 return AS2 (ror%W0,%b2,%0);
5023 return AS2 (ror%W0,%2,%0);
5026 (define_insn "rotrqi3"
5027 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5028 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5029 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5033 if (REG_P (operands[2]))
5034 return AS2 (ror%B0,%b2,%0);
5036 return AS2 (ror%B0,%2,%0);
5040 ;; This usually looses. But try a define_expand to recognize a few case
5041 ;; we can do efficiently, such as accessing the "high" QImode registers,
5042 ;; %ah, %bh, %ch, %dh.
5043 ;; ??? Note this has a botch on the mode of operand 0, which needs to be
5044 ;; fixed if this is ever enabled.
5046 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
5047 (match_operand:SI 1 "immediate_operand" "i")
5048 (match_operand:SI 2 "immediate_operand" "i"))
5049 (match_operand:SI 3 "nonmemory_operand" "ri"))]
5053 if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
5055 if (GET_CODE (operands[3]) == CONST_INT)
5057 unsigned int mask = (1 << INTVAL (operands[1])) - 1;
5058 operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
5059 output_asm_insn (AS2 (and%L0,%1,%0), operands);
5060 operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
5061 output_asm_insn (AS2 (or%L0,%3,%0), operands);
5065 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
5066 if (INTVAL (operands[2]))
5067 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5068 output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
5069 operands[2] = GEN_INT (BITS_PER_WORD
5070 - INTVAL (operands[1]) - INTVAL (operands[2]));
5071 if (INTVAL (operands[2]))
5072 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5078 ;; ??? There are problems with the mode of operand[3]. The point of this
5079 ;; is to represent an HImode move to a "high byte" register.
5081 (define_expand "insv"
5082 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
5083 (match_operand:SI 1 "immediate_operand" "")
5084 (match_operand:SI 2 "immediate_operand" ""))
5085 (match_operand:QI 3 "nonmemory_operand" "ri"))]
5089 if (GET_CODE (operands[1]) != CONST_INT
5090 || GET_CODE (operands[2]) != CONST_INT)
5093 if (! (INTVAL (operands[1]) == 8
5094 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
5095 && ! INTVAL (operands[1]) == 1)
5100 ;; On i386, the register count for a bit operation is *not* truncated,
5101 ;; so SHIFT_COUNT_TRUNCATED must not be defined.
5103 ;; On i486, the shift & or/and code is faster than bts or btr. If
5104 ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
5106 ;; On i386, bts is a little faster if operands[0] is a reg, and a
5107 ;; little slower if operands[0] is a MEM, than the shift & or/and code.
5108 ;; Use bts & btr, since they reload better.
5110 ;; General bit set and clear.
5112 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm")
5114 (match_operand:SI 2 "register_operand" "r"))
5115 (match_operand:SI 3 "const_int_operand" "n"))]
5116 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5121 if (INTVAL (operands[3]) == 1)
5122 return AS2 (bts%L0,%2,%0);
5124 return AS2 (btr%L0,%2,%0);
5127 ;; Bit complement. See comments on previous pattern.
5128 ;; ??? Is this really worthwhile?
5130 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5131 (xor:SI (ashift:SI (const_int 1)
5132 (match_operand:SI 1 "register_operand" "r"))
5133 (match_operand:SI 2 "nonimmediate_operand" "0")))]
5134 "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT"
5139 return AS2 (btc%L0,%1,%0);
5143 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5144 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5145 (ashift:SI (const_int 1)
5146 (match_operand:SI 2 "register_operand" "r"))))]
5147 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5152 return AS2 (btc%L0,%2,%0);
5155 ;; Recognizers for bit-test instructions.
5157 ;; The bt opcode allows a MEM in operands[0]. But on both i386 and
5158 ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
5159 ;; bt on the MEM directly.
5161 ;; ??? The first argument of a zero_extract must not be reloaded, so
5162 ;; don't allow a MEM in the operand predicate without allowing it in the
5166 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5168 (match_operand:SI 1 "register_operand" "r")))]
5169 "GET_CODE (operands[1]) != CONST_INT"
5172 cc_status.flags |= CC_Z_IN_NOT_C;
5173 return AS2 (bt%L0,%1,%0);
5177 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5178 (match_operand:SI 1 "const_int_operand" "n")
5179 (match_operand:SI 2 "const_int_operand" "n")))]
5185 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5186 operands[1] = GEN_INT (mask);
5188 if (QI_REG_P (operands[0]))
5190 if ((mask & ~0xff) == 0)
5192 cc_status.flags |= CC_NOT_NEGATIVE;
5193 return AS2 (test%B0,%1,%b0);
5196 if ((mask & ~0xff00) == 0)
5198 cc_status.flags |= CC_NOT_NEGATIVE;
5199 operands[1] = GEN_INT (mask >> 8);
5200 return AS2 (test%B0,%1,%h0);
5204 return AS2 (test%L0,%1,%0);
5207 ;; ??? All bets are off if operand 0 is a volatile MEM reference.
5208 ;; The CPU may access unspecified bytes around the actual target byte.
5211 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
5212 (match_operand:SI 1 "const_int_operand" "n")
5213 (match_operand:SI 2 "const_int_operand" "n")))]
5214 "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
5219 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5220 operands[1] = GEN_INT (mask);
5222 if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
5224 if ((mask & ~0xff) == 0)
5226 cc_status.flags |= CC_NOT_NEGATIVE;
5227 return AS2 (test%B0,%1,%b0);
5230 if ((mask & ~0xff00) == 0)
5232 cc_status.flags |= CC_NOT_NEGATIVE;
5233 operands[1] = GEN_INT (mask >> 8);
5235 if (QI_REG_P (operands[0]))
5236 return AS2 (test%B0,%1,%h0);
5239 operands[0] = adj_offsettable_operand (operands[0], 1);
5240 return AS2 (test%B0,%1,%b0);
5244 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
5246 cc_status.flags |= CC_NOT_NEGATIVE;
5247 operands[1] = GEN_INT (mask >> 16);
5248 operands[0] = adj_offsettable_operand (operands[0], 2);
5249 return AS2 (test%B0,%1,%b0);
5252 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
5254 cc_status.flags |= CC_NOT_NEGATIVE;
5255 operands[1] = GEN_INT (mask >> 24);
5256 operands[0] = adj_offsettable_operand (operands[0], 3);
5257 return AS2 (test%B0,%1,%b0);
5261 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
5262 return AS2 (test%L0,%1,%0);
5264 return AS2 (test%L1,%0,%1);
5267 ;; Store-flag instructions.
5269 ;; For all sCOND expanders, also expand the compare or test insn that
5270 ;; generates cc0. Generate an equality comparison if `seq' or
`sne'.
5272 ;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may
5273 ;; not have any input reloads. A MEM write might need an input reload
5274 ;; for the address of the MEM. So don't allow MEM as the SET_DEST.
5276 (define_expand "seq"
5278 (set (match_operand:QI 0 "register_operand" "")
5279 (eq:QI (cc0) (const_int 0)))]
5284 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5285 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5287 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5291 [(set (match_operand:QI 0 "register_operand" "=q")
5292 (eq:QI (cc0) (const_int 0)))]
5296 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5297 return AS1 (setnb,%0);
5299 return AS1 (sete,%0);
5302 (define_expand "sne"
5304 (set (match_operand:QI 0 "register_operand" "")
5305 (ne:QI (cc0) (const_int 0)))]
5310 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5311 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5313 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5317 [(set (match_operand:QI 0 "register_operand" "=q")
5318 (ne:QI (cc0) (const_int 0)))]
5322 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5323 return AS1 (setb,%0);
5325 return AS1 (setne,%0);
5329 (define_expand "sgt"
5331 (set (match_operand:QI 0 "register_operand" "")
5332 (gt:QI (cc0) (const_int 0)))]
5334 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5337 [(set (match_operand:QI 0 "register_operand" "=q")
5338 (gt:QI (cc0) (const_int 0)))]
5342 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5343 && ! (cc_prev_status.flags & CC_FCOMI))
5344 return AS1 (sete,%0);
5346 OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR);
5349 (define_expand "sgtu"
5351 (set (match_operand:QI 0 "register_operand" "")
5352 (gtu:QI (cc0) (const_int 0)))]
5354 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5357 [(set (match_operand:QI 0 "register_operand" "=q")
5358 (gtu:QI (cc0) (const_int 0)))]
5360 "* return \"seta %0\"; ")
5362 (define_expand "slt"
5364 (set (match_operand:QI 0 "register_operand" "")
5365 (lt:QI (cc0) (const_int 0)))]
5367 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5370 [(set (match_operand:QI 0 "register_operand" "=q")
5371 (lt:QI (cc0) (const_int 0)))]
5375 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5376 && ! (cc_prev_status.flags & CC_FCOMI))
5377 return AS1 (sete,%0);
5379 OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\");
5382 (define_expand "sltu"
5384 (set (match_operand:QI 0 "register_operand" "")
5385 (ltu:QI (cc0) (const_int 0)))]
5387 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5390 [(set (match_operand:QI 0 "register_operand" "=q")
5391 (ltu:QI (cc0) (const_int 0)))]
5393 "* return \"setb %0\"; ")
5395 (define_expand "sge"
5397 (set (match_operand:QI 0 "register_operand" "")
5398 (ge:QI (cc0) (const_int 0)))]
5400 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5403 [(set (match_operand:QI 0 "register_operand" "=q")
5404 (ge:QI (cc0) (const_int 0)))]
5408 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5409 && ! (cc_prev_status.flags & CC_FCOMI))
5410 return AS1 (sete,%0);
5412 OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\");
5415 (define_expand "sgeu"
5417 (set (match_operand:QI 0 "register_operand" "")
5418 (geu:QI (cc0) (const_int 0)))]
5420 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5423 [(set (match_operand:QI 0 "register_operand" "=q")
5424 (geu:QI (cc0) (const_int 0)))]
5426 "* return \"setae %0\"; ")
5428 (define_expand "sle"
5430 (set (match_operand:QI 0 "register_operand" "")
5431 (le:QI (cc0) (const_int 0)))]
5433 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5436 [(set (match_operand:QI 0 "register_operand" "=q")
5437 (le:QI (cc0) (const_int 0)))]
5441 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5442 && ! (cc_prev_status.flags & CC_FCOMI))
5443 return AS1 (setb,%0);
5445 OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR);
5448 (define_expand "sleu"
5450 (set (match_operand:QI 0 "register_operand" "")
5451 (leu:QI (cc0) (const_int 0)))]
5453 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5456 [(set (match_operand:QI 0 "register_operand" "=q")
5457 (leu:QI (cc0) (const_int 0)))]
5459 "* return \"setbe %0\"; ")
5461 ;; Basic conditional jump instructions.
5462 ;; We ignore the overflow flag for signed branch instructions.
5464 ;; For all bCOND expanders, also expand the compare or test insn that
5465 ;; generates cc0. Generate an equality comparison if `beq' or
`bne'.
5467 (define_expand "beq"
5470 (if_then_else (eq (cc0)
5472 (label_ref (match_operand 0 "" ""))
5478 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5479 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5481 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5486 (if_then_else (eq (cc0)
5488 (label_ref (match_operand 0 "" ""))
5493 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5496 if (cc_prev_status.flags & CC_TEST_AX)
5498 operands[1] = gen_rtx_REG (SImode, 0);
5499 operands[2] = GEN_INT (0x4000);
5500 output_asm_insn (AS2 (testl,%2,%1), operands);
5501 return AS1 (jne,%l0);
5507 (define_expand "bne"
5510 (if_then_else (ne (cc0)
5512 (label_ref (match_operand 0 "" ""))
5518 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5519 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5521 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5526 (if_then_else (ne (cc0)
5528 (label_ref (match_operand 0 "" ""))
5533 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5536 if (cc_prev_status.flags & CC_TEST_AX)
5538 operands[1] = gen_rtx_REG (SImode, 0);
5539 operands[2] = GEN_INT (0x4000);
5540 output_asm_insn (AS2 (testl,%2,%1), operands);
5541 return AS1 (je,%l0);
5547 (define_expand "bgt"
5550 (if_then_else (gt (cc0)
5552 (label_ref (match_operand 0 "" ""))
5555 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5559 (if_then_else (gt (cc0)
5561 (label_ref (match_operand 0 "" ""))
5566 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5567 && ! (cc_prev_status.flags & CC_FCOMI))
5568 return AS1 (je,%l0);
5570 if (cc_prev_status.flags & CC_TEST_AX)
5572 operands[1] = gen_rtx_REG (SImode, 0);
5573 operands[2] = GEN_INT (0x4100);
5574 output_asm_insn (AS2 (testl,%2,%1), operands);
5575 return AS1 (je,%l0);
5577 OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
5580 (define_expand "bgtu"
5583 (if_then_else (gtu (cc0)
5585 (label_ref (match_operand 0 "" ""))
5588 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5592 (if_then_else (gtu (cc0)
5594 (label_ref (match_operand 0 "" ""))
5599 (define_expand "blt"
5602 (if_then_else (lt (cc0)
5604 (label_ref (match_operand 0 "" ""))
5607 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5611 (if_then_else (lt (cc0)
5613 (label_ref (match_operand 0 "" ""))
5618 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5619 && ! (cc_prev_status.flags & CC_FCOMI))
5620 return AS1 (je,%l0);
5622 if (cc_prev_status.flags & CC_TEST_AX)
5624 operands[1] = gen_rtx_REG (SImode, 0);
5625 operands[2] = GEN_INT (0x100);
5626 output_asm_insn (AS2 (testl,%2,%1), operands);
5627 return AS1 (jne,%l0);
5629 OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
5632 (define_expand "bltu"
5635 (if_then_else (ltu (cc0)
5637 (label_ref (match_operand 0 "" ""))
5640 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5644 (if_then_else (ltu (cc0)
5646 (label_ref (match_operand 0 "" ""))
5651 (define_expand "bge"
5654 (if_then_else (ge (cc0)
5656 (label_ref (match_operand 0 "" ""))
5659 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5663 (if_then_else (ge (cc0)
5665 (label_ref (match_operand 0 "" ""))
5670 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5671 && ! (cc_prev_status.flags & CC_FCOMI))
5672 return AS1 (je,%l0);
5673 if (cc_prev_status.flags & CC_TEST_AX)
5675 operands[1] = gen_rtx_REG (SImode, 0);
5676 operands[2] = GEN_INT (0x100);
5677 output_asm_insn (AS2 (testl,%2,%1), operands);
5678 return AS1 (je,%l0);
5680 OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
5683 (define_expand "bgeu"
5686 (if_then_else (geu (cc0)
5688 (label_ref (match_operand 0 "" ""))
5691 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5695 (if_then_else (geu (cc0)
5697 (label_ref (match_operand 0 "" ""))
5702 (define_expand "ble"
5705 (if_then_else (le (cc0)
5707 (label_ref (match_operand 0 "" ""))
5710 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5714 (if_then_else (le (cc0)
5716 (label_ref (match_operand 0 "" ""))
5721 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5722 && ! (cc_prev_status.flags & CC_FCOMI))
5723 return AS1 (jb,%l0);
5724 if (cc_prev_status.flags & CC_TEST_AX)
5726 operands[1] = gen_rtx_REG (SImode, 0);
5727 operands[2] = GEN_INT (0x4100);
5728 output_asm_insn (AS2 (testl,%2,%1), operands);
5729 return AS1 (jne,%l0);
5732 OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
5735 (define_expand "bleu"
5738 (if_then_else (leu (cc0)
5740 (label_ref (match_operand 0 "" ""))
5743 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5747 (if_then_else (leu (cc0)
5749 (label_ref (match_operand 0 "" ""))
5754 ;; Negated conditional jump instructions.
5758 (if_then_else (eq (cc0)
5761 (label_ref (match_operand 0 "" ""))))]
5765 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5768 if (cc_prev_status.flags & CC_TEST_AX)
5770 operands[1] = gen_rtx_REG (SImode, 0);
5771 operands[2] = GEN_INT (0x4000);
5772 output_asm_insn (AS2 (testl,%2,%1), operands);
5773 return AS1 (je,%l0);
5780 (if_then_else (ne (cc0)
5783 (label_ref (match_operand 0 "" ""))))]
5787 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5790 if (cc_prev_status.flags & CC_TEST_AX)
5792 operands[1] = gen_rtx_REG (SImode, 0);
5793 operands[2] = GEN_INT (0x4000);
5794 output_asm_insn (AS2 (testl,%2,%1), operands);
5795 return AS1 (jne,%l0);
5802 (if_then_else (gt (cc0)
5805 (label_ref (match_operand 0 "" ""))))]
5809 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5810 && ! (cc_prev_status.flags & CC_FCOMI))
5811 return AS1 (jne,%l0);
5812 if (cc_prev_status.flags & CC_TEST_AX)
5814 operands[1] = gen_rtx_REG (SImode, 0);
5815 operands[2] = GEN_INT (0x4100);
5816 output_asm_insn (AS2 (testl,%2,%1), operands);
5817 return AS1 (jne,%l0);
5819 OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
5824 (if_then_else (gtu (cc0)
5827 (label_ref (match_operand 0 "" ""))))]
5833 (if_then_else (lt (cc0)
5836 (label_ref (match_operand 0 "" ""))))]
5840 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5841 && ! (cc_prev_status.flags & CC_FCOMI))
5842 return AS1 (jne,%l0);
5843 if (cc_prev_status.flags & CC_TEST_AX)
5845 operands[1] = gen_rtx_REG (SImode, 0);
5846 operands[2] = GEN_INT (0x100);
5847 output_asm_insn (AS2 (testl,%2,%1), operands);
5848 return AS1 (je,%l0);
5851 OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
5856 (if_then_else (ltu (cc0)
5859 (label_ref (match_operand 0 "" ""))))]
5865 (if_then_else (ge (cc0)
5868 (label_ref (match_operand 0 "" ""))))]
5872 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5873 && ! (cc_prev_status.flags & CC_FCOMI))
5874 return AS1 (jne,%l0);
5875 if (cc_prev_status.flags & CC_TEST_AX)
5877 operands[1] = gen_rtx_REG (SImode, 0);
5878 operands[2] = GEN_INT (0x100);
5879 output_asm_insn (AS2 (testl,%2,%1), operands);
5880 return AS1 (jne,%l0);
5882 OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
5887 (if_then_else (geu (cc0)
5890 (label_ref (match_operand 0 "" ""))))]
5896 (if_then_else (le (cc0)
5899 (label_ref (match_operand 0 "" ""))))]
5903 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5904 && ! (cc_prev_status.flags & CC_FCOMI))
5905 return AS1 (jae,%l0);
5907 if (cc_prev_status.flags & CC_TEST_AX)
5909 operands[1] = gen_rtx_REG (SImode, 0);
5910 operands[2] = GEN_INT (0x4100);
5911 output_asm_insn (AS2 (testl,%2,%1), operands);
5912 return AS1 (je,%l0);
5914 OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
5919 (if_then_else (leu (cc0)
5922 (label_ref (match_operand 0 "" ""))))]
5926 ;; Unconditional and other jump instructions
5930 (label_ref (match_operand 0 "" "")))]
5934 (define_insn "indirect_jump"
5935 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
5941 return AS1 (jmp,%*%0);
5944 ;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
5945 ;; if S does not change i
5947 (define_expand "decrement_and_branch_until_zero"
5948 [(parallel [(set (pc)
5949 (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "")
5952 (label_ref (match_operand 1 "" ""))
5955 (plus:SI (match_dup 0)
5962 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
5963 [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
5964 (match_operand:SI 2 "general_operand" "rmi,ri"))
5966 (label_ref (match_operand 3 "" ""))
5969 (plus:SI (match_dup 1)
5975 if (operands[2] == constm1_rtx)
5976 output_asm_insn (AS1 (dec%L1,%1), operands);
5978 else if (operands[2] == const1_rtx)
5979 output_asm_insn (AS1 (inc%L1,%1), operands);
5982 output_asm_insn (AS2 (add%L1,%2,%1), operands);
5984 return AS1 (%J0,%l3);
5989 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
5990 [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
5991 (match_operand:SI 2 "general_operand" "rmi,ri"))
5993 (label_ref (match_operand 3 "" ""))
5996 (minus:SI (match_dup 1)
6002 if (operands[2] == const1_rtx)
6003 output_asm_insn (AS1 (dec%L1,%1), operands);
6005 else if (operands[1] == constm1_rtx)
6006 output_asm_insn (AS1 (inc%L1,%1), operands);
6009 output_asm_insn (AS2 (sub%L1,%2,%1), operands);
6011 return AS1 (%J0,%l3);
6016 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6018 (label_ref (match_operand 1 "" ""))
6021 (plus:SI (match_dup 0)
6027 operands[2] = const1_rtx;
6028 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6034 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6036 (label_ref (match_operand 1 "" ""))
6039 (plus:SI (match_dup 0)
6045 operands[2] = const1_rtx;
6046 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6052 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6054 (label_ref (match_operand 1 "" ""))
6057 (plus:SI (match_dup 0)
6063 output_asm_insn (AS1 (dec%L0,%0), operands);
6069 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6071 (label_ref (match_operand 1 "" ""))
6074 (plus:SI (match_dup 0)
6080 output_asm_insn (AS1 (dec%L0,%0), operands);
6086 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6088 (label_ref (match_operand 1 "" ""))
6091 (plus:SI (match_dup 0)
6097 output_asm_insn (AS1 (inc%L0,%0), operands);
6103 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6105 (label_ref (match_operand 1 "" ""))
6108 (plus:SI (match_dup 0)
6114 output_asm_insn (AS1 (inc%L0,%0), operands);
6118 ;; Implement switch statements when generating PIC code. Switches are
6119 ;; implemented by `tablejump' when not using -fpic.
6121 ;; Emit code here to do the range checking and make the index zero based.
6123 (define_expand "casesi"
6125 (match_operand:SI
0 "general_operand" ""))
6127 (minus:SI (match_dup
5)
6128 (match_operand:SI
1 "general_operand" "")))
6130 (compare:CC (match_dup
6)
6131 (match_operand:SI
2 "general_operand" "")))
6133 (if_then_else (gtu (cc0)
6135 (label_ref (match_operand
4 "" ""))
6139 (minus:SI (reg:SI
3)
6140 (mem:SI (plus:SI (mult:SI (match_dup
6)
6142 (label_ref (match_operand
3 "" ""))))))
6143 (clobber (match_scratch:SI
7 ""))])]
6147 operands[
5] = gen_reg_rtx (SImode);
6148 operands[
6] = gen_reg_rtx (SImode);
6149 current_function_uses_pic_offset_table =
1;
6152 ;; Implement a casesi insn.
6154 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
6157 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
6159 ;;
1. An expression involving an external reference may only use the
6160 ;; addition operator, and only with an assembly-time constant.
6161 ;; The example above satisfies this because ".-.L2" is a constant.
6163 ;;
2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
6164 ;; given the value of "GOT - .", where GOT is the actual address of
6165 ;; the Global Offset Table. Therefore, the .long above actually
6166 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
6167 ;; expression "GOT - .L2" by itself would generate an error from as(
1).
6169 ;; The pattern below emits code that looks like this:
6172 ;; subl TABLE@GOTOFF(%ebx,index,
4),reg
6175 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
6176 ;; the addr_diff_vec is known to be part of this module.
6178 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
6179 ;; evaluates to just ".L2".
6183 (minus:SI (reg:SI
3)
6185 (mult:SI (match_operand:SI
0 "register_operand" "r")
6187 (label_ref (match_operand
1 "" ""))))))
6188 (clobber (match_scratch:SI
2 "=&r"))]
6194 xops[
0] = operands[
0];
6195 xops[
1] = operands[
1];
6196 xops[
2] = operands[
2];
6197 xops[
3] = pic_offset_table_rtx;
6199 output_asm_insn (AS2 (mov%L2,%
3,%
2), xops);
6200 output_asm_insn (
\"sub%L2 %l1@GOTOFF(%
3,%
0,
4),%
2\", xops);
6201 output_asm_insn (AS1 (jmp,%*%
2), xops);
6202 ASM_OUTPUT_ALIGN (asm_out_file, i386_align_jumps);
6206 (define_insn "tablejump"
6207 [(set (pc) (match_operand:SI
0 "nonimmediate_operand" "rm"))
6208 (use (label_ref (match_operand
1 "" "")))]
6214 return AS1 (jmp,%*%
0);
6219 ;; If generating PIC code, the predicate indirect_operand will fail
6220 ;; for operands[
0] containing symbolic references on all of the named
6221 ;; call* patterns. Each named pattern is followed by an unnamed pattern
6222 ;; that matches any call to a symbolic CONST (ie, a symbol_ref). The
6223 ;; unnamed patterns are only used while generating PIC code, because
6224 ;; otherwise the named patterns match.
6226 ;; Call subroutine returning no value.
6228 (define_expand "call_pop"
6229 [(parallel [(call (match_operand:QI
0 "indirect_operand" "")
6230 (match_operand:SI
1 "general_operand" ""))
6233 (match_operand:SI
3 "immediate_operand" "")))])]
6240 current_function_uses_pic_offset_table =
1;
6242 /* With half-pic, force the address into a register. */
6243 addr = XEXP (operands[
0],
0);
6244 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6245 XEXP (operands[
0],
0) = force_reg (Pmode, addr);
6247 if (! expander_call_insn_operand (operands[
0], QImode))
6249 = change_address (operands[
0], VOIDmode,
6250 copy_to_mode_reg (Pmode, XEXP (operands[
0],
0)));
6254 [(call (match_operand:QI
0 "call_insn_operand" "m")
6255 (match_operand:SI
1 "general_operand" "g"))
6256 (set (reg:SI
7) (plus:SI (reg:SI
7)
6257 (match_operand:SI
3 "immediate_operand" "i")))]
6261 if (GET_CODE (operands[
0]) == MEM
6262 && ! CONSTANT_ADDRESS_P (XEXP (operands[
0],
0)))
6264 operands[
0] = XEXP (operands[
0],
0);
6265 return AS1 (call,%*%
0);
6268 return AS1 (call,%P0);
6272 [(call (mem:QI (match_operand:SI
0 "symbolic_operand" ""))
6273 (match_operand:SI
1 "general_operand" "g"))
6274 (set (reg:SI
7) (plus:SI (reg:SI
7)
6275 (match_operand:SI
3 "immediate_operand" "i")))]
6279 (define_expand "call"
6280 [(call (match_operand:QI
0 "indirect_operand" "")
6281 (match_operand:SI
1 "general_operand" ""))]
6282 ;; Operand
1 not used on the i386.
6289 current_function_uses_pic_offset_table =
1;
6291 /* With half-pic, force the address into a register. */
6292 addr = XEXP (operands[
0],
0);
6293 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6294 XEXP (operands[
0],
0) = force_reg (Pmode, addr);
6296 if (! expander_call_insn_operand (operands[
0], QImode))
6298 = change_address (operands[
0], VOIDmode,
6299 copy_to_mode_reg (Pmode, XEXP (operands[
0],
0)));
6303 [(call (match_operand:QI
0 "call_insn_operand" "m")
6304 (match_operand:SI
1 "general_operand" "g"))]
6305 ;; Operand
1 not used on the i386.
6309 if (GET_CODE (operands[
0]) == MEM
6310 && ! CONSTANT_ADDRESS_P (XEXP (operands[
0],
0)))
6312 operands[
0] = XEXP (operands[
0],
0);
6313 return AS1 (call,%*%
0);
6316 return AS1 (call,%P0);
6320 [(call (mem:QI (match_operand:SI
0 "symbolic_operand" ""))
6321 (match_operand:SI
1 "general_operand" "g"))]
6322 ;; Operand
1 not used on the i386.
6326 ;; Call subroutine, returning value in operand
0
6327 ;; (which must be a hard register).
6329 (define_expand "call_value_pop"
6330 [(parallel [(set (match_operand
0 "" "")
6331 (call (match_operand:QI
1 "indirect_operand" "")
6332 (match_operand:SI
2 "general_operand" "")))
6335 (match_operand:SI
4 "immediate_operand" "")))])]
6342 current_function_uses_pic_offset_table =
1;
6344 /* With half-pic, force the address into a register. */
6345 addr = XEXP (operands[
1],
0);
6346 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6347 XEXP (operands[
1],
0) = force_reg (Pmode, addr);
6349 if (! expander_call_insn_operand (operands[
1], QImode))
6351 = change_address (operands[
1], VOIDmode,
6352 copy_to_mode_reg (Pmode, XEXP (operands[
1],
0)));
6356 [(set (match_operand
0 "" "=rf")
6357 (call (match_operand:QI
1 "call_insn_operand" "m")
6358 (match_operand:SI
2 "general_operand" "g")))
6359 (set (reg:SI
7) (plus:SI (reg:SI
7)
6360 (match_operand:SI
4 "immediate_operand" "i")))]
6364 if (GET_CODE (operands[
1]) == MEM
6365 && ! CONSTANT_ADDRESS_P (XEXP (operands[
1],
0)))
6367 operands[
1] = XEXP (operands[
1],
0);
6368 output_asm_insn (AS1 (call,%*%
1), operands);
6371 output_asm_insn (AS1 (call,%P1), operands);
6377 [(set (match_operand
0 "" "=rf")
6378 (call (mem:QI (match_operand:SI
1 "symbolic_operand" ""))
6379 (match_operand:SI
2 "general_operand" "g")))
6380 (set (reg:SI
7) (plus:SI (reg:SI
7)
6381 (match_operand:SI
4 "immediate_operand" "i")))]
6385 (define_expand "call_value"
6386 [(set (match_operand
0 "" "")
6387 (call (match_operand:QI
1 "indirect_operand" "")
6388 (match_operand:SI
2 "general_operand" "")))]
6389 ;; Operand
2 not used on the i386.
6396 current_function_uses_pic_offset_table =
1;
6398 /* With half-pic, force the address into a register. */
6399 addr = XEXP (operands[
1],
0);
6400 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6401 XEXP (operands[
1],
0) = force_reg (Pmode, addr);
6403 if (! expander_call_insn_operand (operands[
1], QImode))
6405 = change_address (operands[
1], VOIDmode,
6406 copy_to_mode_reg (Pmode, XEXP (operands[
1],
0)));
6410 [(set (match_operand
0 "" "=rf")
6411 (call (match_operand:QI
1 "call_insn_operand" "m")
6412 (match_operand:SI
2 "general_operand" "g")))]
6413 ;; Operand
2 not used on the i386.
6417 if (GET_CODE (operands[
1]) == MEM
6418 && ! CONSTANT_ADDRESS_P (XEXP (operands[
1],
0)))
6420 operands[
1] = XEXP (operands[
1],
0);
6421 output_asm_insn (AS1 (call,%*%
1), operands);
6424 output_asm_insn (AS1 (call,%P1), operands);
6430 [(set (match_operand
0 "" "=rf")
6431 (call (mem:QI (match_operand:SI
1 "symbolic_operand" ""))
6432 (match_operand:SI
2 "general_operand" "g")))]
6433 ;; Operand
2 not used on the i386.
6437 ;; Call subroutine returning any type.
6439 (define_expand "untyped_call"
6440 [(parallel [(call (match_operand
0 "" "")
6442 (match_operand
1 "" "")
6443 (match_operand
2 "" "")])]
6449 /* In order to give reg-stack an easier job in validating two
6450 coprocessor registers as containing a possible return value,
6451 simply pretend the untyped call returns a complex long double
6454 emit_call_insn (TARGET_80387
6455 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
6456 operands[
0], const0_rtx)
6457 : gen_call (operands[
0], const0_rtx));
6459 for (i =
0; i < XVECLEN (operands[
2],
0); i++)
6461 rtx set = XVECEXP (operands[
2],
0, i);
6462 emit_move_insn (SET_DEST (set), SET_SRC (set));
6465 /* The optimizer does not know that the call sets the function value
6466 registers we stored in the result block. We avoid problems by
6467 claiming that all hard registers are used and clobbered at this
6469 emit_insn (gen_blockage ());
6474 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6475 ;; all of memory. This blocks insns from being moved across this point.
6477 (define_insn "blockage"
6478 [(unspec_volatile [(const_int
0)]
0)]
6482 ;; Insn emitted into the body of a function to return from a function.
6483 ;; This is only done if the function's epilogue is known to be simple.
6484 ;; See comments for simple_386_epilogue in i386.c.
6486 (define_expand "return"
6488 "ix86_can_use_return_insn_p ()"
6491 (define_insn "return_internal"
6496 (define_insn "return_pop_internal"
6498 (use (match_operand:SI
0 "const_int_operand" ""))]
6507 (define_expand "prologue"
6512 ix86_expand_prologue ();
6516 ;; The use of UNSPEC here is currently not necessary - a simple SET of ebp
6517 ;; to itself would be enough. But this way we are safe even if some optimizer
6518 ;; becomes too clever in the future.
6519 (define_insn "prologue_set_stack_ptr"
6521 (minus:SI (reg:SI
7) (match_operand:SI
0 "immediate_operand" "i")))
6522 (set (reg:SI
6) (unspec:SI [(reg:SI
6)]
4))]
6528 xops[
0] = operands[
0];
6529 xops[
1] = stack_pointer_rtx;
6530 output_asm_insn (AS2 (sub%L1,%
0,%
1), xops);
6534 (define_insn "prologue_set_got"
6535 [(set (match_operand:SI
0 "" "")
6537 [(plus:SI (match_dup
0)
6538 (plus:SI (match_operand:SI
1 "symbolic_operand" "")
6539 (minus:SI (pc) (match_operand
2 "" ""))))]
1))]
6545 if (TARGET_DEEP_BRANCH_PREDICTION)
6547 sprintf (buffer,
\"addl %s,%%
0\", XSTR (operands[
1],
0));
6548 output_asm_insn (buffer, operands);
6552 sprintf (buffer,
\"addl %s+[.-%%X2],%%
0\", XSTR (operands[
1],
0));
6553 output_asm_insn (buffer, operands);
6558 (define_insn "prologue_get_pc"
6559 [(set (match_operand:SI
0 "" "")
6560 (unspec_volatile [(plus:SI (pc) (match_operand
1 "" ""))]
2))]
6566 output_asm_insn (AS1 (call,%X1), operands);
6567 if (! TARGET_DEEP_BRANCH_PREDICTION)
6569 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file,
\"L
\", CODE_LABEL_NUMBER (operands[
1]));
6574 (define_insn "prologue_get_pc_and_set_got"
6575 [(unspec_volatile [(match_operand:SI
0 "" "")]
3)]
6579 operands[
1] = gen_label_rtx ();
6580 output_asm_insn (AS1 (call,%X1), operands);
6581 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file,
\"L
\",
6582 CODE_LABEL_NUMBER (operands[
1]));
6583 output_asm_insn (AS1 (pop%L0,%
0), operands);
6584 output_asm_insn (
\"addl $_GLOBAL_OFFSET_TABLE_+[.-%X1],%
0\", operands);
6588 (define_expand "epilogue"
6593 ix86_expand_epilogue ();
6597 (define_insn "epilogue_set_stack_ptr"
6598 [(set (reg:SI
7) (reg:SI
6))
6599 (clobber (reg:SI
6))]
6605 xops[
0] = frame_pointer_rtx;
6606 xops[
1] = stack_pointer_rtx;
6607 output_asm_insn (AS2 (mov%L0,%
0,%
1), xops);
6611 (define_insn "leave"
6613 (clobber (reg:SI
6))
6614 (clobber (reg:SI
7))]
6619 [(set (match_operand:SI
0 "register_operand" "r")
6620 (mem:SI (reg:SI
7)))
6621 (set (reg:SI
7) (plus:SI (reg:SI
7) (const_int
4)))]
6625 output_asm_insn (AS1 (pop%L0,%P0), operands);
6629 (define_expand "movstrsi"
6630 [(parallel [(set (match_operand:BLK
0 "memory_operand" "")
6631 (match_operand:BLK
1 "memory_operand" ""))
6632 (use (match_operand:SI
2 "const_int_operand" ""))
6633 (use (match_operand:SI
3 "const_int_operand" ""))
6634 (clobber (match_scratch:SI
4 ""))
6635 (clobber (match_dup
5))
6636 (clobber (match_dup
6))])]
6642 if (GET_CODE (operands[
2]) != CONST_INT)
6645 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[
0],
0));
6646 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[
1],
0));
6648 operands[
5] = addr0;
6649 operands[
6] = addr1;
6651 operands[
0] = change_address (operands[
0], VOIDmode, addr0);
6652 operands[
1] = change_address (operands[
1], VOIDmode, addr1);
6655 ;; It might seem that operands
0 &
1 could use predicate register_operand.
6656 ;; But strength reduction might offset the MEM expression. So we let
6657 ;; reload put the address into %edi & %esi.
6660 [(set (mem:BLK (match_operand:SI
0 "address_operand" "D"))
6661 (mem:BLK (match_operand:SI
1 "address_operand" "S")))
6662 (use (match_operand:SI
2 "const_int_operand" "n"))
6663 (use (match_operand:SI
3 "immediate_operand" "i"))
6664 (clobber (match_scratch:SI
4 "=&c"))
6665 (clobber (match_dup
0))
6666 (clobber (match_dup
1))]
6672 output_asm_insn (
\"cld
\", operands);
6673 if (GET_CODE (operands[
2]) == CONST_INT)
6675 if (INTVAL (operands[
2]) & ~
0x03)
6677 xops[
0] = GEN_INT ((INTVAL (operands[
2]) >>
2) &
0x3fffffff);
6678 xops[
1] = operands[
4];
6680 output_asm_insn (AS2 (mov%L1,%
0,%
1), xops);
6682 output_asm_insn (
\"rep movsd
\", xops);
6684 output_asm_insn (
\"rep\;movsl
\", xops);
6687 if (INTVAL (operands[
2]) &
0x02)
6688 output_asm_insn (
\"movsw
\", operands);
6689 if (INTVAL (operands[
2]) &
0x01)
6690 output_asm_insn (
\"movsb
\", operands);
6697 (define_expand "clrstrsi"
6698 [(set (match_dup
3) (const_int
0))
6699 (parallel [(set (match_operand:BLK
0 "memory_operand" "")
6701 (use (match_operand:SI
1 "const_int_operand" ""))
6702 (use (match_operand:SI
2 "const_int_operand" ""))
6704 (clobber (match_scratch:SI
4 ""))
6705 (clobber (match_dup
5))])]
6711 if (GET_CODE (operands[
1]) != CONST_INT)
6714 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[
0],
0));
6716 operands[
3] = gen_reg_rtx (SImode);
6717 operands[
5] = addr0;
6719 operands[
0] = gen_rtx_MEM (BLKmode, addr0);
6722 ;; It might seem that operand
0 could use predicate register_operand.
6723 ;; But strength reduction might offset the MEM expression. So we let
6724 ;; reload put the address into %edi.
6727 [(set (mem:BLK (match_operand:SI
0 "address_operand" "D"))
6729 (use (match_operand:SI
1 "const_int_operand" "n"))
6730 (use (match_operand:SI
2 "immediate_operand" "i"))
6731 (use (match_operand:SI
3 "register_operand" "a"))
6732 (clobber (match_scratch:SI
4 "=&c"))
6733 (clobber (match_dup
0))]
6739 output_asm_insn (
\"cld
\", operands);
6740 if (GET_CODE (operands[
1]) == CONST_INT)
6742 if (INTVAL (operands[
1]) & ~
0x03)
6744 xops[
0] = GEN_INT ((INTVAL (operands[
1]) >>
2) &
0x3fffffff);
6745 xops[
1] = operands[
4];
6747 output_asm_insn (AS2 (mov%L1,%
0,%
1), xops);
6749 output_asm_insn (
\"rep stosd
\", xops);
6751 output_asm_insn (
\"rep\;stosl
\", xops);
6754 if (INTVAL (operands[
1]) &
0x02)
6755 output_asm_insn (
\"stosw
\", operands);
6756 if (INTVAL (operands[
1]) &
0x01)
6757 output_asm_insn (
\"stosb
\", operands);
6764 (define_expand "cmpstrsi"
6765 [(parallel [(set (match_operand:SI
0 "general_operand" "")
6766 (compare:SI (match_operand:BLK
1 "general_operand" "")
6767 (match_operand:BLK
2 "general_operand" "")))
6768 (use (match_operand:SI
3 "general_operand" ""))
6769 (use (match_operand:SI
4 "immediate_operand" ""))
6770 (clobber (match_dup
5))
6771 (clobber (match_dup
6))
6772 (clobber (match_dup
3))])]
6778 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[
1],
0));
6779 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[
2],
0));
6780 operands[
3] = copy_to_mode_reg (SImode, operands[
3]);
6782 operands[
5] = addr1;
6783 operands[
6] = addr2;
6785 operands[
1] = gen_rtx_MEM (BLKmode, addr1);
6786 operands[
2] = gen_rtx_MEM (BLKmode, addr2);
6790 ;; memcmp recognizers. The
`cmpsb' opcode does nothing if the count is
6791 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
6793 ;; It might seem that operands 0 & 1 could use predicate register_operand.
6794 ;; But strength reduction might offset the MEM expression. So we let
6795 ;; reload put the address into %edi & %esi.
6797 ;; ??? Most comparisons have a constant length, and it's therefore
6798 ;; possible to know that the length is non-zero, and to avoid the extra
6799 ;; code to handle zero-length compares.
6802 [(set (match_operand:SI 0 "register_operand" "=&r")
6803 (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
6804 (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
6805 (use (match_operand:SI 3 "register_operand" "c"))
6806 (use (match_operand:SI 4 "immediate_operand" "i"))
6807 (clobber (match_dup 1))
6808 (clobber (match_dup 2))
6809 (clobber (match_dup 3))]
6815 label = gen_label_rtx ();
6817 output_asm_insn (\"cld\", operands);
6818 output_asm_insn (AS2 (xor%L0,%0,%0), operands);
6819 output_asm_insn (\"repz\;cmps%B2\", operands);
6820 output_asm_insn (\"je %l0\", &label);
6822 xops[0] = operands[0];
6823 xops[1] = const1_rtx;
6824 output_asm_insn (AS2 (sbb%L0,%0,%0), xops);
6825 if (QI_REG_P (xops[0]))
6826 output_asm_insn (AS2 (or%B0,%1,%b0), xops);
6828 output_asm_insn (AS2 (or%L0,%1,%0), xops);
6830 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
6836 (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
6837 (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
6838 (use (match_operand:SI 2 "register_operand" "c"))
6839 (use (match_operand:SI 3 "immediate_operand" "i"))
6840 (clobber (match_dup 0))
6841 (clobber (match_dup 1))
6842 (clobber (match_dup 2))]
6848 cc_status.flags |= CC_NOT_SIGNED;
6850 xops[0] = gen_rtx_REG (QImode, 0);
6851 xops[1] = CONST0_RTX (QImode);
6853 output_asm_insn (\"cld\", operands);
6854 output_asm_insn (AS2 (test%B0,%1,%0), xops);
6855 return \"repz\;cmps%B2\";
6859 ;; Note, you cannot optimize away the branch following the bsfl by assuming
6860 ;; that the destination is not modified if the input is 0, since not all
6861 ;; x86 implementations do this.
6863 (define_expand "ffssi2"
6864 [(set (match_operand:SI 0 "general_operand" "")
6865 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
6869 rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode);
6871 emit_insn (gen_ffssi_1 (temp, operands[1]));
6872 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0);
6873 emit_jump_insn (gen_bne (label));
6874 emit_move_insn (temp, constm1_rtx);
6876 temp = expand_binop (SImode, add_optab, temp, const1_rtx,
6877 operands[0], 0, OPTAB_WIDEN);
6879 if (temp != operands[0])
6880 emit_move_insn (operands[0], temp);
6884 (define_insn "ffssi_1"
6885 [(set (match_operand:SI 0 "register_operand" "=r")
6886 (unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
6888 "* return AS2 (bsf%L0,%1,%0);")
6890 (define_expand "ffshi2"
6891 [(set (match_operand:SI 0 "general_operand" "")
6892 (ffs:HI (match_operand:HI 1 "general_operand" "")))]
6896 rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode);
6898 emit_insn (gen_ffshi_1 (temp, operands[1]));
6899 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0);
6900 emit_jump_insn (gen_bne (label));
6901 emit_move_insn (temp, constm1_rtx);
6903 temp = expand_binop (HImode, add_optab, temp, const1_rtx,
6904 operands[0], 0, OPTAB_WIDEN);
6906 if (temp != operands[0])
6907 emit_move_insn (operands[0], temp);
6911 (define_insn "ffshi_1"
6912 [(set (match_operand:HI 0 "register_operand" "=r")
6913 (unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
6915 "* return AS2 (bsf%W0,%1,%0);")
6917 ;; These patterns match the binary 387 instructions for addM3, subM3,
6918 ;; mulM3 and divM3. There are three patterns for each of DFmode and
6919 ;; SFmode. The first is the normal insn, the second the same insn but
6920 ;; with one operand a conversion, and the third the same insn but with
6921 ;; the other operand a conversion. The conversion may be SFmode or
6922 ;; SImode if the target mode DFmode, but only SImode if the target mode
6926 [(set (match_operand:DF 0 "register_operand" "=f,f")
6927 (match_operator:DF 3 "binary_387_op"
6928 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
6929 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
6931 "* return output_387_binary_op (insn, operands);"
6933 (cond [(match_operand:DF 3 "is_mul" "")
6934 (const_string "fpmul")
6935 (match_operand:DF 3 "is_div" "")
6936 (const_string "fpdiv")
6938 (const_string "fpop")
6943 [(set (match_operand:DF 0 "register_operand" "=f")
6944 (match_operator:DF 3 "binary_387_op"
6945 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "rm"))
6946 (match_operand:DF 2 "register_operand" "0")]))]
6948 "* return output_387_binary_op (insn, operands);"
6950 (cond [(match_operand:DF 3 "is_mul" "")
6951 (const_string "fpmul")
6952 (match_operand:DF 3 "is_div" "")
6953 (const_string "fpdiv")
6955 (const_string "fpop")
6960 [(set (match_operand:XF 0 "register_operand" "=f,f")
6961 (match_operator:XF 3 "binary_387_op"
6962 [(match_operand:XF 1 "register_operand" "0,f")
6963 (match_operand:XF 2 "register_operand" "f,0")]))]
6965 "* return output_387_binary_op (insn, operands);"
6967 (cond [(match_operand:DF 3 "is_mul" "")
6968 (const_string "fpmul")
6969 (match_operand:DF 3 "is_div" "")
6970 (const_string "fpdiv")
6972 (const_string "fpop")
6977 [(set (match_operand:XF 0 "register_operand" "=f")
6978 (match_operator:XF 3 "binary_387_op"
6979 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "rm"))
6980 (match_operand:XF 2 "register_operand" "0")]))]
6982 "* return output_387_binary_op (insn, operands);"
6984 (cond [(match_operand:DF 3 "is_mul" "")
6985 (const_string "fpmul")
6986 (match_operand:DF 3 "is_div" "")
6987 (const_string "fpdiv")
6989 (const_string "fpop")
6994 [(set (match_operand:XF 0 "register_operand" "=f,f")
6995 (match_operator:XF 3 "binary_387_op"
6996 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
6997 (match_operand:XF 2 "register_operand" "0,f")]))]
6999 "* return output_387_binary_op (insn, operands);"
7001 (cond [(match_operand:DF 3 "is_mul" "")
7002 (const_string "fpmul")
7003 (match_operand:DF 3 "is_div" "")
7004 (const_string "fpdiv")
7006 (const_string "fpop")
7011 [(set (match_operand:XF 0 "register_operand" "=f")
7012 (match_operator:XF 3 "binary_387_op"
7013 [(match_operand:XF 1 "register_operand" "0")
7014 (float:XF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
7016 "* return output_387_binary_op (insn, operands);"
7018 (cond [(match_operand:DF 3 "is_mul" "")
7019 (const_string "fpmul")
7020 (match_operand:DF 3 "is_div" "")
7021 (const_string "fpdiv")
7023 (const_string "fpop")
7028 [(set (match_operand:XF 0 "register_operand" "=f,f")
7029 (match_operator:XF 3 "binary_387_op"
7030 [(match_operand:XF 1 "register_operand" "0,f")
7032 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7034 "* return output_387_binary_op (insn, operands);"
7036 (cond [(match_operand:DF 3 "is_mul" "")
7037 (const_string "fpmul")
7038 (match_operand:DF 3 "is_div" "")
7039 (const_string "fpdiv")
7041 (const_string "fpop")
7046 [(set (match_operand:DF 0 "register_operand" "=f,f")
7047 (match_operator:DF 3 "binary_387_op"
7048 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7049 (match_operand:DF 2 "register_operand" "0,f")]))]
7051 "* return output_387_binary_op (insn, operands);"
7053 (cond [(match_operand:DF 3 "is_mul" "")
7054 (const_string "fpmul")
7055 (match_operand:DF 3 "is_div" "")
7056 (const_string "fpdiv")
7058 (const_string "fpop")
7063 [(set (match_operand:DF 0 "register_operand" "=f")
7064 (match_operator:DF 3 "binary_387_op"
7065 [(match_operand:DF 1 "register_operand" "0")
7066 (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
7068 "* return output_387_binary_op (insn, operands);"
7070 (cond [(match_operand:DF 3 "is_mul" "")
7071 (const_string "fpmul")
7072 (match_operand:DF 3 "is_div" "")
7073 (const_string "fpdiv")
7075 (const_string "fpop")
7080 [(set (match_operand:DF 0 "register_operand" "=f,f")
7081 (match_operator:DF 3 "binary_387_op"
7082 [(match_operand:DF 1 "register_operand" "0,f")
7084 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7086 "* return output_387_binary_op (insn, operands);"
7088 (cond [(match_operand:DF 3 "is_mul" "")
7089 (const_string "fpmul")
7090 (match_operand:DF 3 "is_div" "")
7091 (const_string "fpdiv")
7093 (const_string "fpop")
7098 [(set (match_operand:SF 0 "register_operand" "=f,f")
7099 (match_operator:SF 3 "binary_387_op"
7100 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
7101 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
7103 "* return output_387_binary_op (insn, operands);"
7105 (cond [(match_operand:DF 3 "is_mul" "")
7106 (const_string "fpmul")
7107 (match_operand:DF 3 "is_div" "")
7108 (const_string "fpdiv")
7110 (const_string "fpop")
7115 [(set (match_operand:SF 0 "register_operand" "=f")
7116 (match_operator:SF 3 "binary_387_op"
7117 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "rm"))
7118 (match_operand:SF 2 "register_operand" "0")]))]
7120 "* return output_387_binary_op (insn, operands);"
7122 (cond [(match_operand:DF 3 "is_mul" "")
7123 (const_string "fpmul")
7124 (match_operand:DF 3 "is_div" "")
7125 (const_string "fpdiv")
7127 (const_string "fpop")
7132 [(set (match_operand:SF 0 "register_operand" "=f")
7133 (match_operator:SF 3 "binary_387_op"
7134 [(match_operand:SF 1 "register_operand" "0")
7135 (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
7137 "* return output_387_binary_op (insn, operands);"
7139 (cond [(match_operand:DF 3 "is_mul" "")
7140 (const_string "fpmul")
7141 (match_operand:DF 3 "is_div" "")
7142 (const_string "fpdiv")
7144 (const_string "fpop")
7148 (define_expand "strlensi"
7149 [(parallel [(set (match_dup 4)
7150 (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
7151 (match_operand:QI 2 "immediate_operand" "")
7152 (match_operand:SI 3 "immediate_operand" "")] 0))
7153 (clobber (match_dup 1))])
7155 (not:SI (match_dup 4)))
7156 (set (match_operand:SI 0 "register_operand" "")
7157 (plus:SI (match_dup 5)
7162 if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1)
7167 /* well it seems that some optimizer does not combine a call like
7168 foo(strlen(bar), strlen(bar));
7169 when the move and the subtraction is done here. It does calculate
7170 the length just once when these instructions are done inside of
7171 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
7172 often used and I use one fewer register for the lifetime of
7173 output_strlen_unroll() this is better. */
7174 scratch = gen_reg_rtx (SImode);
7175 address = force_reg (SImode, XEXP (operands[1], 0));
7177 /* move address to scratch-register
7178 this is done here because the i586 can do the following and
7179 in the same cycle with the following move. */
7180 if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4)
7181 emit_insn (gen_movsi (scratch, address));
7183 emit_insn (gen_movsi (operands[0], address));
7185 if(TARGET_USE_Q_REG)
7186 emit_insn (gen_strlensi_unroll5 (operands[0],
7191 emit_insn (gen_strlensi_unroll4 (operands[0],
7196 /* gen_strlensi_unroll[45] returns the address of the zero
7197 at the end of the string, like memchr(), so compute the
7198 length by subtracting the startaddress. */
7199 emit_insn (gen_subsi3 (operands[0], operands[0], address));
7203 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7204 operands[4] = gen_reg_rtx (SImode);
7205 operands[5] = gen_reg_rtx (SImode);
7208 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7209 ;; But strength reduction might offset the MEM expression. So we let
7210 ;; reload put the address into %edi.
7213 [(set (match_operand:SI 0 "register_operand" "=&c")
7214 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
7215 (match_operand:QI 2 "immediate_operand" "a")
7216 (match_operand:SI 3 "immediate_operand" "i")] 0))
7217 (clobber (match_dup 1))]
7223 xops[0] = operands[0];
7224 xops[1] = constm1_rtx;
7225 output_asm_insn (\"cld\", operands);
7226 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
7227 return \"repnz\;scas%B2\";
7230 /* Conditional move define_insns. */
7232 ;; These are all disabled, because they are buggy. They are all susceptible
7233 ;; to problems with input reloads clobbering the condition code registers.
7234 ;; It appears the only safe way to write a integer/FP conditional move pattern
7235 ;; is to write one which emits both the compare and the cmov, and which can be
7236 ;; split only after reload.
7238 (define_expand "movsicc"
7240 (parallel [(set (match_operand 0 "register_operand" "")
7241 (if_then_else:SI (match_operand 1 "comparison_operator" "")
7242 (match_operand:SI 2 "general_operand" "")
7243 (match_operand:SI 3 "general_operand" "")))
7244 (clobber (match_scratch:SI 4 "=&r"))])]
7248 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7251 (define_expand "movhicc"
7253 (parallel [(set (match_operand 0 "register_operand" "")
7254 (if_then_else:HI (match_operand 1 "comparison_operator" "")
7255 (match_operand:HI 2 "general_operand" "")
7256 (match_operand:HI 3 "general_operand" "")))
7257 (clobber (match_scratch:SI 4 "=&r"))])]
7261 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7264 (define_insn "movsicc_1"
7265 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,&r,rm")
7266 (if_then_else:SI (match_operator 1 "comparison_operator"
7267 [(cc0) (const_int 0)])
7268 (match_operand:SI 2 "general_operand" "rm,0,rm,g")
7269 (match_operand:SI 3 "general_operand" "0,rm,rm,g")))
7270 (clobber (match_scratch:SI 4 "X,X,X,=&r"))]
7274 if (which_alternative == 0)
7276 /* r <- cond ? arg : r */
7277 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7279 else if (which_alternative == 1)
7281 /* r <- cond ? r : arg */
7282 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7284 else if (which_alternative == 2)
7286 /* r <- cond ? arg1 : arg2 */
7287 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7288 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7290 else if (which_alternative == 3)
7292 /* r <- cond ? arg1 : arg2 */
7295 xops[0] = gen_label_rtx ();
7296 xops[1] = gen_label_rtx ();
7297 xops[2] = operands[1];
7299 output_asm_insn (\"j%c2 %l0\", xops);
7300 if (! rtx_equal_p (operands[0], operands[2]))
7301 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[2]) == MEM)
7303 output_asm_insn (AS2 (mov%z2,%2,%4), operands);
7304 output_asm_insn (AS2 (mov%z2,%4,%0), operands);
7307 output_asm_insn (AS2 (mov%z0,%2,%0), operands);
7308 output_asm_insn (\"jmp %l1\", xops);
7309 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
7310 if (! rtx_equal_p (operands[0], operands[3]))
7312 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[3]) == MEM)
7314 output_asm_insn (AS2 (mov%z3,%3,%4), operands);
7315 output_asm_insn (AS2 (mov%z3,%4,%0), operands);
7318 output_asm_insn (AS2 (mov%z0,%3,%0), operands);
7320 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
7325 (define_insn "movhicc_1"
7326 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,&r,rm")
7327 (if_then_else:HI (match_operator 1 "comparison_operator"
7328 [(cc0) (const_int 0)])
7329 (match_operand:HI 2 "general_operand" "rm,0,rm,g")
7330 (match_operand:HI 3 "general_operand" "0,rm,rm,g")))
7331 (clobber (match_scratch:SI 4 "X,X,X,=&r"))]
7335 if (which_alternative == 0)
7337 /* r <- cond ? arg : r */
7338 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7340 else if (which_alternative == 1)
7342 /* r <- cond ? r : arg */
7343 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7345 else if (which_alternative == 2)
7347 /* r <- cond ? arg1 : arg2 */
7348 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7349 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7351 else if (which_alternative == 3)
7353 /* r <- cond ? arg1 : arg2 */
7356 xops[0] = gen_label_rtx ();
7357 xops[1] = gen_label_rtx ();
7358 xops[2] = operands[1];
7360 output_asm_insn (\"j%c2 %l0\", xops);
7361 if (! rtx_equal_p (operands[0], operands[2]))
7362 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[2]) == MEM)
7364 output_asm_insn (AS2 (mov%z2,%2,%4), operands);
7365 output_asm_insn (AS2 (mov%z2,%4,%0), operands);
7368 output_asm_insn (AS2 (mov%z0,%2,%0), operands);
7369 output_asm_insn (\"jmp %l1\", xops);
7370 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
7371 if (! rtx_equal_p (operands[0], operands[3]))
7373 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[3]) == MEM)
7375 output_asm_insn (AS2 (mov%z3,%3,%4), operands);
7376 output_asm_insn (AS2 (mov%z3,%4,%0), operands);
7379 output_asm_insn (AS2 (mov%z0,%3,%0), operands);
7381 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
7385 ;; We need to disable the FP forms of these since they do not support
7386 ;; memory as written, but no input reloads are permitted for insns
7387 ;; that use cc0. Also, movxfcc is not present.
7389 (define_expand "movsfcc"
7391 (set (match_operand 0 "register_operand" "")
7392 (if_then_else:SF (match_operand 1 "comparison_operator" "")
7393 (match_operand:SF 2 "register_operand" "")
7394 (match_operand:SF 3 "register_operand" "")))]
7398 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7401 (define_expand "movdfcc"
7403 (set (match_operand 0 "register_operand" "t")
7404 (if_then_else:DF (match_operand 1 "comparison_operator" "")
7405 (match_operand:DF 2 "register_operand" "")
7406 (match_operand:DF 3 "register_operand" "")))]
7410 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7413 (define_expand "movxfcc"
7415 (set (match_operand 0 "register_operand" "")
7416 (if_then_else:XF (match_operand 1 "comparison_operator" "")
7417 (match_operand:XF 2 "register_operand" "")
7418 (match_operand:XF 3 "register_operand" "")))]
7422 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7425 (define_insn "movsfcc_1"
7426 [(set (match_operand:SF 0 "general_operand" "=f,f,&f")
7427 (if_then_else:SF (match_operator 1 "comparison_operator"
7428 [(cc0) (const_int 0)])
7429 (match_operand:SF 2 "register_operand" "0,f,f")
7430 (match_operand:SF 3 "register_operand" "f,0,f")))]
7434 switch (which_alternative)
7437 /* r <- cond ? arg : r */
7438 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7442 /* r <- cond ? r : arg */
7443 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7447 /* r <- cond ? r : arg */
7448 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7449 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7456 (define_insn "movdfcc_1"
7457 [(set (match_operand:DF 0 "general_operand" "=f,f,&f")
7458 (if_then_else:DF (match_operator 1 "comparison_operator"
7459 [(cc0) (const_int 0)])
7460 (match_operand:DF 2 "register_operand" "0,f,f")
7461 (match_operand:DF 3 "register_operand" "f,0,f")))]
7465 switch (which_alternative)
7468 /* r <- cond ? arg : r */
7469 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7473 /* r <- cond ? r : arg */
7474 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7478 /* r <- cond ? r : arg */
7479 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7480 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7487 (define_insn "strlensi_unroll"
7488 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
7489 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r"))
7490 (match_operand:SI 2 "immediate_operand" "i,i")] 0))
7491 (clobber (match_scratch:SI 3 "=&q,&r"))]
7493 "* return output_strlen_unroll (operands);")
7495 ;; the only difference between the following patterns is the register preference
7496 ;; on a pentium using a q-register saves one clock cycle per 4 characters
7498 (define_insn "strlensi_unroll4"
7499 [(set (match_operand:SI 0 "register_operand" "=r,r")
7500 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0"))
7501 (match_operand:SI 1 "immediate_operand" "i,i")
7502 (match_operand:SI 2 "register_operand" "+q,!r")] 0))
7503 (clobber (match_dup 2))]
7504 "(TARGET_USE_ANY_REG && optimize > 1)"
7505 "* return output_strlen_unroll (operands);")
7507 (define_insn "strlensi_unroll5"
7508 [(set (match_operand:SI 0 "register_operand" "=r")
7509 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0"))
7510 (match_operand:SI 1 "immediate_operand" "i")
7511 (match_operand:SI 2 "register_operand" "+q")] 0))
7512 (clobber (match_dup 2))]
7513 "(TARGET_USE_Q_REG && optimize > 1)"
7514 "* return output_strlen_unroll (operands);"
7517 (define_insn "allocate_stack_worker"
7518 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
7519 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
7520 (clobber (match_dup 0))]
7521 "TARGET_STACK_PROBE"
7522 "* return AS1(call,__alloca);")
7524 (define_expand "allocate_stack"
7525 [(set (match_operand:SI 0 "register_operand" "=r")
7526 (minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" "")))
7527 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))]
7528 "TARGET_STACK_PROBE"
7531 #ifdef CHECK_STACK_LIMIT
7532 if (GET_CODE (operands[1]) == CONST_INT
7533 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
7534 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
7538 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
7541 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
7545 (define_expand "nonlocal_goto_receiver"
7550 load_pic_register (1);