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.
67 ;; 6 This is the @GOT offset of a PIC address.
68 ;; 7 This is the @GOTOFF offset of a PIC address.
69 ;; 8 This is a reference to a symbol's @PLT address.
71 ;; This shadows the processor_type enumeration, so changes must be made
72 ;; to i386.h at the same time.
75 "integer,binary,memory,test,compare,fcompare,idiv,imul,lea,fld,fpop,fpdiv,fpmul"
76 (const_string "integer"))
78 (define_attr "memory" "none,load,store"
79 (cond [(eq_attr "type" "idiv,lea")
82 (eq_attr "type" "fld")
85 (eq_attr "type" "test")
86 (if_then_else (match_operand 0 "memory_operand" "")
88 (const_string "none"))
90 (eq_attr "type" "compare,fcompare")
91 (if_then_else (ior (match_operand 0 "memory_operand" "")
92 (match_operand 1 "memory_operand" ""))
94 (const_string "none"))
96 (and (eq_attr "type" "integer,memory,fpop")
97 (match_operand 0 "memory_operand" ""))
98 (const_string "store")
100 (and (eq_attr "type" "integer,memory,fpop")
101 (match_operand 1 "memory_operand" ""))
102 (const_string "load")
104 (and (eq_attr "type" "binary,imul,fpmul,fpdiv")
105 (ior (match_operand 1 "memory_operand" "")
106 (match_operand 2 "memory_operand" "")))
107 (const_string "load")]
109 (const_string "none")))
113 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
114 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
116 ; pentiumpro has a reservation station with 5 ports
117 ; port 0 has integer, float add, integer divide, float divide, float
118 ; multiply, and shifter units.
119 ; port 1 has integer, and jump units.
120 ; port 2 has the load address generation unit
121 ; ports 3 and 4 have the store address generation units
123 ; pentium has two integer pipelines, the main u pipe and the secondary v pipe.
124 ; and a float pipeline
128 (define_function_unit "fp" 1 0
129 (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "i386,i486"))
132 (define_function_unit "fp" 1 0
133 (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "pentium,pentiumpro"))
136 (define_function_unit "fp" 1 0
137 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentium"))
140 (define_function_unit "fp" 1 0
141 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentiumpro"))
144 (define_function_unit "fp" 1 0
145 (and (eq_attr "type" "idiv") (eq_attr "cpu" "pentiumpro"))
148 (define_function_unit "fp" 1 0
149 (and (eq_attr "type" "imul") (eq_attr "cpu" "pentiumpro"))
152 (define_function_unit "fp" 1 0
153 (eq_attr "type" "fpdiv")
156 (define_function_unit "fp" 1 0
157 (and (eq_attr "type" "fld") (eq_attr "cpu" "!pentiumpro,k6"))
160 ;; K6 FPU is not pipelined.
161 (define_function_unit "fp" 1 0
162 (and (eq_attr "type" "fpop,fpmul,fcompare") (eq_attr "cpu" "k6"))
165 ;; i386 and i486 have one integer unit, which need not be modeled
167 (define_function_unit "integer" 2 0
168 (and (eq_attr "type" "integer,binary,test,compare,lea") (eq_attr "cpu" "pentium,pentiumpro"))
171 (define_function_unit "integer" 2 0
172 (and (eq_attr "cpu" "k6")
173 (and (eq_attr "type" "integer,binary,test,compare")
174 (eq_attr "memory" "!load")))
177 ;; Internally, K6 converts REG OP MEM instructions into a load (2 cycles)
178 ;; and a register operation (1 cycle).
179 (define_function_unit "integer" 2 0
180 (and (eq_attr "cpu" "k6")
181 (and (eq_attr "type" "integer,binary,test,compare")
182 (eq_attr "memory" "load")))
185 ;; Multiplies use one of the integer units
186 (define_function_unit "integer" 2 0
187 (and (eq_attr "cpu" "pentium") (eq_attr "type" "imul"))
190 (define_function_unit "integer" 2 0
191 (and (eq_attr "cpu" "k6") (eq_attr "type" "imul"))
194 (define_function_unit "integer" 2 0
195 (and (eq_attr "cpu" "pentium") (eq_attr "type" "idiv"))
198 (define_function_unit "integer" 2 0
199 (and (eq_attr "cpu" "k6") (eq_attr "type" "idiv"))
202 ;; Pentium Pro and K6 have a separate load unit.
203 (define_function_unit "load" 1 0
204 (and (eq_attr "cpu" "pentiumpro") (eq_attr "memory" "load"))
207 (define_function_unit "load" 1 0
208 (and (eq_attr "cpu" "k6") (eq_attr "memory" "load"))
211 ;; Pentium Pro and K6 have a separate store unit.
212 (define_function_unit "store" 1 0
213 (and (eq_attr "cpu" "pentiumpro,k6") (eq_attr "memory" "store"))
216 ;; lea executes in the K6 store unit with 1 cycle latency
217 (define_function_unit "store" 1 0
218 (and (eq_attr "cpu" "k6") (eq_attr "type" "lea"))
222 ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
223 ;; But restricting MEM here would mean that gcc could not remove a redundant
224 ;; test in cases like "incl MEM / je TARGET".
226 ;; We don't want to allow a constant operand for test insns because
227 ;; (set (cc0) (const_int foo)) has no mode information. Such insns will
228 ;; be folded while optimizing anyway.
230 ;; All test insns have expanders that save the operands away without
231 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
232 ;; after the tstM or cmp) will actually emit the tstM or cmpM.
234 ;; Processor type -- this attribute must exactly match the processor_type
235 ;; enumeration in i386.h.
237 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6"
238 (const (symbol_ref "ix86_cpu")))
240 (define_insn "tstsi_1"
242 (match_operand:SI 0 "nonimmediate_operand" "rm"))]
246 if (REG_P (operands[0]))
247 return AS2 (test%L0,%0,%0);
249 operands[1] = const0_rtx;
250 return AS2 (cmp%L0,%1,%0);
252 [(set_attr "type" "test")])
254 (define_expand "tstsi"
256 (match_operand:SI 0 "nonimmediate_operand" ""))]
260 i386_compare_gen = gen_tstsi_1;
261 i386_compare_op0 = operands[0];
262 i386_compare_op1 = const0_rtx;
266 (define_insn "tsthi_1"
268 (match_operand:HI 0 "nonimmediate_operand" "rm"))]
272 if (REG_P (operands[0]))
273 return AS2 (test%W0,%0,%0);
275 operands[1] = const0_rtx;
276 return AS2 (cmp%W0,%1,%0);
278 [(set_attr "type" "test")])
280 (define_expand "tsthi"
282 (match_operand:HI 0 "nonimmediate_operand" ""))]
286 i386_compare_gen = gen_tsthi_1;
287 i386_compare_op0 = operands[0];
288 i386_compare_op1 = const0_rtx;
292 (define_insn "tstqi_1"
294 (match_operand:QI 0 "nonimmediate_operand" "qm"))]
298 if (REG_P (operands[0]))
299 return AS2 (test%B0,%0,%0);
301 operands[1] = const0_rtx;
302 return AS2 (cmp%B0,%1,%0);
304 [(set_attr "type" "test")])
306 (define_expand "tstqi"
308 (match_operand:QI 0 "nonimmediate_operand" ""))]
312 i386_compare_gen = gen_tstqi_1;
313 i386_compare_op0 = operands[0];
314 i386_compare_op1 = const0_rtx;
318 (define_insn "tstsf_cc"
320 (match_operand:SF 0 "register_operand" "f"))
321 (clobber (match_scratch:HI 1 "=a"))]
322 "TARGET_80387 && ! TARGET_IEEE_FP"
325 if (! STACK_TOP_P (operands[0]))
328 output_asm_insn (\"ftst\", operands);
330 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
331 output_asm_insn (AS1 (fstp,%y0), operands);
333 return output_fp_cc0_set (insn);
335 [(set_attr "type" "test")])
337 ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
338 ;; isn't IEEE compliant.
340 (define_expand "tstsf"
341 [(parallel [(set (cc0)
342 (match_operand:SF
0 "register_operand" ""))
343 (clobber (match_scratch:HI
1 ""))])]
344 "TARGET_80387 && ! TARGET_IEEE_FP"
347 i386_compare_gen = gen_tstsf_cc;
348 i386_compare_op0 = operands[
0];
349 i386_compare_op1 = const0_rtx;
353 (define_insn "tstdf_cc"
355 (match_operand:DF
0 "register_operand" "f"))
356 (clobber (match_scratch:HI
1 "=a"))]
357 "TARGET_80387 && ! TARGET_IEEE_FP"
360 if (! STACK_TOP_P (operands[
0]))
363 output_asm_insn (
\"ftst
\", operands);
365 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
366 output_asm_insn (AS1 (fstp,%y0), operands);
368 return output_fp_cc0_set (insn);
370 [(set_attr "type" "test")])
372 ;; Don't generate tstdf if generating IEEE code, since the
`ftst' opcode
373 ;; isn't IEEE compliant.
375 (define_expand "tstdf"
376 [(parallel [(set (cc0)
377 (match_operand:DF 0 "register_operand" ""))
378 (clobber (match_scratch:HI 1 ""))])]
379 "TARGET_80387 && ! TARGET_IEEE_FP"
382 i386_compare_gen = gen_tstdf_cc;
383 i386_compare_op0 = operands[0];
384 i386_compare_op1 = const0_rtx;
388 (define_insn "tstxf_cc"
390 (match_operand:XF 0 "register_operand" "f"))
391 (clobber (match_scratch:HI 1 "=a"))]
392 "TARGET_80387 && ! TARGET_IEEE_FP"
395 if (! STACK_TOP_P (operands[0]))
398 output_asm_insn (\"ftst\", operands);
400 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
401 output_asm_insn (AS1 (fstp,%y0), operands);
403 return output_fp_cc0_set (insn);
405 [(set_attr "type" "test")])
407 ;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode
408 ;; isn't IEEE compliant.
410 (define_expand "tstxf"
411 [(parallel [(set (cc0)
412 (match_operand:XF
0 "register_operand" ""))
413 (clobber (match_scratch:HI
1 ""))])]
414 "TARGET_80387 && ! TARGET_IEEE_FP"
417 i386_compare_gen = gen_tstxf_cc;
418 i386_compare_op0 = operands[
0];
419 i386_compare_op1 = const0_rtx;
423 ;;- compare instructions. See comments above tstM patterns about
424 ;; expansion of these insns.
426 (define_insn "cmpsi_1"
428 (compare (match_operand:SI
0 "nonimmediate_operand" "mr,r")
429 (match_operand:SI
1 "general_operand" "ri,mr")))]
430 "GET_CODE (operands[
0]) != MEM || GET_CODE (operands[
1]) != MEM"
431 "* return AS2 (cmp%L0,%
1,%
0);"
432 [(set_attr "type" "compare")])
434 (define_expand "cmpsi"
436 (compare (match_operand:SI
0 "nonimmediate_operand" "")
437 (match_operand:SI
1 "general_operand" "")))]
441 if (GET_CODE (operands[
0]) == MEM && GET_CODE (operands[
1]) == MEM)
442 operands[
0] = force_reg (SImode, operands[
0]);
444 i386_compare_gen = gen_cmpsi_1;
445 i386_compare_op0 = operands[
0];
446 i386_compare_op1 = operands[
1];
450 (define_insn "cmphi_1"
452 (compare (match_operand:HI
0 "nonimmediate_operand" "mr,r")
453 (match_operand:HI
1 "general_operand" "ri,mr")))]
454 "GET_CODE (operands[
0]) != MEM || GET_CODE (operands[
1]) != MEM"
455 "* return AS2 (cmp%W0,%
1,%
0);"
456 [(set_attr "type" "compare")])
458 (define_expand "cmphi"
460 (compare (match_operand:HI
0 "nonimmediate_operand" "")
461 (match_operand:HI
1 "general_operand" "")))]
465 if (GET_CODE (operands[
0]) == MEM && GET_CODE (operands[
1]) == MEM)
466 operands[
0] = force_reg (HImode, operands[
0]);
468 i386_compare_gen = gen_cmphi_1;
469 i386_compare_op0 = operands[
0];
470 i386_compare_op1 = operands[
1];
474 (define_insn "cmpqi_1"
476 (compare (match_operand:QI
0 "nonimmediate_operand" "q,mq")
477 (match_operand:QI
1 "general_operand" "qm,nq")))]
478 "GET_CODE (operands[
0]) != MEM || GET_CODE (operands[
1]) != MEM"
479 "* return AS2 (cmp%B0,%
1,%
0);"
480 [(set_attr "type" "compare")])
482 (define_expand "cmpqi"
484 (compare (match_operand:QI
0 "nonimmediate_operand" "")
485 (match_operand:QI
1 "general_operand" "")))]
489 if (GET_CODE (operands[
0]) == MEM && GET_CODE (operands[
1]) == MEM)
490 operands[
0] = force_reg (QImode, operands[
0]);
492 i386_compare_gen = gen_cmpqi_1;
493 i386_compare_op0 = operands[
0];
494 i386_compare_op1 = operands[
1];
498 ;; These implement float point compares. For each of DFmode and
499 ;; SFmode, there is the normal insn, and an insn where the second operand
500 ;; is converted to the desired mode.
504 (match_operator
2 "VOIDmode_compare_op"
505 [(match_operand:XF
0 "register_operand" "f")
506 (match_operand:XF
1 "register_operand" "f")]))
507 (clobber (match_scratch:HI
3 "=a"))]
509 "* return output_float_compare (insn, operands);"
510 [(set_attr "type" "fcompare")])
514 (match_operator
2 "VOIDmode_compare_op"
515 [(match_operand:XF
0 "register_operand" "f")
517 (match_operand:SI
1 "nonimmediate_operand" "rm"))]))
518 (clobber (match_scratch:HI
3 "=a"))]
520 "* return output_float_compare (insn, operands);"
521 [(set_attr "type" "fcompare")])
525 (match_operator
2 "VOIDmode_compare_op"
527 (match_operand:SI
0 "nonimmediate_operand" "rm"))
528 (match_operand:XF
1 "register_operand" "f")]))
529 (clobber (match_scratch:HI
3 "=a"))]
531 "* return output_float_compare (insn, operands);"
532 [(set_attr "type" "fcompare")])
536 (match_operator
2 "VOIDmode_compare_op"
537 [(match_operand:XF
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);"
543 [(set_attr "type" "fcompare")])
547 (match_operator
2 "VOIDmode_compare_op"
549 (match_operand:DF
0 "nonimmediate_operand" "fm"))
550 (match_operand:XF
1 "register_operand" "f")]))
551 (clobber (match_scratch:HI
3 "=a"))]
553 "* return output_float_compare (insn, operands);"
554 [(set_attr "type" "fcompare")])
558 (match_operator
2 "VOIDmode_compare_op"
559 [(match_operand:XF
0 "register_operand" "f")
561 (match_operand:SF
1 "nonimmediate_operand" "fm"))]))
562 (clobber (match_scratch:HI
3 "=a"))]
564 "* return output_float_compare (insn, operands);"
565 [(set_attr "type" "fcompare")])
569 (match_operator
2 "VOIDmode_compare_op"
571 (match_operand:SF
0 "nonimmediate_operand" "fm"))
572 (match_operand:XF
1 "register_operand" "f")]))
573 (clobber (match_scratch:HI
3 "=a"))]
575 "* return output_float_compare (insn, operands);"
576 [(set_attr "type" "fcompare")])
580 (compare:CCFPEQ (match_operand:XF
0 "register_operand" "f")
581 (match_operand:XF
1 "register_operand" "f")))
582 (clobber (match_scratch:HI
2 "=a"))]
584 "* return output_float_compare (insn, operands);"
585 [(set_attr "type" "fcompare")])
589 (match_operator
2 "VOIDmode_compare_op"
590 [(match_operand:DF
0 "nonimmediate_operand" "f,fm")
591 (match_operand:DF
1 "nonimmediate_operand" "fm,f")]))
592 (clobber (match_scratch:HI
3 "=a,a"))]
594 && (GET_CODE (operands[
0]) != MEM || GET_CODE (operands[
1]) != MEM)"
595 "* return output_float_compare (insn, operands);"
596 [(set_attr "type" "fcompare")])
600 (match_operator
2 "VOIDmode_compare_op"
601 [(match_operand:DF
0 "register_operand" "f")
603 (match_operand:SI
1 "nonimmediate_operand" "rm"))]))
604 (clobber (match_scratch:HI
3 "=a"))]
606 "* return output_float_compare (insn, operands);"
607 [(set_attr "type" "fcompare")])
611 (match_operator
2 "VOIDmode_compare_op"
613 (match_operand:SI
0 "nonimmediate_operand" "rm"))
614 (match_operand:DF
1 "register_operand" "f")]))
615 (clobber (match_scratch:HI
3 "=a"))]
617 "* return output_float_compare (insn, operands);"
618 [(set_attr "type" "fcompare")])
622 (match_operator
2 "VOIDmode_compare_op"
623 [(match_operand:DF
0 "register_operand" "f")
625 (match_operand:SF
1 "nonimmediate_operand" "fm"))]))
626 (clobber (match_scratch:HI
3 "=a"))]
628 "* return output_float_compare (insn, operands);"
629 [(set_attr "type" "fcompare")])
633 (match_operator
2 "VOIDmode_compare_op"
635 (match_operand:SF
0 "nonimmediate_operand" "fm"))
636 (match_operand:DF
1 "register_operand" "f")]))
637 (clobber (match_scratch:HI
3 "=a"))]
639 "* return output_float_compare (insn, operands);"
640 [(set_attr "type" "fcompare")])
644 (match_operator
2 "VOIDmode_compare_op"
646 (match_operand:SF
0 "register_operand" "f"))
647 (match_operand:DF
1 "nonimmediate_operand" "fm")]))
648 (clobber (match_scratch:HI
3 "=a"))]
650 "* return output_float_compare (insn, operands);"
651 [(set_attr "type" "fcompare")])
655 (compare:CCFPEQ (match_operand:DF
0 "register_operand" "f")
656 (match_operand:DF
1 "register_operand" "f")))
657 (clobber (match_scratch:HI
2 "=a"))]
659 "* return output_float_compare (insn, operands);"
660 [(set_attr "type" "fcompare")])
662 ;; These two insns will never be generated by combine due to the mode of
666 ; (compare:CCFPEQ (match_operand:DF
0 "register_operand" "f")
668 ; (match_operand:SF
1 "register_operand" "f"))))
669 ; (clobber (match_scratch:HI
2 "=a"))]
671 ; "* return output_float_compare (insn, operands);")
675 ; (compare:CCFPEQ (float_extend:DF
676 ; (match_operand:SF
0 "register_operand" "f"))
677 ; (match_operand:DF
1 "register_operand" "f")))
678 ; (clobber (match_scratch:HI
2 "=a"))]
680 ; "* return output_float_compare (insn, operands);")
682 (define_insn "*cmpsf_cc_1"
684 (match_operator
2 "VOIDmode_compare_op"
685 [(match_operand:SF
0 "nonimmediate_operand" "f,fm")
686 (match_operand:SF
1 "nonimmediate_operand" "fm,f")]))
687 (clobber (match_scratch:HI
3 "=a,a"))]
689 && (GET_CODE (operands[
0]) != MEM || GET_CODE (operands[
1]) != MEM)"
690 "* return output_float_compare (insn, operands);"
691 [(set_attr "type" "fcompare")])
695 (match_operator
2 "VOIDmode_compare_op"
696 [(match_operand:SF
0 "register_operand" "f")
698 (match_operand:SI
1 "nonimmediate_operand" "rm"))]))
699 (clobber (match_scratch:HI
3 "=a"))]
701 "* return output_float_compare (insn, operands);"
702 [(set_attr "type" "fcompare")])
706 (match_operator
2 "VOIDmode_compare_op"
708 (match_operand:SI
0 "nonimmediate_operand" "rm"))
709 (match_operand:SF
1 "register_operand" "f")]))
710 (clobber (match_scratch:HI
3 "=a"))]
712 "* return output_float_compare (insn, operands);"
713 [(set_attr "type" "fcompare")])
717 (compare:CCFPEQ (match_operand:SF
0 "register_operand" "f")
718 (match_operand:SF
1 "register_operand" "f")))
719 (clobber (match_scratch:HI
2 "=a"))]
721 "* return output_float_compare (insn, operands);"
722 [(set_attr "type" "fcompare")])
724 (define_expand "cmpxf"
726 (compare (match_operand:XF
0 "register_operand" "")
727 (match_operand:XF
1 "register_operand" "")))]
731 i386_compare_gen = gen_cmpxf_cc;
732 i386_compare_gen_eq = gen_cmpxf_ccfpeq;
733 i386_compare_op0 = operands[
0];
734 i386_compare_op1 = operands[
1];
738 (define_expand "cmpdf"
740 (compare (match_operand:DF
0 "register_operand" "")
741 (match_operand:DF
1 "general_operand" "")))]
745 i386_compare_gen = gen_cmpdf_cc;
746 i386_compare_gen_eq = gen_cmpdf_ccfpeq;
747 i386_compare_op0 = operands[
0];
748 i386_compare_op1 = (immediate_operand (operands[
1], DFmode))
749 ? copy_to_mode_reg (DFmode, operands[
1]) : operands[
1];
753 (define_expand "cmpsf"
755 (compare (match_operand:SF
0 "register_operand" "")
756 (match_operand:SF
1 "general_operand" "")))]
760 i386_compare_gen = gen_cmpsf_cc;
761 i386_compare_gen_eq = gen_cmpsf_ccfpeq;
762 i386_compare_op0 = operands[
0];
763 i386_compare_op1 = (immediate_operand (operands[
1], SFmode))
764 ? copy_to_mode_reg (SFmode, operands[
1]) : operands[
1];
768 (define_expand "cmpxf_cc"
769 [(parallel [(set (cc0)
770 (compare (match_operand:XF
0 "register_operand" "")
771 (match_operand:XF
1 "register_operand" "")))
772 (clobber (match_scratch:HI
2 ""))])]
776 (define_expand "cmpxf_ccfpeq"
777 [(parallel [(set (cc0)
778 (compare:CCFPEQ (match_operand:XF
0 "register_operand" "")
779 (match_operand:XF
1 "register_operand" "")))
780 (clobber (match_scratch:HI
2 ""))])]
784 (define_expand "cmpdf_cc"
785 [(parallel [(set (cc0)
786 (compare (match_operand:DF
0 "register_operand" "")
787 (match_operand:DF
1 "register_operand" "")))
788 (clobber (match_scratch:HI
2 ""))])]
792 (define_expand "cmpdf_ccfpeq"
793 [(parallel [(set (cc0)
794 (compare:CCFPEQ (match_operand:DF
0 "register_operand" "")
795 (match_operand:DF
1 "register_operand" "")))
796 (clobber (match_scratch:HI
2 ""))])]
800 if (! register_operand (operands[
1], DFmode))
801 operands[
1] = copy_to_mode_reg (DFmode, operands[
1]);
804 (define_expand "cmpsf_cc"
805 [(parallel [(set (cc0)
806 (compare (match_operand:SF
0 "register_operand" "")
807 (match_operand:SF
1 "register_operand" "")))
808 (clobber (match_scratch:HI
2 ""))])]
812 (define_expand "cmpsf_ccfpeq"
813 [(parallel [(set (cc0)
814 (compare:CCFPEQ (match_operand:SF
0 "register_operand" "")
815 (match_operand:SF
1 "register_operand" "")))
816 (clobber (match_scratch:HI
2 ""))])]
820 if (! register_operand (operands[
1], SFmode))
821 operands[
1] = copy_to_mode_reg (SFmode, operands[
1]);
828 (and:SI (match_operand:SI
0 "general_operand" "%ro")
829 (match_operand:SI
1 "nonmemory_operand" "ri")))]
833 /* For small integers, we may actually use testb. */
834 if (GET_CODE (operands[
1]) == CONST_INT
835 && ! (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
836 && (! REG_P (operands[
0]) || QI_REG_P (operands[
0])))
838 /* We may set the sign bit spuriously. */
840 if ((INTVAL (operands[
1]) & ~
0xff) ==
0)
842 cc_status.flags |= CC_NOT_NEGATIVE;
843 return AS2 (test%B0,%
1,%b0);
846 if ((INTVAL (operands[
1]) & ~
0xff00) ==
0)
848 cc_status.flags |= CC_NOT_NEGATIVE;
849 operands[
1] = GEN_INT (INTVAL (operands[
1]) >>
8);
851 if (QI_REG_P (operands[
0]))
852 return AS2 (test%B0,%
1,%h0);
855 operands[
0] = adj_offsettable_operand (operands[
0],
1);
856 return AS2 (test%B0,%
1,%b0);
860 if (GET_CODE (operands[
0]) == MEM
861 && (INTVAL (operands[
1]) & ~
0xff0000) ==
0)
863 cc_status.flags |= CC_NOT_NEGATIVE;
864 operands[
1] = GEN_INT (INTVAL (operands[
1]) >>
16);
865 operands[
0] = adj_offsettable_operand (operands[
0],
2);
866 return AS2 (test%B0,%
1,%b0);
869 if (GET_CODE (operands[
0]) == MEM
870 && (INTVAL (operands[
1]) & ~
0xff000000) ==
0)
872 operands[
1] = GEN_INT ((INTVAL (operands[
1]) >>
24) &
0xff);
873 operands[
0] = adj_offsettable_operand (operands[
0],
3);
874 return AS2 (test%B0,%
1,%b0);
878 if (CONSTANT_P (operands[
1]) || GET_CODE (operands[
0]) == MEM)
879 return AS2 (test%L0,%
1,%
0);
881 return AS2 (test%L1,%
0,%
1);
883 [(set_attr "type" "compare")])
887 (and:HI (match_operand:HI
0 "general_operand" "%ro")
888 (match_operand:HI
1 "nonmemory_operand" "ri")))]
892 if (GET_CODE (operands[
1]) == CONST_INT
893 && ! (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
894 && (! REG_P (operands[
0]) || QI_REG_P (operands[
0])))
896 if ((INTVAL (operands[
1]) &
0xff00) ==
0)
898 /* ??? This might not be necessary. */
899 if (INTVAL (operands[
1]) &
0xffff0000)
900 operands[
1] = GEN_INT (INTVAL (operands[
1]) &
0xff);
902 /* We may set the sign bit spuriously. */
903 cc_status.flags |= CC_NOT_NEGATIVE;
904 return AS2 (test%B0,%
1,%b0);
907 if ((INTVAL (operands[
1]) &
0xff) ==
0)
909 operands[
1] = GEN_INT ((INTVAL (operands[
1]) >>
8) &
0xff);
911 if (QI_REG_P (operands[
0]))
912 return AS2 (test%B0,%
1,%h0);
915 operands[
0] = adj_offsettable_operand (operands[
0],
1);
916 return AS2 (test%B0,%
1,%b0);
921 /* use
32-bit test instruction if there are no sign issues */
922 if (GET_CODE (operands[
1]) == CONST_INT
923 && !(INTVAL (operands[
1]) & ~
0x7fff)
924 && i386_aligned_p (operands[
0]))
925 return AS2 (test%L0,%
1,%k0);
927 if (CONSTANT_P (operands[
1]) || GET_CODE (operands[
0]) == MEM)
928 return AS2 (test%W0,%
1,%
0);
930 return AS2 (test%W1,%
0,%
1);
932 [(set_attr "type" "compare")])
936 (and:QI (match_operand:QI
0 "nonimmediate_operand" "%qm")
937 (match_operand:QI
1 "nonmemory_operand" "qi")))]
941 if (CONSTANT_P (operands[
1]) || GET_CODE (operands[
0]) == MEM)
942 return AS2 (test%B0,%
1,%
0);
944 return AS2 (test%B1,%
0,%
1);
946 [(set_attr "type" "compare")])
948 ;; move instructions.
949 ;; There is one for each machine mode,
950 ;; and each is preceded by a corresponding push-insn pattern
951 ;; (since pushes are not general_operands on the
386).
954 [(set (match_operand:SI
0 "push_operand" "=<")
955 (match_operand:SI
1 "nonmemory_operand" "rn"))]
957 "* return AS1 (push%L0,%
1);"
958 [(set_attr "memory" "store")])
961 [(set (match_operand:SI
0 "push_operand" "=<")
962 (match_operand:SI
1 "nonmemory_operand" "ri"))]
964 "* return AS1 (push%L0,%
1);"
965 [(set_attr "memory" "store")])
967 ;; On a
386, it is faster to push MEM directly.
970 [(set (match_operand:SI
0 "push_operand" "=<")
971 (match_operand:SI
1 "memory_operand" "m"))]
973 "* return AS1 (push%L0,%
1);"
974 [(set_attr "type" "memory")
975 (set_attr "memory" "load")])
977 ;; General case of fullword move.
979 ;; If generating PIC code and operands[
1] is a symbolic CONST, emit a
980 ;; move to get the address of the symbolic object from the GOT.
982 (define_expand "movsi"
983 [(set (match_operand:SI
0 "general_operand" "")
984 (match_operand:SI
1 "general_operand" ""))]
990 if (flag_pic && SYMBOLIC_CONST (operands[
1]))
991 emit_pic_move (operands, SImode);
993 /* Don't generate memory->memory moves, go through a register */
995 && (reload_in_progress | reload_completed) ==
0
996 && GET_CODE (operands[
0]) == MEM
997 && GET_CODE (operands[
1]) == MEM)
999 operands[
1] = force_reg (SImode, operands[
1]);
1003 ;; On i486, incl reg is faster than movl $
1,reg.
1006 [(set (match_operand:SI
0 "general_operand" "=g,r,r")
1007 (match_operand:SI
1 "general_operand" "rn,i,m"))]
1008 "((!TARGET_MOVE || GET_CODE (operands[
0]) != MEM)
1009 || (GET_CODE (operands[
1]) != MEM))
1015 /* K6: mov reg,
0 is slightly faster than xor reg,reg but is
3 bytes
1017 if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
1018 && operands[
1] == const0_rtx && REG_P (operands[
0]))
1019 return AS2 (xor%L0,%
0,%
0);
1021 if (operands[
1] == const1_rtx
1022 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
1023 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1024 && (link = find_reg_note (insn, REG_WAS_0,
0))
1025 /* Make sure the insn that stored the
0 is still present. */
1026 && ! INSN_DELETED_P (XEXP (link,
0))
1027 && GET_CODE (XEXP (link,
0)) != NOTE
1028 /* Make sure cross jumping didn't happen here. */
1029 && no_labels_between_p (XEXP (link,
0), insn)
1030 /* Make sure the reg hasn't been clobbered. */
1031 && ! reg_set_between_p (operands[
0], XEXP (link,
0), insn))
1032 /* Fastest way to change a
0 to a
1. */
1033 return AS1 (inc%L0,%
0);
1035 if (SYMBOLIC_CONST (operands[
1]))
1036 return AS2 (lea%L0,%a1,%
0);
1038 return AS2 (mov%L0,%
1,%
0);
1040 [(set_attr "type" "integer,integer,memory")
1041 (set_attr "memory" "*,*,load")])
1044 [(set (match_operand:SI
0 "general_operand" "=g,r")
1045 (match_operand:SI
1 "general_operand" "ri,m"))]
1046 "((!TARGET_MOVE || GET_CODE (operands[
0]) != MEM)
1047 || (GET_CODE (operands[
1]) != MEM))
1052 if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
1053 && operands[
1] == const0_rtx && REG_P (operands[
0]))
1054 return AS2 (xor%L0,%
0,%
0);
1056 if (operands[
1] == const1_rtx
1057 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
1058 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1059 && (link = find_reg_note (insn, REG_WAS_0,
0))
1060 /* Make sure the insn that stored the
0 is still present. */
1061 && ! INSN_DELETED_P (XEXP (link,
0))
1062 && GET_CODE (XEXP (link,
0)) != NOTE
1063 /* Make sure cross jumping didn't happen here. */
1064 && no_labels_between_p (XEXP (link,
0), insn)
1065 /* Make sure the reg hasn't been clobbered. */
1066 && ! reg_set_between_p (operands[
0], XEXP (link,
0), insn))
1067 /* Fastest way to change a
0 to a
1. */
1068 return AS1 (inc%L0,%
0);
1070 return AS2 (mov%L0,%
1,%
0);
1072 [(set_attr "type" "integer,memory")
1073 (set_attr "memory" "*,load")])
1076 [(set (match_operand:HI
0 "push_operand" "=<")
1077 (match_operand:HI
1 "nonmemory_operand" "ri"))]
1079 "* return AS1 (push%W0,%
1);"
1080 [(set_attr "type" "memory")
1081 (set_attr "memory" "store")])
1084 [(set (match_operand:HI
0 "push_operand" "=<")
1085 (match_operand:HI
1 "memory_operand" "m"))]
1086 "TARGET_PUSH_MEMORY"
1087 "* return AS1 (push%W0,%
1);"
1088 [(set_attr "type" "memory")
1089 (set_attr "memory" "load")])
1091 ;; On i486, an incl and movl are both faster than incw and movw.
1093 (define_expand "movhi"
1094 [(set (match_operand:HI
0 "general_operand" "")
1095 (match_operand:HI
1 "general_operand" ""))]
1099 /* Don't generate memory->memory moves, go through a register */
1101 && (reload_in_progress | reload_completed) ==
0
1102 && GET_CODE (operands[
0]) == MEM
1103 && GET_CODE (operands[
1]) == MEM)
1105 operands[
1] = force_reg (HImode, operands[
1]);
1110 [(set (match_operand:HI
0 "general_operand" "=g,r")
1111 (match_operand:HI
1 "general_operand" "ri,m"))]
1112 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM) || (GET_CODE (operands[
1]) != MEM)"
1116 if (REG_P (operands[
0]) && operands[
1] == const0_rtx)
1117 return AS2 (xor%L0,%k0,%k0);
1119 if (REG_P (operands[
0]) && operands[
1] == const1_rtx
1120 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
1121 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1122 && (link = find_reg_note (insn, REG_WAS_0,
0))
1123 /* Make sure the insn that stored the
0 is still present. */
1124 && ! INSN_DELETED_P (XEXP (link,
0))
1125 && GET_CODE (XEXP (link,
0)) != NOTE
1126 /* Make sure cross jumping didn't happen here. */
1127 && no_labels_between_p (XEXP (link,
0), insn)
1128 /* Make sure the reg hasn't been clobbered. */
1129 && ! reg_set_between_p (operands[
0], XEXP (link,
0), insn))
1130 /* Fastest way to change a
0 to a
1. */
1131 return AS1 (inc%L0,%k0);
1133 if (REG_P (operands[
0]))
1135 if (i386_aligned_p (operands[
1]))
1137 operands[
1] = i386_sext16_if_const (operands[
1]);
1138 return AS2 (mov%L0,%k1,%k0);
1140 if (! TARGET_ZERO_EXTEND_WITH_AND)
1142 /* movzwl is faster than movw on the Pentium Pro,
1143 * although not as fast as an aligned movl. */
1145 return AS2 (movzx,%
1,%k0);
1147 return AS2 (movz%W0%L0,%
1,%k0);
1152 return AS2 (mov%W0,%
1,%
0);
1154 [(set_attr "type" "integer,memory")
1155 (set_attr "memory" "*,load")])
1157 (define_expand "movstricthi"
1158 [(set (strict_low_part (match_operand:HI
0 "general_operand" ""))
1159 (match_operand:HI
1 "general_operand" ""))]
1163 /* Don't generate memory->memory moves, go through a register */
1165 && (reload_in_progress | reload_completed) ==
0
1166 && GET_CODE (operands[
0]) == MEM
1167 && GET_CODE (operands[
1]) == MEM)
1169 operands[
1] = force_reg (HImode, operands[
1]);
1174 [(set (strict_low_part (match_operand:HI
0 "general_operand" "+g,r"))
1175 (match_operand:HI
1 "general_operand" "ri,m"))]
1176 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM) || (GET_CODE (operands[
1]) != MEM)"
1180 if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
1181 && operands[
1] == const0_rtx && REG_P (operands[
0]))
1182 return AS2 (xor%W0,%
0,%
0);
1184 if (operands[
1] == const1_rtx
1185 /* PPRO and K6 prefer mov to inc to reduce dependencies. */
1186 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1187 && (link = find_reg_note (insn, REG_WAS_0,
0))
1188 /* Make sure the insn that stored the
0 is still present. */
1189 && ! INSN_DELETED_P (XEXP (link,
0))
1190 && GET_CODE (XEXP (link,
0)) != NOTE
1191 /* Make sure cross jumping didn't happen here. */
1192 && no_labels_between_p (XEXP (link,
0), insn)
1193 /* Make sure the reg hasn't been clobbered. */
1194 && ! reg_set_between_p (operands[
0], XEXP (link,
0), insn))
1195 /* Fastest way to change a
0 to a
1. */
1196 return AS1 (inc%W0,%
0);
1198 return AS2 (mov%W0,%
1,%
0);
1200 [(set_attr "type" "integer,memory")])
1202 ;; emit_push_insn when it calls move_by_pieces
1203 ;; requires an insn to "push a byte".
1204 ;; But actually we use pushw, which has the effect of rounding
1205 ;; the amount pushed up to a halfword.
1207 [(set (match_operand:QI
0 "push_operand" "=<")
1208 (match_operand:QI
1 "const_int_operand" "n"))]
1210 "* return AS1(push%W0,%
1);")
1213 [(set (match_operand:QI
0 "push_operand" "=<")
1214 (match_operand:QI
1 "register_operand" "q"))]
1218 operands[
1] = gen_rtx_REG (HImode, REGNO (operands[
1]));
1219 return AS1 (push%W0,%
1);
1222 ;; On i486, incb reg is faster than movb $
1,reg.
1224 ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
1225 ;; or writes %ah, %bh, %ch, %dh.
1227 (define_expand "movqi"
1228 [(set (match_operand:QI
0 "general_operand" "")
1229 (match_operand:QI
1 "general_operand" ""))]
1233 /* Don't generate memory->memory moves, go through a register */
1235 && (reload_in_progress | reload_completed) ==
0
1236 && GET_CODE (operands[
0]) == MEM
1237 && GET_CODE (operands[
1]) == MEM)
1239 operands[
1] = force_reg (QImode, operands[
1]);
1244 [(set (match_operand:QI
0 "nonimmediate_operand" "=q,*r,qm")
1245 (match_operand:QI
1 "general_operand" "*g,*rn,qn"))]
1246 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM) || (GET_CODE (operands[
1]) != MEM)"
1251 /* movb $
0,reg8 is
2 bytes, the same as xorl reg8,reg8.
1252 It is at least as fast as xor on any processor except a Pentium. */
1254 if (operands[
1] == const1_rtx
1255 && ix86_cpu == PROCESSOR_PENTIUM
1256 && (link = find_reg_note (insn, REG_WAS_0,
0))
1257 /* Make sure the insn that stored the
0 is still present. */
1258 && ! INSN_DELETED_P (XEXP (link,
0))
1259 && GET_CODE (XEXP (link,
0)) != NOTE
1260 /* Make sure cross jumping didn't happen here. */
1261 && no_labels_between_p (XEXP (link,
0), insn)
1262 /* Make sure the reg hasn't been clobbered. */
1263 && ! reg_set_between_p (operands[
0], XEXP (link,
0), insn))
1265 /* Fastest way to change a
0 to a
1.
1266 If inc%B0 isn't allowed, use inc%L0. */
1267 if (NON_QI_REG_P (operands[
0]))
1268 return AS1 (inc%L0,%k0);
1270 return AS1 (inc%B0,%
0);
1273 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1274 if (NON_QI_REG_P (operands[
0]) || NON_QI_REG_P (operands[
1]))
1275 return (AS2 (mov%L0,%k1,%k0));
1277 return (AS2 (mov%B0,%
1,%
0));
1280 ;; If it becomes necessary to support movstrictqi into %esi or %edi,
1281 ;; use the insn sequence:
1283 ;; shrdl $
8,srcreg,dstreg
1286 ;; If operands[
1] is a constant, then an andl/orl sequence would be
1289 (define_expand "movstrictqi"
1290 [(set (strict_low_part (match_operand:QI
0 "general_operand" ""))
1291 (match_operand:QI
1 "general_operand" ""))]
1295 /* Don't generate memory->memory moves, go through a register */
1297 && (reload_in_progress | reload_completed) ==
0
1298 && GET_CODE (operands[
0]) == MEM
1299 && GET_CODE (operands[
1]) == MEM)
1301 operands[
1] = force_reg (QImode, operands[
1]);
1306 [(set (strict_low_part (match_operand:QI
0 "nonimmediate_operand" "+qm,q"))
1307 (match_operand:QI
1 "general_operand" "*qn,m"))]
1308 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM) || (GET_CODE (operands[
1]) != MEM)"
1313 /* movb $
0,reg8 is
2 bytes, the same as xorl reg8,reg8. */
1315 if (operands[
1] == const1_rtx
1316 && ix86_cpu == PROCESSOR_PENTIUM
1317 && ! NON_QI_REG_P (operands[
0])
1318 && (link = find_reg_note (insn, REG_WAS_0,
0))
1319 /* Make sure the insn that stored the
0 is still present. */
1320 && ! INSN_DELETED_P (XEXP (link,
0))
1321 && GET_CODE (XEXP (link,
0)) != NOTE
1322 /* Make sure cross jumping didn't happen here. */
1323 && no_labels_between_p (XEXP (link,
0), insn)
1324 /* Make sure the reg hasn't been clobbered. */
1325 && ! reg_set_between_p (operands[
0], XEXP (link,
0), insn))
1326 /* Fastest way to change a
0 to a
1. */
1327 return AS1 (inc%B0,%
0);
1329 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1330 if (NON_QI_REG_P (operands[
0]) || NON_QI_REG_P (operands[
1]))
1333 return (AS2 (mov%L0,%k1,%k0));
1336 return AS2 (mov%B0,%
1,%
0);
1339 (define_insn "movsf_push"
1340 [(set (match_operand:SF
0 "push_operand" "=<,<")
1341 (match_operand:SF
1 "general_operand" "*rfF,m"))]
1342 "GET_CODE (operands[
1]) != MEM || reload_in_progress || reload_completed"
1345 if (STACK_REG_P (operands[
1]))
1349 if (! STACK_TOP_P (operands[
1]))
1352 xops[
0] = AT_SP (SFmode);
1353 xops[
1] = GEN_INT (
4);
1354 xops[
2] = stack_pointer_rtx;
1356 output_asm_insn (AS2 (sub%L2,%
1,%
2), xops);
1358 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1359 output_asm_insn (AS1 (fstp%S0,%
0), xops);
1361 output_asm_insn (AS1 (fst%S0,%
0), xops);
1366 return AS1 (push%L0,%
1);
1369 (define_insn "movsf_push_memory"
1370 [(set (match_operand:SF
0 "push_operand" "=<")
1371 (match_operand:SF
1 "memory_operand" "m"))]
1372 "TARGET_PUSH_MEMORY"
1373 "* return AS1 (push%L0,%
1);")
1375 (define_expand "movsf"
1376 [(set (match_operand:SF
0 "general_operand" "")
1377 (match_operand:SF
1 "general_operand" ""))]
1381 /* Don't generate memory->memory moves, go through a register */
1383 && (reload_in_progress | reload_completed) ==
0
1384 && GET_CODE (operands[
0]) == MEM
1385 && GET_CODE (operands[
1]) == MEM)
1387 operands[
1] = force_reg (SFmode, operands[
1]);
1390 /* If we are loading a floating point constant that isn't
0 or
1
1391 into a register, force the value to memory now, since we'll
1392 get better code out the back end. */
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 operands[
1] = validize_mem (force_const_mem (SFmode, operands[
1]));
1402 ;; For the purposes of regclass, prefer FLOAT_REGS.
1404 [(set (match_operand:SF
0 "nonimmediate_operand" "=*rfm,*rf,f,!*rm")
1405 (match_operand:SF
1 "general_operand" "*rf,*rfm,fG,fF"))]
1406 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM) || (GET_CODE (operands[
1]) != MEM)"
1409 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) !=
0;
1411 /* First handle a
`pop' insn or a `fld %st(
0)' */
1413 if (STACK_TOP_P (operands[
0]) && STACK_TOP_P (operands[
1]))
1416 return AS1 (fstp,%y0);
1418 return AS1 (fld,%y0);
1421 /* Handle a transfer between the
387 and a
386 register */
1423 if (STACK_TOP_P (operands[
0]) && NON_STACK_REG_P (operands[
1]))
1425 output_op_from_reg (operands[
1], AS1 (fld%z0,%y1));
1429 if (STACK_TOP_P (operands[
1]) && NON_STACK_REG_P (operands[
0]))
1431 output_to_reg (operands[
0], stack_top_dies,
0);
1435 /* Handle other kinds of writes from the
387 */
1437 if (STACK_TOP_P (operands[
1]))
1440 return AS1 (fstp%z0,%y0);
1442 return AS1 (fst%z0,%y0);
1445 /* Handle other kinds of reads to the
387 */
1447 if (STACK_TOP_P (operands[
0]) && GET_CODE (operands[
1]) == CONST_DOUBLE)
1448 return output_move_const_single (operands);
1450 if (STACK_TOP_P (operands[
0]))
1451 return AS1 (fld%z1,%y1);
1453 /* Handle all SFmode moves not involving the
387 */
1455 return singlemove_string (operands);
1457 [(set_attr "type" "fld")])
1460 (define_insn "swapsf"
1461 [(set (match_operand:SF
0 "register_operand" "f")
1462 (match_operand:SF
1 "register_operand" "f"))
1468 if (STACK_TOP_P (operands[
0]))
1469 return AS1 (fxch,%
1);
1471 return AS1 (fxch,%
0);
1475 (define_insn "movdf_push"
1476 [(set (match_operand:DF
0 "push_operand" "=<,<")
1477 (match_operand:DF
1 "general_operand" "*rfF,o"))]
1478 "GET_CODE (operands[
1]) != MEM || reload_in_progress || reload_completed"
1481 if (STACK_REG_P (operands[
1]))
1485 xops[
0] = AT_SP (DFmode);
1486 xops[
1] = GEN_INT (
8);
1487 xops[
2] = stack_pointer_rtx;
1489 output_asm_insn (AS2 (sub%L2,%
1,%
2), xops);
1491 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1492 output_asm_insn (AS1 (fstp%Q0,%
0), xops);
1494 output_asm_insn (AS1 (fst%Q0,%
0), xops);
1499 if (which_alternative ==
1)
1500 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode),
0,
0);
1502 return output_move_double (operands);
1505 (define_insn "movdf_push_memory"
1506 [(set (match_operand:DF
0 "push_operand" "=<")
1507 (match_operand:DF
1 "memory_operand" "o"))]
1508 "TARGET_PUSH_MEMORY"
1509 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode),
0,
0);")
1511 (define_expand "movdf"
1512 [(set (match_operand:DF
0 "general_operand" "")
1513 (match_operand:DF
1 "general_operand" ""))]
1517 /* Don't generate memory->memory moves, go through a register */
1519 && (reload_in_progress | reload_completed) ==
0
1520 && GET_CODE (operands[
0]) == MEM
1521 && GET_CODE (operands[
1]) == MEM)
1523 operands[
1] = force_reg (DFmode, operands[
1]);
1526 /* If we are loading a floating point constant that isn't
0 or
1 into a
1527 register, indicate we need the pic register loaded. This could be
1528 optimized into stores of constants if the target eventually moves to
1529 memory, but better safe than sorry. */
1530 else if ((reload_in_progress | reload_completed) ==
0
1531 && GET_CODE (operands[
0]) != MEM
1532 && GET_CODE (operands[
1]) == CONST_DOUBLE
1533 && !standard_80387_constant_p (operands[
1]))
1535 operands[
1] = validize_mem (force_const_mem (DFmode, operands[
1]));
1539 ;; For the purposes of regclass, prefer FLOAT_REGS.
1541 [(set (match_operand:DF
0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
1542 (match_operand:DF
1 "general_operand" "fmG,f,*rfm,*rfF"))]
1543 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM)
1544 || (GET_CODE (operands[
1]) != MEM)"
1547 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) !=
0;
1549 /* First handle a
`pop' insn or a `fld %st(
0)' */
1551 if (STACK_TOP_P (operands[
0]) && STACK_TOP_P (operands[
1]))
1554 return AS1 (fstp,%y0);
1556 return AS1 (fld,%y0);
1559 /* Handle a transfer between the
387 and a
386 register */
1561 if (STACK_TOP_P (operands[
0]) && NON_STACK_REG_P (operands[
1]))
1563 output_op_from_reg (operands[
1], AS1 (fld%z0,%y1));
1567 if (STACK_TOP_P (operands[
1]) && NON_STACK_REG_P (operands[
0]))
1569 output_to_reg (operands[
0], stack_top_dies,
0);
1573 /* Handle other kinds of writes from the
387 */
1575 if (STACK_TOP_P (operands[
1]))
1578 return AS1 (fstp%z0,%y0);
1580 return AS1 (fst%z0,%y0);
1583 /* Handle other kinds of reads to the
387 */
1585 if (STACK_TOP_P (operands[
0]) && GET_CODE (operands[
1]) == CONST_DOUBLE)
1586 return output_move_const_single (operands);
1588 if (STACK_TOP_P (operands[
0]))
1589 return AS1 (fld%z1,%y1);
1591 /* Handle all DFmode moves not involving the
387 */
1593 return output_move_double (operands);
1595 [(set_attr "type" "fld")])
1599 (define_insn "swapdf"
1600 [(set (match_operand:DF
0 "register_operand" "f")
1601 (match_operand:DF
1 "register_operand" "f"))
1607 if (STACK_TOP_P (operands[
0]))
1608 return AS1 (fxch,%
1);
1610 return AS1 (fxch,%
0);
1613 (define_insn "movxf_push"
1614 [(set (match_operand:XF
0 "push_operand" "=<,<")
1615 (match_operand:XF
1 "general_operand" "*rfF,o"))]
1616 "GET_CODE (operands[
1]) != MEM || reload_in_progress || reload_completed"
1619 if (STACK_REG_P (operands[
1]))
1623 xops[
0] = AT_SP (XFmode);
1624 xops[
1] = GEN_INT (
12);
1625 xops[
2] = stack_pointer_rtx;
1627 output_asm_insn (AS2 (sub%L2,%
1,%
2), xops);
1629 output_asm_insn (AS1 (fstp%T0,%
0), xops);
1630 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1631 output_asm_insn (AS1 (fld%T0,%
0), xops);
1636 if (which_alternative ==
1)
1637 return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode),
0,
0);
1639 return output_move_double (operands);
1642 (define_insn "movxf_push_memory"
1643 [(set (match_operand:XF
0 "push_operand" "=<")
1644 (match_operand:XF
1 "memory_operand" "o"))]
1645 "TARGET_PUSH_MEMORY"
1646 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode),
0,
0);")
1648 (define_expand "movxf"
1649 [(set (match_operand:XF
0 "general_operand" "")
1650 (match_operand:XF
1 "general_operand" ""))]
1654 /* Don't generate memory->memory moves, go through a register */
1656 && (reload_in_progress | reload_completed) ==
0
1657 && GET_CODE (operands[
0]) == MEM
1658 && GET_CODE (operands[
1]) == MEM)
1660 operands[
1] = force_reg (XFmode, operands[
1]);
1663 /* If we are loading a floating point constant that isn't
0 or
1
1664 into a register, indicate we need the pic register loaded. This could
1665 be optimized into stores of constants if the target eventually moves
1666 to memory, but better safe than sorry. */
1667 else if ((reload_in_progress | reload_completed) ==
0
1668 && GET_CODE (operands[
0]) != MEM
1669 && GET_CODE (operands[
1]) == CONST_DOUBLE
1670 && !standard_80387_constant_p (operands[
1]))
1672 operands[
1] = validize_mem (force_const_mem (XFmode, operands[
1]));
1678 [(set (match_operand:XF
0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
1679 (match_operand:XF
1 "general_operand" "fmG,f,*rfm,*rfF"))]
1680 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM)
1681 || (GET_CODE (operands[
1]) != MEM)"
1684 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) !=
0;
1686 /* First handle a
`pop' insn or a `fld %st(
0)' */
1688 if (STACK_TOP_P (operands[
0]) && STACK_TOP_P (operands[
1]))
1691 return AS1 (fstp,%y0);
1693 return AS1 (fld,%y0);
1696 /* Handle a transfer between the
387 and a
386 register */
1698 if (STACK_TOP_P (operands[
0]) && NON_STACK_REG_P (operands[
1]))
1700 output_op_from_reg (operands[
1], AS1 (fld%z0,%y1));
1704 if (STACK_TOP_P (operands[
1]) && NON_STACK_REG_P (operands[
0]))
1706 output_to_reg (operands[
0], stack_top_dies,
0);
1710 /* Handle other kinds of writes from the
387 */
1712 if (STACK_TOP_P (operands[
1]))
1714 output_asm_insn (AS1 (fstp%z0,%y0), operands);
1715 if (! stack_top_dies)
1716 return AS1 (fld%z0,%y0);
1721 /* Handle other kinds of reads to the
387 */
1723 if (STACK_TOP_P (operands[
0]) && GET_CODE (operands[
1]) == CONST_DOUBLE)
1724 return output_move_const_single (operands);
1726 if (STACK_TOP_P (operands[
0]))
1727 return AS1 (fld%z1,%y1);
1729 /* Handle all XFmode moves not involving the
387 */
1731 return output_move_double (operands);
1734 (define_insn "swapxf"
1735 [(set (match_operand:XF
0 "register_operand" "f")
1736 (match_operand:XF
1 "register_operand" "f"))
1742 if (STACK_TOP_P (operands[
0]))
1743 return AS1 (fxch,%
1);
1745 return AS1 (fxch,%
0);
1749 [(set (match_operand:DI
0 "push_operand" "=<")
1750 (match_operand:DI
1 "general_operand" "riF"))]
1752 "* return output_move_double (operands);")
1755 [(set (match_operand:DI
0 "push_operand" "=<")
1756 (match_operand:DI
1 "memory_operand" "o"))]
1757 "TARGET_PUSH_MEMORY"
1758 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode),
0,
0);")
1760 (define_expand "movdi"
1761 [(set (match_operand:DI
0 "general_operand" "")
1762 (match_operand:DI
1 "general_operand" ""))]
1766 /* Don't generate memory->memory moves, go through a register */
1768 && (reload_in_progress | reload_completed) ==
0
1769 && GET_CODE (operands[
0]) == MEM
1770 && GET_CODE (operands[
1]) == MEM)
1772 operands[
1] = force_reg (DImode, operands[
1]);
1777 [(set (match_operand:DI
0 "general_operand" "=g,r")
1778 (match_operand:DI
1 "general_operand" "riF,m"))]
1779 "(!TARGET_MOVE || GET_CODE (operands[
0]) != MEM)
1780 || (GET_CODE (operands[
1]) != MEM)"
1781 "* return output_move_double (operands);"
1782 [(set_attr "type" "integer,memory")
1783 (set_attr "memory" "*,load")])
1786 ;;- conversion instructions
1789 ;;- zero extension instructions
1790 ;; See comments by
`andsi' for when andl is faster than movzx.
1792 (define_insn "zero_extendhisi2"
1793 [(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
1794 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
1800 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1801 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1803 xops[0] = operands[0];
1804 xops[1] = GEN_INT (0xffff);
1805 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1808 if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1]))
1810 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1811 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1815 if (TARGET_ZERO_EXTEND_WITH_AND)
1817 xops[0] = operands[0];
1818 xops[1] = GEN_INT (0xffff);
1819 if (i386_aligned_p (operands[1]))
1820 output_asm_insn (AS2 (mov%L0,%k1,%k0),operands);
1822 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1823 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1828 return AS2 (movzx,%1,%0);
1830 return AS2 (movz%W0%L0,%1,%0);
1835 [(set (match_operand:SI 0 "register_operand" "")
1836 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1837 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])"
1840 (set (strict_low_part (match_dup 2))
1842 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1846 [(set (match_operand:SI 0 "register_operand" "")
1847 (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))]
1848 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])"
1849 [(set (strict_low_part (match_dup 2))
1852 (and:SI (match_dup 0)
1853 (const_int 65535)))]
1854 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1856 (define_insn "zero_extendqihi2"
1857 [(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
1858 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1864 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1865 && REG_P (operands[1])
1866 && REGNO (operands[0]) == REGNO (operands[1]))
1868 xops[0] = operands[0];
1869 xops[1] = GEN_INT (0xff);
1870 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1873 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1875 if(!reg_overlap_mentioned_p(operands[0],operands[1]))
1877 output_asm_insn (AS2 (xor%L0,%k0,%k0), operands);
1878 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1882 xops[0] = operands[0];
1883 xops[1] = GEN_INT (0xff);
1884 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1885 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1891 return AS2 (movzx,%1,%0);
1893 return AS2 (movz%B0%W0,%1,%0);
1898 [(set (match_operand:HI 0 "register_operand" "")
1899 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1900 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1901 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1904 (set (strict_low_part (match_dup 2))
1906 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1910 [(set (match_operand:HI 0 "register_operand" "")
1911 (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))]
1912 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1913 && reg_overlap_mentioned_p (operands[0], operands[1])"
1914 [(set (strict_low_part (match_dup 2))
1917 (and:HI (match_dup 0)
1919 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1922 [(set (match_operand:HI 0 "register_operand" "")
1923 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1924 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND"
1928 (and:HI (match_dup 0)
1930 "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0)
1931 operands[1] = SUBREG_REG (operands[1]);
1932 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG
1933 || REGNO (operands[0]) == REGNO (operands[1]))
1935 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));")
1937 (define_insn "zero_extendqisi2"
1938 [(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
1939 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1945 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1946 && REG_P (operands[1])
1947 && REGNO (operands[0]) == REGNO (operands[1]))
1949 xops[0] = operands[0];
1950 xops[1] = GEN_INT (0xff);
1951 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1954 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1956 if(!reg_overlap_mentioned_p (operands[0], operands[1]))
1958 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1959 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1963 xops[0] = operands[0];
1964 xops[1] = GEN_INT (0xff);
1965 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1966 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1971 if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG)
1973 xops[0] = operands[0];
1974 xops[1] = GEN_INT (0xff);
1975 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
1976 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
1977 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1982 return AS2 (movzx,%1,%0);
1984 return AS2 (movz%B0%L0,%1,%0);
1989 [(set (match_operand:SI 0 "register_operand" "")
1990 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1991 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1992 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1995 (set (strict_low_part (match_dup 2))
1997 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2001 [(set (match_operand:SI 0 "register_operand" "")
2002 (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))]
2003 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
2004 && reg_overlap_mentioned_p (operands[0], operands[1])"
2005 [(set (strict_low_part (match_dup 2))
2008 (and:SI (match_dup 0)
2010 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2013 [(set (match_operand:SI 0 "register_operand" "")
2014 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2015 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
2016 && ! reg_overlap_mentioned_p (operands[0], operands[1])"
2020 (and:SI (match_dup 0)
2022 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
2024 (define_insn "zero_extendsidi2"
2025 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m")
2026 (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))]
2030 rtx high[2], low[2], xops[4];
2032 if (REG_P (operands[0]) && REG_P (operands[1])
2033 && REGNO (operands[0]) == REGNO (operands[1]))
2035 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2036 return AS2 (xor%L0,%0,%0);
2039 split_di (operands, 1, low, high);
2041 xops[1] = operands[1];
2043 xops[3] = const0_rtx;
2045 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2046 if (GET_CODE (low[0]) == MEM)
2047 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
2049 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
2054 ;;- sign extension instructions
2056 (define_insn "extendsidi2"
2057 [(set (match_operand:DI 0 "register_operand" "=r")
2058 (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))]
2062 if (REGNO (operands[0]) == 0)
2064 /* This used to be cwtl, but that extends HI to SI somehow. */
2072 operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2073 output_asm_insn (AS2 (mov%L0,%0,%1), operands);
2075 operands[0] = GEN_INT (31);
2076 return AS2 (sar%L1,%0,%1);
2079 ;; Note that the i386 programmers' manual says that the opcodes
2080 ;; are named movsx..., but the assembler on Unix does not accept that.
2081 ;; We use what the Unix assembler expects.
2083 (define_insn "extendhisi2"
2084 [(set (match_operand:SI 0 "register_operand" "=r")
2085 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2089 if (REGNO (operands[0]) == 0
2090 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
2098 return AS2 (movsx,%1,%0);
2100 return AS2 (movs%W0%L0,%1,%0);
2104 (define_insn "extendqihi2"
2105 [(set (match_operand:HI 0 "register_operand" "=r")
2106 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2110 if (REGNO (operands[0]) == 0
2111 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
2115 return AS2 (movsx,%1,%0);
2117 return AS2 (movs%B0%W0,%1,%0);
2121 (define_insn "extendqisi2"
2122 [(set (match_operand:SI 0 "register_operand" "=r")
2123 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2128 return AS2 (movsx,%1,%0);
2130 return AS2 (movs%B0%L0,%1,%0);
2135 ;; Truncation of long long -> 32 bit
2137 (define_expand "truncdisi2"
2138 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2139 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2143 /* Don't generate memory->memory moves, go through a register */
2145 && (reload_in_progress | reload_completed) == 0
2146 && GET_CODE (operands[0]) == MEM
2147 && GET_CODE (operands[1]) == MEM)
2149 rtx target = gen_reg_rtx (SImode);
2150 emit_insn (gen_truncdisi2 (target, operands[1]));
2151 emit_move_insn (operands[0], target);
2157 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2158 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2159 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2162 rtx low[2], high[2], xops[2];
2164 split_di (&operands[1], 1, low, high);
2165 xops[0] = operands[0];
2167 if (!rtx_equal_p (xops[0], xops[1]))
2168 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2174 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2175 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
2177 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2180 rtx low[2], high[2], xops[2];
2182 split_di (&operands[1], 1, low, high);
2183 xops[0] = operands[0];
2185 if (!rtx_equal_p (xops[0], xops[1]))
2186 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2193 ;; Conversions between float and double.
2195 (define_insn "extendsfdf2"
2196 [(set (match_operand:DF 0 "nonimmediate_operand" "=fm,f")
2198 (match_operand:SF 1 "nonimmediate_operand" "f,fm")))]
2202 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2204 if (NON_STACK_REG_P (operands[1]))
2206 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2210 if (NON_STACK_REG_P (operands[0]))
2212 output_to_reg (operands[0], stack_top_dies, 0);
2216 if (STACK_TOP_P (operands[0]))
2217 return AS1 (fld%z1,%y1);
2219 if (GET_CODE (operands[0]) == MEM)
2222 return AS1 (fstp%z0,%y0);
2224 return AS1 (fst%z0,%y0);
2230 (define_insn "extenddfxf2"
2231 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
2233 (match_operand:DF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
2237 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2239 if (NON_STACK_REG_P (operands[1]))
2241 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2245 if (NON_STACK_REG_P (operands[0]))
2247 output_to_reg (operands[0], stack_top_dies, 0);
2251 if (STACK_TOP_P (operands[0]))
2252 return AS1 (fld%z1,%y1);
2254 if (GET_CODE (operands[0]) == MEM)
2256 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2257 if (! stack_top_dies)
2258 return AS1 (fld%z0,%y0);
2265 (define_insn "extendsfxf2"
2266 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
2268 (match_operand:SF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
2272 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2274 if (NON_STACK_REG_P (operands[1]))
2276 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2280 if (NON_STACK_REG_P (operands[0]))
2282 output_to_reg (operands[0], stack_top_dies, 0);
2286 if (STACK_TOP_P (operands[0]))
2287 return AS1 (fld%z1,%y1);
2289 if (GET_CODE (operands[0]) == MEM)
2291 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2292 if (! stack_top_dies)
2293 return AS1 (fld%z0,%y0);
2300 (define_expand "truncdfsf2"
2301 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2303 (match_operand:DF 1 "register_operand" "")))
2304 (clobber (match_dup 2))])]
2308 operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2311 ;; This cannot output into an f-reg because there is no way to be sure
2312 ;; of truncating in that case. Otherwise this is just like a simple move
2313 ;; insn. So we pretend we can output to a reg in order to get better
2314 ;; register preferencing, but we really use a stack slot.
2317 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
2319 (match_operand:DF 1 "register_operand" "0,f")))
2320 (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
2324 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2326 if (GET_CODE (operands[0]) == MEM)
2329 return AS1 (fstp%z0,%0);
2331 return AS1 (fst%z0,%0);
2333 else if (STACK_TOP_P (operands[0]))
2335 output_asm_insn (AS1 (fstp%z2,%y2), operands);
2336 return AS1 (fld%z2,%y2);
2342 (define_insn "truncxfsf2"
2343 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r")
2345 (match_operand:XF 1 "register_operand" "f,f")))]
2349 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2351 if (NON_STACK_REG_P (operands[0]))
2353 if (stack_top_dies == 0)
2355 output_asm_insn (AS1 (fld,%y1), operands);
2358 output_to_reg (operands[0], stack_top_dies, 0);
2361 else if (GET_CODE (operands[0]) == MEM)
2364 return AS1 (fstp%z0,%0);
2367 output_asm_insn (AS1 (fld,%y1), operands);
2368 return AS1 (fstp%z0,%0);
2375 (define_insn "truncxfdf2"
2376 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!*r")
2378 (match_operand:XF 1 "register_operand" "f,f")))]
2382 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2384 if (NON_STACK_REG_P (operands[0]))
2386 if (stack_top_dies == 0)
2388 output_asm_insn (AS1 (fld,%y1), operands);
2391 output_to_reg (operands[0], stack_top_dies, 0);
2394 else if (GET_CODE (operands[0]) == MEM)
2397 return AS1 (fstp%z0,%0);
2400 output_asm_insn (AS1 (fld,%y1), operands);
2401 return AS1 (fstp%z0,%0);
2409 ;; The 387 requires that the stack top dies after converting to DImode.
2411 ;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
2412 ;; doing a signed conversion to DImode, and then taking just the low
2415 (define_expand "fixuns_truncxfsi2"
2417 (match_operand:XF 1 "register_operand" ""))
2418 (parallel [(set (match_dup 2)
2419 (fix:DI (fix:XF (match_dup 4))))
2420 (clobber (match_dup 4))
2421 (clobber (match_dup 5))
2422 (clobber (match_dup 6))
2423 (clobber (match_scratch:SI 7 ""))])
2424 (set (match_operand:SI 0 "general_operand" "")
2429 operands[2] = gen_reg_rtx (DImode);
2430 operands[3] = gen_lowpart (SImode, operands[2]);
2431 operands[4] = gen_reg_rtx (XFmode);
2432 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2433 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2436 (define_expand "fixuns_truncdfsi2"
2438 (match_operand:DF 1 "register_operand" ""))
2439 (parallel [(set (match_dup 2)
2440 (fix:DI (fix:DF (match_dup 4))))
2441 (clobber (match_dup 4))
2442 (clobber (match_dup 5))
2443 (clobber (match_dup 6))
2444 (clobber (match_scratch:SI 7 ""))])
2445 (set (match_operand:SI 0 "general_operand" "")
2450 operands[2] = gen_reg_rtx (DImode);
2451 operands[3] = gen_lowpart (SImode, operands[2]);
2452 operands[4] = gen_reg_rtx (DFmode);
2453 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2454 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2457 (define_expand "fixuns_truncsfsi2"
2459 (match_operand:SF 1 "register_operand" ""))
2460 (parallel [(set (match_dup 2)
2461 (fix:DI (fix:SF (match_dup 4))))
2462 (clobber (match_dup 4))
2463 (clobber (match_dup 5))
2464 (clobber (match_dup 6))
2465 (clobber (match_scratch:SI 7 ""))])
2466 (set (match_operand:SI 0 "general_operand" "")
2471 operands[2] = gen_reg_rtx (DImode);
2472 operands[3] = gen_lowpart (SImode, operands[2]);
2473 operands[4] = gen_reg_rtx (SFmode);
2474 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2475 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2478 ;; Signed conversion to DImode.
2480 (define_expand "fix_truncxfdi2"
2482 (match_operand:XF 1 "register_operand" ""))
2483 (parallel [(set (match_operand:DI 0 "general_operand" "")
2484 (fix:DI (fix:XF (match_dup 2))))
2485 (clobber (match_dup 2))
2486 (clobber (match_dup 3))
2487 (clobber (match_dup 4))
2488 (clobber (match_scratch:SI 5 ""))])]
2492 operands[1] = copy_to_mode_reg (XFmode, operands[1]);
2493 operands[2] = gen_reg_rtx (XFmode);
2494 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2495 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2498 (define_expand "fix_truncdfdi2"
2500 (match_operand:DF 1 "register_operand" ""))
2501 (parallel [(set (match_operand:DI 0 "general_operand" "")
2502 (fix:DI (fix:DF (match_dup 2))))
2503 (clobber (match_dup 2))
2504 (clobber (match_dup 3))
2505 (clobber (match_dup 4))
2506 (clobber (match_scratch:SI 5 ""))])]
2510 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
2511 operands[2] = gen_reg_rtx (DFmode);
2512 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2513 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2516 (define_expand "fix_truncsfdi2"
2518 (match_operand:SF 1 "register_operand" ""))
2519 (parallel [(set (match_operand:DI 0 "general_operand" "")
2520 (fix:DI (fix:SF (match_dup 2))))
2521 (clobber (match_dup 2))
2522 (clobber (match_dup 3))
2523 (clobber (match_dup 4))
2524 (clobber (match_scratch:SI 5 ""))])]
2528 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
2529 operands[2] = gen_reg_rtx (SFmode);
2530 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2531 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2534 ;; These match a signed conversion of either DFmode or SFmode to DImode.
2537 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2538 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "+f"))))
2539 (clobber (match_dup 1))
2540 (clobber (match_operand:SI 2 "memory_operand" "m"))
2541 (clobber (match_operand:DI 3 "memory_operand" "m"))
2542 (clobber (match_scratch:SI 4 "=&q"))]
2544 "* return output_fix_trunc (insn, operands);")
2547 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2548 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "+f"))))
2549 (clobber (match_dup 1))
2550 (clobber (match_operand:SI 2 "memory_operand" "m"))
2551 (clobber (match_operand:DI 3 "memory_operand" "m"))
2552 (clobber (match_scratch:SI 4 "=&q"))]
2554 "* return output_fix_trunc (insn, operands);")
2557 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2558 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "+f"))))
2559 (clobber (match_dup 1))
2560 (clobber (match_operand:SI 2 "memory_operand" "m"))
2561 (clobber (match_operand:DI 3 "memory_operand" "m"))
2562 (clobber (match_scratch:SI 4 "=&q"))]
2564 "* return output_fix_trunc (insn, operands);")
2566 ;; Signed MODE_FLOAT conversion to SImode.
2568 (define_expand "fix_truncxfsi2"
2569 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2571 (fix:XF (match_operand:XF 1 "register_operand" ""))))
2572 (clobber (match_dup 2))
2573 (clobber (match_dup 3))
2574 (clobber (match_scratch:SI 4 ""))])]
2578 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2579 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2582 (define_expand "fix_truncdfsi2"
2583 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2585 (fix:DF (match_operand:DF 1 "register_operand" ""))))
2586 (clobber (match_dup 2))
2587 (clobber (match_dup 3))
2588 (clobber (match_scratch:SI 4 ""))])]
2592 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2593 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2596 (define_expand "fix_truncsfsi2"
2597 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2599 (fix:SF (match_operand:SF 1 "register_operand" ""))))
2600 (clobber (match_dup 2))
2601 (clobber (match_dup 3))
2602 (clobber (match_scratch:SI 4 ""))])]
2606 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2607 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2611 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2612 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
2613 (clobber (match_operand:SI 2 "memory_operand" "m"))
2614 (clobber (match_operand:DI 3 "memory_operand" "m"))
2615 (clobber (match_scratch:SI 4 "=&q"))]
2617 "* return output_fix_trunc (insn, operands);")
2620 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2621 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2622 (clobber (match_operand:SI 2 "memory_operand" "m"))
2623 (clobber (match_operand:DI 3 "memory_operand" "m"))
2624 (clobber (match_scratch:SI 4 "=&q"))]
2626 "* return output_fix_trunc (insn, operands);")
2629 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2630 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
2631 (clobber (match_operand:SI 2 "memory_operand" "m"))
2632 (clobber (match_operand:DI 3 "memory_operand" "m"))
2633 (clobber (match_scratch:SI 4 "=&q"))]
2635 "* return output_fix_trunc (insn, operands);")
2637 ;; Conversion between fixed point and floating point.
2638 ;; The actual pattern that matches these is at the end of this file.
2640 ;; ??? Possibly represent floatunssidf2 here in gcc2.
2642 (define_expand "floatsisf2"
2643 [(set (match_operand:SF 0 "register_operand" "")
2644 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
2648 (define_expand "floatdisf2"
2649 [(set (match_operand:SF 0 "register_operand" "")
2650 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
2654 (define_expand "floatsidf2"
2655 [(set (match_operand:DF 0 "register_operand" "")
2656 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
2660 (define_expand "floatdidf2"
2661 [(set (match_operand:DF 0 "register_operand" "")
2662 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
2666 (define_expand "floatsixf2"
2667 [(set (match_operand:XF 0 "register_operand" "")
2668 (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
2672 (define_expand "floatdixf2"
2673 [(set (match_operand:XF 0 "register_operand" "")
2674 (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
2675 "TARGET_80387 && LONG_DOUBLE_TYPE_SIZE == 96"
2678 ;; This will convert from SImode or DImode to MODE_FLOAT.
2681 [(set (match_operand:XF 0 "register_operand" "=f")
2682 (float:XF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2686 if (NON_STACK_REG_P (operands[1]))
2688 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2691 else if (GET_CODE (operands[1]) == MEM)
2692 return AS1 (fild%z1,%1);
2698 [(set (match_operand:DF 0 "register_operand" "=f")
2699 (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2703 if (NON_STACK_REG_P (operands[1]))
2705 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2708 else if (GET_CODE (operands[1]) == MEM)
2709 return AS1 (fild%z1,%1);
2715 [(set (match_operand:SF 0 "register_operand" "=f")
2716 (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2720 if (NON_STACK_REG_P (operands[1]))
2722 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2725 else if (GET_CODE (operands[1]) == MEM)
2726 return AS1 (fild%z1,%1);
2732 [(set (match_operand:DF 0 "register_operand" "=f")
2733 (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
2737 if (NON_STACK_REG_P (operands[1]))
2739 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2742 else if (GET_CODE (operands[1]) == MEM)
2743 return AS1 (fild%z1,%1);
2749 [(set (match_operand:XF 0 "register_operand" "=f,f")
2750 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!*r")))]
2754 if (NON_STACK_REG_P (operands[1]))
2756 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2759 else if (GET_CODE (operands[1]) == MEM)
2760 return AS1 (fild%z1,%1);
2766 [(set (match_operand:SF 0 "register_operand" "=f")
2767 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
2771 if (NON_STACK_REG_P (operands[1]))
2773 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2776 else if (GET_CODE (operands[1]) == MEM)
2777 return AS1 (fild%z1,%1);
2782 ;;- add instructions
2784 (define_insn "*addsidi3_1"
2785 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o")
2786 (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o")
2787 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri"))))
2788 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))]
2792 rtx low[3], high[3], xops[7], temp;
2796 split_di (operands, 2, low, high);
2797 high[2] = const0_rtx;
2798 low[2] = operands[2];
2800 if (!rtx_equal_p (operands[0], operands[1]))
2807 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2809 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2810 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2816 xops[6] = operands[3];
2817 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2818 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2819 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2820 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2821 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2822 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2827 output_asm_insn (AS2 (add%L0,%2,%0), low);
2828 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2829 cc_status.value1 = high[0];
2830 cc_status.flags = CC_NO_OVERFLOW;
2833 [(set_attr "type" "binary")])
2835 (define_insn "addsidi3_2"
2836 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o")
2837 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r"))
2838 (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o")))
2839 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))]
2843 rtx low[3], high[3], xops[7], temp;
2847 split_di (operands, 2, low, high);
2848 high[2] = const0_rtx;
2849 low[2] = operands[2];
2851 if (!rtx_equal_p (operands[0], operands[1]))
2858 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2860 if (rtx_equal_p (low[0], operands[2]))
2862 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2863 output_asm_insn (AS2 (add%L0,%1,%0), low);
2864 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2867 if (rtx_equal_p (high[0], operands[2]))
2869 if (GET_CODE (operands[0]) != MEM)
2871 output_asm_insn (AS2 (mov%L0,%2,%0), low);
2872 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2873 output_asm_insn (AS2 (add%L0,%1,%0), low);
2874 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2878 /* It's too late to ask for a scratch now - but this
2879 will probably not happen too often. */
2880 output_asm_insn (AS2 (add%L1,%2,%1), low);
2881 output_asm_insn (AS2 (mov%L0,%1,%0), low);
2882 output_asm_insn (AS2 (mov%L1,%2,%1), low);
2883 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2884 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2885 output_asm_insn (AS2 (sub%L1,%0,%1), low);
2886 output_asm_insn (AS1 (neg%L1,%1), low);
2890 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2891 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2897 xops[6] = operands[3];
2898 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2899 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2900 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2901 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2902 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2903 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2908 output_asm_insn (AS2 (add%L0,%2,%0), low);
2909 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2910 cc_status.value1 = high[0];
2911 cc_status.flags = CC_NO_OVERFLOW;
2914 [(set_attr "type" "binary")])
2916 (define_insn "adddi3"
2917 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
2918 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
2919 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
2920 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
2924 rtx low[3], high[3], xops[7], temp;
2928 if (rtx_equal_p (operands[0], operands[2]))
2931 operands[1] = operands[2];
2935 split_di (operands, 3, low, high);
2936 if (!rtx_equal_p (operands[0], operands[1]))
2943 if (GET_CODE (operands[0]) != MEM)
2945 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2946 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2952 xops[6] = operands[3];
2953 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2954 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2955 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2956 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2957 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2958 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2963 cc_status.value1 = high[0];
2964 cc_status.flags = CC_NO_OVERFLOW;
2966 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
2972 xops[4] = operands[3];
2974 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
2975 output_asm_insn (AS2 (add%L1,%4,%1), xops);
2976 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
2977 output_asm_insn (AS2 (adc%L0,%4,%0), xops);
2980 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
2982 output_asm_insn (AS2 (add%L0,%2,%0), low);
2983 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2987 output_asm_insn (AS2 (add%L0,%2,%0), high);
2991 [(set_attr "type" "binary")])
2993 ;; On a 486, it is faster to do movl/addl than to do a single leal if
2994 ;; operands[1] and operands[2] are both registers.
2996 (define_expand "addsi3"
2997 [(set (match_operand:SI 0 "nonimmediate_operand" "")
2998 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
2999 (match_operand:SI 2 "general_operand" "")))]
3001 "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);")
3004 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
3005 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
3006 (match_operand:SI 2 "general_operand" "rmi,ri,ri")))]
3007 "ix86_binary_operator_ok (PLUS, SImode, operands)"
3010 if (REG_P (operands[0]) && REG_P (operands[1])
3011 && (REG_P (operands[2]) || GET_CODE (operands[2]) == CONST_INT)
3012 && REGNO (operands[0]) != REGNO (operands[1]))
3014 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3015 return AS2 (add%L0,%1,%0);
3017 if (operands[2] == stack_pointer_rtx)
3022 operands[1] = operands[2];
3026 if (operands[2] != stack_pointer_rtx)
3029 operands[1] = SET_SRC (PATTERN (insn));
3030 return AS2 (lea%L0,%a1,%0);
3034 if (!rtx_equal_p (operands[0], operands[1]))
3035 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
3037 if (operands[2] == const1_rtx)
3038 return AS1 (inc%L0,%0);
3040 if (operands[2] == constm1_rtx)
3041 return AS1 (dec%L0,%0);
3043 /* subl $-128,%ebx is smaller than addl $128,%ebx. */
3044 if (GET_CODE (operands[2]) == CONST_INT
3045 && INTVAL (operands[2]) == 128)
3047 /* This doesn't compute the carry bit in the same way
3048 * as add%L0, but we use inc and dec above and they
3049 * don't set the carry bit at all. If inc/dec don't need
3050 * a CC_STATUS_INIT, this doesn't either... */
3051 operands[2] = GEN_INT (-128);
3052 return AS2 (sub%L0,%2,%0);
3055 return AS2 (add%L0,%2,%0);
3057 [(set_attr "type" "binary")])
3059 ;; addsi3 is faster, so put this after.
3061 (define_insn "movsi_lea"
3062 [(set (match_operand:SI 0 "register_operand" "=r")
3063 (match_operand:QI 1 "address_operand" "p"))]
3067 /* Adding a constant to a register is faster with an add. */
3068 /* ??? can this ever happen? */
3069 if (GET_CODE (operands[1]) == PLUS
3070 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
3071 && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
3073 operands[1] = XEXP (operands[1], 1);
3075 if (operands[1] == const1_rtx)
3076 return AS1 (inc%L0,%0);
3078 if (operands[1] == constm1_rtx)
3079 return AS1 (dec%L0,%0);
3081 return AS2 (add%L0,%1,%0);
3085 return AS2 (lea%L0,%a1,%0);
3087 [(set_attr "type" "lea")])
3089 ;; ??? `lea' here, for three operand add? If leaw is used, only %bx,
3090 ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
3091 ;; able to handle the operand. But leal always works?
3093 (define_expand "addhi3"
3094 [(set (match_operand:HI
0 "general_operand" "")
3095 (plus:HI (match_operand:HI
1 "nonimmediate_operand" "")
3096 (match_operand:HI
2 "general_operand" "")))]
3098 "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);")
3101 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
3102 (plus:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,
0")
3103 (match_operand:HI
2 "general_operand" "ri,rm")))]
3104 "ix86_binary_operator_ok (PLUS, HImode, operands)"
3107 /* ??? what about offsettable memory references? */
3108 if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */
3109 && QI_REG_P (operands[
0])
3110 && GET_CODE (operands[
2]) == CONST_INT
3111 && (INTVAL (operands[
2]) &
0xff) ==
0
3112 && i386_cc_probably_useless_p (insn))
3114 int byteval = (INTVAL (operands[
2]) >>
8) &
0xff;
3118 return AS1 (inc%B0,%h0);
3119 else if (byteval ==
255)
3120 return AS1 (dec%B0,%h0);
3122 operands[
2] = GEN_INT (byteval);
3123 return AS2 (add%B0,%
2,%h0);
3126 /* Use a
32-bit operation when possible, to avoid the prefix penalty. */
3127 if (REG_P (operands[
0])
3128 && i386_aligned_p (operands[
2])
3129 && i386_cc_probably_useless_p (insn))
3133 if (GET_CODE (operands[
2]) == CONST_INT)
3135 HOST_WIDE_INT intval =
0xffff & INTVAL (operands[
2]);
3138 return AS1 (inc%L0,%k0);
3140 if (intval ==
0xffff)
3141 return AS1 (dec%L0,%k0);
3143 operands[
2] = i386_sext16_if_const (operands[
2]);
3145 return AS2 (add%L0,%k2,%k0);
3148 if (operands[
2] == const1_rtx)
3149 return AS1 (inc%W0,%
0);
3151 if (operands[
2] == constm1_rtx
3152 || (GET_CODE (operands[
2]) == CONST_INT
3153 && INTVAL (operands[
2]) ==
65535))
3154 return AS1 (dec%W0,%
0);
3156 return AS2 (add%W0,%
2,%
0);
3158 [(set_attr "type" "binary")])
3160 (define_expand "addqi3"
3161 [(set (match_operand:QI
0 "general_operand" "")
3162 (plus:QI (match_operand:QI
1 "general_operand" "")
3163 (match_operand:QI
2 "general_operand" "")))]
3165 "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);")
3168 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
3169 (plus:QI (match_operand:QI
1 "nonimmediate_operand" "%
0,
0")
3170 (match_operand:QI
2 "general_operand" "qn,qmn")))]
3171 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3174 if (operands[
2] == const1_rtx)
3175 return AS1 (inc%B0,%
0);
3177 if (operands[
2] == constm1_rtx
3178 || (GET_CODE (operands[
2]) == CONST_INT
3179 && INTVAL (operands[
2]) ==
255))
3180 return AS1 (dec%B0,%
0);
3182 return AS2 (add%B0,%
2,%
0);
3184 [(set_attr "type" "binary")])
3186 ;Lennart Augustsson <augustss@cs.chalmers.se>
3187 ;says this pattern just makes slower code:
3191 ; leal -
80(%ebp),%eax
3195 ; [(set (match_operand:SI
0 "push_operand" "=<")
3196 ; (plus:SI (match_operand:SI
1 "register_operand" "%r")
3197 ; (match_operand:SI
2 "nonmemory_operand" "ri")))]
3202 ; xops[
0] = operands[
0];
3203 ; xops[
1] = operands[
1];
3204 ; xops[
2] = operands[
2];
3205 ; xops[
3] = gen_rtx_MEM (SImode, stack_pointer_rtx);
3206 ; output_asm_insn (
\"push%z1 %
1\", xops);
3207 ; output_asm_insn (AS2 (add%z3,%
2,%
3), xops);
3211 ;; The patterns that match these are at the end of this file.
3213 (define_expand "addxf3"
3214 [(set (match_operand:XF
0 "register_operand" "")
3215 (plus:XF (match_operand:XF
1 "register_operand" "")
3216 (match_operand:XF
2 "register_operand" "")))]
3220 (define_expand "adddf3"
3221 [(set (match_operand:DF
0 "register_operand" "")
3222 (plus:DF (match_operand:DF
1 "nonimmediate_operand" "")
3223 (match_operand:DF
2 "nonimmediate_operand" "")))]
3227 (define_expand "addsf3"
3228 [(set (match_operand:SF
0 "register_operand" "")
3229 (plus:SF (match_operand:SF
1 "nonimmediate_operand" "")
3230 (match_operand:SF
2 "nonimmediate_operand" "")))]
3234 ;;- subtract instructions
3236 (define_insn "subsidi3"
3237 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o")
3238 (minus:DI (match_operand:DI
1 "general_operand" "
0iF,
0,roiF,roiF,riF,o,o")
3239 (zero_extend:DI (match_operand:SI
2 "general_operand" "o,ri,ri,o,ri,i,r"))))
3240 (clobber (match_scratch:SI
3 "=X,X,X,X,X,&r,&r"))]
3244 rtx low[
3], high[
3], xops[
7];
3248 split_di (operands,
2, low, high);
3249 high[
2] = const0_rtx;
3250 low[
2] = operands[
2];
3252 if (!rtx_equal_p (operands[
0], operands[
1]))
3259 if (GET_CODE (operands[
0]) != MEM || GET_CODE (operands[
1]) != MEM)
3261 output_asm_insn (AS2 (mov%L1,%
3,%
1), xops);
3262 output_asm_insn (AS2 (mov%L0,%
2,%
0), xops);
3268 xops[
6] = operands[
3];
3269 output_asm_insn (AS2 (mov%L6,%
3,%
6), xops);
3270 output_asm_insn (AS2 (sub%L6,%
5,%
6), xops);
3271 output_asm_insn (AS2 (mov%L1,%
6,%
1), xops);
3272 output_asm_insn (AS2 (mov%L6,%
2,%
6), xops);
3273 output_asm_insn (AS2 (sbb%L6,%
4,%
6), xops);
3274 output_asm_insn (AS2 (mov%L0,%
6,%
0), xops);
3279 output_asm_insn (AS2 (sub%L0,%
2,%
0), low);
3280 output_asm_insn (AS2 (sbb%L0,%
2,%
0), high);
3281 cc_status.value1 = high[
0];
3282 cc_status.flags = CC_NO_OVERFLOW;
3286 [(set_attr "type" "binary")])
3288 (define_insn "subdi3"
3289 [(set (match_operand:DI
0 "general_operand" "=&r,&ro,o,o,!&r,!o")
3290 (minus:DI (match_operand:DI
1 "general_operand" "
0,
0,
0iF,or,roiF,roiF")
3291 (match_operand:DI
2 "general_operand" "or,riF,or,iF,roiF,roiF")))
3292 (clobber (match_scratch:SI
3 "=X,X,&r,&r,X,&r"))]
3296 rtx low[
3], high[
3], xops[
7];
3300 split_di (operands,
3, low, high);
3302 if (!rtx_equal_p (operands[
0], operands[
1]))
3309 if (GET_CODE (operands[
0]) != MEM)
3311 output_asm_insn (AS2 (mov%L1,%
3,%
1), xops);
3312 output_asm_insn (AS2 (mov%L0,%
2,%
0), xops);
3318 xops[
6] = operands[
3];
3319 output_asm_insn (AS2 (mov%L6,%
3,%
6), xops);
3320 output_asm_insn (AS2 (sub%L6,%
5,%
6), xops);
3321 output_asm_insn (AS2 (mov%L1,%
6,%
1), xops);
3322 output_asm_insn (AS2 (mov%L6,%
2,%
6), xops);
3323 output_asm_insn (AS2 (sbb%L6,%
4,%
6), xops);
3324 output_asm_insn (AS2 (mov%L0,%
6,%
0), xops);
3329 cc_status.value1 = high[
0];
3330 cc_status.flags = CC_NO_OVERFLOW;
3332 if (GET_CODE (operands[
3]) == REG)
3338 xops[
4] = operands[
3];
3340 output_asm_insn (AS2 (mov%L4,%
3,%
4), xops);
3341 output_asm_insn (AS2 (sub%L1,%
4,%
1), xops);
3342 output_asm_insn (AS2 (mov%L4,%
2,%
4), xops);
3343 output_asm_insn (AS2 (sbb%L0,%
4,%
0), xops);
3346 else if (GET_CODE (low[
2]) != CONST_INT || INTVAL (low[
2]) !=
0)
3348 output_asm_insn (AS2 (sub%L0,%
2,%
0), low);
3349 output_asm_insn (AS2 (sbb%L0,%
2,%
0), high);
3353 output_asm_insn (AS2 (sub%L0,%
2,%
0), high);
3358 [(set_attr "type" "binary")])
3360 (define_expand "subsi3"
3361 [(set (match_operand:SI
0 "nonimmediate_operand" "")
3362 (minus:SI (match_operand:SI
1 "nonimmediate_operand" "")
3363 (match_operand:SI
2 "general_operand" "")))]
3365 "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);")
3368 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm,r")
3369 (minus:SI (match_operand:SI
1 "nonimmediate_operand" "
0,
0")
3370 (match_operand:SI
2 "general_operand" "ri,rm")))]
3371 "ix86_binary_operator_ok (MINUS, SImode, operands)"
3372 "* return AS2 (sub%L0,%
2,%
0);"
3373 [(set_attr "type" "binary")])
3375 (define_expand "subhi3"
3376 [(set (match_operand:HI
0 "general_operand" "")
3377 (minus:HI (match_operand:HI
1 "nonimmediate_operand" "")
3378 (match_operand:HI
2 "general_operand" "")))]
3380 "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);")
3383 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
3384 (minus:HI (match_operand:HI
1 "nonimmediate_operand" "
0,
0")
3385 (match_operand:HI
2 "general_operand" "ri,rm")))]
3386 "ix86_binary_operator_ok (MINUS, HImode, operands)"
3389 if (REG_P (operands[
0])
3390 && i386_aligned_p (operands[
2])
3391 && i386_cc_probably_useless_p (insn))
3394 operands[
2] = i386_sext16_if_const (operands[
2]);
3395 return AS2 (sub%L0,%k2,%k0);
3397 return AS2 (sub%W0,%
2,%
0);
3399 [(set_attr "type" "binary")])
3401 (define_expand "subqi3"
3402 [(set (match_operand:QI
0 "general_operand" "")
3403 (minus:QI (match_operand:QI
1 "general_operand" "")
3404 (match_operand:QI
2 "general_operand" "")))]
3406 "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);")
3409 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
3410 (minus:QI (match_operand:QI
1 "nonimmediate_operand" "
0,
0")
3411 (match_operand:QI
2 "general_operand" "qn,qmn")))]
3412 "ix86_binary_operator_ok (MINUS, QImode, operands)"
3413 "* return AS2 (sub%B0,%
2,%
0);"
3414 [(set_attr "type" "binary")])
3416 ;; The patterns that match these are at the end of this file.
3418 (define_expand "subxf3"
3419 [(set (match_operand:XF
0 "register_operand" "")
3420 (minus:XF (match_operand:XF
1 "register_operand" "")
3421 (match_operand:XF
2 "register_operand" "")))]
3425 (define_expand "subdf3"
3426 [(set (match_operand:DF
0 "register_operand" "")
3427 (minus:DF (match_operand:DF
1 "nonimmediate_operand" "")
3428 (match_operand:DF
2 "nonimmediate_operand" "")))]
3432 (define_expand "subsf3"
3433 [(set (match_operand:SF
0 "register_operand" "")
3434 (minus:SF (match_operand:SF
1 "nonimmediate_operand" "")
3435 (match_operand:SF
2 "nonimmediate_operand" "")))]
3439 ;;- multiply instructions
3441 ;(define_insn "mulqi3"
3442 ; [(set (match_operand:QI
0 "register_operand" "=a")
3443 ; (mult:QI (match_operand:QI
1 "register_operand" "%
0")
3444 ; (match_operand:QI
2 "nonimmediate_operand" "qm")))]
3448 (define_insn "mulhi3"
3449 [(set (match_operand:HI
0 "register_operand" "=r,r")
3450 (mult:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,rm")
3451 (match_operand:HI
2 "general_operand" "g,i")))]
3455 if (GET_CODE (operands[
1]) == REG
3456 && REGNO (operands[
1]) == REGNO (operands[
0])
3457 && (GET_CODE (operands[
2]) == MEM || GET_CODE (operands[
2]) == REG))
3458 /* Assembler has weird restrictions. */
3459 return AS2 (imul%W0,%
2,%
0);
3460 return AS3 (imul%W0,%
2,%
1,%
0);
3462 [(set_attr "type" "imul")])
3464 (define_insn "mulsi3"
3465 [(set (match_operand:SI
0 "register_operand" "=r,r")
3466 (mult:SI (match_operand:SI
1 "nonimmediate_operand" "%
0,rm")
3467 (match_operand:SI
2 "general_operand" "g,i")))]
3471 if (GET_CODE (operands[
1]) == REG
3472 && REGNO (operands[
1]) == REGNO (operands[
0])
3473 && (GET_CODE (operands[
2]) == MEM || GET_CODE (operands[
2]) == REG))
3474 /* Assembler has weird restrictions. */
3475 return AS2 (imul%L0,%
2,%
0);
3476 return AS3 (imul%L0,%
2,%
1,%
0);
3478 [(set_attr "type" "imul")])
3480 (define_insn "umulqihi3"
3481 [(set (match_operand:HI
0 "register_operand" "=a")
3482 (mult:HI (zero_extend:HI (match_operand:QI
1 "register_operand" "%
0"))
3483 (zero_extend:HI (match_operand:QI
2 "nonimmediate_operand" "qm"))))]
3486 [(set_attr "type" "imul")])
3488 (define_insn "mulqihi3"
3489 [(set (match_operand:HI
0 "register_operand" "=a")
3490 (mult:HI (sign_extend:HI (match_operand:QI
1 "register_operand" "%
0"))
3491 (sign_extend:HI (match_operand:QI
2 "nonimmediate_operand" "qm"))))]
3494 [(set_attr "type" "imul")])
3496 (define_insn "umulsidi3"
3497 [(set (match_operand:DI
0 "register_operand" "=A")
3498 (mult:DI (zero_extend:DI (match_operand:SI
1 "register_operand" "%
0"))
3499 (zero_extend:DI (match_operand:SI
2 "nonimmediate_operand" "rm"))))]
3500 "TARGET_WIDE_MULTIPLY"
3502 [(set_attr "type" "imul")])
3504 (define_insn "mulsidi3"
3505 [(set (match_operand:DI
0 "register_operand" "=A")
3506 (mult:DI (sign_extend:DI (match_operand:SI
1 "register_operand" "%
0"))
3507 (sign_extend:DI (match_operand:SI
2 "nonimmediate_operand" "rm"))))]
3508 "TARGET_WIDE_MULTIPLY"
3510 [(set_attr "type" "imul")])
3512 (define_insn "umulsi3_highpart"
3513 [(set (match_operand:SI
0 "register_operand" "=d")
3514 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI
1 "register_operand" "%a"))
3515 (zero_extend:DI (match_operand:SI
2 "nonimmediate_operand" "rm")))
3517 (clobber (match_scratch:SI
3 "=a"))]
3518 "TARGET_WIDE_MULTIPLY"
3520 [(set_attr "type" "imul")])
3522 (define_insn "smulsi3_highpart"
3523 [(set (match_operand:SI
0 "register_operand" "=d")
3524 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI
1 "register_operand" "%a"))
3525 (sign_extend:DI (match_operand:SI
2 "nonimmediate_operand" "rm")))
3527 (clobber (match_scratch:SI
3 "=a"))]
3528 "TARGET_WIDE_MULTIPLY"
3530 [(set_attr "type" "imul")])
3532 ;; The patterns that match these are at the end of this file.
3534 (define_expand "mulxf3"
3535 [(set (match_operand:XF
0 "register_operand" "")
3536 (mult:XF (match_operand:XF
1 "register_operand" "")
3537 (match_operand:XF
2 "register_operand" "")))]
3541 (define_expand "muldf3"
3542 [(set (match_operand:DF
0 "register_operand" "")
3543 (mult:DF (match_operand:DF
1 "register_operand" "")
3544 (match_operand:DF
2 "nonimmediate_operand" "")))]
3548 (define_expand "mulsf3"
3549 [(set (match_operand:SF
0 "register_operand" "")
3550 (mult:SF (match_operand:SF
1 "register_operand" "")
3551 (match_operand:SF
2 "nonimmediate_operand" "")))]
3555 ;;- divide instructions
3557 (define_insn "divqi3"
3558 [(set (match_operand:QI
0 "register_operand" "=a")
3559 (div:QI (match_operand:HI
1 "register_operand" "
0")
3560 (match_operand:QI
2 "nonimmediate_operand" "qm")))]
3564 (define_insn "udivqi3"
3565 [(set (match_operand:QI
0 "register_operand" "=a")
3566 (udiv:QI (match_operand:HI
1 "register_operand" "
0")
3567 (match_operand:QI
2 "nonimmediate_operand" "qm")))]
3570 [(set_attr "type" "idiv")])
3572 ;; The patterns that match these are at the end of this file.
3574 (define_expand "divxf3"
3575 [(set (match_operand:XF
0 "register_operand" "")
3576 (div:XF (match_operand:XF
1 "register_operand" "")
3577 (match_operand:XF
2 "register_operand" "")))]
3581 (define_expand "divdf3"
3582 [(set (match_operand:DF
0 "register_operand" "")
3583 (div:DF (match_operand:DF
1 "register_operand" "")
3584 (match_operand:DF
2 "nonimmediate_operand" "")))]
3588 (define_expand "divsf3"
3589 [(set (match_operand:SF
0 "register_operand" "")
3590 (div:SF (match_operand:SF
1 "register_operand" "")
3591 (match_operand:SF
2 "nonimmediate_operand" "")))]
3595 ;; Remainder instructions.
3597 (define_insn "divmodsi4"
3598 [(set (match_operand:SI
0 "register_operand" "=a")
3599 (div:SI (match_operand:SI
1 "register_operand" "
0")
3600 (match_operand:SI
2 "nonimmediate_operand" "rm")))
3601 (set (match_operand:SI
3 "register_operand" "=&d")
3602 (mod:SI (match_dup
1) (match_dup
2)))]
3607 output_asm_insn (
\"cdq
\", operands);
3609 output_asm_insn (
\"cltd
\", operands);
3611 return AS1 (idiv%L0,%
2);
3613 [(set_attr "type" "idiv")])
3615 (define_insn "divmodhi4"
3616 [(set (match_operand:HI
0 "register_operand" "=a")
3617 (div:HI (match_operand:HI
1 "register_operand" "
0")
3618 (match_operand:HI
2 "nonimmediate_operand" "rm")))
3619 (set (match_operand:HI
3 "register_operand" "=&d")
3620 (mod:HI (match_dup
1) (match_dup
2)))]
3623 [(set_attr "type" "idiv")])
3625 ;; ??? Can we make gcc zero extend operand[
0]?
3626 (define_insn "udivmodsi4"
3627 [(set (match_operand:SI
0 "register_operand" "=a")
3628 (udiv:SI (match_operand:SI
1 "register_operand" "
0")
3629 (match_operand:SI
2 "nonimmediate_operand" "rm")))
3630 (set (match_operand:SI
3 "register_operand" "=&d")
3631 (umod:SI (match_dup
1) (match_dup
2)))]
3635 output_asm_insn (AS2 (xor%L3,%
3,%
3), operands);
3636 return AS1 (div%L0,%
2);
3638 [(set_attr "type" "idiv")])
3640 ;; ??? Can we make gcc zero extend operand[
0]?
3641 (define_insn "udivmodhi4"
3642 [(set (match_operand:HI
0 "register_operand" "=a")
3643 (udiv:HI (match_operand:HI
1 "register_operand" "
0")
3644 (match_operand:HI
2 "nonimmediate_operand" "rm")))
3645 (set (match_operand:HI
3 "register_operand" "=&d")
3646 (umod:HI (match_dup
1) (match_dup
2)))]
3650 output_asm_insn (AS2 (xor%W0,%
3,%
3), operands);
3651 return AS1 (div%W0,%
2);
3653 [(set_attr "type" "idiv")])
3656 ;;this should be a valid double division which we may want to add
3659 [(set (match_operand:SI
0 "register_operand" "=a")
3660 (udiv:DI (match_operand:DI
1 "register_operand" "a")
3661 (match_operand:SI
2 "nonimmediate_operand" "rm")))
3662 (set (match_operand:SI
3 "register_operand" "=d")
3663 (umod:SI (match_dup
1) (match_dup
2)))]
3666 [(set_attr "type" "idiv")])
3669 ;;- and instructions
3676 ;; but if the reg is %eax, then the "andl" is faster.
3678 ;; On i486, the "andl" is always faster than the "movzbl".
3680 ;; On both i386 and i486, a three operand AND is as fast with movzbl or
3681 ;; movzwl as with andl, if operands[
0] != operands[
1].
3683 ;; The
`r' in `rm' for operand
3 looks redundant, but it causes
3684 ;; optional reloads to be generated if op
3 is a pseudo in a stack slot.
3686 (define_insn "andsi3"
3687 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm,r")
3688 (and:SI (match_operand:SI
1 "nonimmediate_operand" "%
0,
0")
3689 (match_operand:SI
2 "general_operand" "ri,rm")))]
3693 HOST_WIDE_INT intval;
3694 if (!rtx_equal_p (operands[
0], operands[
1])
3695 && rtx_equal_p (operands[
0], operands[
2]))
3699 operands[
1] = operands[
2];
3702 switch (GET_CODE (operands[
2]))
3705 if (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
3707 intval = INTVAL (operands[
2]);
3708 /* zero-extend
16->
32? */
3709 if (intval ==
0xffff && REG_P (operands[
0])
3710 && (! REG_P (operands[
1])
3711 || REGNO (operands[
0]) !=
0 || REGNO (operands[
1]) !=
0)
3712 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[
0], operands[
1])))
3714 /* ??? tege: Should forget CC_STATUS only if we clobber a
3715 remembered operand. Fix that later. */
3718 return AS2 (movzx,%w1,%
0);
3720 return AS2 (movz%W0%L0,%w1,%
0);
3724 /* zero extend
8->
32? */
3725 if (intval ==
0xff && REG_P (operands[
0])
3726 && !(REG_P (operands[
1]) && NON_QI_REG_P (operands[
1]))
3727 && (! REG_P (operands[
1])
3728 || REGNO (operands[
0]) !=
0 || REGNO (operands[
1]) !=
0)
3729 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[
0], operands[
1])))
3731 /* ??? tege: Should forget CC_STATUS only if we clobber a
3732 remembered operand. Fix that later. */
3735 return AS2 (movzx,%b1,%
0);
3737 return AS2 (movz%B0%L0,%b1,%
0);
3741 /* Check partial bytes.. non-QI-regs are not available */
3742 if (REG_P (operands[
0]) && ! QI_REG_P (operands[
0]))
3745 /* only low byte has zero bits? */
3746 if (~(intval |
0xff) ==
0)
3749 if (REG_P (operands[
0]))
3754 return AS2 (xor%B0,%b0,%b0);
3757 /* we're better off with the
32-bit version if reg != EAX */
3758 /* the value is sign-extended in
8 bits */
3759 if (REGNO (operands[
0]) !=
0 && (intval &
0x80))
3765 operands[
2] = GEN_INT (intval);
3768 return AS2 (mov%B0,%
2,%b0);
3770 return AS2 (and%B0,%
2,%b0);
3773 /* only second byte has zero? */
3774 if (~(intval |
0xff00) ==
0)
3778 intval = (intval >>
8) &
0xff;
3779 operands[
2] = GEN_INT (intval);
3782 if (REG_P (operands[
0]))
3783 return AS2 (xor%B0,%h0,%h0);
3784 operands[
0] = adj_offsettable_operand (operands[
0],
1);
3785 return AS2 (mov%B0,%
2,%b0);
3788 if (REG_P (operands[
0]))
3789 return AS2 (and%B0,%
2,%h0);
3791 operands[
0] = adj_offsettable_operand (operands[
0],
1);
3792 return AS2 (and%B0,%
2,%b0);
3795 if (REG_P (operands[
0]))
3798 /* third byte has zero bits? */
3799 if (~(intval |
0xff0000) ==
0)
3801 intval = (intval >>
16) &
0xff;
3802 operands[
0] = adj_offsettable_operand (operands[
0],
2);
3805 operands[
2] = GEN_INT (intval);
3807 return AS2 (mov%B0,%
2,%b0);
3808 return AS2 (and%B0,%
2,%b0);
3811 /* fourth byte has zero bits? */
3812 if (~(intval |
0xff000000) ==
0)
3814 intval = (intval >>
24) &
0xff;
3815 operands[
0] = adj_offsettable_operand (operands[
0],
3);
3816 goto byte_and_operation;
3819 /* Low word is zero? */
3820 if (intval ==
0xffff0000)
3822 word_zero_and_operation:
3824 operands[
2] = const0_rtx;
3825 return AS2 (mov%W0,%
2,%w0);
3828 /* High word is zero? */
3829 if (intval ==
0x0000ffff)
3831 operands[
0] = adj_offsettable_operand (operands[
0],
2);
3832 goto word_zero_and_operation;
3839 return AS2 (and%L0,%
2,%
0);
3841 [(set_attr "type" "binary")])
3843 (define_insn "andhi3"
3844 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
3845 (and:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,
0")
3846 (match_operand:HI
2 "general_operand" "ri,rm")))]
3850 if (GET_CODE (operands[
2]) == CONST_INT
3851 && ! (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0])))
3853 /* Can we ignore the upper byte? */
3854 if ((! REG_P (operands[
0]) || QI_REG_P (operands[
0]))
3855 && (INTVAL (operands[
2]) &
0xff00) ==
0xff00)
3859 if ((INTVAL (operands[
2]) &
0xff) ==
0)
3861 operands[
2] = const0_rtx;
3862 return AS2 (mov%B0,%
2,%b0);
3865 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0xff);
3866 return AS2 (and%B0,%
2,%b0);
3869 /* Can we ignore the lower byte? */
3870 /* ??? what about offsettable memory references? */
3871 if (QI_REG_P (operands[
0]) && (INTVAL (operands[
2]) &
0xff) ==
0xff)
3875 if ((INTVAL (operands[
2]) &
0xff00) ==
0)
3877 operands[
2] = const0_rtx;
3878 return AS2 (mov%B0,%
2,%h0);
3881 operands[
2] = GEN_INT ((INTVAL (operands[
2]) >>
8) &
0xff);
3882 return AS2 (and%B0,%
2,%h0);
3885 /* use
32-bit ops on registers when there are no sign issues.. */
3886 if (REG_P (operands[
0]))
3888 if (!(INTVAL (operands[
2]) & ~
0x7fff))
3889 return AS2 (and%L0,%
2,%k0);
3893 if (REG_P (operands[
0])
3894 && i386_aligned_p (operands[
2]))
3897 /* If op[
2] is constant, we should zero-extend it and */
3898 /* make a note that op[
0] has been zero-extended, so */
3899 /* that we could use
32-bit ops on it forthwith, but */
3900 /* there is no such reg-note available. Instead we do */
3901 /* a sign extension as that can result in shorter asm */
3902 operands[
2] = i386_sext16_if_const (operands[
2]);
3903 return AS2 (and%L0,%k2,%k0);
3906 /* Use a
32-bit word with the upper bits set, invalidate CC */
3907 if (GET_CODE (operands[
2]) == CONST_INT
3908 && i386_aligned_p (operands[
0]))
3910 HOST_WIDE_INT val = INTVAL (operands[
2]);
3913 if (val != INTVAL (operands[
2]))
3914 operands[
2] = GEN_INT (val);
3915 return AS2 (and%L0,%k2,%k0);
3918 return AS2 (and%W0,%
2,%
0);
3920 [(set_attr "type" "binary")])
3922 (define_insn "andqi3"
3923 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
3924 (and:QI (match_operand:QI
1 "nonimmediate_operand" "%
0,
0")
3925 (match_operand:QI
2 "general_operand" "qn,qmn")))]
3927 "* return AS2 (and%B0,%
2,%
0);"
3928 [(set_attr "type" "binary")])
3930 /* I am nervous about these two.. add them later..
3931 ;I presume this means that we have something in say op0= eax which is small
3932 ;and we want to and it with memory so we can do this by just an
3933 ;andb m,%al and have success.
3935 [(set (match_operand:SI
0 "general_operand" "=r")
3936 (and:SI (zero_extend:SI
3937 (match_operand:HI
1 "nonimmediate_operand" "rm"))
3938 (match_operand:SI
2 "general_operand" "
0")))]
3939 "GET_CODE (operands[
2]) == CONST_INT
3940 && (unsigned int) INTVAL (operands[
2]) < (
1 << GET_MODE_BITSIZE (HImode))"
3944 [(set (match_operand:SI
0 "register_operand" "=q")
3946 (zero_extend:SI (match_operand:QI
1 "nonimmediate_operand" "qm"))
3947 (match_operand:SI
2 "register_operand" "
0")))]
3948 "GET_CODE (operands[
2]) == CONST_INT
3949 && (unsigned int) INTVAL (operands[
2]) < (
1 << GET_MODE_BITSIZE (QImode))"
3954 ;;- Bit set (inclusive or) instructions
3956 ;; This optimizes known byte-wide operations to memory, and in some cases
3957 ;; to QI registers.. Note that we don't want to use the QI registers too
3958 ;; aggressively, because often the
32-bit register instruction is the same
3959 ;; size, and likely to be faster on PentiumPro.
3960 (define_insn "iorsi3"
3961 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm,r")
3962 (ior:SI (match_operand:SI
1 "nonimmediate_operand" "%
0,
0")
3963 (match_operand:SI
2 "general_operand" "ri,rm")))]
3967 HOST_WIDE_INT intval;
3968 switch (GET_CODE (operands[
2]))
3972 if (REG_P (operands[
0]) && ! QI_REG_P (operands[
0]))
3975 /* don't try to optimize volatile accesses */
3976 if (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
3979 intval = INTVAL (operands[
2]);
3980 if ((intval & ~
0xff) ==
0)
3982 if (REG_P (operands[
0]))
3984 /* Do low byte access only for %eax or when high bit is set */
3985 if (REGNO (operands[
0]) !=
0 && !(intval &
0x80))
3992 if (intval != INTVAL (operands[
2]))
3993 operands[
2] = GEN_INT (intval);
3996 return AS2 (mov%B0,%
2,%b0);
3998 return AS2 (or%B0,%
2,%b0);
4002 if ((intval & ~
0xff00) ==
0)
4006 if (REG_P (operands[
0]))
4009 operands[
2] = GEN_INT (intval);
4011 return AS2 (mov%B0,%
2,%h0);
4013 return AS2 (or%B0,%
2,%h0);
4016 operands[
0] = adj_offsettable_operand (operands[
0],
1);
4017 goto byte_or_operation;
4020 if (REG_P (operands[
0]))
4024 if ((intval & ~
0xff0000) ==
0)
4027 operands[
0] = adj_offsettable_operand (operands[
0],
2);
4028 goto byte_or_operation;
4032 if ((intval & ~
0xff000000) ==
0)
4034 intval = (intval >>
24) &
0xff;
4035 operands[
0] = adj_offsettable_operand (operands[
0],
3);
4036 goto byte_or_operation;
4043 return AS2 (or%L0,%
2,%
0);
4045 [(set_attr "type" "binary")])
4047 (define_insn "iorhi3"
4048 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
4049 (ior:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,
0")
4050 (match_operand:HI
2 "general_operand" "ri,rm")))]
4054 HOST_WIDE_INT intval;
4055 switch (GET_CODE (operands[
2]))
4059 if (REG_P (operands[
0]) && ! QI_REG_P (operands[
0]))
4062 /* don't try to optimize volatile accesses */
4063 if (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
4066 intval =
0xffff & INTVAL (operands[
2]);
4068 if ((intval &
0xff00) ==
0)
4070 if (REG_P (operands[
0]))
4072 /* Do low byte access only for %eax or when high bit is set */
4073 if (REGNO (operands[
0]) !=
0 && !(intval &
0x80))
4081 return AS2 (mov%B0,%
2,%b0);
4083 return AS2 (or%B0,%
2,%b0);
4087 if ((intval &
0xff) ==
0)
4090 operands[
2] = GEN_INT (intval);
4092 if (REG_P (operands[
0]))
4096 return AS2 (mov%B0,%
2,%h0);
4098 return AS2 (or%B0,%
2,%h0);
4101 operands[
0] = adj_offsettable_operand (operands[
0],
1);
4103 goto byte_or_operation;
4110 if (REG_P (operands[
0])
4111 && i386_aligned_p (operands[
2]))
4114 operands[
2] = i386_sext16_if_const (operands[
2]);
4115 return AS2 (or%L0,%k2,%k0);
4118 if (GET_CODE (operands[
2]) == CONST_INT
4119 && i386_aligned_p (operands[
0]))
4122 intval =
0xffff & INTVAL (operands[
2]);
4123 if (intval != INTVAL (operands[
2]))
4124 operands[
2] = GEN_INT (intval);
4125 return AS2 (or%L0,%
2,%k0);
4128 return AS2 (or%W0,%
2,%
0);
4130 [(set_attr "type" "binary")])
4132 (define_insn "iorqi3"
4133 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
4134 (ior:QI (match_operand:QI
1 "nonimmediate_operand" "%
0,
0")
4135 (match_operand:QI
2 "general_operand" "qn,qmn")))]
4137 "* return AS2 (or%B0,%
2,%
0);"
4138 [(set_attr "type" "binary")])
4140 ;;- xor instructions
4142 (define_insn "xorsi3"
4143 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm,r")
4144 (xor:SI (match_operand:SI
1 "nonimmediate_operand" "%
0,
0")
4145 (match_operand:SI
2 "general_operand" "ri,rm")))]
4149 HOST_WIDE_INT intval;
4150 switch (GET_CODE (operands[
2]))
4154 if (REG_P (operands[
0]) && ! QI_REG_P (operands[
0]))
4157 /* don't try to optimize volatile accesses */
4158 if (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0]))
4161 intval = INTVAL (operands[
2]);
4162 if ((intval & ~
0xff) ==
0)
4164 if (REG_P (operands[
0]))
4166 /* Do low byte access only for %eax or when high bit is set */
4167 if (REGNO (operands[
0]) !=
0 && !(intval &
0x80))
4175 return AS1 (not%B0,%b0);
4177 if (intval != INTVAL (operands[
2]))
4178 operands[
2] = GEN_INT (intval);
4179 return AS2 (xor%B0,%
2,%b0);
4183 if ((intval & ~
0xff00) ==
0)
4187 if (REG_P (operands[
0]))
4191 return AS1 (not%B0,%h0);
4193 operands[
2] = GEN_INT (intval);
4194 return AS2 (xor%B0,%
2,%h0);
4197 operands[
0] = adj_offsettable_operand (operands[
0],
1);
4199 goto byte_xor_operation;
4202 if (REG_P (operands[
0]))
4206 if ((intval & ~
0xff0000) ==
0)
4209 operands[
0] = adj_offsettable_operand (operands[
0],
2);
4210 goto byte_xor_operation;
4214 if ((intval & ~
0xff000000) ==
0)
4216 intval = (intval >>
24) &
0xff;
4217 operands[
0] = adj_offsettable_operand (operands[
0],
3);
4218 goto byte_xor_operation;
4225 return AS2 (xor%L0,%
2,%
0);
4227 [(set_attr "type" "binary")])
4229 (define_insn "xorhi3"
4230 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm,r")
4231 (xor:HI (match_operand:HI
1 "nonimmediate_operand" "%
0,
0")
4232 (match_operand:HI
2 "general_operand" "ri,rm")))]
4236 if (GET_CODE (operands[
2]) == CONST_INT
4237 && ! (GET_CODE (operands[
0]) == MEM && MEM_VOLATILE_P (operands[
0])))
4239 /* Can we ignore the upper byte? */
4240 if ((! REG_P (operands[
0]) || QI_REG_P (operands[
0]))
4241 && (INTVAL (operands[
2]) &
0xff00) ==
0)
4244 if (INTVAL (operands[
2]) &
0xffff0000)
4245 operands[
2] = GEN_INT (INTVAL (operands[
2]) &
0xffff);
4247 if (INTVAL (operands[
2]) ==
0xff)
4248 return AS1 (not%B0,%b0);
4250 return AS2 (xor%B0,%
2,%b0);
4253 /* Can we ignore the lower byte? */
4254 /* ??? what about offsettable memory references? */
4255 if (QI_REG_P (operands[
0])
4256 && (INTVAL (operands[
2]) &
0xff) ==
0)
4259 operands[
2] = GEN_INT ((INTVAL (operands[
2]) >>
8) &
0xff);
4261 if (INTVAL (operands[
2]) ==
0xff)
4262 return AS1 (not%B0,%h0);
4264 return AS2 (xor%B0,%
2,%h0);
4268 if (REG_P (operands[
0])
4269 && i386_aligned_p (operands[
2]))
4272 operands[
2] = i386_sext16_if_const (operands[
2]);
4273 return AS2 (xor%L0,%k2,%k0);
4276 if (GET_CODE (operands[
2]) == CONST_INT
4277 && i386_aligned_p (operands[
0]))
4279 HOST_WIDE_INT intval;
4281 intval =
0xffff & INTVAL (operands[
2]);
4282 if (intval != INTVAL (operands[
2]))
4283 operands[
2] = GEN_INT (intval);
4284 return AS2 (xor%L0,%
2,%k0);
4287 return AS2 (xor%W0,%
2,%
0);
4289 [(set_attr "type" "binary")])
4291 (define_insn "xorqi3"
4292 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm,q")
4293 (xor:QI (match_operand:QI
1 "nonimmediate_operand" "%
0,
0")
4294 (match_operand:QI
2 "general_operand" "qn,qm")))]
4296 "* return AS2 (xor%B0,%
2,%
0);"
4297 [(set_attr "type" "binary")])
4299 ;; logical operations for DImode
4301 (define_insn "anddi3"
4302 [(set (match_operand:DI
0 "general_operand" "=&r,&ro")
4303 (and:DI (match_operand:DI
1 "general_operand" "
0,
0")
4304 (match_operand:DI
2 "general_operand" "oriF,riF")))]
4307 [(set_attr "type" "binary")])
4310 (define_insn "iordi3"
4311 [(set (match_operand:DI
0 "general_operand" "=&r,&ro")
4312 (ior:DI (match_operand:DI
1 "general_operand" "
0,
0")
4313 (match_operand:DI
2 "general_operand" "oriF,riF")))]
4316 [(set_attr "type" "binary")])
4318 (define_insn "xordi3"
4319 [(set (match_operand:DI
0 "general_operand" "=&r,&ro")
4320 (xor:DI (match_operand:DI
1 "general_operand" "
0,
0")
4321 (match_operand:DI
2 "general_operand" "oriF,riF")))]
4324 [(set_attr "type" "binary")])
4327 [(set (match_operand:DI
0 "general_operand" "")
4328 (match_operator:DI
3 "ix86_logical_operator"
4329 [(match_operand:DI
1 "general_operand" "")
4330 (match_operand:DI
2 "general_operand" "")]))]
4332 [(set (match_dup
4) (match_op_dup:SI
3 [(match_dup
6) (match_dup
8)]))
4333 (set (match_dup
5) (match_op_dup:SI
3 [(match_dup
7) (match_dup
9)]))]
4334 "split_di (&operands[
0],
1, &operands[
4], &operands[
5]);
4335 split_di (&operands[
1],
1, &operands[
6], &operands[
7]);
4336 split_di (&operands[
2],
1, &operands[
8], &operands[
9]);")
4338 ;;- negation instructions
4340 (define_insn "negdi2"
4341 [(set (match_operand:DI
0 "general_operand" "=&ro")
4342 (neg:DI (match_operand:DI
1 "general_operand" "
0")))]
4346 rtx xops[
2], low[
1], high[
1];
4350 split_di (operands,
1, low, high);
4351 xops[
0] = const0_rtx;
4354 output_asm_insn (AS1 (neg%L0,%
0), low);
4355 output_asm_insn (AS2 (adc%L1,%
0,%
1), xops);
4356 output_asm_insn (AS1 (neg%L0,%
0), high);
4360 (define_insn "negsi2"
4361 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm")
4362 (neg:SI (match_operand:SI
1 "nonimmediate_operand" "
0")))]
4366 (define_insn "neghi2"
4367 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm")
4368 (neg:HI (match_operand:HI
1 "nonimmediate_operand" "
0")))]
4372 (define_insn "negqi2"
4373 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm")
4374 (neg:QI (match_operand:QI
1 "nonimmediate_operand" "
0")))]
4378 (define_insn "negsf2"
4379 [(set (match_operand:SF
0 "register_operand" "=f")
4380 (neg:SF (match_operand:SF
1 "register_operand" "
0")))]
4384 (define_insn "negdf2"
4385 [(set (match_operand:DF
0 "register_operand" "=f")
4386 (neg:DF (match_operand:DF
1 "register_operand" "
0")))]
4391 [(set (match_operand:DF
0 "register_operand" "=f")
4392 (neg:DF (float_extend:DF (match_operand:SF
1 "register_operand" "
0"))))]
4396 (define_insn "negxf2"
4397 [(set (match_operand:XF
0 "register_operand" "=f")
4398 (neg:XF (match_operand:XF
1 "register_operand" "
0")))]
4403 [(set (match_operand:XF
0 "register_operand" "=f")
4404 (neg:XF (float_extend:XF (match_operand:DF
1 "register_operand" "
0"))))]
4408 ;; Absolute value instructions
4410 (define_insn "abssf2"
4411 [(set (match_operand:SF
0 "register_operand" "=f")
4412 (abs:SF (match_operand:SF
1 "register_operand" "
0")))]
4415 [(set_attr "type" "fpop")])
4417 (define_insn "absdf2"
4418 [(set (match_operand:DF
0 "register_operand" "=f")
4419 (abs:DF (match_operand:DF
1 "register_operand" "
0")))]
4422 [(set_attr "type" "fpop")])
4425 [(set (match_operand:DF
0 "register_operand" "=f")
4426 (abs:DF (float_extend:DF (match_operand:SF
1 "register_operand" "
0"))))]
4429 [(set_attr "type" "fpop")])
4431 (define_insn "absxf2"
4432 [(set (match_operand:XF
0 "register_operand" "=f")
4433 (abs:XF (match_operand:XF
1 "register_operand" "
0")))]
4436 [(set_attr "type" "fpop")])
4439 [(set (match_operand:XF
0 "register_operand" "=f")
4440 (abs:XF (float_extend:XF (match_operand:DF
1 "register_operand" "
0"))))]
4443 [(set_attr "type" "fpop")])
4445 (define_insn "sqrtsf2"
4446 [(set (match_operand:SF
0 "register_operand" "=f")
4447 (sqrt:SF (match_operand:SF
1 "register_operand" "
0")))]
4448 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4451 (define_insn "sqrtdf2"
4452 [(set (match_operand:DF
0 "register_operand" "=f")
4453 (sqrt:DF (match_operand:DF
1 "register_operand" "
0")))]
4454 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4455 && (TARGET_IEEE_FP || flag_fast_math) "
4459 [(set (match_operand:DF
0 "register_operand" "=f")
4460 (sqrt:DF (float_extend:DF
4461 (match_operand:SF
1 "register_operand" "
0"))))]
4462 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4465 (define_insn "sqrtxf2"
4466 [(set (match_operand:XF
0 "register_operand" "=f")
4467 (sqrt:XF (match_operand:XF
1 "register_operand" "
0")))]
4468 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4469 && (TARGET_IEEE_FP || flag_fast_math) "
4473 [(set (match_operand:XF
0 "register_operand" "=f")
4474 (sqrt:XF (float_extend:XF
4475 (match_operand:DF
1 "register_operand" "
0"))))]
4476 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4480 [(set (match_operand:XF
0 "register_operand" "=f")
4481 (sqrt:XF (float_extend:XF
4482 (match_operand:SF
1 "register_operand" "
0"))))]
4483 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4486 (define_insn "sindf2"
4487 [(set (match_operand:DF
0 "register_operand" "=f")
4488 (unspec:DF [(match_operand:DF
1 "register_operand" "
0")]
1))]
4489 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4492 (define_insn "sinsf2"
4493 [(set (match_operand:SF
0 "register_operand" "=f")
4494 (unspec:SF [(match_operand:SF
1 "register_operand" "
0")]
1))]
4495 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4499 [(set (match_operand:DF
0 "register_operand" "=f")
4500 (unspec:DF [(float_extend:DF
4501 (match_operand:SF
1 "register_operand" "
0"))]
1))]
4502 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4505 (define_insn "sinxf2"
4506 [(set (match_operand:XF
0 "register_operand" "=f")
4507 (unspec:XF [(match_operand:XF
1 "register_operand" "
0")]
1))]
4508 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4511 (define_insn "cosdf2"
4512 [(set (match_operand:DF
0 "register_operand" "=f")
4513 (unspec:DF [(match_operand:DF
1 "register_operand" "
0")]
2))]
4514 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4517 (define_insn "cossf2"
4518 [(set (match_operand:SF
0 "register_operand" "=f")
4519 (unspec:SF [(match_operand:SF
1 "register_operand" "
0")]
2))]
4520 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4524 [(set (match_operand:DF
0 "register_operand" "=f")
4525 (unspec:DF [(float_extend:DF
4526 (match_operand:SF
1 "register_operand" "
0"))]
2))]
4527 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4530 (define_insn "cosxf2"
4531 [(set (match_operand:XF
0 "register_operand" "=f")
4532 (unspec:XF [(match_operand:XF
1 "register_operand" "
0")]
2))]
4533 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4536 ;;- one complement instructions
4538 (define_insn "one_cmplsi2"
4539 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm")
4540 (not:SI (match_operand:SI
1 "nonimmediate_operand" "
0")))]
4544 (define_insn "one_cmplhi2"
4545 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm")
4546 (not:HI (match_operand:HI
1 "nonimmediate_operand" "
0")))]
4550 (define_insn "one_cmplqi2"
4551 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm")
4552 (not:QI (match_operand:QI
1 "nonimmediate_operand" "
0")))]
4556 ;;- arithmetic shift instructions
4558 ;; DImode shifts are implemented using the i386 "shift double" opcode,
4559 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
4560 ;; is variable, then the count is in %cl and the "imm" operand is dropped
4561 ;; from the assembler input.
4563 ;; This instruction shifts the target reg/mem as usual, but instead of
4564 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
4565 ;; is a left shift double, bits are taken from the high order bits of
4566 ;; reg, else if the insn is a shift right double, bits are taken from the
4567 ;; low order bits of reg. So if %eax is "
1234" and %edx is "
5678",
4568 ;; "shldl $
8,%edx,%eax" leaves %edx unchanged and sets %eax to "
2345".
4570 ;; Since sh[lr]d does not change the
`reg' operand, that is done
4571 ;; separately, making all shifts emit pairs of shift double and normal
4572 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
4573 ;; support a 63 bit shift, each shift where the count is in a reg expands
4574 ;; to a pair of shifts, a branch, a shift by 32 and a label.
4576 ;; If the shift count is a constant, we need never emit more than one
4577 ;; shift pair, instead using moves and sign extension for counts greater
4580 (define_expand "ashldi3"
4581 [(set (match_operand:DI 0 "register_operand" "")
4582 (ashift:DI (match_operand:DI 1 "register_operand" "")
4583 (match_operand:QI 2 "nonmemory_operand" "")))]
4587 if (GET_CODE (operands[2]) != CONST_INT
4588 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4590 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4591 emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
4595 emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
4600 (define_insn "ashldi3_const_int"
4601 [(set (match_operand:DI 0 "register_operand" "=&r")
4602 (ashift:DI (match_operand:DI 1 "register_operand" "0")
4603 (match_operand:QI 2 "const_int_operand" "J")))]
4604 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
4607 rtx xops[4], low[1], high[1];
4611 split_di (operands, 1, low, high);
4612 xops[0] = operands[2];
4613 xops[1] = const1_rtx;
4617 if (INTVAL (xops[0]) > 31)
4619 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
4620 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4622 if (INTVAL (xops[0]) > 32)
4624 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
4625 output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
4630 output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
4631 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
4636 (define_insn "ashldi3_non_const_int"
4637 [(set (match_operand:DI 0 "register_operand" "=&r")
4638 (ashift:DI (match_operand:DI 1 "register_operand" "0")
4639 (match_operand:QI 2 "register_operand" "c")))]
4643 rtx xops[4], low[1], high[1];
4644 static int ashldi_label_number;
4648 split_di (operands, 1, low, high);
4649 xops[0] = operands[2];
4650 xops[1] = GEN_INT (32);
4654 output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
4655 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
4656 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
4657 asm_fprintf (asm_out_file, \"\\tje %LLASHLDI%d\\n\", ashldi_label_number);
4658 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
4659 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4660 asm_fprintf (asm_out_file, \"%LLASHLDI%d:\\n\", ashldi_label_number++);
4665 ;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
4666 ;; On i486, movl/sall appears slightly faster than leal, but the leal
4667 ;; is smaller - use leal for now unless the shift count is 1.
4669 (define_insn "ashlsi3"
4670 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4671 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,0")
4672 (match_operand:SI 2 "nonmemory_operand" "M,cI")))]
4676 if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
4678 if (TARGET_DOUBLE_WITH_ADD && INTVAL (operands[2]) == 1)
4680 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
4681 return AS2 (add%L0,%1,%0);
4687 if (operands[1] == stack_pointer_rtx)
4689 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
4690 operands[1] = operands[0];
4692 operands[1] = gen_rtx_MULT (SImode, operands[1],
4693 GEN_INT (1 << INTVAL (operands[2])));
4694 return AS2 (lea%L0,%a1,%0);
4698 if (REG_P (operands[2]))
4699 return AS2 (sal%L0,%b2,%0);
4701 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4702 return AS2 (add%L0,%0,%0);
4704 return AS2 (sal%L0,%2,%0);
4707 (define_insn "ashlhi3"
4708 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4709 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4710 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4714 if (REG_P (operands[2]))
4715 return AS2 (sal%W0,%b2,%0);
4717 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4718 return AS2 (add%W0,%0,%0);
4720 return AS2 (sal%W0,%2,%0);
4723 (define_insn "ashlqi3"
4724 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4725 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4726 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4730 if (REG_P (operands[2]))
4731 return AS2 (sal%B0,%b2,%0);
4733 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4734 return AS2 (add%B0,%0,%0);
4736 return AS2 (sal%B0,%2,%0);
4739 ;; See comment above `ashldi3' about how this works.
4741 (define_expand "ashrdi3"
4742 [(set (match_operand:DI
0 "register_operand" "")
4743 (ashiftrt:DI (match_operand:DI
1 "register_operand" "")
4744 (match_operand:QI
2 "nonmemory_operand" "")))]
4748 if (GET_CODE (operands[
2]) != CONST_INT
4749 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[
2]), 'J'))
4751 operands[
2] = copy_to_mode_reg (QImode, operands[
2]);
4752 emit_insn (gen_ashrdi3_non_const_int (operands[
0], operands[
1],
4756 emit_insn (gen_ashrdi3_const_int (operands[
0], operands[
1], operands[
2]));
4761 (define_insn "ashldi3_32"
4762 [(set (match_operand:DI
0 "nonimmediate_operand" "=r,m")
4763 (ashift:DI (match_operand:DI
1 "nonimmediate_operand" "ro,r")
4768 rtx low[
2], high[
2], xops[
4];
4770 split_di (operands,
2, low, high);
4774 xops[
3] = const0_rtx;
4775 if (!rtx_equal_p (xops[
0], xops[
1]))
4776 output_asm_insn (AS2 (mov%L0,%
1,%
0), xops);
4778 if (GET_CODE (low[
0]) == MEM)
4779 output_asm_insn (AS2 (mov%L2,%
3,%
2), xops);
4781 output_asm_insn (AS2 (xor%L2,%
2,%
2), xops);
4786 (define_insn "ashrdi3_const_int"
4787 [(set (match_operand:DI
0 "register_operand" "=&r")
4788 (ashiftrt:DI (match_operand:DI
1 "register_operand" "
0")
4789 (match_operand:QI
2 "const_int_operand" "J")))]
4790 "CONST_OK_FOR_LETTER_P (INTVAL (operands[
2]), 'J')"
4793 rtx xops[
4], low[
1], high[
1];
4797 split_di (operands,
1, low, high);
4798 xops[
0] = operands[
2];
4799 xops[
1] = const1_rtx;
4803 if (INTVAL (xops[
0]) >
31)
4805 xops[
1] = GEN_INT (
31);
4806 output_asm_insn (AS2 (mov%L2,%
3,%
2), xops);
4807 output_asm_insn (AS2 (sar%L3,%
1,%
3), xops); /* shift by
32 */
4809 if (INTVAL (xops[
0]) >
32)
4811 xops[
0] = GEN_INT (INTVAL (xops[
0]) -
32);
4812 output_asm_insn (AS2 (sar%L2,%
0,%
2), xops); /* Remaining shift */
4817 output_asm_insn (AS3 (shrd%L2,%
0,%
3,%
2), xops);
4818 output_asm_insn (AS2 (sar%L3,%
0,%
3), xops);
4824 (define_insn "ashrdi3_non_const_int"
4825 [(set (match_operand:DI
0 "register_operand" "=&r")
4826 (ashiftrt:DI (match_operand:DI
1 "register_operand" "
0")
4827 (match_operand:QI
2 "register_operand" "c")))]
4831 rtx xops[
4], low[
1], high[
1];
4832 static int ashrdi_label_number;
4836 split_di (operands,
1, low, high);
4837 xops[
0] = operands[
2];
4838 xops[
1] = GEN_INT (
32);
4842 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%
0,%
3,%
2), xops);
4843 output_asm_insn (AS2 (sar%L3,%
0,%
3), xops);
4844 output_asm_insn (AS2 (test%B0,%
1,%b0), xops);
4845 asm_fprintf (asm_out_file,
\"\\tje %LLASHRDI%d
\\n
\", ashrdi_label_number);
4846 xops[
1] = GEN_INT (
31);
4847 output_asm_insn (AS2 (mov%L2,%
3,%
2), xops);
4848 output_asm_insn (AS2 (sar%L3,%
1,%
3), xops); /* shift by
32 */
4849 asm_fprintf (asm_out_file,
\"%LLASHRDI%d:
\\n
\", ashrdi_label_number++);
4854 (define_insn "ashrsi3"
4855 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm")
4856 (ashiftrt:SI (match_operand:SI
1 "nonimmediate_operand" "
0")
4857 (match_operand:SI
2 "nonmemory_operand" "cI")))]
4861 if (REG_P (operands[
2]))
4862 return AS2 (sar%L0,%b2,%
0);
4864 return AS2 (sar%L0,%
2,%
0);
4867 (define_insn "ashrhi3"
4868 [(set (match_operand:HI
0 "nonimmediate_operand" "=rm")
4869 (ashiftrt:HI (match_operand:HI
1 "nonimmediate_operand" "
0")
4870 (match_operand:HI
2 "nonmemory_operand" "cI")))]
4874 if (REG_P (operands[
2]))
4875 return AS2 (sar%W0,%b2,%
0);
4877 return AS2 (sar%W0,%
2,%
0);
4880 (define_insn "ashrqi3"
4881 [(set (match_operand:QI
0 "nonimmediate_operand" "=qm")
4882 (ashiftrt:QI (match_operand:QI
1 "nonimmediate_operand" "
0")
4883 (match_operand:QI
2 "nonmemory_operand" "cI")))]
4887 if (REG_P (operands[
2]))
4888 return AS2 (sar%B0,%b2,%
0);
4890 return AS2 (sar%B0,%
2,%
0);
4893 ;;- logical shift instructions
4895 ;; See comment above
`ashldi3' about how this works.
4897 (define_expand "lshrdi3"
4898 [(set (match_operand:DI 0 "register_operand" "")
4899 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4900 (match_operand:QI 2 "nonmemory_operand" "")))]
4904 if (GET_CODE (operands[2]) != CONST_INT
4905 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4907 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4908 emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
4912 emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
4917 (define_insn "lshrdi3_32"
4918 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
4919 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
4924 rtx low[2], high[2], xops[4];
4926 split_di (operands, 2, low, high);
4930 xops[3] = const0_rtx;
4931 if (!rtx_equal_p (xops[0], xops[1]))
4932 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
4934 if (GET_CODE (low[0]) == MEM)
4935 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4937 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4942 (define_insn "lshrdi3_const_int"
4943 [(set (match_operand:DI 0 "register_operand" "=&r")
4944 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
4945 (match_operand:QI 2 "const_int_operand" "J")))]
4946 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
4949 rtx xops[4], low[1], high[1];
4953 split_di (operands, 1, low, high);
4954 xops[0] = operands[2];
4955 xops[1] = const1_rtx;
4959 if (INTVAL (xops[0]) > 31)
4961 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
4962 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
4964 if (INTVAL (xops[0]) > 32)
4966 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
4967 output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
4972 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
4973 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
4979 (define_insn "lshrdi3_non_const_int"
4980 [(set (match_operand:DI 0 "register_operand" "=&r")
4981 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
4982 (match_operand:QI 2 "register_operand" "c")))]
4986 rtx xops[4], low[1], high[1];
4987 static int lshrdi_label_number;
4991 split_di (operands, 1, low, high);
4992 xops[0] = operands[2];
4993 xops[1] = GEN_INT (32);
4997 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
4998 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
4999 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5000 asm_fprintf (asm_out_file, \"\\tje %LLLSHRDI%d\\n\", lshrdi_label_number);
5001 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
5002 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
5003 asm_fprintf (asm_out_file, \"%LLLSHRDI%d:\\n\", lshrdi_label_number++);
5008 (define_insn "lshrsi3"
5009 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5010 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5011 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5015 if (REG_P (operands[2]))
5016 return AS2 (shr%L0,%b2,%0);
5018 return AS2 (shr%L0,%2,%1);
5021 (define_insn "lshrhi3"
5022 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5023 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5024 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5028 if (REG_P (operands[2]))
5029 return AS2 (shr%W0,%b2,%0);
5031 return AS2 (shr%W0,%2,%0);
5034 (define_insn "lshrqi3"
5035 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5036 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5037 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5041 if (REG_P (operands[2]))
5042 return AS2 (shr%B0,%b2,%0);
5044 return AS2 (shr%B0,%2,%0);
5047 ;;- rotate instructions
5049 (define_insn "rotlsi3"
5050 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5051 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5052 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5056 if (REG_P (operands[2]))
5057 return AS2 (rol%L0,%b2,%0);
5059 return AS2 (rol%L0,%2,%0);
5062 (define_insn "rotlhi3"
5063 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5064 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5065 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5069 if (REG_P (operands[2]))
5070 return AS2 (rol%W0,%b2,%0);
5072 return AS2 (rol%W0,%2,%0);
5075 (define_insn "rotlqi3"
5076 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5077 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5078 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5082 if (REG_P (operands[2]))
5083 return AS2 (rol%B0,%b2,%0);
5085 return AS2 (rol%B0,%2,%0);
5088 (define_insn "rotrsi3"
5089 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5090 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5091 (match_operand:SI 2 "nonmemory_operand" "cI")))]
5095 if (REG_P (operands[2]))
5096 return AS2 (ror%L0,%b2,%0);
5098 return AS2 (ror%L0,%2,%0);
5101 (define_insn "rotrhi3"
5102 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5103 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5104 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5108 if (REG_P (operands[2]))
5109 return AS2 (ror%W0,%b2,%0);
5111 return AS2 (ror%W0,%2,%0);
5114 (define_insn "rotrqi3"
5115 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5116 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5117 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5121 if (REG_P (operands[2]))
5122 return AS2 (ror%B0,%b2,%0);
5124 return AS2 (ror%B0,%2,%0);
5128 ;; This usually looses. But try a define_expand to recognize a few case
5129 ;; we can do efficiently, such as accessing the "high" QImode registers,
5130 ;; %ah, %bh, %ch, %dh.
5131 ;; ??? Note this has a botch on the mode of operand 0, which needs to be
5132 ;; fixed if this is ever enabled.
5134 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
5135 (match_operand:SI 1 "immediate_operand" "i")
5136 (match_operand:SI 2 "immediate_operand" "i"))
5137 (match_operand:SI 3 "nonmemory_operand" "ri"))]
5141 if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
5143 if (GET_CODE (operands[3]) == CONST_INT)
5145 unsigned int mask = (1 << INTVAL (operands[1])) - 1;
5146 operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
5147 output_asm_insn (AS2 (and%L0,%1,%0), operands);
5148 operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
5149 output_asm_insn (AS2 (or%L0,%3,%0), operands);
5153 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
5154 if (INTVAL (operands[2]))
5155 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5156 output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
5157 operands[2] = GEN_INT (BITS_PER_WORD
5158 - INTVAL (operands[1]) - INTVAL (operands[2]));
5159 if (INTVAL (operands[2]))
5160 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5166 ;; ??? There are problems with the mode of operand[3]. The point of this
5167 ;; is to represent an HImode move to a "high byte" register.
5169 (define_expand "insv"
5170 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
5171 (match_operand:SI 1 "immediate_operand" "")
5172 (match_operand:SI 2 "immediate_operand" ""))
5173 (match_operand:QI 3 "nonmemory_operand" "ri"))]
5177 if (GET_CODE (operands[1]) != CONST_INT
5178 || GET_CODE (operands[2]) != CONST_INT)
5181 if (! (INTVAL (operands[1]) == 8
5182 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
5183 && ! INTVAL (operands[1]) == 1)
5188 ;; On i386, the register count for a bit operation is *not* truncated,
5189 ;; so SHIFT_COUNT_TRUNCATED must not be defined.
5191 ;; On i486, the shift & or/and code is faster than bts or btr. If
5192 ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
5194 ;; On i386, bts is a little faster if operands[0] is a reg, and a
5195 ;; little slower if operands[0] is a MEM, than the shift & or/and code.
5196 ;; Use bts & btr, since they reload better.
5198 ;; General bit set and clear.
5200 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm")
5202 (match_operand:SI 2 "register_operand" "r"))
5203 (match_operand:SI 3 "const_int_operand" "n"))]
5204 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5209 if (INTVAL (operands[3]) == 1)
5210 return AS2 (bts%L0,%2,%0);
5212 return AS2 (btr%L0,%2,%0);
5215 ;; Bit complement. See comments on previous pattern.
5216 ;; ??? Is this really worthwhile?
5218 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5219 (xor:SI (ashift:SI (const_int 1)
5220 (match_operand:SI 1 "register_operand" "r"))
5221 (match_operand:SI 2 "nonimmediate_operand" "0")))]
5222 "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT"
5227 return AS2 (btc%L0,%1,%0);
5231 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5232 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5233 (ashift:SI (const_int 1)
5234 (match_operand:SI 2 "register_operand" "r"))))]
5235 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5240 return AS2 (btc%L0,%2,%0);
5243 ;; Recognizers for bit-test instructions.
5245 ;; The bt opcode allows a MEM in operands[0]. But on both i386 and
5246 ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
5247 ;; bt on the MEM directly.
5249 ;; ??? The first argument of a zero_extract must not be reloaded, so
5250 ;; don't allow a MEM in the operand predicate without allowing it in the
5254 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5256 (match_operand:SI 1 "register_operand" "r")))]
5257 "GET_CODE (operands[1]) != CONST_INT"
5260 cc_status.flags |= CC_Z_IN_NOT_C;
5261 return AS2 (bt%L0,%1,%0);
5265 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5266 (match_operand:SI 1 "const_int_operand" "n")
5267 (match_operand:SI 2 "const_int_operand" "n")))]
5273 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5274 operands[1] = GEN_INT (mask);
5276 if (QI_REG_P (operands[0]))
5278 if ((mask & ~0xff) == 0)
5280 cc_status.flags |= CC_NOT_NEGATIVE;
5281 return AS2 (test%B0,%1,%b0);
5284 if ((mask & ~0xff00) == 0)
5286 cc_status.flags |= CC_NOT_NEGATIVE;
5287 operands[1] = GEN_INT (mask >> 8);
5288 return AS2 (test%B0,%1,%h0);
5292 return AS2 (test%L0,%1,%0);
5295 ;; ??? All bets are off if operand 0 is a volatile MEM reference.
5296 ;; The CPU may access unspecified bytes around the actual target byte.
5299 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
5300 (match_operand:SI 1 "const_int_operand" "n")
5301 (match_operand:SI 2 "const_int_operand" "n")))]
5302 "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
5307 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5308 operands[1] = GEN_INT (mask);
5310 if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
5312 if ((mask & ~0xff) == 0)
5314 cc_status.flags |= CC_NOT_NEGATIVE;
5315 return AS2 (test%B0,%1,%b0);
5318 if ((mask & ~0xff00) == 0)
5320 cc_status.flags |= CC_NOT_NEGATIVE;
5321 operands[1] = GEN_INT (mask >> 8);
5323 if (QI_REG_P (operands[0]))
5324 return AS2 (test%B0,%1,%h0);
5327 operands[0] = adj_offsettable_operand (operands[0], 1);
5328 return AS2 (test%B0,%1,%b0);
5332 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
5334 cc_status.flags |= CC_NOT_NEGATIVE;
5335 operands[1] = GEN_INT (mask >> 16);
5336 operands[0] = adj_offsettable_operand (operands[0], 2);
5337 return AS2 (test%B0,%1,%b0);
5340 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
5342 cc_status.flags |= CC_NOT_NEGATIVE;
5343 operands[1] = GEN_INT (mask >> 24);
5344 operands[0] = adj_offsettable_operand (operands[0], 3);
5345 return AS2 (test%B0,%1,%b0);
5349 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
5350 return AS2 (test%L0,%1,%0);
5352 return AS2 (test%L1,%0,%1);
5355 ;; Store-flag instructions.
5357 ;; For all sCOND expanders, also expand the compare or test insn that
5358 ;; generates cc0. Generate an equality comparison if `seq' or
`sne'.
5360 (define_expand "seq"
5362 (set (match_operand:QI 0 "register_operand" "")
5363 (eq:QI (cc0) (const_int 0)))]
5368 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5369 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5371 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5374 (define_expand "sne"
5376 (set (match_operand:QI 0 "register_operand" "")
5377 (ne:QI (cc0) (const_int 0)))]
5382 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5383 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5385 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5388 (define_expand "sgt"
5390 (set (match_operand:QI 0 "register_operand" "")
5391 (gt:QI (cc0) (const_int 0)))]
5393 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5395 (define_expand "sgtu"
5397 (set (match_operand:QI 0 "register_operand" "")
5398 (gtu:QI (cc0) (const_int 0)))]
5400 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5402 (define_expand "slt"
5404 (set (match_operand:QI 0 "register_operand" "")
5405 (lt:QI (cc0) (const_int 0)))]
5407 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5409 (define_expand "sltu"
5411 (set (match_operand:QI 0 "register_operand" "")
5412 (ltu:QI (cc0) (const_int 0)))]
5414 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5416 (define_expand "sge"
5418 (set (match_operand:QI 0 "register_operand" "")
5419 (ge:QI (cc0) (const_int 0)))]
5421 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5423 (define_expand "sgeu"
5425 (set (match_operand:QI 0 "register_operand" "")
5426 (geu:QI (cc0) (const_int 0)))]
5428 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5430 (define_expand "sle"
5432 (set (match_operand:QI 0 "register_operand" "")
5433 (le:QI (cc0) (const_int 0)))]
5435 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5437 (define_expand "sleu"
5439 (set (match_operand:QI 0 "register_operand" "")
5440 (leu:QI (cc0) (const_int 0)))]
5442 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5444 ;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may
5445 ;; not have any input reloads. A MEM write might need an input reload
5446 ;; for the address of the MEM. So don't allow MEM as the SET_DEST.
5448 (define_insn "*setcc"
5449 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5450 (match_operator:QI 1 "comparison_operator" [(cc0) (const_int 0)]))]
5451 "reload_completed || register_operand (operands[0], QImode)"
5454 enum rtx_code code = GET_CODE (operands[1]);
5455 if (cc_prev_status.flags & CC_TEST_AX)
5459 operands[2] = gen_rtx_REG (SImode, 0);
5489 operands[3] = GEN_INT (c);
5490 output_asm_insn (AS2 (testl,%3,%2), operands);
5491 return eq ? AS1 (sete,%0) : AS1 (setne, %0);
5494 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
5496 return AS1(set%D1,%0);
5500 ;; Basic conditional jump instructions.
5501 ;; We ignore the overflow flag for signed branch instructions.
5503 ;; For all bCOND expanders, also expand the compare or test insn that
5504 ;; generates cc0. Generate an equality comparison if `beq' or
`bne'.
5506 (define_expand "beq"
5509 (if_then_else (eq (cc0)
5511 (label_ref (match_operand 0 "" ""))
5517 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5518 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5520 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5523 (define_expand "bne"
5526 (if_then_else (ne (cc0)
5528 (label_ref (match_operand 0 "" ""))
5534 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5535 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5537 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5541 (define_expand "bgt"
5544 (if_then_else (gt (cc0)
5546 (label_ref (match_operand 0 "" ""))
5549 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5551 (define_expand "bgtu"
5554 (if_then_else (gtu (cc0)
5556 (label_ref (match_operand 0 "" ""))
5559 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5561 (define_expand "blt"
5564 (if_then_else (lt (cc0)
5566 (label_ref (match_operand 0 "" ""))
5569 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5572 (define_expand "bltu"
5575 (if_then_else (ltu (cc0)
5577 (label_ref (match_operand 0 "" ""))
5580 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5582 (define_expand "bge"
5585 (if_then_else (ge (cc0)
5587 (label_ref (match_operand 0 "" ""))
5590 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5592 (define_expand "bgeu"
5595 (if_then_else (geu (cc0)
5597 (label_ref (match_operand 0 "" ""))
5600 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5602 (define_expand "ble"
5605 (if_then_else (le (cc0)
5607 (label_ref (match_operand 0 "" ""))
5610 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5612 (define_expand "bleu"
5615 (if_then_else (leu (cc0)
5617 (label_ref (match_operand 0 "" ""))
5620 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5624 (if_then_else (match_operator 0 "comparison_operator"
5625 [(cc0) (const_int 0)])
5626 (label_ref (match_operand 1 "" ""))
5631 enum rtx_code code = GET_CODE (operands[0]);
5632 if (cc_prev_status.flags & CC_TEST_AX)
5636 operands[2] = gen_rtx_REG (SImode, 0);
5666 operands[3] = GEN_INT (c);
5667 output_asm_insn (AS2 (testl,%3,%2), operands);
5668 return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
5670 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
5673 return AS1(j%D0,%l1);
5678 (if_then_else (match_operator 0 "comparison_operator"
5679 [(cc0) (const_int 0)])
5681 (label_ref (match_operand 1 "" ""))))]
5685 enum rtx_code code = GET_CODE (operands[0]);
5686 if (cc_prev_status.flags & CC_TEST_AX)
5690 operands[2] = gen_rtx_REG (SImode, 0);
5720 operands[3] = GEN_INT (c);
5721 output_asm_insn (AS2 (testl,%3,%2), operands);
5722 return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
5724 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
5727 return AS1(j%d0,%l1);
5730 ;; Unconditional and other jump instructions
5734 (label_ref (match_operand 0 "" "")))]
5738 (define_insn "indirect_jump"
5739 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
5745 return AS1 (jmp,%*%0);
5748 ;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
5749 ;; if S does not change i
5751 (define_expand "decrement_and_branch_until_zero"
5752 [(parallel [(set (pc)
5753 (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "")
5756 (label_ref (match_operand 1 "" ""))
5759 (plus:SI (match_dup 0)
5766 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
5767 [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+c*r,m")
5768 (match_operand:SI 2 "general_operand" "rmi,ri"))
5770 (label_ref (match_operand 3 "" ""))
5773 (plus:SI (match_dup 1)
5780 if (GET_CODE (operands[1]) == REG && REGNO (operands[2]) == 2 &&
5781 operands[2] == constm1_rtx && ix86_cpu == PROCESSOR_K6)
5782 return \"loop %l3\";
5784 if (operands[2] == constm1_rtx)
5785 output_asm_insn (AS1 (dec%L1,%1), operands);
5787 else if (operands[2] == const1_rtx)
5788 output_asm_insn (AS1 (inc%L1,%1), operands);
5791 output_asm_insn (AS2 (add%L1,%2,%1), operands);
5793 return AS1 (%J0,%l3);
5798 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
5799 [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
5800 (match_operand:SI 2 "general_operand" "rmi,ri"))
5802 (label_ref (match_operand 3 "" ""))
5805 (minus:SI (match_dup 1)
5811 if (operands[2] == const1_rtx)
5812 output_asm_insn (AS1 (dec%L1,%1), operands);
5814 else if (operands[1] == constm1_rtx)
5815 output_asm_insn (AS1 (inc%L1,%1), operands);
5818 output_asm_insn (AS2 (sub%L1,%2,%1), operands);
5820 return AS1 (%J0,%l3);
5825 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
5827 (label_ref (match_operand 1 "" ""))
5830 (plus:SI (match_dup 0)
5836 operands[2] = const1_rtx;
5837 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
5843 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
5845 (label_ref (match_operand 1 "" ""))
5848 (plus:SI (match_dup 0)
5854 operands[2] = const1_rtx;
5855 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
5861 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
5863 (label_ref (match_operand 1 "" ""))
5866 (plus:SI (match_dup 0)
5872 output_asm_insn (AS1 (dec%L0,%0), operands);
5878 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
5880 (label_ref (match_operand 1 "" ""))
5883 (plus:SI (match_dup 0)
5889 output_asm_insn (AS1 (dec%L0,%0), operands);
5895 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
5897 (label_ref (match_operand 1 "" ""))
5900 (plus:SI (match_dup 0)
5906 output_asm_insn (AS1 (inc%L0,%0), operands);
5912 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
5914 (label_ref (match_operand 1 "" ""))
5917 (plus:SI (match_dup 0)
5923 output_asm_insn (AS1 (inc%L0,%0), operands);
5927 ;; Implement switch statements when generating PIC code. Switches are
5928 ;; implemented by `tablejump' when not using -fpic.
5930 ;; Emit code here to do the range checking and make the index zero based.
5932 (define_expand "casesi"
5934 (match_operand:SI
0 "general_operand" ""))
5936 (minus:SI (match_dup
5)
5937 (match_operand:SI
1 "general_operand" "")))
5939 (compare:CC (match_dup
6)
5940 (match_operand:SI
2 "general_operand" "")))
5942 (if_then_else (gtu (cc0)
5944 (label_ref (match_operand
4 "" ""))
5948 (minus:SI (reg:SI
3)
5949 (mem:SI (plus:SI (mult:SI (match_dup
6)
5951 (label_ref (match_operand
3 "" ""))))))
5952 (clobber (match_scratch:SI
7 ""))])]
5956 operands[
5] = gen_reg_rtx (SImode);
5957 operands[
6] = gen_reg_rtx (SImode);
5958 current_function_uses_pic_offset_table =
1;
5961 ;; Implement a casesi insn.
5963 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
5966 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
5968 ;;
1. An expression involving an external reference may only use the
5969 ;; addition operator, and only with an assembly-time constant.
5970 ;; The example above satisfies this because ".-.L2" is a constant.
5972 ;;
2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
5973 ;; given the value of "GOT - .", where GOT is the actual address of
5974 ;; the Global Offset Table. Therefore, the .long above actually
5975 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
5976 ;; expression "GOT - .L2" by itself would generate an error from as(
1).
5978 ;; The pattern below emits code that looks like this:
5981 ;; subl TABLE@GOTOFF(%ebx,index,
4),reg
5984 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
5985 ;; the addr_diff_vec is known to be part of this module.
5987 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
5988 ;; evaluates to just ".L2".
5992 (minus:SI (reg:SI
3)
5994 (mult:SI (match_operand:SI
0 "register_operand" "r")
5996 (label_ref (match_operand
1 "" ""))))))
5997 (clobber (match_scratch:SI
2 "=&r"))]
6003 xops[
0] = operands[
0];
6004 xops[
1] = operands[
1];
6005 xops[
2] = operands[
2];
6006 xops[
3] = pic_offset_table_rtx;
6008 output_asm_insn (AS2 (mov%L2,%
3,%
2), xops);
6009 output_asm_insn (
\"sub%L2 %l1@GOTOFF(%
3,%
0,
4),%
2\", xops);
6010 output_asm_insn (AS1 (jmp,%*%
2), xops);
6011 ASM_OUTPUT_ALIGN (asm_out_file, i386_align_jumps);
6015 (define_insn "tablejump"
6016 [(set (pc) (match_operand:SI
0 "nonimmediate_operand" "rm"))
6017 (use (label_ref (match_operand
1 "" "")))]
6023 return AS1 (jmp,%*%
0);
6028 ;; If generating PIC code, the predicate indirect_operand will fail
6029 ;; for operands[
0] containing symbolic references on all of the named
6030 ;; call* patterns. Each named pattern is followed by an unnamed pattern
6031 ;; that matches any call to a symbolic CONST (ie, a symbol_ref). The
6032 ;; unnamed patterns are only used while generating PIC code, because
6033 ;; otherwise the named patterns match.
6035 ;; Call subroutine returning no value.
6037 (define_expand "call_pop"
6038 [(parallel [(call (match_operand:QI
0 "indirect_operand" "")
6039 (match_operand:SI
1 "general_operand" ""))
6042 (match_operand:SI
3 "immediate_operand" "")))])]
6049 current_function_uses_pic_offset_table =
1;
6051 /* With half-pic, force the address into a register. */
6052 addr = XEXP (operands[
0],
0);
6053 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6054 XEXP (operands[
0],
0) = force_reg (Pmode, addr);
6056 if (! expander_call_insn_operand (operands[
0], QImode))
6058 = change_address (operands[
0], VOIDmode,
6059 copy_to_mode_reg (Pmode, XEXP (operands[
0],
0)));
6063 [(call (match_operand:QI
0 "call_insn_operand" "m")
6064 (match_operand:SI
1 "general_operand" "g"))
6065 (set (reg:SI
7) (plus:SI (reg:SI
7)
6066 (match_operand:SI
3 "immediate_operand" "i")))]
6070 if (GET_CODE (operands[
0]) == MEM
6071 && ! CONSTANT_ADDRESS_P (XEXP (operands[
0],
0)))
6073 operands[
0] = XEXP (operands[
0],
0);
6074 return AS1 (call,%*%
0);
6077 return AS1 (call,%P0);
6081 [(call (mem:QI (match_operand:SI
0 "symbolic_operand" ""))
6082 (match_operand:SI
1 "general_operand" "g"))
6083 (set (reg:SI
7) (plus:SI (reg:SI
7)
6084 (match_operand:SI
3 "immediate_operand" "i")))]
6088 (define_expand "call"
6089 [(call (match_operand:QI
0 "indirect_operand" "")
6090 (match_operand:SI
1 "general_operand" ""))]
6091 ;; Operand
1 not used on the i386.
6098 current_function_uses_pic_offset_table =
1;
6100 /* With half-pic, force the address into a register. */
6101 addr = XEXP (operands[
0],
0);
6102 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6103 XEXP (operands[
0],
0) = force_reg (Pmode, addr);
6105 if (! expander_call_insn_operand (operands[
0], QImode))
6107 = change_address (operands[
0], VOIDmode,
6108 copy_to_mode_reg (Pmode, XEXP (operands[
0],
0)));
6112 [(call (match_operand:QI
0 "call_insn_operand" "m")
6113 (match_operand:SI
1 "general_operand" "g"))]
6114 ;; Operand
1 not used on the i386.
6118 if (GET_CODE (operands[
0]) == MEM
6119 && ! CONSTANT_ADDRESS_P (XEXP (operands[
0],
0)))
6121 operands[
0] = XEXP (operands[
0],
0);
6122 return AS1 (call,%*%
0);
6125 return AS1 (call,%P0);
6129 [(call (mem:QI (match_operand:SI
0 "symbolic_operand" ""))
6130 (match_operand:SI
1 "general_operand" "g"))]
6131 ;; Operand
1 not used on the i386.
6135 ;; Call subroutine, returning value in operand
0
6136 ;; (which must be a hard register).
6138 (define_expand "call_value_pop"
6139 [(parallel [(set (match_operand
0 "" "")
6140 (call (match_operand:QI
1 "indirect_operand" "")
6141 (match_operand:SI
2 "general_operand" "")))
6144 (match_operand:SI
4 "immediate_operand" "")))])]
6151 current_function_uses_pic_offset_table =
1;
6153 /* With half-pic, force the address into a register. */
6154 addr = XEXP (operands[
1],
0);
6155 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6156 XEXP (operands[
1],
0) = force_reg (Pmode, addr);
6158 if (! expander_call_insn_operand (operands[
1], QImode))
6160 = change_address (operands[
1], VOIDmode,
6161 copy_to_mode_reg (Pmode, XEXP (operands[
1],
0)));
6165 [(set (match_operand
0 "" "=rf")
6166 (call (match_operand:QI
1 "call_insn_operand" "m")
6167 (match_operand:SI
2 "general_operand" "g")))
6168 (set (reg:SI
7) (plus:SI (reg:SI
7)
6169 (match_operand:SI
4 "immediate_operand" "i")))]
6173 if (GET_CODE (operands[
1]) == MEM
6174 && ! CONSTANT_ADDRESS_P (XEXP (operands[
1],
0)))
6176 operands[
1] = XEXP (operands[
1],
0);
6177 output_asm_insn (AS1 (call,%*%
1), operands);
6180 output_asm_insn (AS1 (call,%P1), operands);
6186 [(set (match_operand
0 "" "=rf")
6187 (call (mem:QI (match_operand:SI
1 "symbolic_operand" ""))
6188 (match_operand:SI
2 "general_operand" "g")))
6189 (set (reg:SI
7) (plus:SI (reg:SI
7)
6190 (match_operand:SI
4 "immediate_operand" "i")))]
6194 (define_expand "call_value"
6195 [(set (match_operand
0 "" "")
6196 (call (match_operand:QI
1 "indirect_operand" "")
6197 (match_operand:SI
2 "general_operand" "")))]
6198 ;; Operand
2 not used on the i386.
6205 current_function_uses_pic_offset_table =
1;
6207 /* With half-pic, force the address into a register. */
6208 addr = XEXP (operands[
1],
0);
6209 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6210 XEXP (operands[
1],
0) = force_reg (Pmode, addr);
6212 if (! expander_call_insn_operand (operands[
1], QImode))
6214 = change_address (operands[
1], VOIDmode,
6215 copy_to_mode_reg (Pmode, XEXP (operands[
1],
0)));
6219 [(set (match_operand
0 "" "=rf")
6220 (call (match_operand:QI
1 "call_insn_operand" "m")
6221 (match_operand:SI
2 "general_operand" "g")))]
6222 ;; Operand
2 not used on the i386.
6226 if (GET_CODE (operands[
1]) == MEM
6227 && ! CONSTANT_ADDRESS_P (XEXP (operands[
1],
0)))
6229 operands[
1] = XEXP (operands[
1],
0);
6230 output_asm_insn (AS1 (call,%*%
1), operands);
6233 output_asm_insn (AS1 (call,%P1), operands);
6239 [(set (match_operand
0 "" "=rf")
6240 (call (mem:QI (match_operand:SI
1 "symbolic_operand" ""))
6241 (match_operand:SI
2 "general_operand" "g")))]
6242 ;; Operand
2 not used on the i386.
6246 ;; Call subroutine returning any type.
6248 (define_expand "untyped_call"
6249 [(parallel [(call (match_operand
0 "" "")
6251 (match_operand
1 "" "")
6252 (match_operand
2 "" "")])]
6258 /* In order to give reg-stack an easier job in validating two
6259 coprocessor registers as containing a possible return value,
6260 simply pretend the untyped call returns a complex long double
6263 emit_call_insn (TARGET_80387
6264 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
6265 operands[
0], const0_rtx)
6266 : gen_call (operands[
0], const0_rtx));
6268 for (i =
0; i < XVECLEN (operands[
2],
0); i++)
6270 rtx set = XVECEXP (operands[
2],
0, i);
6271 emit_move_insn (SET_DEST (set), SET_SRC (set));
6274 /* The optimizer does not know that the call sets the function value
6275 registers we stored in the result block. We avoid problems by
6276 claiming that all hard registers are used and clobbered at this
6278 emit_insn (gen_blockage ());
6283 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6284 ;; all of memory. This blocks insns from being moved across this point.
6286 (define_insn "blockage"
6287 [(unspec_volatile [(const_int
0)]
0)]
6291 ;; Insn emitted into the body of a function to return from a function.
6292 ;; This is only done if the function's epilogue is known to be simple.
6293 ;; See comments for simple_386_epilogue in i386.c.
6295 (define_expand "return"
6297 "ix86_can_use_return_insn_p ()"
6300 (define_insn "return_internal"
6305 (define_insn "return_pop_internal"
6307 (use (match_operand:SI
0 "const_int_operand" ""))]
6316 (define_expand "prologue"
6321 ix86_expand_prologue ();
6325 ;; The use of UNSPEC here is currently not necessary - a simple SET of ebp
6326 ;; to itself would be enough. But this way we are safe even if some optimizer
6327 ;; becomes too clever in the future.
6328 (define_insn "prologue_set_stack_ptr"
6330 (minus:SI (reg:SI
7) (match_operand:SI
0 "immediate_operand" "i")))
6331 (set (reg:SI
6) (unspec:SI [(reg:SI
6)]
4))]
6337 xops[
0] = operands[
0];
6338 xops[
1] = stack_pointer_rtx;
6339 output_asm_insn (AS2 (sub%L1,%
0,%
1), xops);
6343 (define_insn "prologue_set_got"
6344 [(set (match_operand:SI
0 "" "")
6346 [(plus:SI (match_dup
0)
6347 (plus:SI (match_operand:SI
1 "symbolic_operand" "")
6348 (minus:SI (pc) (match_operand
2 "" ""))))]
1))]
6354 if (TARGET_DEEP_BRANCH_PREDICTION)
6356 sprintf (buffer,
\"addl %s,%%
0\", XSTR (operands[
1],
0));
6357 output_asm_insn (buffer, operands);
6361 sprintf (buffer,
\"addl %s+[.-%%X2],%%
0\", XSTR (operands[
1],
0));
6362 output_asm_insn (buffer, operands);
6367 (define_insn "prologue_get_pc"
6368 [(set (match_operand:SI
0 "" "")
6369 (unspec_volatile [(plus:SI (pc) (match_operand
1 "" ""))]
2))]
6375 output_asm_insn (AS1 (call,%X1), operands);
6376 if (! TARGET_DEEP_BRANCH_PREDICTION)
6378 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file,
\"L
\", CODE_LABEL_NUMBER (operands[
1]));
6383 (define_insn "prologue_get_pc_and_set_got"
6384 [(unspec_volatile [(match_operand:SI
0 "" "")]
3)]
6388 operands[
1] = gen_label_rtx ();
6389 output_asm_insn (AS1 (call,%X1), operands);
6390 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file,
\"L
\",
6391 CODE_LABEL_NUMBER (operands[
1]));
6392 output_asm_insn (AS1 (pop%L0,%
0), operands);
6393 output_asm_insn (
\"addl $_GLOBAL_OFFSET_TABLE_+[.-%X1],%
0\", operands);
6397 (define_expand "epilogue"
6402 ix86_expand_epilogue ();
6406 (define_insn "epilogue_set_stack_ptr"
6407 [(set (reg:SI
7) (reg:SI
6))
6408 (clobber (reg:SI
6))]
6414 xops[
0] = frame_pointer_rtx;
6415 xops[
1] = stack_pointer_rtx;
6416 output_asm_insn (AS2 (mov%L0,%
0,%
1), xops);
6420 (define_insn "leave"
6422 (clobber (reg:SI
6))
6423 (clobber (reg:SI
7))]
6428 [(set (match_operand:SI
0 "register_operand" "r")
6429 (mem:SI (reg:SI
7)))
6430 (set (reg:SI
7) (plus:SI (reg:SI
7) (const_int
4)))]
6434 output_asm_insn (AS1 (pop%L0,%P0), operands);
6438 (define_expand "movstrsi"
6439 [(parallel [(set (match_operand:BLK
0 "memory_operand" "")
6440 (match_operand:BLK
1 "memory_operand" ""))
6441 (use (match_operand:SI
2 "const_int_operand" ""))
6442 (use (match_operand:SI
3 "const_int_operand" ""))
6443 (clobber (match_scratch:SI
4 ""))
6444 (clobber (match_dup
5))
6445 (clobber (match_dup
6))])]
6451 if (GET_CODE (operands[
2]) != CONST_INT)
6454 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[
0],
0));
6455 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[
1],
0));
6457 operands[
5] = addr0;
6458 operands[
6] = addr1;
6460 operands[
0] = change_address (operands[
0], VOIDmode, addr0);
6461 operands[
1] = change_address (operands[
1], VOIDmode, addr1);
6464 ;; It might seem that operands
0 &
1 could use predicate register_operand.
6465 ;; But strength reduction might offset the MEM expression. So we let
6466 ;; reload put the address into %edi & %esi.
6469 [(set (mem:BLK (match_operand:SI
0 "address_operand" "D"))
6470 (mem:BLK (match_operand:SI
1 "address_operand" "S")))
6471 (use (match_operand:SI
2 "const_int_operand" "n"))
6472 (use (match_operand:SI
3 "immediate_operand" "i"))
6473 (clobber (match_scratch:SI
4 "=&c"))
6474 (clobber (match_dup
0))
6475 (clobber (match_dup
1))]
6481 output_asm_insn (
\"cld
\", operands);
6482 if (GET_CODE (operands[
2]) == CONST_INT)
6484 if (INTVAL (operands[
2]) & ~
0x03)
6486 xops[
0] = GEN_INT ((INTVAL (operands[
2]) >>
2) &
0x3fffffff);
6487 xops[
1] = operands[
4];
6489 output_asm_insn (AS2 (mov%L1,%
0,%
1), xops);
6491 output_asm_insn (
\"rep movsd
\", xops);
6493 output_asm_insn (
\"rep\;movsl
\", xops);
6496 if (INTVAL (operands[
2]) &
0x02)
6497 output_asm_insn (
\"movsw
\", operands);
6498 if (INTVAL (operands[
2]) &
0x01)
6499 output_asm_insn (
\"movsb
\", operands);
6506 (define_expand "clrstrsi"
6507 [(set (match_dup
3) (const_int
0))
6508 (parallel [(set (match_operand:BLK
0 "memory_operand" "")
6510 (use (match_operand:SI
1 "const_int_operand" ""))
6511 (use (match_operand:SI
2 "const_int_operand" ""))
6513 (clobber (match_scratch:SI
4 ""))
6514 (clobber (match_dup
5))])]
6520 if (GET_CODE (operands[
1]) != CONST_INT)
6523 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[
0],
0));
6525 operands[
3] = gen_reg_rtx (SImode);
6526 operands[
5] = addr0;
6528 operands[
0] = gen_rtx_MEM (BLKmode, addr0);
6531 ;; It might seem that operand
0 could use predicate register_operand.
6532 ;; But strength reduction might offset the MEM expression. So we let
6533 ;; reload put the address into %edi.
6535 (define_insn "*bzero"
6536 [(set (mem:BLK (match_operand:SI
0 "address_operand" "D"))
6538 (use (match_operand:SI
1 "const_int_operand" "n"))
6539 (use (match_operand:SI
2 "immediate_operand" "i"))
6540 (use (match_operand:SI
3 "register_operand" "a"))
6541 (clobber (match_scratch:SI
4 "=&c"))
6542 (clobber (match_dup
0))]
6548 output_asm_insn (
\"cld
\", operands);
6549 if (GET_CODE (operands[
1]) == CONST_INT)
6551 unsigned int count = INTVAL (operands[
1]) &
0xffffffff;
6554 xops[
0] = GEN_INT (count /
4);
6555 xops[
1] = operands[
4];
6557 /* K6: stos takes
1 cycle, rep stos takes
8 + %ecx cycles.
6558 80386:
4/
5+
5n (+
2 for set of ecx)
6559 80486:
5/
7+
5n (+
1 for set of ecx)
6561 if (count /
4 < ((int) ix86_cpu < (int)PROCESSOR_PENTIUM ?
4 :
6))
6565 output_asm_insn (
\"stosd
\", xops);
6567 output_asm_insn (
\"stosl
\", xops);
6569 while ((count -=
4) >
3);
6573 output_asm_insn (AS2 (mov%L1,%
0,%
1), xops);
6575 output_asm_insn (
\"rep stosd
\", xops);
6577 output_asm_insn (
\"rep\;stosl
\", xops);
6581 if (INTVAL (operands[
1]) &
0x02)
6582 output_asm_insn (
\"stosw
\", operands);
6583 if (INTVAL (operands[
1]) &
0x01)
6584 output_asm_insn (
\"stosb
\", operands);
6591 (define_expand "cmpstrsi"
6592 [(parallel [(set (match_operand:SI
0 "general_operand" "")
6593 (compare:SI (match_operand:BLK
1 "general_operand" "")
6594 (match_operand:BLK
2 "general_operand" "")))
6595 (use (match_operand:SI
3 "general_operand" ""))
6596 (use (match_operand:SI
4 "immediate_operand" ""))
6597 (clobber (match_dup
5))
6598 (clobber (match_dup
6))
6599 (clobber (match_dup
3))])]
6605 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[
1],
0));
6606 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[
2],
0));
6607 operands[
3] = copy_to_mode_reg (SImode, operands[
3]);
6609 operands[
5] = addr1;
6610 operands[
6] = addr2;
6612 operands[
1] = gen_rtx_MEM (BLKmode, addr1);
6613 operands[
2] = gen_rtx_MEM (BLKmode, addr2);
6617 ;; memcmp recognizers. The
`cmpsb' opcode does nothing if the count is
6618 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
6620 ;; It might seem that operands 0 & 1 could use predicate register_operand.
6621 ;; But strength reduction might offset the MEM expression. So we let
6622 ;; reload put the address into %edi & %esi.
6624 ;; ??? Most comparisons have a constant length, and it's therefore
6625 ;; possible to know that the length is non-zero, and to avoid the extra
6626 ;; code to handle zero-length compares.
6629 [(set (match_operand:SI 0 "register_operand" "=&r")
6630 (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
6631 (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
6632 (use (match_operand:SI 3 "register_operand" "c"))
6633 (use (match_operand:SI 4 "immediate_operand" "i"))
6634 (clobber (match_dup 1))
6635 (clobber (match_dup 2))
6636 (clobber (match_dup 3))]
6642 label = gen_label_rtx ();
6644 output_asm_insn (\"cld\", operands);
6645 output_asm_insn (AS2 (xor%L0,%0,%0), operands);
6646 output_asm_insn (\"repz\;cmps%B2\", operands);
6647 output_asm_insn (\"je %l0\", &label);
6649 xops[0] = operands[0];
6650 xops[1] = const1_rtx;
6651 output_asm_insn (AS2 (sbb%L0,%0,%0), xops);
6652 if (QI_REG_P (xops[0]))
6653 output_asm_insn (AS2 (or%B0,%1,%b0), xops);
6655 output_asm_insn (AS2 (or%L0,%1,%0), xops);
6657 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
6663 (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
6664 (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
6665 (use (match_operand:SI 2 "register_operand" "c"))
6666 (use (match_operand:SI 3 "immediate_operand" "i"))
6667 (clobber (match_dup 0))
6668 (clobber (match_dup 1))
6669 (clobber (match_dup 2))]
6675 cc_status.flags |= CC_NOT_SIGNED;
6677 xops[0] = gen_rtx_REG (QImode, 0);
6678 xops[1] = CONST0_RTX (QImode);
6680 output_asm_insn (\"cld\", operands);
6681 output_asm_insn (AS2 (test%B0,%1,%0), xops);
6682 return \"repz\;cmps%B2\";
6686 ;; Note, you cannot optimize away the branch following the bsfl by assuming
6687 ;; that the destination is not modified if the input is 0, since not all
6688 ;; x86 implementations do this.
6690 (define_expand "ffssi2"
6691 [(set (match_operand:SI 0 "general_operand" "")
6692 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
6696 rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode);
6698 emit_insn (gen_ffssi_1 (temp, operands[1]));
6699 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0);
6700 emit_jump_insn (gen_bne (label));
6701 emit_move_insn (temp, constm1_rtx);
6703 temp = expand_binop (SImode, add_optab, temp, const1_rtx,
6704 operands[0], 0, OPTAB_WIDEN);
6706 if (temp != operands[0])
6707 emit_move_insn (operands[0], temp);
6711 (define_insn "ffssi_1"
6712 [(set (match_operand:SI 0 "register_operand" "=r")
6713 (unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
6715 "* return AS2 (bsf%L0,%1,%0);")
6717 (define_expand "ffshi2"
6718 [(set (match_operand:SI 0 "general_operand" "")
6719 (ffs:HI (match_operand:HI 1 "general_operand" "")))]
6723 rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode);
6725 emit_insn (gen_ffshi_1 (temp, operands[1]));
6726 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0);
6727 emit_jump_insn (gen_bne (label));
6728 emit_move_insn (temp, constm1_rtx);
6730 temp = expand_binop (HImode, add_optab, temp, const1_rtx,
6731 operands[0], 0, OPTAB_WIDEN);
6733 if (temp != operands[0])
6734 emit_move_insn (operands[0], temp);
6738 (define_insn "ffshi_1"
6739 [(set (match_operand:HI 0 "register_operand" "=r")
6740 (unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
6742 "* return AS2 (bsf%W0,%1,%0);")
6744 ;; These patterns match the binary 387 instructions for addM3, subM3,
6745 ;; mulM3 and divM3. There are three patterns for each of DFmode and
6746 ;; SFmode. The first is the normal insn, the second the same insn but
6747 ;; with one operand a conversion, and the third the same insn but with
6748 ;; the other operand a conversion. The conversion may be SFmode or
6749 ;; SImode if the target mode DFmode, but only SImode if the target mode
6753 [(set (match_operand:DF 0 "register_operand" "=f,f")
6754 (match_operator:DF 3 "binary_387_op"
6755 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
6756 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
6758 "* return output_387_binary_op (insn, operands);"
6760 (cond [(match_operand:DF 3 "is_mul" "")
6761 (const_string "fpmul")
6762 (match_operand:DF 3 "is_div" "")
6763 (const_string "fpdiv")
6765 (const_string "fpop")
6770 [(set (match_operand:DF 0 "register_operand" "=f")
6771 (match_operator:DF 3 "binary_387_op"
6772 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "rm"))
6773 (match_operand:DF 2 "register_operand" "0")]))]
6775 "* return output_387_binary_op (insn, operands);"
6777 (cond [(match_operand:DF 3 "is_mul" "")
6778 (const_string "fpmul")
6779 (match_operand:DF 3 "is_div" "")
6780 (const_string "fpdiv")
6782 (const_string "fpop")
6787 [(set (match_operand:XF 0 "register_operand" "=f,f")
6788 (match_operator:XF 3 "binary_387_op"
6789 [(match_operand:XF 1 "register_operand" "0,f")
6790 (match_operand:XF 2 "register_operand" "f,0")]))]
6792 "* return output_387_binary_op (insn, operands);"
6794 (cond [(match_operand:DF 3 "is_mul" "")
6795 (const_string "fpmul")
6796 (match_operand:DF 3 "is_div" "")
6797 (const_string "fpdiv")
6799 (const_string "fpop")
6804 [(set (match_operand:XF 0 "register_operand" "=f")
6805 (match_operator:XF 3 "binary_387_op"
6806 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "rm"))
6807 (match_operand:XF 2 "register_operand" "0")]))]
6809 "* return output_387_binary_op (insn, operands);"
6811 (cond [(match_operand:DF 3 "is_mul" "")
6812 (const_string "fpmul")
6813 (match_operand:DF 3 "is_div" "")
6814 (const_string "fpdiv")
6816 (const_string "fpop")
6821 [(set (match_operand:XF 0 "register_operand" "=f,f")
6822 (match_operator:XF 3 "binary_387_op"
6823 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
6824 (match_operand:XF 2 "register_operand" "0,f")]))]
6826 "* return output_387_binary_op (insn, operands);"
6828 (cond [(match_operand:DF 3 "is_mul" "")
6829 (const_string "fpmul")
6830 (match_operand:DF 3 "is_div" "")
6831 (const_string "fpdiv")
6833 (const_string "fpop")
6838 [(set (match_operand:XF 0 "register_operand" "=f")
6839 (match_operator:XF 3 "binary_387_op"
6840 [(match_operand:XF 1 "register_operand" "0")
6841 (float:XF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
6843 "* return output_387_binary_op (insn, operands);"
6845 (cond [(match_operand:DF 3 "is_mul" "")
6846 (const_string "fpmul")
6847 (match_operand:DF 3 "is_div" "")
6848 (const_string "fpdiv")
6850 (const_string "fpop")
6855 [(set (match_operand:XF 0 "register_operand" "=f,f")
6856 (match_operator:XF 3 "binary_387_op"
6857 [(match_operand:XF 1 "register_operand" "0,f")
6859 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
6861 "* return output_387_binary_op (insn, operands);"
6863 (cond [(match_operand:DF 3 "is_mul" "")
6864 (const_string "fpmul")
6865 (match_operand:DF 3 "is_div" "")
6866 (const_string "fpdiv")
6868 (const_string "fpop")
6873 [(set (match_operand:DF 0 "register_operand" "=f,f")
6874 (match_operator:DF 3 "binary_387_op"
6875 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
6876 (match_operand:DF 2 "register_operand" "0,f")]))]
6878 "* return output_387_binary_op (insn, operands);"
6880 (cond [(match_operand:DF 3 "is_mul" "")
6881 (const_string "fpmul")
6882 (match_operand:DF 3 "is_div" "")
6883 (const_string "fpdiv")
6885 (const_string "fpop")
6890 [(set (match_operand:DF 0 "register_operand" "=f")
6891 (match_operator:DF 3 "binary_387_op"
6892 [(match_operand:DF 1 "register_operand" "0")
6893 (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
6895 "* return output_387_binary_op (insn, operands);"
6897 (cond [(match_operand:DF 3 "is_mul" "")
6898 (const_string "fpmul")
6899 (match_operand:DF 3 "is_div" "")
6900 (const_string "fpdiv")
6902 (const_string "fpop")
6907 [(set (match_operand:DF 0 "register_operand" "=f,f")
6908 (match_operator:DF 3 "binary_387_op"
6909 [(match_operand:DF 1 "register_operand" "0,f")
6911 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
6913 "* return output_387_binary_op (insn, operands);"
6915 (cond [(match_operand:DF 3 "is_mul" "")
6916 (const_string "fpmul")
6917 (match_operand:DF 3 "is_div" "")
6918 (const_string "fpdiv")
6920 (const_string "fpop")
6925 [(set (match_operand:SF 0 "register_operand" "=f,f")
6926 (match_operator:SF 3 "binary_387_op"
6927 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
6928 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
6930 "* return output_387_binary_op (insn, operands);"
6932 (cond [(match_operand:DF 3 "is_mul" "")
6933 (const_string "fpmul")
6934 (match_operand:DF 3 "is_div" "")
6935 (const_string "fpdiv")
6937 (const_string "fpop")
6942 [(set (match_operand:SF 0 "register_operand" "=f")
6943 (match_operator:SF 3 "binary_387_op"
6944 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "rm"))
6945 (match_operand:SF 2 "register_operand" "0")]))]
6947 "* return output_387_binary_op (insn, operands);"
6949 (cond [(match_operand:DF 3 "is_mul" "")
6950 (const_string "fpmul")
6951 (match_operand:DF 3 "is_div" "")
6952 (const_string "fpdiv")
6954 (const_string "fpop")
6959 [(set (match_operand:SF 0 "register_operand" "=f")
6960 (match_operator:SF 3 "binary_387_op"
6961 [(match_operand:SF 1 "register_operand" "0")
6962 (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
6964 "* return output_387_binary_op (insn, operands);"
6966 (cond [(match_operand:DF 3 "is_mul" "")
6967 (const_string "fpmul")
6968 (match_operand:DF 3 "is_div" "")
6969 (const_string "fpdiv")
6971 (const_string "fpop")
6975 (define_expand "strlensi"
6976 [(parallel [(set (match_dup 4)
6977 (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
6978 (match_operand:QI 2 "immediate_operand" "")
6979 (match_operand:SI 3 "immediate_operand" "")] 0))
6980 (clobber (match_dup 1))])
6982 (not:SI (match_dup 4)))
6983 (set (match_operand:SI 0 "register_operand" "")
6984 (plus:SI (match_dup 5)
6989 if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1)
6994 /* well it seems that some optimizer does not combine a call like
6995 foo(strlen(bar), strlen(bar));
6996 when the move and the subtraction is done here. It does calculate
6997 the length just once when these instructions are done inside of
6998 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
6999 often used and I use one fewer register for the lifetime of
7000 output_strlen_unroll() this is better. */
7001 scratch = gen_reg_rtx (SImode);
7002 address = force_reg (SImode, XEXP (operands[1], 0));
7004 /* move address to scratch-register
7005 this is done here because the i586 can do the following and
7006 in the same cycle with the following move. */
7007 if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4)
7008 emit_insn (gen_movsi (scratch, address));
7010 emit_insn (gen_movsi (operands[0], address));
7012 if(TARGET_USE_Q_REG)
7013 emit_insn (gen_strlensi_unroll5 (operands[0],
7018 emit_insn (gen_strlensi_unroll4 (operands[0],
7023 /* gen_strlensi_unroll[45] returns the address of the zero
7024 at the end of the string, like memchr(), so compute the
7025 length by subtracting the startaddress. */
7026 emit_insn (gen_subsi3 (operands[0], operands[0], address));
7030 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7031 operands[4] = gen_reg_rtx (SImode);
7032 operands[5] = gen_reg_rtx (SImode);
7035 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7036 ;; But strength reduction might offset the MEM expression. So we let
7037 ;; reload put the address into %edi.
7040 [(set (match_operand:SI 0 "register_operand" "=&c")
7041 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
7042 (match_operand:QI 2 "immediate_operand" "a")
7043 (match_operand:SI 3 "immediate_operand" "i")] 0))
7044 (clobber (match_dup 1))]
7050 xops[0] = operands[0];
7051 xops[1] = constm1_rtx;
7052 output_asm_insn (\"cld\", operands);
7053 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
7054 return \"repnz\;scas%B2\";
7057 /* Conditional move define_insns. */
7059 (define_expand "movsicc"
7060 [(set (match_operand:SI 0 "register_operand" "")
7061 (if_then_else:SI (match_operand 1 "comparison_operator" "")
7062 (match_operand:SI 2 "nonimmediate_operand" "")
7063 (match_operand:SI 3 "nonimmediate_operand" "")))]
7067 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7070 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7071 GET_MODE (i386_compare_op0),
7072 i386_compare_op0, i386_compare_op1);
7076 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
7077 (if_then_else:SI (match_operator 1 "comparison_operator"
7078 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
7079 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
7080 (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
7081 (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
7086 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
7087 (if_then_else:SI (match_operator 1 "comparison_operator"
7088 [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
7089 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
7090 (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
7091 (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
7092 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7096 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7097 (if_then_else:SI (match_operator 1 "comparison_operator"
7098 [(match_operand 2 "nonimmediate_operand" "")
7100 (match_operand:SI 3 "nonimmediate_operand" "rm,0,rm")
7101 (match_operand:SI 4 "nonimmediate_operand" "0,rm,rm")))]
7102 "TARGET_CMOVE && reload_completed"
7106 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7107 (match_dup 3) (match_dup 4)))]
7111 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7112 (if_then_else:SI (match_operator 1 "comparison_operator"
7113 [(match_operand 2 "nonimmediate_operand" "")
7114 (match_operand 3 "general_operand" "")])
7115 (match_operand:SI 4 "nonimmediate_operand" "rm,0,rm")
7116 (match_operand:SI 5 "nonimmediate_operand" "0,rm,rm")))]
7117 "TARGET_CMOVE && reload_completed"
7118 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7120 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7121 (match_dup 4) (match_dup 5)))]
7125 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7126 (if_then_else:SI (match_operator 1 "comparison_operator"
7127 [(cc0) (const_int 0)])
7128 (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm")
7129 (match_operand:SI 3 "nonimmediate_operand" "0,rm,rm")))]
7130 "TARGET_CMOVE && reload_completed"
7131 "* return output_int_conditional_move (which_alternative, operands);")
7133 (define_expand "movhicc"
7134 [(set (match_operand:HI 0 "register_operand" "")
7135 (if_then_else:HI (match_operand 1 "comparison_operator" "")
7136 (match_operand:HI 2 "nonimmediate_operand" "")
7137 (match_operand:HI 3 "nonimmediate_operand" "")))]
7141 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7144 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7145 GET_MODE (i386_compare_op0),
7146 i386_compare_op0, i386_compare_op1);
7150 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
7151 (if_then_else:HI (match_operator 1 "comparison_operator"
7152 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
7153 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
7154 (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
7155 (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
7160 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
7161 (if_then_else:HI (match_operator 1 "comparison_operator"
7162 [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
7163 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
7164 (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
7165 (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
7166 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7170 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7171 (if_then_else:HI (match_operator 1 "comparison_operator"
7172 [(match_operand 2 "nonimmediate_operand" "")
7174 (match_operand:HI 3 "nonimmediate_operand" "rm,0,rm")
7175 (match_operand:HI 4 "nonimmediate_operand" "0,rm,rm")))]
7176 "TARGET_CMOVE && reload_completed"
7180 (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7181 (match_dup 3) (match_dup 4)))]
7185 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7186 (if_then_else:HI (match_operator 1 "comparison_operator"
7187 [(match_operand 2 "nonimmediate_operand" "")
7188 (match_operand 3 "general_operand" "")])
7189 (match_operand:HI 4 "nonimmediate_operand" "rm,0,rm")
7190 (match_operand:HI 5 "nonimmediate_operand" "0,rm,rm")))]
7191 "TARGET_CMOVE && reload_completed"
7193 (compare (match_dup 2) (match_dup 3)))
7195 (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7196 (match_dup 4) (match_dup 5)))]
7200 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7201 (if_then_else:HI (match_operator 1 "comparison_operator"
7202 [(cc0) (const_int 0)])
7203 (match_operand:HI 2 "nonimmediate_operand" "rm,0,rm")
7204 (match_operand:HI 3 "nonimmediate_operand" "0,rm,rm")))]
7205 "TARGET_CMOVE && reload_completed"
7206 "* return output_int_conditional_move (which_alternative, operands);")
7208 (define_expand "movsfcc"
7209 [(set (match_operand:SF 0 "register_operand" "")
7210 (if_then_else:SF (match_operand 1 "comparison_operator" "")
7211 (match_operand:SF 2 "register_operand" "")
7212 (match_operand:SF 3 "register_operand" "")))]
7218 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7221 /* The floating point conditional move instructions don't directly
7222 support conditions resulting from a signed integer comparison. */
7224 switch (GET_CODE (operands[1]))
7230 temp = emit_store_flag (gen_reg_rtx (QImode),
7231 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7237 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7241 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7242 GET_MODE (i386_compare_op0),
7243 i386_compare_op0, i386_compare_op1);
7249 [(set (match_operand:SF 0 "register_operand" "=f,f,f,f,f,f")
7250 (if_then_else:SF (match_operator 1 "comparison_operator"
7251 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
7252 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
7253 (match_operand:SF 4 "register_operand" "f,f,0,0,f,f")
7254 (match_operand:SF 5 "register_operand" "0,0,f,f,f,f")))]
7256 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7257 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7261 [(set (match_operand:SF 0 "register_operand" "=f,f,f,f,f,f")
7262 (if_then_else:SF (match_operator 1 "comparison_operator"
7263 [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
7264 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
7265 (match_operand:SF 4 "register_operand" "f,f,0,0,f,f")
7266 (match_operand:SF 5 "register_operand" "0,0,f,f,f,f")))]
7267 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7268 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7269 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7273 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
7274 (if_then_else:SF (match_operator 1 "comparison_operator"
7275 [(match_operand 2 "nonimmediate_operand" "")
7277 (match_operand:SF 3 "register_operand" "f,0,f")
7278 (match_operand:SF 4 "register_operand" "0,f,f")))]
7279 "TARGET_CMOVE && reload_completed"
7283 (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7284 (match_dup 3) (match_dup 4)))]
7288 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
7289 (if_then_else:SF (match_operator 1 "comparison_operator"
7290 [(match_operand 2 "nonimmediate_operand" "")
7291 (match_operand 3 "general_operand" "")])
7292 (match_operand:SF 4 "register_operand" "f,0,f")
7293 (match_operand:SF 5 "register_operand" "0,f,f")))]
7294 "TARGET_CMOVE && reload_completed"
7295 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7297 (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7298 (match_dup 4) (match_dup 5)))]
7302 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
7303 (if_then_else:SF (match_operator 1 "comparison_operator"
7304 [(cc0) (const_int 0)])
7305 (match_operand:SF 2 "register_operand" "f,0,f")
7306 (match_operand:SF 3 "register_operand" "0,f,f")))]
7307 "TARGET_CMOVE && reload_completed"
7308 "* return output_fp_conditional_move (which_alternative, operands);")
7310 (define_expand "movdfcc"
7311 [(set (match_operand:DF 0 "register_operand" "")
7312 (if_then_else:DF (match_operand 1 "comparison_operator" "")
7313 (match_operand:DF 2 "register_operand" "")
7314 (match_operand:DF 3 "register_operand" "")))]
7320 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7323 /* The floating point conditional move instructions don't directly
7324 support conditions resulting from a signed integer comparison. */
7326 switch (GET_CODE (operands[1]))
7332 temp = emit_store_flag (gen_reg_rtx (QImode),
7333 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7339 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7343 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7344 GET_MODE (i386_compare_op0),
7345 i386_compare_op0, i386_compare_op1);
7351 [(set (match_operand:DF 0 "register_operand" "=f,f,f,f,f,f")
7352 (if_then_else:DF (match_operator 1 "comparison_operator"
7353 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
7354 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
7355 (match_operand:DF 4 "register_operand" "f,f,0,0,f,f")
7356 (match_operand:DF 5 "register_operand" "0,0,f,f,f,f")))]
7358 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7359 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7363 [(set (match_operand:DF 0 "register_operand" "=f,f,f,f,f,f")
7364 (if_then_else:DF (match_operator 1 "comparison_operator"
7365 [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
7366 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
7367 (match_operand:DF 4 "register_operand" "f,f,0,0,f,f")
7368 (match_operand:DF 5 "register_operand" "0,0,f,f,f,f")))]
7369 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7370 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7371 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7375 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
7376 (if_then_else:DF (match_operator 1 "comparison_operator"
7377 [(match_operand 2 "nonimmediate_operand" "")
7379 (match_operand:DF 3 "register_operand" "f,0,f")
7380 (match_operand:DF 4 "register_operand" "0,f,f")))]
7381 "TARGET_CMOVE && reload_completed"
7385 (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7386 (match_dup 3) (match_dup 4)))]
7390 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
7391 (if_then_else:DF (match_operator 1 "comparison_operator"
7392 [(match_operand 2 "nonimmediate_operand" "")
7393 (match_operand 3 "general_operand" "")])
7394 (match_operand:DF 4 "register_operand" "f,0,f")
7395 (match_operand:DF 5 "register_operand" "0,f,f")))]
7396 "TARGET_CMOVE && reload_completed"
7397 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7399 (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7400 (match_dup 4) (match_dup 5)))]
7404 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
7405 (if_then_else:DF (match_operator 1 "comparison_operator"
7406 [(cc0) (const_int 0)])
7407 (match_operand:DF 2 "register_operand" "f,0,f")
7408 (match_operand:DF 3 "register_operand" "0,f,f")))]
7409 "TARGET_CMOVE && reload_completed"
7410 "* return output_fp_conditional_move (which_alternative, operands);")
7412 (define_expand "movxfcc"
7413 [(set (match_operand:XF 0 "register_operand" "")
7414 (if_then_else:XF (match_operand 1 "comparison_operator" "")
7415 (match_operand:XF 2 "register_operand" "")
7416 (match_operand:XF 3 "register_operand" "")))]
7422 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7425 /* The floating point conditional move instructions don't directly
7426 support conditions resulting from a signed integer comparison. */
7428 switch (GET_CODE (operands[1]))
7434 temp = emit_store_flag (gen_reg_rtx (QImode),
7435 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7441 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7445 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7446 GET_MODE (i386_compare_op0),
7447 i386_compare_op0, i386_compare_op1);
7453 [(set (match_operand:XF 0 "register_operand" "=f,f,f,f,f,f")
7454 (if_then_else:XF (match_operator 1 "comparison_operator"
7455 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
7456 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
7457 (match_operand:XF 4 "register_operand" "f,f,0,0,f,f")
7458 (match_operand:XF 5 "register_operand" "0,0,f,f,f,f")))]
7460 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7461 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7465 [(set (match_operand:XF 0 "register_operand" "=f,f,f,f,f,f")
7466 (if_then_else:XF (match_operator 1 "comparison_operator"
7467 [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
7468 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
7469 (match_operand:XF 4 "register_operand" "f,f,0,0,f,f")
7470 (match_operand:XF 5 "register_operand" "0,0,f,f,f,f")))]
7471 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7472 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7473 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7477 [(set (match_operand:XF 0 "register_operand" "=f,f,f")
7478 (if_then_else:XF (match_operator 1 "comparison_operator"
7479 [(match_operand 2 "nonimmediate_operand" "")
7481 (match_operand:XF 3 "register_operand" "f,0,f")
7482 (match_operand:XF 4 "register_operand" "0,f,f")))]
7483 "TARGET_CMOVE && reload_completed"
7487 (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
7488 (match_dup 3) (match_dup 4)))]
7492 [(set (match_operand:XF 0 "register_operand" "=f,f,f")
7493 (if_then_else:XF (match_operator 1 "comparison_operator"
7494 [(match_operand 2 "nonimmediate_operand" "")
7495 (match_operand 3 "general_operand" "")])
7496 (match_operand:XF 4 "register_operand" "f,0,f")
7497 (match_operand:XF 5 "register_operand" "0,f,f")))]
7498 "TARGET_CMOVE && reload_completed"
7499 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7501 (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
7502 (match_dup 4) (match_dup 5)))]
7506 [(set (match_operand:XF 0 "register_operand" "=f,f,f")
7507 (if_then_else:XF (match_operator 1 "comparison_operator"
7508 [(cc0) (const_int 0)])
7509 (match_operand:XF 2 "register_operand" "f,0,f")
7510 (match_operand:XF 3 "register_operand" "0,f,f")))]
7511 "TARGET_CMOVE && reload_completed"
7512 "* return output_fp_conditional_move (which_alternative, operands);")
7514 (define_expand "movdicc"
7515 [(set (match_operand:DI 0 "register_operand" "")
7516 (if_then_else:DI (match_operand 1 "comparison_operator" "")
7517 (match_operand:DI 2 "nonimmediate_operand" "")
7518 (match_operand:DI 3 "nonimmediate_operand" "")))]
7522 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7525 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7526 GET_MODE (i386_compare_op0),
7527 i386_compare_op0, i386_compare_op1);
7531 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r,&r,&r")
7532 (if_then_else:DI (match_operator 1 "comparison_operator"
7533 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
7534 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
7535 (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0,ro,ro")
7536 (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro,ro,ro")))]
7541 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r,&r,&r")
7542 (if_then_else:DI (match_operator 1 "comparison_operator"
7543 [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
7544 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
7545 (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0,ro,ro")
7546 (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro,ro,ro")))]
7547 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7551 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
7552 (if_then_else:DI (match_operator 1 "comparison_operator"
7553 [(match_operand 2 "nonimmediate_operand" "")
7555 (match_operand:DI 3 "nonimmediate_operand" "ro,0,ro")
7556 (match_operand:DI 4 "nonimmediate_operand" "0,ro,ro")))]
7557 "TARGET_CMOVE && reload_completed"
7561 (if_then_else:DI (match_op_dup 1 [(cc0) (const_int 0)])
7562 (match_dup 3) (match_dup 4)))]
7566 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
7567 (if_then_else:DI (match_operator 1 "comparison_operator"
7568 [(match_operand 2 "nonimmediate_operand" "")
7569 (match_operand 3 "general_operand" "")])
7570 (match_operand:DI 4 "nonimmediate_operand" "ro,0,ro")
7571 (match_operand:DI 5 "nonimmediate_operand" "0,ro,ro")))]
7572 "TARGET_CMOVE && reload_completed"
7573 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7575 (if_then_else:DI (match_op_dup 1 [(cc0) (const_int 0)])
7576 (match_dup 4) (match_dup 5)))]
7580 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
7581 (if_then_else:DI (match_operator 1 "comparison_operator"
7582 [(cc0) (const_int 0)])
7583 (match_operand:DI 2 "nonimmediate_operand" "ro,0,ro")
7584 (match_operand:DI 3 "nonimmediate_operand" "0,ro,ro")))]
7585 "TARGET_CMOVE && reload_completed"
7586 "* return output_int_conditional_move (which_alternative, operands);")
7588 (define_insn "strlensi_unroll"
7589 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
7590 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r"))
7591 (match_operand:SI 2 "immediate_operand" "i,i")] 0))
7592 (clobber (match_scratch:SI 3 "=&q,&r"))]
7594 "* return output_strlen_unroll (operands);")
7596 ;; the only difference between the following patterns is the register preference
7597 ;; on a pentium using a q-register saves one clock cycle per 4 characters
7599 (define_insn "strlensi_unroll4"
7600 [(set (match_operand:SI 0 "register_operand" "=r,r")
7601 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0"))
7602 (match_operand:SI 1 "immediate_operand" "i,i")
7603 (match_operand:SI 2 "register_operand" "+q,!r")] 0))
7604 (clobber (match_dup 2))]
7605 "(TARGET_USE_ANY_REG && optimize > 1)"
7606 "* return output_strlen_unroll (operands);")
7608 (define_insn "strlensi_unroll5"
7609 [(set (match_operand:SI 0 "register_operand" "=r")
7610 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0"))
7611 (match_operand:SI 1 "immediate_operand" "i")
7612 (match_operand:SI 2 "register_operand" "+q")] 0))
7613 (clobber (match_dup 2))]
7614 "(TARGET_USE_Q_REG && optimize > 1)"
7615 "* return output_strlen_unroll (operands);"
7618 (define_insn "allocate_stack_worker"
7619 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
7620 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
7621 (clobber (match_dup 0))]
7622 "TARGET_STACK_PROBE"
7623 "* return AS1(call,__alloca);")
7625 (define_expand "allocate_stack"
7626 [(set (match_operand:SI 0 "register_operand" "=r")
7627 (minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" "")))
7628 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))]
7629 "TARGET_STACK_PROBE"
7632 #ifdef CHECK_STACK_LIMIT
7633 if (GET_CODE (operands[1]) == CONST_INT
7634 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
7635 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
7639 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
7642 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
7646 (define_expand "exception_receiver"
7651 load_pic_register (1);