1 ; GCC machine description for Intel X86.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997 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.
67 ;; This shadows the processor_type enumeration, so changes must be made
68 ;; to i386.h at the same time.
70 (define_attr "type" "integer,idiv,imul,fld,fpop,fpdiv,fpmul"
71 (const_string "integer"))
75 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
76 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
78 ; pentiumpro has a reservation station with 5 ports
79 ; port 0 has integer, float add, integer divide, float divide, float
80 ; multiply, and shifter units.
81 ; port 1 has integer, and jump units.
82 ; port 2 has the load address generation unit
83 ; ports 3 and 4 have the store address generation units
85 ; pentium has two integer pipelines, the main u pipe and the secondary v pipe.
86 ; and a float pipeline
90 (define_function_unit "fp" 1 0
91 (and (eq_attr "type" "fpop") (eq_attr "cpu" "i386,i486"))
94 (define_function_unit "fp" 1 0
95 (and (eq_attr "type" "fpop") (eq_attr "cpu" "pentium,pentiumpro"))
98 (define_function_unit "fp" 1 0
99 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentium"))
102 (define_function_unit "fp" 1 0
103 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentiumpro"))
106 (define_function_unit "fp" 1 0
107 (and (eq_attr "type" "idiv") (eq_attr "cpu" "pentiumpro"))
110 (define_function_unit "fp" 1 0
111 (and (eq_attr "type" "imul") (eq_attr "cpu" "pentiumpro"))
114 (define_function_unit "fp" 1 0
115 (eq_attr "type" "fpdiv")
118 (define_function_unit "fp" 1 0
119 (eq_attr "type" "fld")
122 (define_function_unit "integer" 1 0
123 (and (eq_attr "type" "integer") (eq_attr "cpu" "!i386"))
127 ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
128 ;; But restricting MEM here would mean that gcc could not remove a redundant
129 ;; test in cases like "incl MEM / je TARGET".
131 ;; We don't want to allow a constant operand for test insns because
132 ;; (set (cc0) (const_int foo)) has no mode information. Such insns will
133 ;; be folded while optimizing anyway.
135 ;; All test insns have expanders that save the operands away without
136 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
137 ;; after the tstM or cmp) will actually emit the tstM or cmpM.
139 ;; Processor type -- this attribute must exactly match the processor_type
140 ;; enumeration in i386.h.
142 (define_attr "cpu" "i386,i486,pentium,pentiumpro"
143 (const (symbol_ref "ix86_cpu")))
145 (define_insn "tstsi_1"
147 (match_operand:SI 0 "nonimmediate_operand" "rm"))]
151 if (REG_P (operands[0]))
152 return AS2 (test%L0,%0,%0);
154 operands[1] = const0_rtx;
155 return AS2 (cmp%L0,%1,%0);
158 (define_expand "tstsi"
160 (match_operand:SI 0 "nonimmediate_operand" ""))]
164 i386_compare_gen = gen_tstsi_1;
165 i386_compare_op0 = operands[0];
169 (define_insn "tsthi_1"
171 (match_operand:HI 0 "nonimmediate_operand" "rm"))]
175 if (REG_P (operands[0]))
176 return AS2 (test%W0,%0,%0);
178 operands[1] = const0_rtx;
179 return AS2 (cmp%W0,%1,%0);
182 (define_expand "tsthi"
184 (match_operand:HI 0 "nonimmediate_operand" ""))]
188 i386_compare_gen = gen_tsthi_1;
189 i386_compare_op0 = operands[0];
193 (define_insn "tstqi_1"
195 (match_operand:QI 0 "nonimmediate_operand" "qm"))]
199 if (REG_P (operands[0]))
200 return AS2 (test%B0,%0,%0);
202 operands[1] = const0_rtx;
203 return AS2 (cmp%B0,%1,%0);
206 (define_expand "tstqi"
208 (match_operand:QI 0 "nonimmediate_operand" ""))]
212 i386_compare_gen = gen_tstqi_1;
213 i386_compare_op0 = operands[0];
217 (define_insn "tstsf_cc"
219 (match_operand:SF 0 "register_operand" "f"))
220 (clobber (match_scratch:HI 1 "=a"))]
221 "TARGET_80387 && ! TARGET_IEEE_FP"
224 if (! STACK_TOP_P (operands[0]))
227 output_asm_insn (\"ftst\", operands);
229 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
230 output_asm_insn (AS1 (fstp,%y0), operands);
232 return output_fp_cc0_set (insn);
235 ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
236 ;; isn't IEEE compliant.
238 (define_expand "tstsf"
239 [(parallel [(set (cc0)
240 (match_operand:SF 0 "register_operand" ""))
241 (clobber (match_scratch:HI 1 ""))])]
242 "TARGET_80387 && ! TARGET_IEEE_FP"
245 i386_compare_gen = gen_tstsf_cc;
246 i386_compare_op0 = operands[0];
250 (define_insn "tstdf_cc"
252 (match_operand:DF 0 "register_operand" "f"))
253 (clobber (match_scratch:HI 1 "=a"))]
254 "TARGET_80387 && ! TARGET_IEEE_FP"
257 if (! STACK_TOP_P (operands[0]))
260 output_asm_insn (\"ftst\", operands);
262 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
263 output_asm_insn (AS1 (fstp,%y0), operands);
265 return output_fp_cc0_set (insn);
268 ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
269 ;; isn't IEEE compliant.
271 (define_expand "tstdf"
272 [(parallel [(set (cc0)
273 (match_operand:DF 0 "register_operand" ""))
274 (clobber (match_scratch:HI 1 ""))])]
275 "TARGET_80387 && ! TARGET_IEEE_FP"
278 i386_compare_gen = gen_tstdf_cc;
279 i386_compare_op0 = operands[0];
283 (define_insn "tstxf_cc"
285 (match_operand:XF 0 "register_operand" "f"))
286 (clobber (match_scratch:HI 1 "=a"))]
287 "TARGET_80387 && ! TARGET_IEEE_FP"
290 if (! STACK_TOP_P (operands[0]))
293 output_asm_insn (\"ftst\", operands);
295 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
296 output_asm_insn (AS1 (fstp,%y0), operands);
298 return output_fp_cc0_set (insn);
301 ;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode
302 ;; isn't IEEE compliant.
304 (define_expand "tstxf"
305 [(parallel [(set (cc0)
306 (match_operand:XF 0 "register_operand" ""))
307 (clobber (match_scratch:HI 1 ""))])]
308 "TARGET_80387 && ! TARGET_IEEE_FP"
311 i386_compare_gen = gen_tstxf_cc;
312 i386_compare_op0 = operands[0];
316 ;;- compare instructions. See comments above tstM patterns about
317 ;; expansion of these insns.
319 (define_insn "cmpsi_1"
321 (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
322 (match_operand:SI 1 "general_operand" "ri,mr")))]
323 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
326 if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
328 cc_status.flags |= CC_REVERSED;
329 return AS2 (cmp%L0,%0,%1);
331 return AS2 (cmp%L0,%1,%0);
334 (define_expand "cmpsi"
336 (compare (match_operand:SI 0 "nonimmediate_operand" "")
337 (match_operand:SI 1 "general_operand" "")))]
341 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
342 operands[0] = force_reg (SImode, operands[0]);
344 i386_compare_gen = gen_cmpsi_1;
345 i386_compare_op0 = operands[0];
346 i386_compare_op1 = operands[1];
350 (define_insn "cmphi_1"
352 (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
353 (match_operand:HI 1 "general_operand" "ri,mr")))]
354 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
357 if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
359 cc_status.flags |= CC_REVERSED;
360 return AS2 (cmp%W0,%0,%1);
362 return AS2 (cmp%W0,%1,%0);
365 (define_expand "cmphi"
367 (compare (match_operand:HI 0 "nonimmediate_operand" "")
368 (match_operand:HI 1 "general_operand" "")))]
372 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
373 operands[0] = force_reg (HImode, operands[0]);
375 i386_compare_gen = gen_cmphi_1;
376 i386_compare_op0 = operands[0];
377 i386_compare_op1 = operands[1];
381 (define_insn "cmpqi_1"
383 (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
384 (match_operand:QI 1 "general_operand" "qm,nq")))]
385 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
388 if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
390 cc_status.flags |= CC_REVERSED;
391 return AS2 (cmp%B0,%0,%1);
393 return AS2 (cmp%B0,%1,%0);
396 (define_expand "cmpqi"
398 (compare (match_operand:QI 0 "nonimmediate_operand" "")
399 (match_operand:QI 1 "general_operand" "")))]
403 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
404 operands[0] = force_reg (QImode, operands[0]);
406 i386_compare_gen = gen_cmpqi_1;
407 i386_compare_op0 = operands[0];
408 i386_compare_op1 = operands[1];
412 ;; These implement float point compares. For each of DFmode and
413 ;; SFmode, there is the normal insn, and an insn where the second operand
414 ;; is converted to the desired mode.
418 (match_operator 2 "VOIDmode_compare_op"
419 [(match_operand:XF 0 "register_operand" "f")
420 (match_operand:XF 1 "register_operand" "f")]))
421 (clobber (match_scratch:HI 3 "=a"))]
423 "* return output_float_compare (insn, operands);")
427 (match_operator 2 "VOIDmode_compare_op"
428 [(match_operand:XF 0 "register_operand" "f")
430 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
431 (clobber (match_scratch:HI 3 "=a"))]
433 "* return output_float_compare (insn, operands);")
437 (match_operator 2 "VOIDmode_compare_op"
439 (match_operand:SI 0 "nonimmediate_operand" "rm"))
440 (match_operand:XF 1 "register_operand" "f")]))
441 (clobber (match_scratch:HI 3 "=a"))]
443 "* return output_float_compare (insn, operands);")
447 (match_operator 2 "VOIDmode_compare_op"
448 [(match_operand:XF 0 "register_operand" "f")
450 (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
451 (clobber (match_scratch:HI 3 "=a"))]
453 "* return output_float_compare (insn, operands);")
457 (match_operator 2 "VOIDmode_compare_op"
459 (match_operand:DF 1 "nonimmediate_operand" "fm"))
460 (match_operand:XF 0 "register_operand" "f")]))
461 (clobber (match_scratch:HI 3 "=a"))]
463 "* return output_float_compare (insn, operands);")
467 (match_operator 2 "VOIDmode_compare_op"
468 [(match_operand:XF 0 "register_operand" "f")
470 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
471 (clobber (match_scratch:HI 3 "=a"))]
473 "* return output_float_compare (insn, operands);")
477 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
478 (match_operand:XF 1 "register_operand" "f")))
479 (clobber (match_scratch:HI 2 "=a"))]
481 "* return output_float_compare (insn, operands);")
485 (match_operator 2 "VOIDmode_compare_op"
486 [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
487 (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
488 (clobber (match_scratch:HI 3 "=a,a"))]
490 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
491 "* return output_float_compare (insn, operands);")
495 (match_operator 2 "VOIDmode_compare_op"
496 [(match_operand:DF 0 "register_operand" "f")
498 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
499 (clobber (match_scratch:HI 3 "=a"))]
501 "* return output_float_compare (insn, operands);")
505 (match_operator 2 "VOIDmode_compare_op"
507 (match_operand:SI 0 "nonimmediate_operand" "rm"))
508 (match_operand:DF 1 "register_operand" "f")]))
509 (clobber (match_scratch:HI 3 "=a"))]
511 "* return output_float_compare (insn, operands);")
515 (match_operator 2 "VOIDmode_compare_op"
516 [(match_operand:DF 0 "register_operand" "f")
518 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
519 (clobber (match_scratch:HI 3 "=a"))]
521 "* return output_float_compare (insn, operands);")
525 (match_operator 2 "VOIDmode_compare_op"
527 (match_operand:SF 0 "nonimmediate_operand" "fm"))
528 (match_operand:DF 1 "register_operand" "f")]))
529 (clobber (match_scratch:HI 3 "=a"))]
531 "* return output_float_compare (insn, operands);")
535 (match_operator 2 "VOIDmode_compare_op"
537 (match_operand:SF 0 "register_operand" "f"))
538 (match_operand:DF 1 "nonimmediate_operand" "fm")]))
539 (clobber (match_scratch:HI 3 "=a"))]
541 "* return output_float_compare (insn, operands);")
545 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
546 (match_operand:DF 1 "register_operand" "f")))
547 (clobber (match_scratch:HI 2 "=a"))]
549 "* return output_float_compare (insn, operands);")
551 ;; These two insns will never be generated by combine due to the mode of
555 ; (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
557 ; (match_operand:SF 1 "register_operand" "f"))))
558 ; (clobber (match_scratch:HI 2 "=a"))]
560 ; "* return output_float_compare (insn, operands);")
564 ; (compare:CCFPEQ (float_extend:DF
565 ; (match_operand:SF 0 "register_operand" "f"))
566 ; (match_operand:DF 1 "register_operand" "f")))
567 ; (clobber (match_scratch:HI 2 "=a"))]
569 ; "* return output_float_compare (insn, operands);")
571 (define_insn "cmpsf_cc_1"
573 (match_operator 2 "VOIDmode_compare_op"
574 [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
575 (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
576 (clobber (match_scratch:HI 3 "=a,a"))]
578 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
579 "* return output_float_compare (insn, operands);")
583 (match_operator 2 "VOIDmode_compare_op"
584 [(match_operand:SF 0 "register_operand" "f")
586 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
587 (clobber (match_scratch:HI 3 "=a"))]
589 "* return output_float_compare (insn, operands);")
593 (match_operator 2 "VOIDmode_compare_op"
595 (match_operand:SI 0 "nonimmediate_operand" "rm"))
596 (match_operand:SF 1 "register_operand" "f")]))
597 (clobber (match_scratch:HI 3 "=a"))]
599 "* return output_float_compare (insn, operands);")
603 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
604 (match_operand:SF 1 "register_operand" "f")))
605 (clobber (match_scratch:HI 2 "=a"))]
607 "* return output_float_compare (insn, operands);")
609 (define_expand "cmpxf"
611 (compare (match_operand:XF 0 "register_operand" "")
612 (match_operand:XF 1 "register_operand" "")))]
616 i386_compare_gen = gen_cmpxf_cc;
617 i386_compare_gen_eq = gen_cmpxf_ccfpeq;
618 i386_compare_op0 = operands[0];
619 i386_compare_op1 = operands[1];
623 (define_expand "cmpdf"
625 (compare (match_operand:DF 0 "register_operand" "")
626 (match_operand:DF 1 "general_operand" "")))]
630 i386_compare_gen = gen_cmpdf_cc;
631 i386_compare_gen_eq = gen_cmpdf_ccfpeq;
632 i386_compare_op0 = operands[0];
633 i386_compare_op1 = (immediate_operand (operands[1], DFmode))
634 ? copy_to_mode_reg (DFmode, operands[1]) : operands[1];
638 (define_expand "cmpsf"
640 (compare (match_operand:SF 0 "register_operand" "")
641 (match_operand:SF 1 "general_operand" "")))]
645 i386_compare_gen = gen_cmpsf_cc;
646 i386_compare_gen_eq = gen_cmpsf_ccfpeq;
647 i386_compare_op0 = operands[0];
648 i386_compare_op1 = (immediate_operand (operands[1], SFmode))
649 ? copy_to_mode_reg (SFmode, operands[1]) : operands[1];
653 (define_expand "cmpxf_cc"
654 [(parallel [(set (cc0)
655 (compare (match_operand:XF 0 "register_operand" "")
656 (match_operand:XF 1 "register_operand" "")))
657 (clobber (match_scratch:HI 2 ""))])]
661 (define_expand "cmpxf_ccfpeq"
662 [(parallel [(set (cc0)
663 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
664 (match_operand:XF 1 "register_operand" "")))
665 (clobber (match_scratch:HI 2 ""))])]
669 (define_expand "cmpdf_cc"
670 [(parallel [(set (cc0)
671 (compare (match_operand:DF 0 "register_operand" "")
672 (match_operand:DF 1 "register_operand" "")))
673 (clobber (match_scratch:HI 2 ""))])]
677 (define_expand "cmpdf_ccfpeq"
678 [(parallel [(set (cc0)
679 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
680 (match_operand:DF 1 "register_operand" "")))
681 (clobber (match_scratch:HI 2 ""))])]
685 if (! register_operand (operands[1], DFmode))
686 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
689 (define_expand "cmpsf_cc"
690 [(parallel [(set (cc0)
691 (compare (match_operand:SF 0 "register_operand" "")
692 (match_operand:SF 1 "register_operand" "")))
693 (clobber (match_scratch:HI 2 ""))])]
697 (define_expand "cmpsf_ccfpeq"
698 [(parallel [(set (cc0)
699 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
700 (match_operand:SF 1 "register_operand" "")))
701 (clobber (match_scratch:HI 2 ""))])]
705 if (! register_operand (operands[1], SFmode))
706 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
713 (and:SI (match_operand:SI 0 "general_operand" "%ro")
714 (match_operand:SI 1 "nonmemory_operand" "ri")))]
718 /* For small integers, we may actually use testb. */
719 if (GET_CODE (operands[1]) == CONST_INT
720 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
721 && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
723 /* We may set the sign bit spuriously. */
725 if ((INTVAL (operands[1]) & ~0xff) == 0)
727 cc_status.flags |= CC_NOT_NEGATIVE;
728 return AS2 (test%B0,%1,%b0);
731 if ((INTVAL (operands[1]) & ~0xff00) == 0)
733 cc_status.flags |= CC_NOT_NEGATIVE;
734 operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
736 if (QI_REG_P (operands[0]))
737 return AS2 (test%B0,%1,%h0);
740 operands[0] = adj_offsettable_operand (operands[0], 1);
741 return AS2 (test%B0,%1,%b0);
745 if (GET_CODE (operands[0]) == MEM
746 && (INTVAL (operands[1]) & ~0xff0000) == 0)
748 cc_status.flags |= CC_NOT_NEGATIVE;
749 operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
750 operands[0] = adj_offsettable_operand (operands[0], 2);
751 return AS2 (test%B0,%1,%b0);
754 if (GET_CODE (operands[0]) == MEM
755 && (INTVAL (operands[1]) & ~0xff000000) == 0)
757 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
758 operands[0] = adj_offsettable_operand (operands[0], 3);
759 return AS2 (test%B0,%1,%b0);
763 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
764 return AS2 (test%L0,%1,%0);
766 return AS2 (test%L1,%0,%1);
771 (and:HI (match_operand:HI 0 "general_operand" "%ro")
772 (match_operand:HI 1 "nonmemory_operand" "ri")))]
776 if (GET_CODE (operands[1]) == CONST_INT
777 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
778 && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
780 if ((INTVAL (operands[1]) & 0xff00) == 0)
782 /* ??? This might not be necessary. */
783 if (INTVAL (operands[1]) & 0xffff0000)
784 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
786 /* We may set the sign bit spuriously. */
787 cc_status.flags |= CC_NOT_NEGATIVE;
788 return AS2 (test%B0,%1,%b0);
791 if ((INTVAL (operands[1]) & 0xff) == 0)
793 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
795 if (QI_REG_P (operands[0]))
796 return AS2 (test%B0,%1,%h0);
799 operands[0] = adj_offsettable_operand (operands[0], 1);
800 return AS2 (test%B0,%1,%b0);
805 /* use 32-bit test instruction if there are no sign issues */
806 if (GET_CODE (operands[1]) == CONST_INT
807 && !(INTVAL (operands[1]) & ~0x7fff)
808 && i386_aligned_p (operands[0]))
809 return AS2 (test%L0,%1,%k0);
811 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
812 return AS2 (test%W0,%1,%0);
814 return AS2 (test%W1,%0,%1);
819 (and:QI (match_operand:QI 0 "nonimmediate_operand" "%qm")
820 (match_operand:QI 1 "nonmemory_operand" "qi")))]
824 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
825 return AS2 (test%B0,%1,%0);
827 return AS2 (test%B1,%0,%1);
830 ;; move instructions.
831 ;; There is one for each machine mode,
832 ;; and each is preceded by a corresponding push-insn pattern
833 ;; (since pushes are not general_operands on the 386).
836 [(set (match_operand:SI 0 "push_operand" "=<")
837 (match_operand:SI 1 "general_operand" "g"))]
841 ;; If not a 386, it is faster to move MEM to a REG and then push, rather than
842 ;; push MEM directly.
845 [(set (match_operand:SI 0 "push_operand" "=<")
846 (match_operand:SI 1 "nonmemory_operand" "ri"))]
847 "!TARGET_PUSH_MEMORY && TARGET_MOVE"
851 [(set (match_operand:SI 0 "push_operand" "=<")
852 (match_operand:SI 1 "nonmemory_operand" "ri"))]
853 "!TARGET_PUSH_MEMORY && !TARGET_MOVE"
856 ;; General case of fullword move.
858 ;; If generating PIC code and operands[1] is a symbolic CONST, emit a
859 ;; move to get the address of the symbolic object from the GOT.
861 (define_expand "movsi"
862 [(set (match_operand:SI 0 "general_operand" "")
863 (match_operand:SI 1 "general_operand" ""))]
869 if (flag_pic && SYMBOLIC_CONST (operands[1]))
870 emit_pic_move (operands, SImode);
872 /* Don't generate memory->memory moves, go through a register */
874 && (reload_in_progress | reload_completed) == 0
875 && GET_CODE (operands[0]) == MEM
876 && GET_CODE (operands[1]) == MEM)
878 operands[1] = force_reg (SImode, operands[1]);
882 ;; On i486, incl reg is faster than movl $1,reg.
885 [(set (match_operand:SI 0 "general_operand" "=g,r")
886 (match_operand:SI 1 "general_operand" "ri,m"))]
887 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
891 if (operands[1] == const0_rtx && REG_P (operands[0]))
892 return AS2 (xor%L0,%0,%0);
894 if (operands[1] == const1_rtx
895 && (link = find_reg_note (insn, REG_WAS_0, 0))
896 /* Make sure the insn that stored the 0 is still present. */
897 && ! INSN_DELETED_P (XEXP (link, 0))
898 && GET_CODE (XEXP (link, 0)) != NOTE
899 /* Make sure cross jumping didn't happen here. */
900 && no_labels_between_p (XEXP (link, 0), insn)
901 /* Make sure the reg hasn't been clobbered. */
902 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
903 /* Fastest way to change a 0 to a 1. */
904 return AS1 (inc%L0,%0);
906 if (flag_pic && SYMBOLIC_CONST (operands[1]))
907 return AS2 (lea%L0,%a1,%0);
909 return AS2 (mov%L0,%1,%0);
913 [(set (match_operand:HI 0 "push_operand" "=<")
914 (match_operand:HI 1 "general_operand" "g"))]
919 [(set (match_operand:HI 0 "push_operand" "=<")
920 (match_operand:HI 1 "nonmemory_operand" "ri"))]
921 "!TARGET_PUSH_MEMORY && TARGET_MOVE"
925 [(set (match_operand:HI 0 "push_operand" "=<")
926 (match_operand:HI 1 "nonmemory_operand" "ri"))]
927 "!TARGET_PUSH_MEMORY && !TARGET_MOVE"
930 ;; On i486, an incl and movl are both faster than incw and movw.
932 (define_expand "movhi"
933 [(set (match_operand:HI 0 "general_operand" "")
934 (match_operand:HI 1 "general_operand" ""))]
938 /* Don't generate memory->memory moves, go through a register */
940 && (reload_in_progress | reload_completed) == 0
941 && GET_CODE (operands[0]) == MEM
942 && GET_CODE (operands[1]) == MEM)
944 operands[1] = force_reg (HImode, operands[1]);
949 [(set (match_operand:HI 0 "general_operand" "=g,r")
950 (match_operand:HI 1 "general_operand" "ri,m"))]
951 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
955 if (REG_P (operands[0]) && operands[1] == const0_rtx)
956 return AS2 (xor%L0,%k0,%k0);
958 if (REG_P (operands[0]) && operands[1] == const1_rtx
959 && (link = find_reg_note (insn, REG_WAS_0, 0))
960 /* Make sure the insn that stored the 0 is still present. */
961 && ! INSN_DELETED_P (XEXP (link, 0))
962 && GET_CODE (XEXP (link, 0)) != NOTE
963 /* Make sure cross jumping didn't happen here. */
964 && no_labels_between_p (XEXP (link, 0), insn)
965 /* Make sure the reg hasn't been clobbered. */
966 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
967 /* Fastest way to change a 0 to a 1. */
968 return AS1 (inc%L0,%k0);
970 if (REG_P (operands[0]))
972 if (i386_aligned_p (operands[1]))
974 operands[1] = i386_sext16_if_const (operands[1]);
975 return AS2 (mov%L0,%k1,%k0);
977 if (TARGET_PENTIUMPRO)
979 /* movzwl is faster than movw on the Pentium Pro,
980 * although not as fast as an aligned movl. */
982 return AS2 (movzx,%1,%k0);
984 return AS2 (movz%W0%L0,%1,%k0);
989 return AS2 (mov%W0,%1,%0);
992 (define_expand "movstricthi"
993 [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
994 (match_operand:HI 1 "general_operand" ""))]
998 /* Don't generate memory->memory moves, go through a register */
1000 && (reload_in_progress | reload_completed) == 0
1001 && GET_CODE (operands[0]) == MEM
1002 && GET_CODE (operands[1]) == MEM)
1004 operands[1] = force_reg (HImode, operands[1]);
1009 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
1010 (match_operand:HI 1 "general_operand" "ri,m"))]
1011 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1015 if (operands[1] == const0_rtx && REG_P (operands[0]))
1016 return AS2 (xor%W0,%0,%0);
1018 if (operands[1] == const1_rtx
1019 && (link = find_reg_note (insn, REG_WAS_0, 0))
1020 /* Make sure the insn that stored the 0 is still present. */
1021 && ! INSN_DELETED_P (XEXP (link, 0))
1022 && GET_CODE (XEXP (link, 0)) != NOTE
1023 /* Make sure cross jumping didn't happen here. */
1024 && no_labels_between_p (XEXP (link, 0), insn)
1025 /* Make sure the reg hasn't been clobbered. */
1026 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1027 /* Fastest way to change a 0 to a 1. */
1028 return AS1 (inc%W0,%0);
1030 return AS2 (mov%W0,%1,%0);
1033 ;; emit_push_insn when it calls move_by_pieces
1034 ;; requires an insn to "push a byte".
1035 ;; But actually we use pushw, which has the effect of rounding
1036 ;; the amount pushed up to a halfword.
1038 [(set (match_operand:QI 0 "push_operand" "=<")
1039 (match_operand:QI 1 "const_int_operand" "n"))]
1041 "* return AS1 (push%W0,%1);")
1044 [(set (match_operand:QI 0 "push_operand" "=<")
1045 (match_operand:QI 1 "register_operand" "q"))]
1049 operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
1050 return AS1 (push%W0,%1);
1054 [(set (match_operand:QI 0 "push_operand" "=<")
1055 (match_operand:QI 1 "register_operand" "q"))]
1059 operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
1060 return AS1 (push%W0,%1);
1063 ;; On i486, incb reg is faster than movb $1,reg.
1065 ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
1066 ;; or writes %ah, %bh, %ch, %dh.
1068 (define_expand "movqi"
1069 [(set (match_operand:QI 0 "general_operand" "")
1070 (match_operand:QI 1 "general_operand" ""))]
1074 /* Don't generate memory->memory moves, go through a register */
1076 && (reload_in_progress | reload_completed) == 0
1077 && GET_CODE (operands[0]) == MEM
1078 && GET_CODE (operands[1]) == MEM)
1080 operands[1] = force_reg (QImode, operands[1]);
1085 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,*r,qm")
1086 (match_operand:QI 1 "general_operand" "*g,r,qn"))]
1087 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1091 if (operands[1] == const0_rtx && REG_P (operands[0]))
1092 return AS2 (xor%L0,%k0,%k0);
1094 if (operands[1] == const1_rtx
1095 && (link = find_reg_note (insn, REG_WAS_0, 0))
1096 /* Make sure the insn that stored the 0 is still present. */
1097 && ! INSN_DELETED_P (XEXP (link, 0))
1098 && GET_CODE (XEXP (link, 0)) != NOTE
1099 /* Make sure cross jumping didn't happen here. */
1100 && no_labels_between_p (XEXP (link, 0), insn)
1101 /* Make sure the reg hasn't been clobbered. */
1102 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1103 /* Fastest way to change a 0 to a 1. */
1104 return AS1 (inc%B0,%0);
1106 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1107 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1108 return (AS2 (mov%L0,%k1,%k0));
1110 return (AS2 (mov%B0,%1,%0));
1113 ;; If it becomes necessary to support movstrictqi into %esi or %edi,
1114 ;; use the insn sequence:
1116 ;; shrdl $8,srcreg,dstreg
1119 ;; If operands[1] is a constant, then an andl/orl sequence would be
1122 (define_expand "movstrictqi"
1123 [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
1124 (match_operand:QI 1 "general_operand" ""))]
1128 /* Don't generate memory->memory moves, go through a register */
1130 && (reload_in_progress | reload_completed) == 0
1131 && GET_CODE (operands[0]) == MEM
1132 && GET_CODE (operands[1]) == MEM)
1134 operands[1] = force_reg (QImode, operands[1]);
1139 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1140 (match_operand:QI 1 "general_operand" "*qn,m"))]
1141 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1145 if (operands[1] == const0_rtx && REG_P (operands[0]))
1146 return AS2 (xor%B0,%0,%0);
1148 if (operands[1] == const1_rtx
1149 && (link = find_reg_note (insn, REG_WAS_0, 0))
1150 /* Make sure the insn that stored the 0 is still present. */
1151 && ! INSN_DELETED_P (XEXP (link, 0))
1152 && GET_CODE (XEXP (link, 0)) != NOTE
1153 /* Make sure cross jumping didn't happen here. */
1154 && no_labels_between_p (XEXP (link, 0), insn)
1155 /* Make sure the reg hasn't been clobbered. */
1156 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1157 /* Fastest way to change a 0 to a 1. */
1158 return AS1 (inc%B0,%0);
1160 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1161 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1164 return (AS2 (mov%L0,%k1,%k0));
1167 return AS2 (mov%B0,%1,%0);
1170 (define_expand "movsf"
1171 [(set (match_operand:SF 0 "general_operand" "")
1172 (match_operand:SF 1 "general_operand" ""))]
1176 /* Special case memory->memory moves and pushes */
1178 && (reload_in_progress | reload_completed) == 0
1179 && GET_CODE (operands[0]) == MEM
1180 && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], SFmode)))
1182 rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], SFmode))
1186 emit_insn ((*genfunc) (operands[0], operands[1]));
1190 /* If we are loading a floating point constant that isn't 0 or 1
1191 into a register, indicate we need the pic register loaded. This could
1192 be optimized into stores of constants if the target eventually moves
1193 to memory, but better safe than sorry. */
1194 if ((reload_in_progress | reload_completed) == 0
1195 && GET_CODE (operands[0]) != MEM
1196 && GET_CODE (operands[1]) == CONST_DOUBLE
1197 && !standard_80387_constant_p (operands[1]))
1199 rtx insn, note, fp_const;
1201 fp_const = force_const_mem (SFmode, operands[1]);
1203 current_function_uses_pic_offset_table = 1;
1205 insn = emit_insn (gen_rtx (SET, SFmode, operands[0], fp_const));
1206 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
1209 XEXP (note, 0) = operands[1];
1211 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, operands[1], REG_NOTES (insn));
1215 (define_insn "movsf_push_nomove"
1216 [(set (match_operand:SF 0 "push_operand" "=<,<")
1217 (match_operand:SF 1 "general_operand" "gF,f"))]
1221 if (STACK_REG_P (operands[1]))
1225 if (! STACK_TOP_P (operands[1]))
1228 xops[0] = AT_SP (SFmode);
1229 xops[1] = GEN_INT (4);
1230 xops[2] = stack_pointer_rtx;
1232 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1234 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1235 output_asm_insn (AS1 (fstp%S0,%0), xops);
1237 output_asm_insn (AS1 (fst%S0,%0), xops);
1240 return AS1 (push%L1,%1);
1243 (define_insn "movsf_push"
1244 [(set (match_operand:SF 0 "push_operand" "=<,<,<,<")
1245 (match_operand:SF 1 "general_operand" "rF,f,m,m"))
1246 (clobber (match_scratch:SI 2 "=X,X,r,X"))]
1250 if (STACK_REG_P (operands[1]))
1254 if (! STACK_TOP_P (operands[1]))
1257 xops[0] = AT_SP (SFmode);
1258 xops[1] = GEN_INT (4);
1259 xops[2] = stack_pointer_rtx;
1261 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1263 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1264 output_asm_insn (AS1 (fstp%S0,%0), xops);
1266 output_asm_insn (AS1 (fst%S0,%0), xops);
1270 else if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != REG)
1271 return AS1 (push%L1,%1);
1275 output_asm_insn (AS2 (mov%L2,%1,%2), operands);
1276 return AS1 (push%L2,%2);
1280 ;; Special memory<->memory pattern that combine will recreate from the
1281 ;; moves to pseudos.
1282 (define_insn "movsf_mem"
1283 [(set (match_operand:SF 0 "memory_operand" "=m")
1284 (match_operand:SF 1 "memory_operand" "m"))
1285 (clobber (match_scratch:SI 2 "=&r"))]
1289 output_asm_insn (AS2 (mov%L2,%1,%2), operands);
1290 return AS2 (mov%L0,%2,%0);
1293 ;; For the purposes of regclass, prefer FLOAT_REGS.
1294 (define_insn "movsf_normal"
1295 [(set (match_operand:SF 0 "nonimmediate_operand" "=*rfm,*rf,f,!*rm")
1296 (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
1297 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1300 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1302 /* First handle a `pop' insn or a `fld %st(0)' */
1304 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1307 return AS1 (fstp,%y0);
1309 return AS1 (fld,%y0);
1312 /* Handle a transfer between the 387 and a 386 register */
1314 if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
1316 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1320 if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
1322 output_to_reg (operands[0], stack_top_dies, 0);
1326 /* Handle other kinds of writes from the 387 */
1328 if (STACK_TOP_P (operands[1]))
1331 return AS1 (fstp%z0,%y0);
1333 return AS1 (fst%z0,%y0);
1336 /* Handle other kinds of reads to the 387 */
1338 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1339 return output_move_const_single (operands);
1341 if (STACK_TOP_P (operands[0]))
1342 return AS1 (fld%z1,%y1);
1344 /* Handle all SFmode moves not involving the 387 */
1346 return singlemove_string (operands);
1348 [(set_attr "type" "fld")])
1351 (define_insn "swapsf"
1352 [(set (match_operand:SF 0 "register_operand" "f")
1353 (match_operand:SF 1 "register_operand" "f"))
1359 if (STACK_TOP_P (operands[0]))
1360 return AS1 (fxch,%1);
1362 return AS1 (fxch,%0);
1365 (define_expand "movdf"
1366 [(set (match_operand:DF 0 "general_operand" "")
1367 (match_operand:DF 1 "general_operand" ""))]
1371 /* Special case memory->memory moves and pushes */
1373 && (reload_in_progress | reload_completed) == 0
1374 && GET_CODE (operands[0]) == MEM
1375 && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], DFmode)))
1377 rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], DFmode))
1381 emit_insn ((*genfunc) (operands[0], operands[1]));
1385 /* If we are loading a floating point constant that isn't 0 or 1 into a
1386 register, indicate we need the pic register loaded. This could be
1387 optimized into stores of constants if the target eventually moves to
1388 memory, but better safe than sorry. */
1389 if ((reload_in_progress | reload_completed) == 0
1390 && GET_CODE (operands[0]) != MEM
1391 && GET_CODE (operands[1]) == CONST_DOUBLE
1392 && !standard_80387_constant_p (operands[1]))
1394 rtx insn, note, fp_const;
1396 fp_const = force_const_mem (DFmode, operands[1]);
1398 current_function_uses_pic_offset_table = 1;
1400 insn = emit_insn (gen_rtx (SET, DFmode, operands[0], fp_const));
1401 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
1404 XEXP (note, 0) = operands[1];
1406 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, operands[1], REG_NOTES (insn));
1410 (define_insn "movdf_push_nomove"
1411 [(set (match_operand:DF 0 "push_operand" "=<,<")
1412 (match_operand:DF 1 "general_operand" "gF,f"))]
1416 if (STACK_REG_P (operands[1]))
1420 xops[0] = AT_SP (SFmode);
1421 xops[1] = GEN_INT (8);
1422 xops[2] = stack_pointer_rtx;
1424 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1426 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1427 output_asm_insn (AS1 (fstp%Q0,%0), xops);
1429 output_asm_insn (AS1 (fst%Q0,%0), xops);
1434 return output_move_double (operands);
1437 (define_insn "movdf_push"
1438 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<")
1439 (match_operand:DF 1 "general_operand" "rF,f,o,o,o"))
1440 (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
1441 (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
1445 if (STACK_REG_P (operands[1]))
1449 xops[0] = AT_SP (SFmode);
1450 xops[1] = GEN_INT (8);
1451 xops[2] = stack_pointer_rtx;
1453 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1455 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1456 output_asm_insn (AS1 (fstp%Q0,%0), xops);
1458 output_asm_insn (AS1 (fst%Q0,%0), xops);
1463 else if (GET_CODE (operands[1]) != MEM)
1464 return output_move_double (operands);
1467 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);
1470 (define_insn "movdf_mem"
1471 [(set (match_operand:DF 0 "memory_operand" "=o,o")
1472 (match_operand:DF 1 "memory_operand" "o,o"))
1473 (clobber (match_scratch:SI 2 "=&r,&r"))
1474 (clobber (match_scratch:SI 3 "=&r,X"))]
1476 "* return output_move_memory (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);")
1478 ;; For the purposes of regclass, prefer FLOAT_REGS.
1480 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
1481 (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
1482 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1483 || (GET_CODE (operands[1]) != MEM)"
1486 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1488 /* First handle a `pop' insn or a `fld %st(0)' */
1490 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1493 return AS1 (fstp,%y0);
1495 return AS1 (fld,%y0);
1498 /* Handle a transfer between the 387 and a 386 register */
1500 if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
1502 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1506 if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
1508 output_to_reg (operands[0], stack_top_dies, 0);
1512 /* Handle other kinds of writes from the 387 */
1514 if (STACK_TOP_P (operands[1]))
1517 return AS1 (fstp%z0,%y0);
1519 return AS1 (fst%z0,%y0);
1522 /* Handle other kinds of reads to the 387 */
1524 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1525 return output_move_const_single (operands);
1527 if (STACK_TOP_P (operands[0]))
1528 return AS1 (fld%z1,%y1);
1530 /* Handle all DFmode moves not involving the 387 */
1532 return output_move_double (operands);
1534 [(set_attr "type" "fld")])
1538 (define_insn "swapdf"
1539 [(set (match_operand:DF 0 "register_operand" "f")
1540 (match_operand:DF 1 "register_operand" "f"))
1546 if (STACK_TOP_P (operands[0]))
1547 return AS1 (fxch,%1);
1549 return AS1 (fxch,%0);
1552 (define_expand "movxf"
1553 [(set (match_operand:XF 0 "general_operand" "")
1554 (match_operand:XF 1 "general_operand" ""))]
1558 /* Special case memory->memory moves and pushes */
1560 && (reload_in_progress | reload_completed) == 0
1561 && GET_CODE (operands[0]) == MEM
1562 && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], XFmode)))
1564 rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], XFmode))
1568 emit_insn ((*genfunc) (operands[0], operands[1]));
1572 /* If we are loading a floating point constant that isn't 0 or 1
1573 into a register, indicate we need the pic register loaded. This could
1574 be optimized into stores of constants if the target eventually moves
1575 to memory, but better safe than sorry. */
1576 if ((reload_in_progress | reload_completed) == 0
1577 && GET_CODE (operands[0]) != MEM
1578 && GET_CODE (operands[1]) == CONST_DOUBLE
1579 && !standard_80387_constant_p (operands[1]))
1581 rtx insn, note, fp_const;
1583 fp_const = force_const_mem (XFmode, operands[1]);
1585 current_function_uses_pic_offset_table = 1;
1587 insn = emit_insn (gen_rtx (SET, XFmode, operands[0], fp_const));
1588 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
1591 XEXP (note, 0) = operands[1];
1593 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, operands[1], REG_NOTES (insn));
1598 (define_insn "movxf_push_nomove"
1599 [(set (match_operand:XF 0 "push_operand" "=<,<")
1600 (match_operand:XF 1 "general_operand" "gF,f"))]
1604 if (STACK_REG_P (operands[1]))
1608 xops[0] = AT_SP (SFmode);
1609 xops[1] = GEN_INT (12);
1610 xops[2] = stack_pointer_rtx;
1612 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1613 output_asm_insn (AS1 (fstp%T0,%0), xops);
1614 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1615 output_asm_insn (AS1 (fld%T0,%0), xops);
1620 return output_move_double (operands);
1623 (define_insn "movxf_push"
1624 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
1625 (match_operand:XF 1 "general_operand" "rF,f,o,o,o"))
1626 (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
1627 (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
1631 if (STACK_REG_P (operands[1]))
1635 xops[0] = AT_SP (SFmode);
1636 xops[1] = GEN_INT (12);
1637 xops[2] = stack_pointer_rtx;
1639 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1640 output_asm_insn (AS1 (fstp%T0,%0), xops);
1641 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1642 output_asm_insn (AS1 (fld%T0,%0), xops);
1647 else if (GET_CODE (operands[1]) != MEM
1648 || GET_CODE (operands[2]) != REG)
1649 return output_move_double (operands);
1652 return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);
1655 (define_insn "movxf_mem"
1656 [(set (match_operand:XF 0 "memory_operand" "=o,o")
1657 (match_operand:XF 1 "memory_operand" "o,o"))
1658 (clobber (match_scratch:SI 2 "=&r,&r"))
1659 (clobber (match_scratch:SI 3 "=&r,X"))]
1661 "* return output_move_memory (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);")
1664 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
1665 (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
1666 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1667 || (GET_CODE (operands[1]) != MEM)"
1670 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1672 /* First handle a `pop' insn or a `fld %st(0)' */
1674 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1677 return AS1 (fstp,%y0);
1679 return AS1 (fld,%y0);
1682 /* Handle a transfer between the 387 and a 386 register */
1684 if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
1686 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1690 if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
1692 output_to_reg (operands[0], stack_top_dies, 0);
1696 /* Handle other kinds of writes from the 387 */
1698 if (STACK_TOP_P (operands[1]))
1700 output_asm_insn (AS1 (fstp%z0,%y0), operands);
1701 if (! stack_top_dies)
1702 return AS1 (fld%z0,%y0);
1707 /* Handle other kinds of reads to the 387 */
1709 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1710 return output_move_const_single (operands);
1712 if (STACK_TOP_P (operands[0]))
1713 return AS1 (fld%z1,%y1);
1715 /* Handle all XFmode moves not involving the 387 */
1717 return output_move_double (operands);
1720 (define_insn "swapxf"
1721 [(set (match_operand:XF 0 "register_operand" "f")
1722 (match_operand:XF 1 "register_operand" "f"))
1728 if (STACK_TOP_P (operands[0]))
1729 return AS1 (fxch,%1);
1731 return AS1 (fxch,%0);
1735 [(set (match_operand:DI 0 "push_operand" "=<,<,<,<")
1736 (match_operand:DI 1 "general_operand" "riF,o,o,o"))
1737 (clobber (match_scratch:SI 2 "=X,&r,&r,X"))
1738 (clobber (match_scratch:SI 3 "=X,&r,X,X"))]
1742 if (GET_CODE (operands[1]) != MEM)
1743 return output_move_double (operands);
1746 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
1749 (define_insn "movdi"
1750 [(set (match_operand:DI 0 "general_operand" "=o,o,r,rm")
1751 (match_operand:DI 1 "general_operand" "o,o,m,riF"))
1752 (clobber (match_scratch:SI 2 "=&r,&r,X,X"))
1753 (clobber (match_scratch:SI 3 "=&r,X,X,X"))]
1757 rtx low[2], high[2], xop[6];
1759 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1760 return output_move_double (operands);
1762 return output_move_memory (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
1766 ;;- conversion instructions
1769 ;;- zero extension instructions
1770 ;; See comments by `andsi' for when andl is faster than movzx.
1772 (define_insn "zero_extendhisi2"
1773 [(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
1774 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
1780 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1781 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1783 xops[0] = operands[0];
1784 xops[1] = GEN_INT (0xffff);
1785 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1788 if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1]))
1790 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1791 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1795 if (TARGET_ZERO_EXTEND_WITH_AND)
1797 xops[0] = operands[0];
1798 xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xffff);
1799 if (i386_aligned_p (operands[1]))
1800 output_asm_insn (AS2 (mov%L0,%k1,%k0),operands);
1802 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1803 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1808 return AS2 (movzx,%1,%0);
1810 return AS2 (movz%W0%L0,%1,%0);
1815 [(set (match_operand:SI 0 "register_operand" "")
1816 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1817 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])"
1820 (set (strict_low_part (match_dup 2))
1822 "operands[2] = gen_rtx (REG, HImode, true_regnum (operands[0]));")
1826 [(set (match_operand:SI 0 "register_operand" "")
1827 (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))]
1828 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])"
1829 [(set (strict_low_part (match_dup 2))
1832 (and:SI (match_dup 0)
1833 (const_int 65535)))]
1834 "operands[2] = gen_rtx (REG, HImode, true_regnum (operands[0]));")
1836 (define_insn "zero_extendqihi2"
1837 [(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
1838 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1844 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1845 && REG_P (operands[1])
1846 && REGNO (operands[0]) == REGNO (operands[1]))
1848 xops[0] = operands[0];
1849 xops[1] = GEN_INT (0xff);
1850 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1853 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1855 if(!reg_overlap_mentioned_p(operands[0],operands[1]))
1857 output_asm_insn (AS2 (xor%L0,%k0,%k0), operands);
1858 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1862 xops[0] = operands[0];
1863 xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff);
1864 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1865 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1871 return AS2 (movzx,%1,%0);
1873 return AS2 (movz%B0%W0,%1,%0);
1878 [(set (match_operand:HI 0 "register_operand" "")
1879 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1880 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1881 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1884 (set (strict_low_part (match_dup 2))
1886 "operands[2] = gen_rtx (REG, QImode, REGNO (operands[0]));")
1890 [(set (match_operand:HI 0 "register_operand" "")
1891 (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))]
1892 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1893 && reg_overlap_mentioned_p (operands[0], operands[1])"
1894 [(set (strict_low_part (match_dup 2))
1897 (and:HI (match_dup 0)
1899 "operands[2] = gen_rtx (REG, QImode, REGNO (operands[0]));")
1902 [(set (match_operand:HI 0 "register_operand" "")
1903 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1904 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND"
1908 (and:HI (match_dup 0)
1910 "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0)
1911 operands[1] = SUBREG_REG (operands[1]);
1912 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG
1913 || REGNO (operands[0]) == REGNO (operands[1]))
1915 operands[2] = gen_rtx (REG, HImode, REGNO (operands[1]));")
1917 (define_insn "zero_extendqisi2"
1918 [(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
1919 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1925 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1926 && REG_P (operands[1])
1927 && REGNO (operands[0]) == REGNO (operands[1]))
1929 xops[0] = operands[0];
1930 xops[1] = GEN_INT (0xff);
1931 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1934 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1936 if(!reg_overlap_mentioned_p (operands[0], operands[1]))
1938 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1939 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1943 xops[0] = operands[0];
1944 xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff);
1945 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1946 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1951 if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG)
1953 xops[0] = operands[0];
1954 xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff);
1955 operands[1] = gen_rtx (REG, SImode, REGNO (operands[1]));
1956 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
1957 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1962 return AS2 (movzx,%1,%0);
1964 return AS2 (movz%B0%L0,%1,%0);
1969 [(set (match_operand:SI 0 "register_operand" "")
1970 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1971 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1972 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1975 (set (strict_low_part (match_dup 2))
1977 "operands[2] = gen_rtx (REG, QImode, REGNO (operands[0]));")
1981 [(set (match_operand:SI 0 "register_operand" "")
1982 (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))]
1983 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1984 && reg_overlap_mentioned_p (operands[0], operands[1])"
1985 [(set (strict_low_part (match_dup 2))
1988 (and:SI (match_dup 0)
1990 "operands[2] = gen_rtx (REG, QImode, REGNO (operands[0]));")
1993 [(set (match_operand:SI 0 "register_operand" "")
1994 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1995 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
1996 && ! reg_overlap_mentioned_p (operands[0], operands[1])"
2000 (and:SI (match_dup 0)
2002 "operands[2] = gen_rtx (REG, SImode, true_regnum (operands[1]));")
2004 (define_insn "zero_extendsidi2"
2005 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m")
2006 (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))]
2010 rtx high[2], low[2], xops[4];
2012 if (REG_P (operands[0]) && REG_P (operands[1])
2013 && REGNO (operands[0]) == REGNO (operands[1]))
2015 operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
2016 return AS2 (xor%L0,%0,%0);
2019 split_di (operands, 1, low, high);
2021 xops[1] = operands[1];
2023 xops[3] = const0_rtx;
2025 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2026 if (GET_CODE (low[0]) == MEM)
2027 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
2029 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
2034 ;;- sign extension instructions
2036 (define_insn "extendsidi2"
2037 [(set (match_operand:DI 0 "register_operand" "=r")
2038 (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))]
2042 if (REGNO (operands[0]) == 0)
2044 /* This used to be cwtl, but that extends HI to SI somehow. */
2052 operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
2053 output_asm_insn (AS2 (mov%L0,%0,%1), operands);
2055 operands[0] = GEN_INT (31);
2056 return AS2 (sar%L1,%0,%1);
2059 ;; Note that the i386 programmers' manual says that the opcodes
2060 ;; are named movsx..., but the assembler on Unix does not accept that.
2061 ;; We use what the Unix assembler expects.
2063 (define_insn "extendhisi2"
2064 [(set (match_operand:SI 0 "register_operand" "=r")
2065 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2069 if (REGNO (operands[0]) == 0
2070 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
2078 return AS2 (movsx,%1,%0);
2080 return AS2 (movs%W0%L0,%1,%0);
2084 (define_insn "extendqihi2"
2085 [(set (match_operand:HI 0 "register_operand" "=r")
2086 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2090 if (REGNO (operands[0]) == 0
2091 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
2095 return AS2 (movsx,%1,%0);
2097 return AS2 (movs%B0%W0,%1,%0);
2101 (define_insn "extendqisi2"
2102 [(set (match_operand:SI 0 "register_operand" "=r")
2103 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2108 return AS2 (movsx,%1,%0);
2110 return AS2 (movs%B0%L0,%1,%0);
2115 ;; Truncation of long long -> 32 bit
2117 (define_expand "truncdisi2"
2118 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2119 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2123 /* Don't generate memory->memory moves, go through a register */
2125 && (reload_in_progress | reload_completed) == 0
2126 && GET_CODE (operands[0]) == MEM
2127 && GET_CODE (operands[1]) == MEM)
2129 rtx target = gen_reg_rtx (SImode);
2130 emit_insn (gen_truncdisi2 (target, operands[1]));
2131 emit_move_insn (operands[0], target);
2137 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2138 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2139 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2142 rtx low[2], high[2], xops[2];
2144 split_di (&operands[1], 1, low, high);
2145 xops[0] = operands[0];
2147 if (!rtx_equal_p (xops[0], xops[1]))
2148 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2154 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2155 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
2157 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2160 rtx low[2], high[2], xops[2];
2162 split_di (&operands[1], 1, low, high);
2163 xops[0] = operands[0];
2165 if (!rtx_equal_p (xops[0], xops[1]))
2166 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2173 ;; Conversions between float and double.
2175 (define_insn "extendsfdf2"
2176 [(set (match_operand:DF 0 "nonimmediate_operand" "=fm,f")
2178 (match_operand:SF 1 "nonimmediate_operand" "f,fm")))]
2182 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2184 if (NON_STACK_REG_P (operands[1]))
2186 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2190 if (NON_STACK_REG_P (operands[0]))
2192 output_to_reg (operands[0], stack_top_dies, 0);
2196 if (STACK_TOP_P (operands[0]))
2197 return AS1 (fld%z1,%y1);
2199 if (GET_CODE (operands[0]) == MEM)
2202 return AS1 (fstp%z0,%y0);
2204 return AS1 (fst%z0,%y0);
2210 (define_insn "extenddfxf2"
2211 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
2213 (match_operand:DF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
2217 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2219 if (NON_STACK_REG_P (operands[1]))
2221 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2225 if (NON_STACK_REG_P (operands[0]))
2227 output_to_reg (operands[0], stack_top_dies, 0);
2231 if (STACK_TOP_P (operands[0]))
2232 return AS1 (fld%z1,%y1);
2234 if (GET_CODE (operands[0]) == MEM)
2236 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2237 if (! stack_top_dies)
2238 return AS1 (fld%z0,%y0);
2245 (define_insn "extendsfxf2"
2246 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
2248 (match_operand:SF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
2252 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2254 if (NON_STACK_REG_P (operands[1]))
2256 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2260 if (NON_STACK_REG_P (operands[0]))
2262 output_to_reg (operands[0], stack_top_dies, 0);
2266 if (STACK_TOP_P (operands[0]))
2267 return AS1 (fld%z1,%y1);
2269 if (GET_CODE (operands[0]) == MEM)
2271 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2272 if (! stack_top_dies)
2273 return AS1 (fld%z0,%y0);
2280 (define_expand "truncdfsf2"
2281 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2283 (match_operand:DF 1 "register_operand" "")))
2284 (clobber (match_dup 2))])]
2288 operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2291 ;; This cannot output into an f-reg because there is no way to be sure
2292 ;; of truncating in that case. Otherwise this is just like a simple move
2293 ;; insn. So we pretend we can output to a reg in order to get better
2294 ;; register preferencing, but we really use a stack slot.
2297 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
2299 (match_operand:DF 1 "register_operand" "0,f")))
2300 (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
2304 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2306 if (GET_CODE (operands[0]) == MEM)
2309 return AS1 (fstp%z0,%0);
2311 return AS1 (fst%z0,%0);
2313 else if (STACK_TOP_P (operands[0]))
2315 output_asm_insn (AS1 (fstp%z2,%y2), operands);
2316 return AS1 (fld%z2,%y2);
2322 (define_insn "truncxfsf2"
2323 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r")
2325 (match_operand:XF 1 "register_operand" "f,f")))]
2329 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2331 if (NON_STACK_REG_P (operands[0]))
2333 if (stack_top_dies == 0)
2335 output_asm_insn (AS1 (fld,%y1), operands);
2338 output_to_reg (operands[0], stack_top_dies, 0);
2341 else if (GET_CODE (operands[0]) == MEM)
2344 return AS1 (fstp%z0,%0);
2347 output_asm_insn (AS1 (fld,%y1), operands);
2348 return AS1 (fstp%z0,%0);
2355 (define_insn "truncxfdf2"
2356 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!*r")
2358 (match_operand:XF 1 "register_operand" "f,f")))]
2362 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2364 if (NON_STACK_REG_P (operands[0]))
2366 if (stack_top_dies == 0)
2368 output_asm_insn (AS1 (fld,%y1), operands);
2371 output_to_reg (operands[0], stack_top_dies, 0);
2374 else if (GET_CODE (operands[0]) == MEM)
2377 return AS1 (fstp%z0,%0);
2380 output_asm_insn (AS1 (fld,%y1), operands);
2381 return AS1 (fstp%z0,%0);
2389 ;; The 387 requires that the stack top dies after converting to DImode.
2391 ;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
2392 ;; doing a signed conversion to DImode, and then taking just the low
2395 (define_expand "fixuns_truncxfsi2"
2397 (match_operand:XF 1 "register_operand" ""))
2398 (parallel [(set (match_dup 2)
2399 (fix:DI (fix:XF (match_dup 4))))
2400 (clobber (match_dup 4))
2401 (clobber (match_dup 5))
2402 (clobber (match_dup 6))
2403 (clobber (match_scratch:SI 7 ""))])
2404 (set (match_operand:SI 0 "general_operand" "")
2409 operands[2] = gen_reg_rtx (DImode);
2410 operands[3] = gen_lowpart (SImode, operands[2]);
2411 operands[4] = gen_reg_rtx (XFmode);
2412 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2413 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2416 (define_expand "fixuns_truncdfsi2"
2418 (match_operand:DF 1 "register_operand" ""))
2419 (parallel [(set (match_dup 2)
2420 (fix:DI (fix:DF (match_dup 4))))
2421 (clobber (match_dup 4))
2422 (clobber (match_dup 5))
2423 (clobber (match_dup 6))
2424 (clobber (match_scratch:SI 7 ""))])
2425 (set (match_operand:SI 0 "general_operand" "")
2430 operands[2] = gen_reg_rtx (DImode);
2431 operands[3] = gen_lowpart (SImode, operands[2]);
2432 operands[4] = gen_reg_rtx (DFmode);
2433 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2434 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2437 (define_expand "fixuns_truncsfsi2"
2439 (match_operand:SF 1 "register_operand" ""))
2440 (parallel [(set (match_dup 2)
2441 (fix:DI (fix:SF (match_dup 4))))
2442 (clobber (match_dup 4))
2443 (clobber (match_dup 5))
2444 (clobber (match_dup 6))
2445 (clobber (match_scratch:SI 7 ""))])
2446 (set (match_operand:SI 0 "general_operand" "")
2451 operands[2] = gen_reg_rtx (DImode);
2452 operands[3] = gen_lowpart (SImode, operands[2]);
2453 operands[4] = gen_reg_rtx (SFmode);
2454 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
2455 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
2458 ;; Signed conversion to DImode.
2460 (define_expand "fix_truncxfdi2"
2462 (match_operand:XF 1 "register_operand" ""))
2463 (parallel [(set (match_operand:DI 0 "general_operand" "")
2464 (fix:DI (fix:XF (match_dup 2))))
2465 (clobber (match_dup 2))
2466 (clobber (match_dup 3))
2467 (clobber (match_dup 4))
2468 (clobber (match_scratch:SI 5 ""))])]
2472 operands[1] = copy_to_mode_reg (XFmode, operands[1]);
2473 operands[2] = gen_reg_rtx (XFmode);
2474 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2475 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2478 (define_expand "fix_truncdfdi2"
2480 (match_operand:DF 1 "register_operand" ""))
2481 (parallel [(set (match_operand:DI 0 "general_operand" "")
2482 (fix:DI (fix:DF (match_dup 2))))
2483 (clobber (match_dup 2))
2484 (clobber (match_dup 3))
2485 (clobber (match_dup 4))
2486 (clobber (match_scratch:SI 5 ""))])]
2490 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
2491 operands[2] = gen_reg_rtx (DFmode);
2492 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2493 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2496 (define_expand "fix_truncsfdi2"
2498 (match_operand:SF 1 "register_operand" ""))
2499 (parallel [(set (match_operand:DI 0 "general_operand" "")
2500 (fix:DI (fix:SF (match_dup 2))))
2501 (clobber (match_dup 2))
2502 (clobber (match_dup 3))
2503 (clobber (match_dup 4))
2504 (clobber (match_scratch:SI 5 ""))])]
2508 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
2509 operands[2] = gen_reg_rtx (SFmode);
2510 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
2511 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
2514 ;; These match a signed conversion of either DFmode or SFmode to DImode.
2517 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2518 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
2519 (clobber (match_dup 1))
2520 (clobber (match_operand:SI 2 "memory_operand" "m"))
2521 (clobber (match_operand:DI 3 "memory_operand" "m"))
2522 (clobber (match_scratch:SI 4 "=&q"))]
2524 "* return output_fix_trunc (insn, operands);")
2527 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2528 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2529 (clobber (match_dup 1))
2530 (clobber (match_operand:SI 2 "memory_operand" "m"))
2531 (clobber (match_operand:DI 3 "memory_operand" "m"))
2532 (clobber (match_scratch:SI 4 "=&q"))]
2534 "* return output_fix_trunc (insn, operands);")
2537 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
2538 (fix:DI (fix:SF (match_operand:SF 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);")
2546 ;; Signed MODE_FLOAT conversion to SImode.
2548 (define_expand "fix_truncxfsi2"
2549 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2551 (fix:XF (match_operand:XF 1 "register_operand" ""))))
2552 (clobber (match_dup 2))
2553 (clobber (match_dup 3))
2554 (clobber (match_scratch:SI 4 ""))])]
2558 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2559 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2562 (define_expand "fix_truncdfsi2"
2563 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2565 (fix:DF (match_operand:DF 1 "register_operand" ""))))
2566 (clobber (match_dup 2))
2567 (clobber (match_dup 3))
2568 (clobber (match_scratch:SI 4 ""))])]
2572 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2573 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2576 (define_expand "fix_truncsfsi2"
2577 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2579 (fix:SF (match_operand:SF 1 "register_operand" ""))))
2580 (clobber (match_dup 2))
2581 (clobber (match_dup 3))
2582 (clobber (match_scratch:SI 4 ""))])]
2586 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
2587 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
2591 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2592 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
2593 (clobber (match_operand:SI 2 "memory_operand" "m"))
2594 (clobber (match_operand:DI 3 "memory_operand" "m"))
2595 (clobber (match_scratch:SI 4 "=&q"))]
2597 "* return output_fix_trunc (insn, operands);")
2600 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2601 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2602 (clobber (match_operand:SI 2 "memory_operand" "m"))
2603 (clobber (match_operand:DI 3 "memory_operand" "m"))
2604 (clobber (match_scratch:SI 4 "=&q"))]
2606 "* return output_fix_trunc (insn, operands);")
2609 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
2610 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
2611 (clobber (match_operand:SI 2 "memory_operand" "m"))
2612 (clobber (match_operand:DI 3 "memory_operand" "m"))
2613 (clobber (match_scratch:SI 4 "=&q"))]
2615 "* return output_fix_trunc (insn, operands);")
2617 ;; Conversion between fixed point and floating point.
2618 ;; The actual pattern that matches these is at the end of this file.
2620 ;; ??? Possibly represent floatunssidf2 here in gcc2.
2622 (define_expand "floatsisf2"
2623 [(set (match_operand:SF 0 "register_operand" "")
2624 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
2628 (define_expand "floatdisf2"
2629 [(set (match_operand:SF 0 "register_operand" "")
2630 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
2634 (define_expand "floatsidf2"
2635 [(set (match_operand:DF 0 "register_operand" "")
2636 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
2640 (define_expand "floatdidf2"
2641 [(set (match_operand:DF 0 "register_operand" "")
2642 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
2646 (define_expand "floatsixf2"
2647 [(set (match_operand:XF 0 "register_operand" "")
2648 (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
2652 (define_expand "floatdixf2"
2653 [(set (match_operand:XF 0 "register_operand" "")
2654 (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
2655 "TARGET_80387 && LONG_DOUBLE_TYPE_SIZE == 96"
2658 ;; This will convert from SImode or DImode to MODE_FLOAT.
2661 [(set (match_operand:XF 0 "register_operand" "=f")
2662 (float:XF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2666 if (NON_STACK_REG_P (operands[1]))
2668 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2671 else if (GET_CODE (operands[1]) == MEM)
2672 return AS1 (fild%z1,%1);
2678 [(set (match_operand:DF 0 "register_operand" "=f")
2679 (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2683 if (NON_STACK_REG_P (operands[1]))
2685 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2688 else if (GET_CODE (operands[1]) == MEM)
2689 return AS1 (fild%z1,%1);
2695 [(set (match_operand:SF 0 "register_operand" "=f")
2696 (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
2700 if (NON_STACK_REG_P (operands[1]))
2702 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2705 else if (GET_CODE (operands[1]) == MEM)
2706 return AS1 (fild%z1,%1);
2712 [(set (match_operand:DF 0 "register_operand" "=f")
2713 (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
2717 if (NON_STACK_REG_P (operands[1]))
2719 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2722 else if (GET_CODE (operands[1]) == MEM)
2723 return AS1 (fild%z1,%1);
2729 [(set (match_operand:XF 0 "register_operand" "=f,f")
2730 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!*r")))]
2734 if (NON_STACK_REG_P (operands[1]))
2736 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2739 else if (GET_CODE (operands[1]) == MEM)
2740 return AS1 (fild%z1,%1);
2746 [(set (match_operand:SF 0 "register_operand" "=f")
2747 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
2751 if (NON_STACK_REG_P (operands[1]))
2753 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2756 else if (GET_CODE (operands[1]) == MEM)
2757 return AS1 (fild%z1,%1);
2762 ;;- add instructions
2764 (define_insn "addsidi3_1"
2765 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o")
2766 (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o")
2767 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri"))))
2768 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))]
2772 rtx low[3], high[3], xops[7], temp;
2776 split_di (operands, 2, low, high);
2777 high[2] = const0_rtx;
2778 low[2] = operands[2];
2780 if (!rtx_equal_p (operands[0], operands[1]))
2787 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2790 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2796 xops[6] = operands[3];
2797 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2798 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2799 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2800 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2801 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2802 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2807 output_asm_insn (AS2 (add%L0,%2,%0), low);
2808 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2812 (define_insn "addsidi3_2"
2813 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o")
2814 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r"))
2815 (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o")))
2816 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))]
2820 rtx low[3], high[3], xops[7], temp;
2824 split_di (operands, 2, low, high);
2825 high[2] = const0_rtx;
2826 low[2] = operands[2];
2828 if (!rtx_equal_p (operands[0], operands[1]))
2835 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2837 if (rtx_equal_p (low[0], operands[2]))
2839 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2840 output_asm_insn (AS2 (add%L0,%1,%0), low);
2841 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2844 if (rtx_equal_p (high[0], operands[2]))
2846 if (GET_CODE (operands[0]) != MEM)
2848 output_asm_insn (AS2 (mov%L0,%2,%0), low);
2849 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2850 output_asm_insn (AS2 (add%L0,%1,%0), low);
2851 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2855 /* It's too late to ask for a scratch now - but this
2856 will probably not happen too often. */
2857 output_asm_insn (AS2 (add%L1,%2,%1), low);
2858 output_asm_insn (AS2 (mov%L0,%1,%0), low);
2859 output_asm_insn (AS2 (mov%L1,%2,%1), low);
2860 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2861 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2862 output_asm_insn (AS2 (sub%L1,%0,%1), low);
2863 output_asm_insn (AS1 (neg%L1,%1), low);
2867 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2868 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2874 xops[6] = operands[3];
2875 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2876 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2877 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2878 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2879 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2880 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2885 output_asm_insn (AS2 (add%L0,%2,%0), low);
2886 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2890 (define_insn "adddi3"
2891 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,!&r,!o,!o")
2892 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0iF,or,riF,o")
2893 (match_operand:DI 2 "general_operand" "o,riF,or,or,oriF,o")))
2894 (clobber (match_scratch:SI 3 "=X,X,&r,X,&r,&r"))]
2898 rtx low[3], high[3], xops[7], temp;
2902 if (rtx_equal_p (operands[0], operands[2]))
2905 operands[1] = operands[2];
2909 split_di (operands, 3, low, high);
2910 if (!rtx_equal_p (operands[0], operands[1]))
2917 if (GET_CODE (operands[0]) != MEM)
2919 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2920 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2926 xops[6] = operands[3];
2927 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2928 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2929 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2930 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2931 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2932 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2937 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
2943 xops[4] = operands[3];
2945 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
2946 output_asm_insn (AS2 (add%L1,%4,%1), xops);
2947 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
2948 output_asm_insn (AS2 (adc%L0,%4,%0), xops);
2951 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
2953 output_asm_insn (AS2 (add%L0,%2,%0), low);
2954 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2958 output_asm_insn (AS2 (add%L0,%2,%0), high);
2963 ;; On a 486, it is faster to do movl/addl than to do a single leal if
2964 ;; operands[1] and operands[2] are both registers.
2966 (define_expand "addsi3"
2967 [(set (match_operand:SI 0 "nonimmediate_operand" "")
2968 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
2969 (match_operand:SI 2 "general_operand" "")))]
2971 "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);")
2974 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
2975 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
2976 (match_operand:SI 2 "general_operand" "rmi,ri,ri")))]
2977 "ix86_binary_operator_ok (PLUS, SImode, operands)"
2980 if (REG_P (operands[0]) && REG_P (operands[1])
2981 && (REG_P (operands[2]) || GET_CODE (operands[2]) == CONST_INT)
2982 && REGNO (operands[0]) != REGNO (operands[1]))
2984 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
2985 return AS2 (add%L0,%1,%0);
2987 if (operands[2] == stack_pointer_rtx)
2992 operands[1] = operands[2];
2996 if (operands[2] != stack_pointer_rtx)
2999 operands[1] = SET_SRC (PATTERN (insn));
3000 return AS2 (lea%L0,%a1,%0);
3004 if (!rtx_equal_p (operands[0], operands[1]))
3005 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
3007 if (operands[2] == const1_rtx)
3008 return AS1 (inc%L0,%0);
3010 if (operands[2] == constm1_rtx)
3011 return AS1 (dec%L0,%0);
3013 /* subl $-128,%ebx is smaller than addl $128,%ebx. */
3014 if (GET_CODE (operands[2]) == CONST_INT
3015 && INTVAL (operands[2]) == 128)
3017 /* This doesn't compute the carry bit in the same way
3018 * as add%L0, but we use inc and dec above and they
3019 * don't set the carry bit at all. If inc/dec don't need
3020 * a CC_STATUS_INIT, this doesn't either... */
3021 operands[2] = GEN_INT (-128);
3022 return AS2 (sub%L0,%2,%0);
3025 return AS2 (add%L0,%2,%0);
3028 ;; addsi3 is faster, so put this after.
3030 (define_insn "movsi_lea"
3031 [(set (match_operand:SI 0 "register_operand" "=r")
3032 (match_operand:QI 1 "address_operand" "p"))]
3036 /* Adding a constant to a register is faster with an add. */
3037 /* ??? can this ever happen? */
3038 if (GET_CODE (operands[1]) == PLUS
3039 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
3040 && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
3042 operands[1] = XEXP (operands[1], 1);
3044 if (operands[1] == const1_rtx)
3045 return AS1 (inc%L0,%0);
3047 if (operands[1] == constm1_rtx)
3048 return AS1 (dec%L0,%0);
3050 return AS2 (add%L0,%1,%0);
3054 return AS2 (lea%L0,%a1,%0);
3057 ;; ??? `lea' here, for three operand add? If leaw is used, only %bx,
3058 ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
3059 ;; able to handle the operand. But leal always works?
3061 (define_expand "addhi3"
3062 [(set (match_operand:HI 0 "general_operand" "")
3063 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3064 (match_operand:HI 2 "general_operand" "")))]
3066 "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);")
3069 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3070 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3071 (match_operand:HI 2 "general_operand" "ri,rm")))]
3072 "ix86_binary_operator_ok (PLUS, HImode, operands)"
3075 /* ??? what about offsettable memory references? */
3076 if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */
3077 && QI_REG_P (operands[0])
3078 && GET_CODE (operands[2]) == CONST_INT
3079 && (INTVAL (operands[2]) & 0xff) == 0
3080 && i386_cc_probably_useless_p (insn))
3082 int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
3086 return AS1 (inc%B0,%h0);
3087 else if (byteval == 255)
3088 return AS1 (dec%B0,%h0);
3090 operands[2] = GEN_INT (byteval);
3091 return AS2 (add%B0,%2,%h0);
3094 /* Use a 32-bit operation when possible, to avoid the prefix penalty. */
3095 if (REG_P (operands[0])
3096 && i386_aligned_p (operands[2])
3097 && i386_cc_probably_useless_p (insn))
3101 if (GET_CODE (operands[2]) == CONST_INT)
3103 HOST_WIDE_INT intval = 0xffff & INTVAL (operands[2]);
3106 return AS1 (inc%L0,%k0);
3108 if (intval == 0xffff)
3109 return AS1 (dec%L0,%k0);
3111 operands[2] = i386_sext16_if_const (operands[2]);
3113 return AS2 (add%L0,%k2,%k0);
3116 if (operands[2] == const1_rtx)
3117 return AS1 (inc%W0,%0);
3119 if (operands[2] == constm1_rtx
3120 || (GET_CODE (operands[2]) == CONST_INT
3121 && INTVAL (operands[2]) == 65535))
3122 return AS1 (dec%W0,%0);
3124 return AS2 (add%W0,%2,%0);
3127 (define_expand "addqi3"
3128 [(set (match_operand:QI 0 "general_operand" "")
3129 (plus:QI (match_operand:QI 1 "general_operand" "")
3130 (match_operand:QI 2 "general_operand" "")))]
3132 "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);")
3135 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3136 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3137 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3138 "ix86_binary_operator_ok (PLUS, QImode, operands)"
3141 if (operands[2] == const1_rtx)
3142 return AS1 (inc%B0,%0);
3144 if (operands[2] == constm1_rtx
3145 || (GET_CODE (operands[2]) == CONST_INT
3146 && INTVAL (operands[2]) == 255))
3147 return AS1 (dec%B0,%0);
3149 return AS2 (add%B0,%2,%0);
3152 ;Lennart Augustsson <augustss@cs.chalmers.se>
3153 ;says this pattern just makes slower code:
3157 ; leal -80(%ebp),%eax
3161 ; [(set (match_operand:SI 0 "push_operand" "=<")
3162 ; (plus:SI (match_operand:SI 1 "register_operand" "%r")
3163 ; (match_operand:SI 2 "nonmemory_operand" "ri")))]
3168 ; xops[0] = operands[0];
3169 ; xops[1] = operands[1];
3170 ; xops[2] = operands[2];
3171 ; xops[3] = gen_rtx (MEM, SImode, stack_pointer_rtx);
3172 ; output_asm_insn (\"push%z1 %1\", xops);
3173 ; output_asm_insn (AS2 (add%z3,%2,%3), xops);
3177 ;; The patterns that match these are at the end of this file.
3179 (define_expand "addxf3"
3180 [(set (match_operand:XF 0 "register_operand" "")
3181 (plus:XF (match_operand:XF 1 "register_operand" "")
3182 (match_operand:XF 2 "register_operand" "")))]
3186 (define_expand "adddf3"
3187 [(set (match_operand:DF 0 "register_operand" "")
3188 (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3189 (match_operand:DF 2 "nonimmediate_operand" "")))]
3193 (define_expand "addsf3"
3194 [(set (match_operand:SF 0 "register_operand" "")
3195 (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3196 (match_operand:SF 2 "nonimmediate_operand" "")))]
3200 ;;- subtract instructions
3202 (define_insn "subsidi3"
3203 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o")
3204 (minus:DI (match_operand:DI 1 "general_operand" "0iF,0,roiF,roiF,riF,o,o")
3205 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,ri,i,r"))))
3206 (clobber (match_scratch:SI 3 "=X,X,X,X,X,&r,&r"))]
3210 rtx low[3], high[3], xops[7];
3214 split_di (operands, 2, low, high);
3215 high[2] = const0_rtx;
3216 low[2] = operands[2];
3218 if (!rtx_equal_p (operands[0], operands[1]))
3225 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3227 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3228 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3234 xops[6] = operands[3];
3235 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3236 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3237 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3238 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3239 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3240 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3245 output_asm_insn (AS2 (sub%L0,%2,%0), low);
3246 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3250 (define_insn "subdi3"
3251 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
3252 (minus:DI (match_operand:DI 1 "general_operand" "0,0,0iF,or,roiF,roiF")
3253 (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
3254 (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
3258 rtx low[3], high[3], xops[7];
3262 split_di (operands, 3, low, high);
3264 if (!rtx_equal_p (operands[0], operands[1]))
3271 if (GET_CODE (operands[0]) != MEM)
3273 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3274 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3280 xops[6] = operands[3];
3281 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3282 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3283 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3284 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3285 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3286 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3291 if (GET_CODE (operands[3]) == REG)
3297 xops[4] = operands[3];
3299 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3300 output_asm_insn (AS2 (sub%L1,%4,%1), xops);
3301 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3302 output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
3305 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
3307 output_asm_insn (AS2 (sub%L0,%2,%0), low);
3308 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3312 output_asm_insn (AS2 (sub%L0,%2,%0), high);
3317 (define_expand "subsi3"
3318 [(set (match_operand:SI 0 "nonimmediate_operand" "")
3319 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3320 (match_operand:SI 2 "general_operand" "")))]
3322 "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);")
3325 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3326 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
3327 (match_operand:SI 2 "general_operand" "ri,rm")))]
3328 "ix86_binary_operator_ok (MINUS, SImode, operands)"
3329 "* return AS2 (sub%L0,%2,%0);")
3331 (define_expand "subhi3"
3332 [(set (match_operand:HI 0 "general_operand" "")
3333 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3334 (match_operand:HI 2 "general_operand" "")))]
3336 "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);")
3339 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3340 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
3341 (match_operand:HI 2 "general_operand" "ri,rm")))]
3342 "ix86_binary_operator_ok (MINUS, HImode, operands)"
3345 if (REG_P (operands[0])
3346 && i386_aligned_p (operands[2])
3347 && i386_cc_probably_useless_p (insn))
3350 operands[2] = i386_sext16_if_const (operands[2]);
3351 return AS2 (sub%L0,%k2,%k0);
3353 return AS2 (sub%W0,%2,%0);
3356 (define_expand "subqi3"
3357 [(set (match_operand:QI 0 "general_operand" "")
3358 (minus:QI (match_operand:QI 1 "general_operand" "")
3359 (match_operand:QI 2 "general_operand" "")))]
3361 "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);")
3364 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3365 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
3366 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3367 "ix86_binary_operator_ok (MINUS, QImode, operands)"
3368 "* return AS2 (sub%B0,%2,%0);")
3370 ;; The patterns that match these are at the end of this file.
3372 (define_expand "subxf3"
3373 [(set (match_operand:XF 0 "register_operand" "")
3374 (minus:XF (match_operand:XF 1 "register_operand" "")
3375 (match_operand:XF 2 "register_operand" "")))]
3379 (define_expand "subdf3"
3380 [(set (match_operand:DF 0 "register_operand" "")
3381 (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3382 (match_operand:DF 2 "nonimmediate_operand" "")))]
3386 (define_expand "subsf3"
3387 [(set (match_operand:SF 0 "register_operand" "")
3388 (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3389 (match_operand:SF 2 "nonimmediate_operand" "")))]
3393 ;;- multiply instructions
3395 ;(define_insn "mulqi3"
3396 ; [(set (match_operand:QI 0 "register_operand" "=a")
3397 ; (mult:QI (match_operand:QI 1 "register_operand" "%0")
3398 ; (match_operand:QI 2 "nonimmediate_operand" "qm")))]
3402 (define_insn "mulhi3"
3403 [(set (match_operand:HI 0 "register_operand" "=r,r")
3404 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%0,rm")
3405 (match_operand:HI 2 "general_operand" "g,i")))]
3409 if (GET_CODE (operands[1]) == REG
3410 && REGNO (operands[1]) == REGNO (operands[0])
3411 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3412 /* Assembler has weird restrictions. */
3413 return AS2 (imul%W0,%2,%0);
3414 return AS3 (imul%W0,%2,%1,%0);
3416 [(set_attr "type" "imul")])
3418 (define_insn "mulsi3"
3419 [(set (match_operand:SI 0 "register_operand" "=r,r")
3420 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
3421 (match_operand:SI 2 "general_operand" "g,i")))]
3425 if (GET_CODE (operands[1]) == REG
3426 && REGNO (operands[1]) == REGNO (operands[0])
3427 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3428 /* Assembler has weird restrictions. */
3429 return AS2 (imul%L0,%2,%0);
3430 return AS3 (imul%L0,%2,%1,%0);
3432 [(set_attr "type" "imul")])
3434 (define_insn "umulqihi3"
3435 [(set (match_operand:HI 0 "register_operand" "=a")
3436 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3437 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3440 [(set_attr "type" "imul")])
3442 (define_insn "mulqihi3"
3443 [(set (match_operand:HI 0 "register_operand" "=a")
3444 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3445 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3448 [(set_attr "type" "imul")])
3450 (define_insn "umulsidi3"
3451 [(set (match_operand:DI 0 "register_operand" "=A")
3452 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3453 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
3454 "TARGET_WIDE_MULTIPLY"
3456 [(set_attr "type" "imul")])
3458 (define_insn "mulsidi3"
3459 [(set (match_operand:DI 0 "register_operand" "=A")
3460 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3461 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
3462 "TARGET_WIDE_MULTIPLY"
3464 [(set_attr "type" "imul")])
3466 (define_insn "umulsi3_highpart"
3467 [(set (match_operand:SI 0 "register_operand" "=d")
3468 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
3469 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
3471 (clobber (match_scratch:SI 3 "=a"))]
3472 "TARGET_WIDE_MULTIPLY"
3474 [(set_attr "type" "imul")])
3476 (define_insn "smulsi3_highpart"
3477 [(set (match_operand:SI 0 "register_operand" "=d")
3478 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
3479 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
3481 (clobber (match_scratch:SI 3 "=a"))]
3482 "TARGET_WIDE_MULTIPLY"
3484 [(set_attr "type" "imul")])
3486 ;; The patterns that match these are at the end of this file.
3488 (define_expand "mulxf3"
3489 [(set (match_operand:XF 0 "register_operand" "")
3490 (mult:XF (match_operand:XF 1 "register_operand" "")
3491 (match_operand:XF 2 "register_operand" "")))]
3495 (define_expand "muldf3"
3496 [(set (match_operand:DF 0 "register_operand" "")
3497 (mult:DF (match_operand:DF 1 "register_operand" "")
3498 (match_operand:DF 2 "nonimmediate_operand" "")))]
3502 (define_expand "mulsf3"
3503 [(set (match_operand:SF 0 "register_operand" "")
3504 (mult:SF (match_operand:SF 1 "register_operand" "")
3505 (match_operand:SF 2 "nonimmediate_operand" "")))]
3509 ;;- divide instructions
3511 (define_insn "divqi3"
3512 [(set (match_operand:QI 0 "register_operand" "=a")
3513 (div:QI (match_operand:HI 1 "register_operand" "0")
3514 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
3518 (define_insn "udivqi3"
3519 [(set (match_operand:QI 0 "register_operand" "=a")
3520 (udiv:QI (match_operand:HI 1 "register_operand" "0")
3521 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
3524 [(set_attr "type" "idiv")])
3526 ;; The patterns that match these are at the end of this file.
3528 (define_expand "divxf3"
3529 [(set (match_operand:XF 0 "register_operand" "")
3530 (div:XF (match_operand:XF 1 "register_operand" "")
3531 (match_operand:XF 2 "register_operand" "")))]
3535 (define_expand "divdf3"
3536 [(set (match_operand:DF 0 "register_operand" "")
3537 (div:DF (match_operand:DF 1 "register_operand" "")
3538 (match_operand:DF 2 "nonimmediate_operand" "")))]
3542 (define_expand "divsf3"
3543 [(set (match_operand:SF 0 "register_operand" "")
3544 (div:SF (match_operand:SF 1 "register_operand" "")
3545 (match_operand:SF 2 "nonimmediate_operand" "")))]
3549 ;; Remainder instructions.
3551 (define_insn "divmodsi4"
3552 [(set (match_operand:SI 0 "register_operand" "=a")
3553 (div:SI (match_operand:SI 1 "register_operand" "0")
3554 (match_operand:SI 2 "nonimmediate_operand" "rm")))
3555 (set (match_operand:SI 3 "register_operand" "=&d")
3556 (mod:SI (match_dup 1) (match_dup 2)))]
3561 output_asm_insn (\"cdq\", operands);
3563 output_asm_insn (\"cltd\", operands);
3565 return AS1 (idiv%L0,%2);
3567 [(set_attr "type" "idiv")])
3569 (define_insn "divmodhi4"
3570 [(set (match_operand:HI 0 "register_operand" "=a")
3571 (div:HI (match_operand:HI 1 "register_operand" "0")
3572 (match_operand:HI 2 "nonimmediate_operand" "rm")))
3573 (set (match_operand:HI 3 "register_operand" "=&d")
3574 (mod:HI (match_dup 1) (match_dup 2)))]
3577 [(set_attr "type" "idiv")])
3579 ;; ??? Can we make gcc zero extend operand[0]?
3580 (define_insn "udivmodsi4"
3581 [(set (match_operand:SI 0 "register_operand" "=a")
3582 (udiv:SI (match_operand:SI 1 "register_operand" "0")
3583 (match_operand:SI 2 "nonimmediate_operand" "rm")))
3584 (set (match_operand:SI 3 "register_operand" "=&d")
3585 (umod:SI (match_dup 1) (match_dup 2)))]
3589 output_asm_insn (AS2 (xor%L3,%3,%3), operands);
3590 return AS1 (div%L0,%2);
3592 [(set_attr "type" "idiv")])
3594 ;; ??? Can we make gcc zero extend operand[0]?
3595 (define_insn "udivmodhi4"
3596 [(set (match_operand:HI 0 "register_operand" "=a")
3597 (udiv:HI (match_operand:HI 1 "register_operand" "0")
3598 (match_operand:HI 2 "nonimmediate_operand" "rm")))
3599 (set (match_operand:HI 3 "register_operand" "=&d")
3600 (umod:HI (match_dup 1) (match_dup 2)))]
3604 output_asm_insn (AS2 (xor%W0,%3,%3), operands);
3605 return AS1 (div%W0,%2);
3607 [(set_attr "type" "idiv")])
3610 ;;this should be a valid double division which we may want to add
3613 [(set (match_operand:SI 0 "register_operand" "=a")
3614 (udiv:DI (match_operand:DI 1 "register_operand" "a")
3615 (match_operand:SI 2 "nonimmediate_operand" "rm")))
3616 (set (match_operand:SI 3 "register_operand" "=d")
3617 (umod:SI (match_dup 1) (match_dup 2)))]
3620 [(set_attr "type" "idiv")])
3623 ;;- and instructions
3630 ;; but if the reg is %eax, then the "andl" is faster.
3632 ;; On i486, the "andl" is always faster than the "movzbl".
3634 ;; On both i386 and i486, a three operand AND is as fast with movzbl or
3635 ;; movzwl as with andl, if operands[0] != operands[1].
3637 ;; The `r' in `rm' for operand 3 looks redundant, but it causes
3638 ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
3640 (define_insn "andsi3"
3641 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3642 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3643 (match_operand:SI 2 "general_operand" "ri,rm")))]
3647 HOST_WIDE_INT intval;
3648 if (!rtx_equal_p (operands[0], operands[1])
3649 && rtx_equal_p (operands[0], operands[2]))
3653 operands[1] = operands[2];
3656 switch (GET_CODE (operands[2]))
3659 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
3661 intval = INTVAL (operands[2]);
3662 /* zero-extend 16->32? */
3663 if (intval == 0xffff && REG_P (operands[0])
3664 && (! REG_P (operands[1])
3665 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
3666 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
3668 /* ??? tege: Should forget CC_STATUS only if we clobber a
3669 remembered operand. Fix that later. */
3672 return AS2 (movzx,%w1,%0);
3674 return AS2 (movz%W0%L0,%w1,%0);
3678 /* zero extend 8->32? */
3679 if (intval == 0xff && REG_P (operands[0])
3680 && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
3681 && (! REG_P (operands[1])
3682 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
3683 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
3685 /* ??? tege: Should forget CC_STATUS only if we clobber a
3686 remembered operand. Fix that later. */
3689 return AS2 (movzx,%b1,%0);
3691 return AS2 (movz%B0%L0,%b1,%0);
3695 /* Check partial bytes.. non-QI-regs are not available */
3696 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
3699 /* only low byte has zero bits? */
3700 if (~(intval | 0xff) == 0)
3703 if (REG_P (operands[0]))
3708 return AS2 (xor%B0,%b0,%b0);
3711 /* we're better off with the 32-bit version if reg != EAX */
3712 /* the value is sign-extended in 8 bits */
3713 if (REGNO (operands[0]) != 0 && (intval & 0x80))
3719 operands[2] = GEN_INT (intval);
3722 return AS2 (mov%B0,%2,%b0);
3724 return AS2 (and%B0,%2,%b0);
3727 /* only second byte has zero? */
3728 if (~(intval | 0xff00) == 0)
3732 intval = (intval >> 8) & 0xff;
3733 operands[2] = GEN_INT (intval);
3736 if (REG_P (operands[0]))
3737 return AS2 (xor%B0,%h0,%h0);
3738 operands[0] = adj_offsettable_operand (operands[0], 1);
3739 return AS2 (mov%B0,%2,%b0);
3742 if (REG_P (operands[0]))
3743 return AS2 (and%B0,%2,%h0);
3745 operands[0] = adj_offsettable_operand (operands[0], 1);
3746 return AS2 (and%B0,%2,%b0);
3749 if (REG_P (operands[0]))
3752 /* third byte has zero bits? */
3753 if (~(intval | 0xff0000) == 0)
3755 intval = (intval >> 16) & 0xff;
3756 operands[0] = adj_offsettable_operand (operands[0], 2);
3759 operands[2] = GEN_INT (intval);
3761 return AS2 (mov%B0,%2,%b0);
3762 return AS2 (and%B0,%2,%b0);
3765 /* fourth byte has zero bits? */
3766 if (~(intval | 0xff000000) == 0)
3768 intval = (intval >> 24) & 0xff;
3769 operands[0] = adj_offsettable_operand (operands[0], 3);
3770 goto byte_and_operation;
3773 /* Low word is zero? */
3774 if (intval == 0xffff0000)
3776 word_zero_and_operation:
3778 operands[2] = const0_rtx;
3779 return AS2 (mov%W0,%2,%w0);
3782 /* High word is zero? */
3783 if (intval == 0x0000ffff)
3785 operands[0] = adj_offsettable_operand (operands[0], 2);
3786 goto word_zero_and_operation;
3790 return AS2 (and%L0,%2,%0);
3793 (define_insn "andhi3"
3794 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3795 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3796 (match_operand:HI 2 "general_operand" "ri,rm")))]
3800 if (GET_CODE (operands[2]) == CONST_INT
3801 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
3803 /* Can we ignore the upper byte? */
3804 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
3805 && (INTVAL (operands[2]) & 0xff00) == 0xff00)
3809 if ((INTVAL (operands[2]) & 0xff) == 0)
3811 operands[2] = const0_rtx;
3812 return AS2 (mov%B0,%2,%b0);
3815 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
3816 return AS2 (and%B0,%2,%b0);
3819 /* Can we ignore the lower byte? */
3820 /* ??? what about offsettable memory references? */
3821 if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
3825 if ((INTVAL (operands[2]) & 0xff00) == 0)
3827 operands[2] = const0_rtx;
3828 return AS2 (mov%B0,%2,%h0);
3831 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
3832 return AS2 (and%B0,%2,%h0);
3835 /* use 32-bit ops on registers when there are no sign issues.. */
3836 if (REG_P (operands[0]))
3838 if (!(INTVAL (operands[2]) & ~0x7fff))
3839 return AS2 (and%L0,%2,%k0);
3843 if (REG_P (operands[0])
3844 && i386_aligned_p (operands[2]))
3847 /* If op[2] is constant, we should zero-extend it and */
3848 /* make a note that op[0] has been zero-extended, so */
3849 /* that we could use 32-bit ops on it forthwith, but */
3850 /* there is no such reg-note available. Instead we do */
3851 /* a sign extension as that can result in shorter asm */
3852 operands[2] = i386_sext16_if_const (operands[2]);
3853 return AS2 (and%L0,%k2,%k0);
3856 /* Use a 32-bit word with the upper bits set, invalidate CC */
3857 if (GET_CODE (operands[2]) == CONST_INT
3858 && i386_aligned_p (operands[0]))
3860 HOST_WIDE_INT val = INTVAL (operands[2]);
3863 if (val != INTVAL (operands[2]))
3864 operands[2] = GEN_INT (val);
3865 return AS2 (and%L0,%k2,%k0);
3868 return AS2 (and%W0,%2,%0);
3871 (define_insn "andqi3"
3872 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3873 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3874 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3876 "* return AS2 (and%B0,%2,%0);")
3878 /* I am nervous about these two.. add them later..
3879 ;I presume this means that we have something in say op0= eax which is small
3880 ;and we want to and it with memory so we can do this by just an
3881 ;andb m,%al and have success.
3883 [(set (match_operand:SI 0 "general_operand" "=r")
3884 (and:SI (zero_extend:SI
3885 (match_operand:HI 1 "nonimmediate_operand" "rm"))
3886 (match_operand:SI 2 "general_operand" "0")))]
3887 "GET_CODE (operands[2]) == CONST_INT
3888 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
3892 [(set (match_operand:SI 0 "register_operand" "=q")
3894 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
3895 (match_operand:SI 2 "register_operand" "0")))]
3896 "GET_CODE (operands[2]) == CONST_INT
3897 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
3902 ;;- Bit set (inclusive or) instructions
3904 ;; This optimizes known byte-wide operations to memory, and in some cases
3905 ;; to QI registers.. Note that we don't want to use the QI registers too
3906 ;; aggressively, because often the 32-bit register instruction is the same
3907 ;; size, and likely to be faster on PentiumPro.
3908 (define_insn "iorsi3"
3909 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3910 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3911 (match_operand:SI 2 "general_operand" "ri,rm")))]
3915 HOST_WIDE_INT intval;
3916 switch (GET_CODE (operands[2]))
3920 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
3923 /* don't try to optimize volatile accesses */
3924 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
3927 intval = INTVAL (operands[2]);
3928 if ((intval & ~0xff) == 0)
3930 if (REG_P (operands[0]))
3932 /* Do low byte access only for %eax or when high bit is set */
3933 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
3940 if (intval != INTVAL (operands[2]))
3941 operands[2] = GEN_INT (intval);
3944 return AS2 (mov%B0,%2,%b0);
3946 return AS2 (or%B0,%2,%b0);
3950 if ((intval & ~0xff00) == 0)
3954 if (REG_P (operands[0]))
3957 operands[2] = GEN_INT (intval);
3959 return AS2 (mov%B0,%2,%h0);
3961 return AS2 (or%B0,%2,%h0);
3964 operands[0] = adj_offsettable_operand (operands[0], 1);
3965 goto byte_or_operation;
3968 if (REG_P (operands[0]))
3972 if ((intval & ~0xff0000) == 0)
3975 operands[0] = adj_offsettable_operand (operands[0], 2);
3976 goto byte_or_operation;
3980 if ((intval & ~0xff000000) == 0)
3982 intval = (intval >> 24) & 0xff;
3983 operands[0] = adj_offsettable_operand (operands[0], 3);
3984 goto byte_or_operation;
3988 return AS2 (or%L0,%2,%0);
3991 (define_insn "iorhi3"
3992 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3993 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
3994 (match_operand:HI 2 "general_operand" "ri,rm")))]
3998 HOST_WIDE_INT intval;
3999 switch (GET_CODE (operands[2]))
4003 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4006 /* don't try to optimize volatile accesses */
4007 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4010 intval = 0xffff & INTVAL (operands[2]);
4012 if ((intval & 0xff00) == 0)
4014 if (REG_P (operands[0]))
4016 /* Do low byte access only for %eax or when high bit is set */
4017 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4025 return AS2 (mov%B0,%2,%b0);
4027 return AS2 (or%B0,%2,%b0);
4031 if ((intval & 0xff) == 0)
4034 operands[2] = GEN_INT (intval);
4036 if (REG_P (operands[0]))
4040 return AS2 (mov%B0,%2,%h0);
4042 return AS2 (or%B0,%2,%h0);
4045 operands[0] = adj_offsettable_operand (operands[0], 1);
4047 goto byte_or_operation;
4051 if (REG_P (operands[0])
4052 && i386_aligned_p (operands[2]))
4055 operands[2] = i386_sext16_if_const (operands[2]);
4056 return AS2 (or%L0,%k2,%k0);
4059 if (GET_CODE (operands[2]) == CONST_INT
4060 && i386_aligned_p (operands[0]))
4063 intval = 0xffff & INTVAL (operands[2]);
4064 if (intval != INTVAL (operands[2]))
4065 operands[2] = GEN_INT (intval);
4066 return AS2 (or%L0,%2,%k0);
4069 return AS2 (or%W0,%2,%0);
4072 (define_insn "iorqi3"
4073 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4074 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4075 (match_operand:QI 2 "general_operand" "qn,qmn")))]
4077 "* return AS2 (or%B0,%2,%0);")
4079 ;;- xor instructions
4081 (define_insn "xorsi3"
4082 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4083 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4084 (match_operand:SI 2 "general_operand" "ri,rm")))]
4088 HOST_WIDE_INT intval;
4089 switch (GET_CODE (operands[2]))
4093 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4096 /* don't try to optimize volatile accesses */
4097 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4100 intval = INTVAL (operands[2]);
4101 if ((intval & ~0xff) == 0)
4103 if (REG_P (operands[0]))
4105 /* Do low byte access only for %eax or when high bit is set */
4106 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4114 return AS1 (not%B0,%b0);
4116 if (intval != INTVAL (operands[2]))
4117 operands[2] = GEN_INT (intval);
4118 return AS2 (xor%B0,%2,%b0);
4122 if ((intval & ~0xff00) == 0)
4126 if (REG_P (operands[0]))
4130 return AS1 (not%B0,%h0);
4132 operands[2] = GEN_INT (intval);
4133 return AS2 (xor%B0,%2,%h0);
4136 operands[0] = adj_offsettable_operand (operands[0], 1);
4138 goto byte_xor_operation;
4141 if (REG_P (operands[0]))
4145 if ((intval & ~0xff0000) == 0)
4148 operands[0] = adj_offsettable_operand (operands[0], 2);
4149 goto byte_xor_operation;
4153 if ((intval & ~0xff000000) == 0)
4155 intval = (intval >> 24) & 0xff;
4156 operands[0] = adj_offsettable_operand (operands[0], 3);
4157 goto byte_xor_operation;
4161 return AS2 (xor%L0,%2,%0);
4164 (define_insn "xorhi3"
4165 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4166 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4167 (match_operand:HI 2 "general_operand" "ri,rm")))]
4171 if (GET_CODE (operands[2]) == CONST_INT
4172 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
4174 /* Can we ignore the upper byte? */
4175 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
4176 && (INTVAL (operands[2]) & 0xff00) == 0)
4179 if (INTVAL (operands[2]) & 0xffff0000)
4180 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
4182 if (INTVAL (operands[2]) == 0xff)
4183 return AS1 (not%B0,%b0);
4185 return AS2 (xor%B0,%2,%b0);
4188 /* Can we ignore the lower byte? */
4189 /* ??? what about offsettable memory references? */
4190 if (QI_REG_P (operands[0])
4191 && (INTVAL (operands[2]) & 0xff) == 0)
4194 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
4196 if (INTVAL (operands[2]) == 0xff)
4197 return AS1 (not%B0,%h0);
4199 return AS2 (xor%B0,%2,%h0);
4203 if (REG_P (operands[0])
4204 && i386_aligned_p (operands[2]))
4207 operands[2] = i386_sext16_if_const (operands[2]);
4208 return AS2 (xor%L0,%k2,%k0);
4211 if (GET_CODE (operands[2]) == CONST_INT
4212 && i386_aligned_p (operands[0]))
4214 HOST_WIDE_INT intval;
4216 intval = 0xffff & INTVAL (operands[2]);
4217 if (intval != INTVAL (operands[2]))
4218 operands[2] = GEN_INT (intval);
4219 return AS2 (xor%L0,%2,%k0);
4222 return AS2 (xor%W0,%2,%0);
4225 (define_insn "xorqi3"
4226 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4227 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4228 (match_operand:QI 2 "general_operand" "qn,qm")))]
4230 "* return AS2 (xor%B0,%2,%0);")
4232 ;;- negation instructions
4234 (define_insn "negdi2"
4235 [(set (match_operand:DI 0 "general_operand" "=&ro")
4236 (neg:DI (match_operand:DI 1 "general_operand" "0")))]
4240 rtx xops[2], low[1], high[1];
4244 split_di (operands, 1, low, high);
4245 xops[0] = const0_rtx;
4248 output_asm_insn (AS1 (neg%L0,%0), low);
4249 output_asm_insn (AS2 (adc%L1,%0,%1), xops);
4250 output_asm_insn (AS1 (neg%L0,%0), high);
4254 (define_insn "negsi2"
4255 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4256 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
4260 (define_insn "neghi2"
4261 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4262 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
4266 (define_insn "negqi2"
4267 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4268 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
4272 (define_insn "negsf2"
4273 [(set (match_operand:SF 0 "register_operand" "=f")
4274 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
4278 (define_insn "negdf2"
4279 [(set (match_operand:DF 0 "register_operand" "=f")
4280 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
4285 [(set (match_operand:DF 0 "register_operand" "=f")
4286 (neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
4290 (define_insn "negxf2"
4291 [(set (match_operand:XF 0 "register_operand" "=f")
4292 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
4297 [(set (match_operand:XF 0 "register_operand" "=f")
4298 (neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4302 ;; Absolute value instructions
4304 (define_insn "abssf2"
4305 [(set (match_operand:SF 0 "register_operand" "=f")
4306 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
4309 [(set_attr "type" "fpop")])
4311 (define_insn "absdf2"
4312 [(set (match_operand:DF 0 "register_operand" "=f")
4313 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
4316 [(set_attr "type" "fpop")])
4319 [(set (match_operand:DF 0 "register_operand" "=f")
4320 (abs:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
4323 [(set_attr "type" "fpop")])
4325 (define_insn "absxf2"
4326 [(set (match_operand:XF 0 "register_operand" "=f")
4327 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
4330 [(set_attr "type" "fpop")])
4333 [(set (match_operand:XF 0 "register_operand" "=f")
4334 (abs:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4337 [(set_attr "type" "fpop")])
4339 (define_insn "sqrtsf2"
4340 [(set (match_operand:SF 0 "register_operand" "=f")
4341 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
4342 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4345 (define_insn "sqrtdf2"
4346 [(set (match_operand:DF 0 "register_operand" "=f")
4347 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
4348 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4349 && (TARGET_IEEE_FP || flag_fast_math) "
4353 [(set (match_operand:DF 0 "register_operand" "=f")
4354 (sqrt:DF (float_extend:DF
4355 (match_operand:SF 1 "register_operand" "0"))))]
4356 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4359 (define_insn "sqrtxf2"
4360 [(set (match_operand:XF 0 "register_operand" "=f")
4361 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
4362 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4363 && (TARGET_IEEE_FP || flag_fast_math) "
4367 [(set (match_operand:XF 0 "register_operand" "=f")
4368 (sqrt:XF (float_extend:XF
4369 (match_operand:DF 1 "register_operand" "0"))))]
4370 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4374 [(set (match_operand:XF 0 "register_operand" "=f")
4375 (sqrt:XF (float_extend:XF
4376 (match_operand:SF 1 "register_operand" "0"))))]
4377 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4380 (define_insn "sindf2"
4381 [(set (match_operand:DF 0 "register_operand" "=f")
4382 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
4383 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4386 (define_insn "sinsf2"
4387 [(set (match_operand:SF 0 "register_operand" "=f")
4388 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
4389 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4393 [(set (match_operand:DF 0 "register_operand" "=f")
4394 (unspec:DF [(float_extend:DF
4395 (match_operand:SF 1 "register_operand" "0"))] 1))]
4396 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4399 (define_insn "sinxf2"
4400 [(set (match_operand:XF 0 "register_operand" "=f")
4401 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
4402 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4405 (define_insn "cosdf2"
4406 [(set (match_operand:DF 0 "register_operand" "=f")
4407 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
4408 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4411 (define_insn "cossf2"
4412 [(set (match_operand:SF 0 "register_operand" "=f")
4413 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
4414 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4418 [(set (match_operand:DF 0 "register_operand" "=f")
4419 (unspec:DF [(float_extend:DF
4420 (match_operand:SF 1 "register_operand" "0"))] 2))]
4421 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4424 (define_insn "cosxf2"
4425 [(set (match_operand:XF 0 "register_operand" "=f")
4426 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
4427 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
4430 ;;- one complement instructions
4432 (define_insn "one_cmplsi2"
4433 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4434 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
4438 (define_insn "one_cmplhi2"
4439 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4440 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
4444 (define_insn "one_cmplqi2"
4445 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4446 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
4450 ;;- arithmetic shift instructions
4452 ;; DImode shifts are implemented using the i386 "shift double" opcode,
4453 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
4454 ;; is variable, then the count is in %cl and the "imm" operand is dropped
4455 ;; from the assembler input.
4457 ;; This instruction shifts the target reg/mem as usual, but instead of
4458 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
4459 ;; is a left shift double, bits are taken from the high order bits of
4460 ;; reg, else if the insn is a shift right double, bits are taken from the
4461 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
4462 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
4464 ;; Since sh[lr]d does not change the `reg' operand, that is done
4465 ;; separately, making all shifts emit pairs of shift double and normal
4466 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
4467 ;; support a 63 bit shift, each shift where the count is in a reg expands
4468 ;; to a pair of shifts, a branch, a shift by 32 and a label.
4470 ;; If the shift count is a constant, we need never emit more than one
4471 ;; shift pair, instead using moves and sign extension for counts greater
4474 (define_expand "ashldi3"
4475 [(set (match_operand:DI 0 "register_operand" "")
4476 (ashift:DI (match_operand:DI 1 "register_operand" "")
4477 (match_operand:QI 2 "nonmemory_operand" "")))]
4481 if (GET_CODE (operands[2]) != CONST_INT
4482 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4484 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4485 emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
4489 emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
4494 (define_insn "ashldi3_const_int"
4495 [(set (match_operand:DI 0 "register_operand" "=&r")
4496 (ashift:DI (match_operand:DI 1 "register_operand" "0")
4497 (match_operand:QI 2 "const_int_operand" "J")))]
4498 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
4501 rtx xops[4], low[1], high[1];
4505 split_di (operands, 1, low, high);
4506 xops[0] = operands[2];
4507 xops[1] = const1_rtx;
4511 if (INTVAL (xops[0]) > 31)
4513 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
4514 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4516 if (INTVAL (xops[0]) > 32)
4518 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
4519 output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
4524 output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
4525 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
4530 (define_insn "ashldi3_non_const_int"
4531 [(set (match_operand:DI 0 "register_operand" "=&r")
4532 (ashift:DI (match_operand:DI 1 "register_operand" "0")
4533 (match_operand:QI 2 "register_operand" "c")))]
4537 rtx xops[4], low[1], high[1];
4538 static HOST_WIDE_INT ashldi_label_number;
4542 split_di (operands, 1, low, high);
4543 xops[0] = operands[2];
4544 xops[1] = GEN_INT (32);
4548 output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
4549 output_asm_insn (AS2 (sal%L2,%0,%2), xops);
4550 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
4551 asm_fprintf (asm_out_file, \"\\tje %LLASHLDI%d\\n\", ashldi_label_number);
4552 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */
4553 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4554 asm_fprintf (asm_out_file, \"%LLASHLDI%d:\\n\", ashldi_label_number++);
4559 ;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
4560 ;; On i486, movl/sall appears slightly faster than leal, but the leal
4561 ;; is smaller - use leal for now unless the shift count is 1.
4563 (define_insn "ashlsi3"
4564 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4565 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,0")
4566 (match_operand:SI 2 "nonmemory_operand" "M,cI")))]
4570 if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
4572 if (TARGET_DOUBLE_WITH_ADD && INTVAL (operands[2]) == 1)
4574 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
4575 return AS2 (add%L0,%1,%0);
4581 if (operands[1] == stack_pointer_rtx)
4583 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
4584 operands[1] = operands[0];
4586 operands[1] = gen_rtx (MULT, SImode, operands[1],
4587 GEN_INT (1 << INTVAL (operands[2])));
4588 return AS2 (lea%L0,%a1,%0);
4592 if (REG_P (operands[2]))
4593 return AS2 (sal%L0,%b2,%0);
4595 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4596 return AS2 (add%L0,%0,%0);
4598 return AS2 (sal%L0,%2,%0);
4601 (define_insn "ashlhi3"
4602 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4603 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4604 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4608 if (REG_P (operands[2]))
4609 return AS2 (sal%W0,%b2,%0);
4611 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4612 return AS2 (add%W0,%0,%0);
4614 return AS2 (sal%W0,%2,%0);
4617 (define_insn "ashlqi3"
4618 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4619 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4620 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4624 if (REG_P (operands[2]))
4625 return AS2 (sal%B0,%b2,%0);
4627 if (REG_P (operands[0]) && operands[2] == const1_rtx)
4628 return AS2 (add%B0,%0,%0);
4630 return AS2 (sal%B0,%2,%0);
4633 ;; See comment above `ashldi3' about how this works.
4635 (define_expand "ashrdi3"
4636 [(set (match_operand:DI 0 "register_operand" "")
4637 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4638 (match_operand:QI 2 "nonmemory_operand" "")))]
4642 if (GET_CODE (operands[2]) != CONST_INT
4643 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4645 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4646 emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1],
4650 emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2]));
4655 (define_insn "ashldi3_32"
4656 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
4657 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
4662 rtx low[2], high[2], xops[4];
4664 split_di (operands, 2, low, high);
4668 xops[3] = const0_rtx;
4669 if (!rtx_equal_p (xops[0], xops[1]))
4670 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
4672 if (GET_CODE (low[0]) == MEM)
4673 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4675 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4680 (define_insn "ashrdi3_const_int"
4681 [(set (match_operand:DI 0 "register_operand" "=&r")
4682 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
4683 (match_operand:QI 2 "const_int_operand" "J")))]
4684 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
4687 rtx xops[4], low[1], high[1];
4691 split_di (operands, 1, low, high);
4692 xops[0] = operands[2];
4693 xops[1] = const1_rtx;
4697 if (INTVAL (xops[0]) > 31)
4699 xops[1] = GEN_INT (31);
4700 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4701 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */
4703 if (INTVAL (xops[0]) > 32)
4705 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
4706 output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */
4711 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
4712 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
4718 (define_insn "ashrdi3_non_const_int"
4719 [(set (match_operand:DI 0 "register_operand" "=&r")
4720 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
4721 (match_operand:QI 2 "register_operand" "c")))]
4725 rtx xops[4], low[1], high[1];
4726 static HOST_WIDE_INT ashrdi_label_number;
4730 split_di (operands, 1, low, high);
4731 xops[0] = operands[2];
4732 xops[1] = GEN_INT (32);
4736 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
4737 output_asm_insn (AS2 (sar%L3,%0,%3), xops);
4738 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
4739 asm_fprintf (asm_out_file, \"\\tje %LLASHRDI%d\\n\", ashrdi_label_number);
4740 xops[1] = GEN_INT (31);
4741 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4742 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */
4743 asm_fprintf (asm_out_file, \"%LLASHRDI%d:\\n\", ashrdi_label_number++);
4748 (define_insn "ashrsi3"
4749 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4750 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
4751 (match_operand:SI 2 "nonmemory_operand" "cI")))]
4755 if (REG_P (operands[2]))
4756 return AS2 (sar%L0,%b2,%0);
4758 return AS2 (sar%L0,%2,%0);
4761 (define_insn "ashrhi3"
4762 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4763 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4764 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4768 if (REG_P (operands[2]))
4769 return AS2 (sar%W0,%b2,%0);
4771 return AS2 (sar%W0,%2,%0);
4774 (define_insn "ashrqi3"
4775 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4776 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4777 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4781 if (REG_P (operands[2]))
4782 return AS2 (sar%B0,%b2,%0);
4784 return AS2 (sar%B0,%2,%0);
4787 ;;- logical shift instructions
4789 ;; See comment above `ashldi3' about how this works.
4791 (define_expand "lshrdi3"
4792 [(set (match_operand:DI 0 "register_operand" "")
4793 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4794 (match_operand:QI 2 "nonmemory_operand" "")))]
4798 if (GET_CODE (operands[2]) != CONST_INT
4799 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
4801 operands[2] = copy_to_mode_reg (QImode, operands[2]);
4802 emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
4806 emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
4811 (define_insn "lshrdi3_32"
4812 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
4813 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
4818 rtx low[2], high[2], xops[4];
4820 split_di (operands, 2, low, high);
4824 xops[3] = const0_rtx;
4825 if (!rtx_equal_p (xops[0], xops[1]))
4826 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
4828 if (GET_CODE (low[0]) == MEM)
4829 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
4831 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
4836 (define_insn "lshrdi3_const_int"
4837 [(set (match_operand:DI 0 "register_operand" "=&r")
4838 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
4839 (match_operand:QI 2 "const_int_operand" "J")))]
4840 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
4843 rtx xops[4], low[1], high[1];
4847 split_di (operands, 1, low, high);
4848 xops[0] = operands[2];
4849 xops[1] = const1_rtx;
4853 if (INTVAL (xops[0]) > 31)
4855 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
4856 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
4858 if (INTVAL (xops[0]) > 32)
4860 xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
4861 output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
4866 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
4867 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
4873 (define_insn "lshrdi3_non_const_int"
4874 [(set (match_operand:DI 0 "register_operand" "=&r")
4875 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
4876 (match_operand:QI 2 "register_operand" "c")))]
4880 rtx xops[4], low[1], high[1];
4881 static HOST_WIDE_INT lshrdi_label_number;
4885 split_di (operands, 1, low, high);
4886 xops[0] = operands[2];
4887 xops[1] = GEN_INT (32);
4891 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
4892 output_asm_insn (AS2 (shr%L3,%0,%3), xops);
4893 output_asm_insn (AS2 (test%B0,%1,%b0), xops);
4894 asm_fprintf (asm_out_file, \"\\tje %LLLSHRDI%d\\n\", lshrdi_label_number);
4895 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */
4896 output_asm_insn (AS2 (xor%L3,%3,%3), xops);
4897 asm_fprintf (asm_out_file, \"%LLLSHRDI%d:\\n\", lshrdi_label_number++);
4902 (define_insn "lshrsi3"
4903 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4904 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
4905 (match_operand:SI 2 "nonmemory_operand" "cI")))]
4909 if (REG_P (operands[2]))
4910 return AS2 (shr%L0,%b2,%0);
4912 return AS2 (shr%L0,%2,%1);
4915 (define_insn "lshrhi3"
4916 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4917 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4918 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4922 if (REG_P (operands[2]))
4923 return AS2 (shr%W0,%b2,%0);
4925 return AS2 (shr%W0,%2,%0);
4928 (define_insn "lshrqi3"
4929 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4930 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4931 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4935 if (REG_P (operands[2]))
4936 return AS2 (shr%B0,%b2,%0);
4938 return AS2 (shr%B0,%2,%0);
4941 ;;- rotate instructions
4943 (define_insn "rotlsi3"
4944 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4945 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
4946 (match_operand:SI 2 "nonmemory_operand" "cI")))]
4950 if (REG_P (operands[2]))
4951 return AS2 (rol%L0,%b2,%0);
4953 return AS2 (rol%L0,%2,%0);
4956 (define_insn "rotlhi3"
4957 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4958 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4959 (match_operand:HI 2 "nonmemory_operand" "cI")))]
4963 if (REG_P (operands[2]))
4964 return AS2 (rol%W0,%b2,%0);
4966 return AS2 (rol%W0,%2,%0);
4969 (define_insn "rotlqi3"
4970 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4971 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
4972 (match_operand:QI 2 "nonmemory_operand" "cI")))]
4976 if (REG_P (operands[2]))
4977 return AS2 (rol%B0,%b2,%0);
4979 return AS2 (rol%B0,%2,%0);
4982 (define_insn "rotrsi3"
4983 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4984 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
4985 (match_operand:SI 2 "nonmemory_operand" "cI")))]
4989 if (REG_P (operands[2]))
4990 return AS2 (ror%L0,%b2,%0);
4992 return AS2 (ror%L0,%2,%0);
4995 (define_insn "rotrhi3"
4996 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4997 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
4998 (match_operand:HI 2 "nonmemory_operand" "cI")))]
5002 if (REG_P (operands[2]))
5003 return AS2 (ror%W0,%b2,%0);
5005 return AS2 (ror%W0,%2,%0);
5008 (define_insn "rotrqi3"
5009 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5010 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5011 (match_operand:QI 2 "nonmemory_operand" "cI")))]
5015 if (REG_P (operands[2]))
5016 return AS2 (ror%B0,%b2,%0);
5018 return AS2 (ror%B0,%2,%0);
5022 ;; This usually looses. But try a define_expand to recognize a few case
5023 ;; we can do efficiently, such as accessing the "high" QImode registers,
5024 ;; %ah, %bh, %ch, %dh.
5025 ;; ??? Note this has a botch on the mode of operand 0, which needs to be
5026 ;; fixed if this is ever enabled.
5028 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
5029 (match_operand:SI 1 "immediate_operand" "i")
5030 (match_operand:SI 2 "immediate_operand" "i"))
5031 (match_operand:SI 3 "nonmemory_operand" "ri"))]
5035 if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
5037 if (GET_CODE (operands[3]) == CONST_INT)
5039 unsigned int mask = (1 << INTVAL (operands[1])) - 1;
5040 operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
5041 output_asm_insn (AS2 (and%L0,%1,%0), operands);
5042 operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
5043 output_asm_insn (AS2 (or%L0,%3,%0), operands);
5047 operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
5048 if (INTVAL (operands[2]))
5049 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5050 output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
5051 operands[2] = GEN_INT (BITS_PER_WORD
5052 - INTVAL (operands[1]) - INTVAL (operands[2]));
5053 if (INTVAL (operands[2]))
5054 output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5060 ;; ??? There are problems with the mode of operand[3]. The point of this
5061 ;; is to represent an HImode move to a "high byte" register.
5063 (define_expand "insv"
5064 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
5065 (match_operand:SI 1 "immediate_operand" "")
5066 (match_operand:SI 2 "immediate_operand" ""))
5067 (match_operand:QI 3 "nonmemory_operand" "ri"))]
5071 if (GET_CODE (operands[1]) != CONST_INT
5072 || GET_CODE (operands[2]) != CONST_INT)
5075 if (! (INTVAL (operands[1]) == 8
5076 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
5077 && ! INTVAL (operands[1]) == 1)
5082 ;; On i386, the register count for a bit operation is *not* truncated,
5083 ;; so SHIFT_COUNT_TRUNCATED must not be defined.
5085 ;; On i486, the shift & or/and code is faster than bts or btr. If
5086 ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
5088 ;; On i386, bts is a little faster if operands[0] is a reg, and a
5089 ;; little slower if operands[0] is a MEM, than the shift & or/and code.
5090 ;; Use bts & btr, since they reload better.
5092 ;; General bit set and clear.
5094 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm")
5096 (match_operand:SI 2 "register_operand" "r"))
5097 (match_operand:SI 3 "const_int_operand" "n"))]
5098 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5103 if (INTVAL (operands[3]) == 1)
5104 return AS2 (bts%L0,%2,%0);
5106 return AS2 (btr%L0,%2,%0);
5109 ;; Bit complement. See comments on previous pattern.
5110 ;; ??? Is this really worthwhile?
5112 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5113 (xor:SI (ashift:SI (const_int 1)
5114 (match_operand:SI 1 "register_operand" "r"))
5115 (match_operand:SI 2 "nonimmediate_operand" "0")))]
5116 "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT"
5121 return AS2 (btc%L0,%1,%0);
5125 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5126 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5127 (ashift:SI (const_int 1)
5128 (match_operand:SI 2 "register_operand" "r"))))]
5129 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5134 return AS2 (btc%L0,%2,%0);
5137 ;; Recognizers for bit-test instructions.
5139 ;; The bt opcode allows a MEM in operands[0]. But on both i386 and
5140 ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
5141 ;; bt on the MEM directly.
5143 ;; ??? The first argument of a zero_extract must not be reloaded, so
5144 ;; don't allow a MEM in the operand predicate without allowing it in the
5148 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5150 (match_operand:SI 1 "register_operand" "r")))]
5151 "GET_CODE (operands[1]) != CONST_INT"
5154 cc_status.flags |= CC_Z_IN_NOT_C;
5155 return AS2 (bt%L0,%1,%0);
5159 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5160 (match_operand:SI 1 "const_int_operand" "n")
5161 (match_operand:SI 2 "const_int_operand" "n")))]
5167 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5168 operands[1] = GEN_INT (mask);
5170 if (QI_REG_P (operands[0]))
5172 if ((mask & ~0xff) == 0)
5174 cc_status.flags |= CC_NOT_NEGATIVE;
5175 return AS2 (test%B0,%1,%b0);
5178 if ((mask & ~0xff00) == 0)
5180 cc_status.flags |= CC_NOT_NEGATIVE;
5181 operands[1] = GEN_INT (mask >> 8);
5182 return AS2 (test%B0,%1,%h0);
5186 return AS2 (test%L0,%1,%0);
5189 ;; ??? All bets are off if operand 0 is a volatile MEM reference.
5190 ;; The CPU may access unspecified bytes around the actual target byte.
5193 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
5194 (match_operand:SI 1 "const_int_operand" "n")
5195 (match_operand:SI 2 "const_int_operand" "n")))]
5196 "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
5201 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5202 operands[1] = GEN_INT (mask);
5204 if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
5206 if ((mask & ~0xff) == 0)
5208 cc_status.flags |= CC_NOT_NEGATIVE;
5209 return AS2 (test%B0,%1,%b0);
5212 if ((mask & ~0xff00) == 0)
5214 cc_status.flags |= CC_NOT_NEGATIVE;
5215 operands[1] = GEN_INT (mask >> 8);
5217 if (QI_REG_P (operands[0]))
5218 return AS2 (test%B0,%1,%h0);
5221 operands[0] = adj_offsettable_operand (operands[0], 1);
5222 return AS2 (test%B0,%1,%b0);
5226 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
5228 cc_status.flags |= CC_NOT_NEGATIVE;
5229 operands[1] = GEN_INT (mask >> 16);
5230 operands[0] = adj_offsettable_operand (operands[0], 2);
5231 return AS2 (test%B0,%1,%b0);
5234 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
5236 cc_status.flags |= CC_NOT_NEGATIVE;
5237 operands[1] = GEN_INT (mask >> 24);
5238 operands[0] = adj_offsettable_operand (operands[0], 3);
5239 return AS2 (test%B0,%1,%b0);
5243 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
5244 return AS2 (test%L0,%1,%0);
5246 return AS2 (test%L1,%0,%1);
5249 ;; Store-flag instructions.
5251 ;; For all sCOND expanders, also expand the compare or test insn that
5252 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
5254 ;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may
5255 ;; not have any input reloads. A MEM write might need an input reload
5256 ;; for the address of the MEM. So don't allow MEM as the SET_DEST.
5258 (define_expand "seq"
5260 (set (match_operand:QI 0 "register_operand" "")
5261 (eq:QI (cc0) (const_int 0)))]
5266 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5267 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5269 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5273 [(set (match_operand:QI 0 "register_operand" "=q")
5274 (eq:QI (cc0) (const_int 0)))]
5278 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5279 return AS1 (setnb,%0);
5281 return AS1 (sete,%0);
5284 (define_expand "sne"
5286 (set (match_operand:QI 0 "register_operand" "")
5287 (ne:QI (cc0) (const_int 0)))]
5292 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5293 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5295 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5299 [(set (match_operand:QI 0 "register_operand" "=q")
5300 (ne:QI (cc0) (const_int 0)))]
5304 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5305 return AS1 (setb,%0);
5307 return AS1 (setne,%0);
5311 (define_expand "sgt"
5313 (set (match_operand:QI 0 "register_operand" "")
5314 (gt:QI (cc0) (const_int 0)))]
5316 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5319 [(set (match_operand:QI 0 "register_operand" "=q")
5320 (gt:QI (cc0) (const_int 0)))]
5324 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5325 && ! (cc_prev_status.flags & CC_FCOMI))
5326 return AS1 (sete,%0);
5328 OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR);
5331 (define_expand "sgtu"
5333 (set (match_operand:QI 0 "register_operand" "")
5334 (gtu:QI (cc0) (const_int 0)))]
5336 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5339 [(set (match_operand:QI 0 "register_operand" "=q")
5340 (gtu:QI (cc0) (const_int 0)))]
5342 "* return \"seta %0\"; ")
5344 (define_expand "slt"
5346 (set (match_operand:QI 0 "register_operand" "")
5347 (lt:QI (cc0) (const_int 0)))]
5349 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5352 [(set (match_operand:QI 0 "register_operand" "=q")
5353 (lt:QI (cc0) (const_int 0)))]
5357 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5358 && ! (cc_prev_status.flags & CC_FCOMI))
5359 return AS1 (sete,%0);
5361 OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\");
5364 (define_expand "sltu"
5366 (set (match_operand:QI 0 "register_operand" "")
5367 (ltu:QI (cc0) (const_int 0)))]
5369 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5372 [(set (match_operand:QI 0 "register_operand" "=q")
5373 (ltu:QI (cc0) (const_int 0)))]
5375 "* return \"setb %0\"; ")
5377 (define_expand "sge"
5379 (set (match_operand:QI 0 "register_operand" "")
5380 (ge:QI (cc0) (const_int 0)))]
5382 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5385 [(set (match_operand:QI 0 "register_operand" "=q")
5386 (ge:QI (cc0) (const_int 0)))]
5390 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5391 && ! (cc_prev_status.flags & CC_FCOMI))
5392 return AS1 (sete,%0);
5394 OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\");
5397 (define_expand "sgeu"
5399 (set (match_operand:QI 0 "register_operand" "")
5400 (geu:QI (cc0) (const_int 0)))]
5402 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5405 [(set (match_operand:QI 0 "register_operand" "=q")
5406 (geu:QI (cc0) (const_int 0)))]
5408 "* return \"setae %0\"; ")
5410 (define_expand "sle"
5412 (set (match_operand:QI 0 "register_operand" "")
5413 (le:QI (cc0) (const_int 0)))]
5415 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5418 [(set (match_operand:QI 0 "register_operand" "=q")
5419 (le:QI (cc0) (const_int 0)))]
5423 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5424 && ! (cc_prev_status.flags & CC_FCOMI))
5425 return AS1 (setb,%0);
5427 OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR);
5430 (define_expand "sleu"
5432 (set (match_operand:QI 0 "register_operand" "")
5433 (leu:QI (cc0) (const_int 0)))]
5435 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5438 [(set (match_operand:QI 0 "register_operand" "=q")
5439 (leu:QI (cc0) (const_int 0)))]
5441 "* return \"setbe %0\"; ")
5443 ;; Basic conditional jump instructions.
5444 ;; We ignore the overflow flag for signed branch instructions.
5446 ;; For all bCOND expanders, also expand the compare or test insn that
5447 ;; generates cc0. Generate an equality comparison if `beq' or `bne'.
5449 (define_expand "beq"
5452 (if_then_else (eq (cc0)
5454 (label_ref (match_operand 0 "" ""))
5460 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5461 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5463 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5468 (if_then_else (eq (cc0)
5470 (label_ref (match_operand 0 "" ""))
5475 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5478 if (cc_prev_status.flags & CC_TEST_AX)
5480 operands[1] = gen_rtx (REG, SImode, 0);
5481 operands[2] = GEN_INT (0x4000);
5482 output_asm_insn (AS2 (testl,%2,%1), operands);
5483 return AS1 (jne,%l0);
5489 (define_expand "bne"
5492 (if_then_else (ne (cc0)
5494 (label_ref (match_operand 0 "" ""))
5500 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5501 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5503 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5508 (if_then_else (ne (cc0)
5510 (label_ref (match_operand 0 "" ""))
5515 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5518 if (cc_prev_status.flags & CC_TEST_AX)
5520 operands[1] = gen_rtx (REG, SImode, 0);
5521 operands[2] = GEN_INT (0x4000);
5522 output_asm_insn (AS2 (testl,%2,%1), operands);
5523 return AS1 (je,%l0);
5529 (define_expand "bgt"
5532 (if_then_else (gt (cc0)
5534 (label_ref (match_operand 0 "" ""))
5537 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5541 (if_then_else (gt (cc0)
5543 (label_ref (match_operand 0 "" ""))
5548 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5549 && ! (cc_prev_status.flags & CC_FCOMI))
5550 return AS1 (je,%l0);
5552 if (cc_prev_status.flags & CC_TEST_AX)
5554 operands[1] = gen_rtx (REG, SImode, 0);
5555 operands[2] = GEN_INT (0x4100);
5556 output_asm_insn (AS2 (testl,%2,%1), operands);
5557 return AS1 (je,%l0);
5559 OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
5562 (define_expand "bgtu"
5565 (if_then_else (gtu (cc0)
5567 (label_ref (match_operand 0 "" ""))
5570 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5574 (if_then_else (gtu (cc0)
5576 (label_ref (match_operand 0 "" ""))
5581 (define_expand "blt"
5584 (if_then_else (lt (cc0)
5586 (label_ref (match_operand 0 "" ""))
5589 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5593 (if_then_else (lt (cc0)
5595 (label_ref (match_operand 0 "" ""))
5600 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5601 && ! (cc_prev_status.flags & CC_FCOMI))
5602 return AS1 (je,%l0);
5604 if (cc_prev_status.flags & CC_TEST_AX)
5606 operands[1] = gen_rtx (REG, SImode, 0);
5607 operands[2] = GEN_INT (0x100);
5608 output_asm_insn (AS2 (testl,%2,%1), operands);
5609 return AS1 (jne,%l0);
5611 OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
5614 (define_expand "bltu"
5617 (if_then_else (ltu (cc0)
5619 (label_ref (match_operand 0 "" ""))
5622 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5626 (if_then_else (ltu (cc0)
5628 (label_ref (match_operand 0 "" ""))
5633 (define_expand "bge"
5636 (if_then_else (ge (cc0)
5638 (label_ref (match_operand 0 "" ""))
5641 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5645 (if_then_else (ge (cc0)
5647 (label_ref (match_operand 0 "" ""))
5652 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5653 && ! (cc_prev_status.flags & CC_FCOMI))
5654 return AS1 (je,%l0);
5655 if (cc_prev_status.flags & CC_TEST_AX)
5657 operands[1] = gen_rtx (REG, SImode, 0);
5658 operands[2] = GEN_INT (0x100);
5659 output_asm_insn (AS2 (testl,%2,%1), operands);
5660 return AS1 (je,%l0);
5662 OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
5665 (define_expand "bgeu"
5668 (if_then_else (geu (cc0)
5670 (label_ref (match_operand 0 "" ""))
5673 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5677 (if_then_else (geu (cc0)
5679 (label_ref (match_operand 0 "" ""))
5684 (define_expand "ble"
5687 (if_then_else (le (cc0)
5689 (label_ref (match_operand 0 "" ""))
5692 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5696 (if_then_else (le (cc0)
5698 (label_ref (match_operand 0 "" ""))
5703 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5704 && ! (cc_prev_status.flags & CC_FCOMI))
5705 return AS1 (jb,%l0);
5706 if (cc_prev_status.flags & CC_TEST_AX)
5708 operands[1] = gen_rtx (REG, SImode, 0);
5709 operands[2] = GEN_INT (0x4100);
5710 output_asm_insn (AS2 (testl,%2,%1), operands);
5711 return AS1 (jne,%l0);
5714 OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
5717 (define_expand "bleu"
5720 (if_then_else (leu (cc0)
5722 (label_ref (match_operand 0 "" ""))
5725 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5729 (if_then_else (leu (cc0)
5731 (label_ref (match_operand 0 "" ""))
5736 ;; Negated conditional jump instructions.
5740 (if_then_else (eq (cc0)
5743 (label_ref (match_operand 0 "" ""))))]
5747 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5750 if (cc_prev_status.flags & CC_TEST_AX)
5752 operands[1] = gen_rtx (REG, SImode, 0);
5753 operands[2] = GEN_INT (0x4000);
5754 output_asm_insn (AS2 (testl,%2,%1), operands);
5755 return AS1 (je,%l0);
5762 (if_then_else (ne (cc0)
5765 (label_ref (match_operand 0 "" ""))))]
5769 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
5772 if (cc_prev_status.flags & CC_TEST_AX)
5774 operands[1] = gen_rtx (REG, SImode, 0);
5775 operands[2] = GEN_INT (0x4000);
5776 output_asm_insn (AS2 (testl,%2,%1), operands);
5777 return AS1 (jne,%l0);
5784 (if_then_else (gt (cc0)
5787 (label_ref (match_operand 0 "" ""))))]
5791 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5792 && ! (cc_prev_status.flags & CC_FCOMI))
5793 return AS1 (jne,%l0);
5794 if (cc_prev_status.flags & CC_TEST_AX)
5796 operands[1] = gen_rtx (REG, SImode, 0);
5797 operands[2] = GEN_INT (0x4100);
5798 output_asm_insn (AS2 (testl,%2,%1), operands);
5799 return AS1 (jne,%l0);
5801 OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
5806 (if_then_else (gtu (cc0)
5809 (label_ref (match_operand 0 "" ""))))]
5815 (if_then_else (lt (cc0)
5818 (label_ref (match_operand 0 "" ""))))]
5822 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5823 && ! (cc_prev_status.flags & CC_FCOMI))
5824 return AS1 (jne,%l0);
5825 if (cc_prev_status.flags & CC_TEST_AX)
5827 operands[1] = gen_rtx (REG, SImode, 0);
5828 operands[2] = GEN_INT (0x100);
5829 output_asm_insn (AS2 (testl,%2,%1), operands);
5830 return AS1 (je,%l0);
5833 OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
5838 (if_then_else (ltu (cc0)
5841 (label_ref (match_operand 0 "" ""))))]
5847 (if_then_else (ge (cc0)
5850 (label_ref (match_operand 0 "" ""))))]
5854 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5855 && ! (cc_prev_status.flags & CC_FCOMI))
5856 return AS1 (jne,%l0);
5857 if (cc_prev_status.flags & CC_TEST_AX)
5859 operands[1] = gen_rtx (REG, SImode, 0);
5860 operands[2] = GEN_INT (0x100);
5861 output_asm_insn (AS2 (testl,%2,%1), operands);
5862 return AS1 (jne,%l0);
5864 OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
5869 (if_then_else (geu (cc0)
5872 (label_ref (match_operand 0 "" ""))))]
5878 (if_then_else (le (cc0)
5881 (label_ref (match_operand 0 "" ""))))]
5885 if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
5886 && ! (cc_prev_status.flags & CC_FCOMI))
5887 return AS1 (jae,%l0);
5889 if (cc_prev_status.flags & CC_TEST_AX)
5891 operands[1] = gen_rtx (REG, SImode, 0);
5892 operands[2] = GEN_INT (0x4100);
5893 output_asm_insn (AS2 (testl,%2,%1), operands);
5894 return AS1 (je,%l0);
5896 OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
5901 (if_then_else (leu (cc0)
5904 (label_ref (match_operand 0 "" ""))))]
5908 ;; Unconditional and other jump instructions
5912 (label_ref (match_operand 0 "" "")))]
5916 (define_insn "indirect_jump"
5917 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
5923 return AS1 (jmp,%*%0);
5926 ;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
5927 ;; if S does not change i
5929 (define_expand "decrement_and_branch_until_zero"
5930 [(parallel [(set (pc)
5931 (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "")
5934 (label_ref (match_operand 1 "" ""))
5937 (plus:SI (match_dup 0)
5944 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
5945 [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
5946 (match_operand:SI 2 "general_operand" "rmi,ri"))
5948 (label_ref (match_operand 3 "" ""))
5951 (plus:SI (match_dup 1)
5957 if (operands[2] == constm1_rtx)
5958 output_asm_insn (AS1 (dec%L1,%1), operands);
5960 else if (operands[2] == const1_rtx)
5961 output_asm_insn (AS1 (inc%L1,%1), operands);
5964 output_asm_insn (AS2 (add%L1,%2,%1), operands);
5966 return AS1 (%J0,%l3);
5971 (if_then_else (match_operator 0 "arithmetic_comparison_operator"
5972 [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
5973 (match_operand:SI 2 "general_operand" "rmi,ri"))
5975 (label_ref (match_operand 3 "" ""))
5978 (minus:SI (match_dup 1)
5984 if (operands[2] == const1_rtx)
5985 output_asm_insn (AS1 (dec%L1,%1), operands);
5987 else if (operands[1] == constm1_rtx)
5988 output_asm_insn (AS1 (inc%L1,%1), operands);
5991 output_asm_insn (AS2 (sub%L1,%2,%1), operands);
5993 return AS1 (%J0,%l3);
5998 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6000 (label_ref (match_operand 1 "" ""))
6003 (plus:SI (match_dup 0)
6009 operands[2] = const1_rtx;
6010 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6016 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6018 (label_ref (match_operand 1 "" ""))
6021 (plus:SI (match_dup 0)
6027 operands[2] = const1_rtx;
6028 output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6034 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6036 (label_ref (match_operand 1 "" ""))
6039 (plus:SI (match_dup 0)
6045 output_asm_insn (AS1 (dec%L0,%0), operands);
6051 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6053 (label_ref (match_operand 1 "" ""))
6056 (plus:SI (match_dup 0)
6062 output_asm_insn (AS1 (dec%L0,%0), operands);
6068 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6070 (label_ref (match_operand 1 "" ""))
6073 (plus:SI (match_dup 0)
6079 output_asm_insn (AS1 (inc%L0,%0), operands);
6085 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6087 (label_ref (match_operand 1 "" ""))
6090 (plus:SI (match_dup 0)
6096 output_asm_insn (AS1 (inc%L0,%0), operands);
6100 ;; Implement switch statements when generating PIC code. Switches are
6101 ;; implemented by `tablejump' when not using -fpic.
6103 ;; Emit code here to do the range checking and make the index zero based.
6105 (define_expand "casesi"
6107 (match_operand:SI 0 "general_operand" ""))
6109 (minus:SI (match_dup 5)
6110 (match_operand:SI 1 "general_operand" "")))
6112 (compare:CC (match_dup 6)
6113 (match_operand:SI 2 "general_operand" "")))
6115 (if_then_else (gtu (cc0)
6117 (label_ref (match_operand 4 "" ""))
6121 (minus:SI (reg:SI 3)
6122 (mem:SI (plus:SI (mult:SI (match_dup 6)
6124 (label_ref (match_operand 3 "" ""))))))
6125 (clobber (match_scratch:SI 7 ""))])]
6129 operands[5] = gen_reg_rtx (SImode);
6130 operands[6] = gen_reg_rtx (SImode);
6131 current_function_uses_pic_offset_table = 1;
6134 ;; Implement a casesi insn.
6136 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
6139 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
6141 ;; 1. An expression involving an external reference may only use the
6142 ;; addition operator, and only with an assembly-time constant.
6143 ;; The example above satisfies this because ".-.L2" is a constant.
6145 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
6146 ;; given the value of "GOT - .", where GOT is the actual address of
6147 ;; the Global Offset Table. Therefore, the .long above actually
6148 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
6149 ;; expression "GOT - .L2" by itself would generate an error from as(1).
6151 ;; The pattern below emits code that looks like this:
6154 ;; subl TABLE@GOTOFF(%ebx,index,4),reg
6157 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
6158 ;; the addr_diff_vec is known to be part of this module.
6160 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
6161 ;; evaluates to just ".L2".
6165 (minus:SI (reg:SI 3)
6167 (mult:SI (match_operand:SI 0 "register_operand" "r")
6169 (label_ref (match_operand 1 "" ""))))))
6170 (clobber (match_scratch:SI 2 "=&r"))]
6176 xops[0] = operands[0];
6177 xops[1] = operands[1];
6178 xops[2] = operands[2];
6179 xops[3] = pic_offset_table_rtx;
6181 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
6182 output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
6183 output_asm_insn (AS1 (jmp,%*%2), xops);
6184 ASM_OUTPUT_ALIGN_CODE (asm_out_file);
6188 (define_insn "tablejump"
6189 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
6190 (use (label_ref (match_operand 1 "" "")))]
6196 return AS1 (jmp,%*%0);
6201 ;; If generating PIC code, the predicate indirect_operand will fail
6202 ;; for operands[0] containing symbolic references on all of the named
6203 ;; call* patterns. Each named pattern is followed by an unnamed pattern
6204 ;; that matches any call to a symbolic CONST (ie, a symbol_ref). The
6205 ;; unnamed patterns are only used while generating PIC code, because
6206 ;; otherwise the named patterns match.
6208 ;; Call subroutine returning no value.
6210 (define_expand "call_pop"
6211 [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
6212 (match_operand:SI 1 "general_operand" ""))
6215 (match_operand:SI 3 "immediate_operand" "")))])]
6222 current_function_uses_pic_offset_table = 1;
6224 /* With half-pic, force the address into a register. */
6225 addr = XEXP (operands[0], 0);
6226 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6227 XEXP (operands[0], 0) = force_reg (Pmode, addr);
6229 if (! expander_call_insn_operand (operands[0], QImode))
6231 = change_address (operands[0], VOIDmode,
6232 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
6236 [(call (match_operand:QI 0 "call_insn_operand" "m")
6237 (match_operand:SI 1 "general_operand" "g"))
6238 (set (reg:SI 7) (plus:SI (reg:SI 7)
6239 (match_operand:SI 3 "immediate_operand" "i")))]
6243 if (GET_CODE (operands[0]) == MEM
6244 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6246 operands[0] = XEXP (operands[0], 0);
6247 return AS1 (call,%*%0);
6250 return AS1 (call,%P0);
6254 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6255 (match_operand:SI 1 "general_operand" "g"))
6256 (set (reg:SI 7) (plus:SI (reg:SI 7)
6257 (match_operand:SI 3 "immediate_operand" "i")))]
6261 (define_expand "call"
6262 [(call (match_operand:QI 0 "indirect_operand" "")
6263 (match_operand:SI 1 "general_operand" ""))]
6264 ;; Operand 1 not used on the i386.
6271 current_function_uses_pic_offset_table = 1;
6273 /* With half-pic, force the address into a register. */
6274 addr = XEXP (operands[0], 0);
6275 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6276 XEXP (operands[0], 0) = force_reg (Pmode, addr);
6278 if (! expander_call_insn_operand (operands[0], QImode))
6280 = change_address (operands[0], VOIDmode,
6281 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
6285 [(call (match_operand:QI 0 "call_insn_operand" "m")
6286 (match_operand:SI 1 "general_operand" "g"))]
6287 ;; Operand 1 not used on the i386.
6291 if (GET_CODE (operands[0]) == MEM
6292 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6294 operands[0] = XEXP (operands[0], 0);
6295 return AS1 (call,%*%0);
6298 return AS1 (call,%P0);
6302 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6303 (match_operand:SI 1 "general_operand" "g"))]
6304 ;; Operand 1 not used on the i386.
6308 ;; Call subroutine, returning value in operand 0
6309 ;; (which must be a hard register).
6311 (define_expand "call_value_pop"
6312 [(parallel [(set (match_operand 0 "" "")
6313 (call (match_operand:QI 1 "indirect_operand" "")
6314 (match_operand:SI 2 "general_operand" "")))
6317 (match_operand:SI 4 "immediate_operand" "")))])]
6324 current_function_uses_pic_offset_table = 1;
6326 /* With half-pic, force the address into a register. */
6327 addr = XEXP (operands[1], 0);
6328 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6329 XEXP (operands[1], 0) = force_reg (Pmode, addr);
6331 if (! expander_call_insn_operand (operands[1], QImode))
6333 = change_address (operands[1], VOIDmode,
6334 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
6338 [(set (match_operand 0 "" "=rf")
6339 (call (match_operand:QI 1 "call_insn_operand" "m")
6340 (match_operand:SI 2 "general_operand" "g")))
6341 (set (reg:SI 7) (plus:SI (reg:SI 7)
6342 (match_operand:SI 4 "immediate_operand" "i")))]
6346 if (GET_CODE (operands[1]) == MEM
6347 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6349 operands[1] = XEXP (operands[1], 0);
6350 output_asm_insn (AS1 (call,%*%1), operands);
6353 output_asm_insn (AS1 (call,%P1), operands);
6359 [(set (match_operand 0 "" "=rf")
6360 (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6361 (match_operand:SI 2 "general_operand" "g")))
6362 (set (reg:SI 7) (plus:SI (reg:SI 7)
6363 (match_operand:SI 4 "immediate_operand" "i")))]
6367 (define_expand "call_value"
6368 [(set (match_operand 0 "" "")
6369 (call (match_operand:QI 1 "indirect_operand" "")
6370 (match_operand:SI 2 "general_operand" "")))]
6371 ;; Operand 2 not used on the i386.
6378 current_function_uses_pic_offset_table = 1;
6380 /* With half-pic, force the address into a register. */
6381 addr = XEXP (operands[1], 0);
6382 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6383 XEXP (operands[1], 0) = force_reg (Pmode, addr);
6385 if (! expander_call_insn_operand (operands[1], QImode))
6387 = change_address (operands[1], VOIDmode,
6388 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
6392 [(set (match_operand 0 "" "=rf")
6393 (call (match_operand:QI 1 "call_insn_operand" "m")
6394 (match_operand:SI 2 "general_operand" "g")))]
6395 ;; Operand 2 not used on the i386.
6399 if (GET_CODE (operands[1]) == MEM
6400 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6402 operands[1] = XEXP (operands[1], 0);
6403 output_asm_insn (AS1 (call,%*%1), operands);
6406 output_asm_insn (AS1 (call,%P1), operands);
6412 [(set (match_operand 0 "" "=rf")
6413 (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6414 (match_operand:SI 2 "general_operand" "g")))]
6415 ;; Operand 2 not used on the i386.
6419 ;; Call subroutine returning any type.
6421 (define_expand "untyped_call"
6422 [(parallel [(call (match_operand 0 "" "")
6424 (match_operand 1 "" "")
6425 (match_operand 2 "" "")])]
6431 /* In order to give reg-stack an easier job in validating two
6432 coprocessor registers as containing a possible return value,
6433 simply pretend the untyped call returns a complex long double
6436 emit_call_insn (TARGET_80387
6437 ? gen_call_value (gen_rtx (REG, XCmode, FIRST_FLOAT_REG),
6438 operands[0], const0_rtx)
6439 : gen_call (operands[0], const0_rtx));
6441 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6443 rtx set = XVECEXP (operands[2], 0, i);
6444 emit_move_insn (SET_DEST (set), SET_SRC (set));
6447 /* The optimizer does not know that the call sets the function value
6448 registers we stored in the result block. We avoid problems by
6449 claiming that all hard registers are used and clobbered at this
6451 emit_insn (gen_blockage ());
6456 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6457 ;; all of memory. This blocks insns from being moved across this point.
6459 (define_insn "blockage"
6460 [(unspec_volatile [(const_int 0)] 0)]
6464 ;; Insn emitted into the body of a function to return from a function.
6465 ;; This is only done if the function's epilogue is known to be simple.
6466 ;; See comments for simple_386_epilogue in i386.c.
6468 (define_expand "return"
6470 "ix86_can_use_return_insn_p ()"
6473 (define_insn "return_internal"
6478 (define_insn "return_pop_internal"
6480 (use (match_operand:SI 0 "const_int_operand" ""))]
6489 (define_expand "prologue"
6494 ix86_expand_prologue ();
6498 ;; The use of UNSPEC here is currently not necessary - a simple SET of ebp
6499 ;; to itself would be enough. But this way we are safe even if some optimizer
6500 ;; becomes too clever in the future.
6501 (define_insn "prologue_set_stack_ptr"
6503 (minus:SI (reg:SI 7) (match_operand:SI 0 "immediate_operand" "i")))
6504 (set (reg:SI 6) (unspec:SI [(reg:SI 6)] 4))]
6510 xops[0] = operands[0];
6511 xops[1] = stack_pointer_rtx;
6512 output_asm_insn (AS2 (sub%L1,%0,%1), xops);
6516 (define_insn "prologue_set_got"
6517 [(set (match_operand:SI 0 "" "")
6519 [(plus:SI (match_dup 0)
6520 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
6521 (minus:SI (pc) (match_operand 2 "" ""))))] 1))]
6527 if (TARGET_DEEP_BRANCH_PREDICTION)
6529 sprintf (buffer, \"addl %s,%%0\", XSTR (operands[1], 0));
6530 output_asm_insn (buffer, operands);
6534 sprintf (buffer, \"addl %s+[.-%%P2],%%0\", XSTR (operands[1], 0));
6535 output_asm_insn (buffer, operands);
6540 (define_insn "prologue_get_pc"
6541 [(set (match_operand:SI 0 "" "")
6542 (unspec_volatile [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
6548 output_asm_insn (AS1 (call,%P1), operands);
6549 if (! TARGET_DEEP_BRANCH_PREDICTION)
6551 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1]));
6556 (define_insn "prologue_get_pc_and_set_got"
6557 [(unspec_volatile [(match_operand:SI 0 "" "")] 3)]
6561 operands[1] = gen_label_rtx ();
6562 output_asm_insn (AS1 (call,%P1), operands);
6563 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
6564 CODE_LABEL_NUMBER (operands[1]));
6565 output_asm_insn (AS1 (pop%L0,%0), operands);
6566 output_asm_insn (\"addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0\", operands);
6570 (define_expand "epilogue"
6575 ix86_expand_epilogue ();
6579 (define_insn "epilogue_set_stack_ptr"
6580 [(set (reg:SI 7) (reg:SI 6))
6581 (clobber (reg:SI 6))]
6587 xops[0] = frame_pointer_rtx;
6588 xops[1] = stack_pointer_rtx;
6589 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
6593 (define_insn "leave"
6595 (clobber (reg:SI 6))
6596 (clobber (reg:SI 7))]
6601 [(set (match_operand:SI 0 "register_operand" "r")
6602 (mem:SI (reg:SI 7)))
6603 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))]
6607 output_asm_insn (AS1 (pop%L0,%P0), operands);
6611 (define_expand "movstrsi"
6612 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
6613 (match_operand:BLK 1 "memory_operand" ""))
6614 (use (match_operand:SI 2 "const_int_operand" ""))
6615 (use (match_operand:SI 3 "const_int_operand" ""))
6616 (clobber (match_scratch:SI 4 ""))
6617 (clobber (match_dup 5))
6618 (clobber (match_dup 6))])]
6624 if (GET_CODE (operands[2]) != CONST_INT)
6627 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
6628 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
6630 operands[5] = addr0;
6631 operands[6] = addr1;
6633 operands[0] = change_address (operands[0], VOIDmode, addr0);
6634 operands[1] = change_address (operands[1], VOIDmode, addr1);
6637 ;; It might seem that operands 0 & 1 could use predicate register_operand.
6638 ;; But strength reduction might offset the MEM expression. So we let
6639 ;; reload put the address into %edi & %esi.
6642 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
6643 (mem:BLK (match_operand:SI 1 "address_operand" "S")))
6644 (use (match_operand:SI 2 "const_int_operand" "n"))
6645 (use (match_operand:SI 3 "immediate_operand" "i"))
6646 (clobber (match_scratch:SI 4 "=&c"))
6647 (clobber (match_dup 0))
6648 (clobber (match_dup 1))]
6654 output_asm_insn (\"cld\", operands);
6655 if (GET_CODE (operands[2]) == CONST_INT)
6657 if (INTVAL (operands[2]) & ~0x03)
6659 xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
6660 xops[1] = operands[4];
6662 output_asm_insn (AS2 (mov%L1,%0,%1), xops);
6664 output_asm_insn (\"rep movsd\", xops);
6666 output_asm_insn (\"rep\;movsl\", xops);
6669 if (INTVAL (operands[2]) & 0x02)
6670 output_asm_insn (\"movsw\", operands);
6671 if (INTVAL (operands[2]) & 0x01)
6672 output_asm_insn (\"movsb\", operands);
6679 (define_expand "clrstrsi"
6680 [(set (match_dup 3) (const_int 0))
6681 (parallel [(set (match_operand:BLK 0 "memory_operand" "")
6683 (use (match_operand:SI 1 "const_int_operand" ""))
6684 (use (match_operand:SI 2 "const_int_operand" ""))
6686 (clobber (match_scratch:SI 4 ""))
6687 (clobber (match_dup 5))])]
6693 if (GET_CODE (operands[1]) != CONST_INT)
6696 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
6698 operands[3] = gen_reg_rtx (SImode);
6699 operands[5] = addr0;
6701 operands[0] = gen_rtx (MEM, BLKmode, addr0);
6704 ;; It might seem that operand 0 could use predicate register_operand.
6705 ;; But strength reduction might offset the MEM expression. So we let
6706 ;; reload put the address into %edi.
6709 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
6711 (use (match_operand:SI 1 "const_int_operand" "n"))
6712 (use (match_operand:SI 2 "immediate_operand" "i"))
6713 (use (match_operand:SI 3 "register_operand" "a"))
6714 (clobber (match_scratch:SI 4 "=&c"))
6715 (clobber (match_dup 0))]
6721 output_asm_insn (\"cld\", operands);
6722 if (GET_CODE (operands[1]) == CONST_INT)
6724 if (INTVAL (operands[1]) & ~0x03)
6726 xops[0] = GEN_INT ((INTVAL (operands[1]) >> 2) & 0x3fffffff);
6727 xops[1] = operands[4];
6729 output_asm_insn (AS2 (mov%L1,%0,%1), xops);
6731 output_asm_insn (\"rep stosd\", xops);
6733 output_asm_insn (\"rep\;stosl\", xops);
6736 if (INTVAL (operands[1]) & 0x02)
6737 output_asm_insn (\"stosw\", operands);
6738 if (INTVAL (operands[1]) & 0x01)
6739 output_asm_insn (\"stosb\", operands);
6746 (define_expand "cmpstrsi"
6747 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6748 (compare:SI (match_operand:BLK 1 "general_operand" "")
6749 (match_operand:BLK 2 "general_operand" "")))
6750 (use (match_operand:SI 3 "general_operand" ""))
6751 (use (match_operand:SI 4 "immediate_operand" ""))
6752 (clobber (match_dup 5))
6753 (clobber (match_dup 6))
6754 (clobber (match_dup 3))])]
6760 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
6761 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
6762 operands[3] = copy_to_mode_reg (SImode, operands[3]);
6764 operands[5] = addr1;
6765 operands[6] = addr2;
6767 operands[1] = gen_rtx (MEM, BLKmode, addr1);
6768 operands[2] = gen_rtx (MEM, BLKmode, addr2);
6772 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
6773 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
6775 ;; It might seem that operands 0 & 1 could use predicate register_operand.
6776 ;; But strength reduction might offset the MEM expression. So we let
6777 ;; reload put the address into %edi & %esi.
6779 ;; ??? Most comparisons have a constant length, and it's therefore
6780 ;; possible to know that the length is non-zero, and to avoid the extra
6781 ;; code to handle zero-length compares.
6784 [(set (match_operand:SI 0 "register_operand" "=&r")
6785 (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
6786 (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
6787 (use (match_operand:SI 3 "register_operand" "c"))
6788 (use (match_operand:SI 4 "immediate_operand" "i"))
6789 (clobber (match_dup 1))
6790 (clobber (match_dup 2))
6791 (clobber (match_dup 3))]
6797 label = gen_label_rtx ();
6799 output_asm_insn (\"cld\", operands);
6800 output_asm_insn (AS2 (xor%L0,%0,%0), operands);
6801 output_asm_insn (\"repz\;cmps%B2\", operands);
6802 output_asm_insn (\"je %l0\", &label);
6804 xops[0] = operands[0];
6805 xops[1] = const1_rtx;
6806 output_asm_insn (AS2 (sbb%L0,%0,%0), xops);
6807 if (QI_REG_P (xops[0]))
6808 output_asm_insn (AS2 (or%B0,%1,%b0), xops);
6810 output_asm_insn (AS2 (or%L0,%1,%0), xops);
6812 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
6818 (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
6819 (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
6820 (use (match_operand:SI 2 "register_operand" "c"))
6821 (use (match_operand:SI 3 "immediate_operand" "i"))
6822 (clobber (match_dup 0))
6823 (clobber (match_dup 1))
6824 (clobber (match_dup 2))]
6830 cc_status.flags |= CC_NOT_SIGNED;
6832 xops[0] = gen_rtx (REG, QImode, 0);
6833 xops[1] = CONST0_RTX (QImode);
6835 output_asm_insn (\"cld\", operands);
6836 output_asm_insn (AS2 (test%B0,%1,%0), xops);
6837 return \"repz\;cmps%B2\";
6841 (define_expand "ffssi2"
6843 (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" ""))
6845 (set (match_operand:SI 0 "general_operand" "")
6846 (plus:SI (match_dup 2) (const_int 1)))]
6848 "operands[2] = gen_reg_rtx (SImode);")
6850 ;; Note, you cannot optimize away the branch following the bsfl by assuming
6851 ;; that the destination is not modified if the input is 0, since not all
6852 ;; x86 implementations do this.
6855 [(set (match_operand:SI 0 "register_operand" "=&r")
6856 (plus:SI (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
6862 static int ffssi_label_number;
6865 xops[0] = operands[0];
6866 xops[1] = operands[1];
6867 xops[2] = constm1_rtx;
6868 output_asm_insn (AS2 (bsf%L0,%1,%0), xops);
6869 #ifdef LOCAL_LABEL_PREFIX
6870 sprintf (buffer, \"jnz %sLFFSSI%d\",
6871 LOCAL_LABEL_PREFIX, ffssi_label_number);
6873 sprintf (buffer, \"jnz %sLFFSSI%d\",
6874 \"\", ffssi_label_number);
6876 output_asm_insn (buffer, xops);
6877 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
6878 #ifdef LOCAL_LABEL_PREFIX
6879 sprintf (buffer, \"%sLFFSSI%d:\",
6880 LOCAL_LABEL_PREFIX, ffssi_label_number);
6882 sprintf (buffer, \"%sLFFSSI%d:\",
6883 \"\", ffssi_label_number);
6885 output_asm_insn (buffer, xops);
6887 ffssi_label_number++;
6892 (define_expand "ffshi2"
6894 (plus:HI (ffs:HI (match_operand:HI 1 "general_operand" ""))
6896 (set (match_operand:HI 0 "general_operand" "")
6897 (plus:HI (match_dup 2) (const_int 1)))]
6899 "operands[2] = gen_reg_rtx (HImode);")
6902 [(set (match_operand:HI 0 "register_operand" "=&r")
6903 (plus:HI (ffs:HI (match_operand:SI 1 "nonimmediate_operand" "rm"))
6909 static int ffshi_label_number;
6912 xops[0] = operands[0];
6913 xops[1] = operands[1];
6914 xops[2] = constm1_rtx;
6915 output_asm_insn (AS2 (bsf%W0,%1,%0), xops);
6916 #ifdef LOCAL_LABEL_PREFIX
6917 sprintf (buffer, \"jnz %sLFFSHI%d\",
6918 LOCAL_LABEL_PREFIX, ffshi_label_number);
6920 sprintf (buffer, \"jnz %sLFFSHI%d\",
6921 \"\", ffshi_label_number);
6923 output_asm_insn (buffer, xops);
6924 output_asm_insn (AS2 (mov%W0,%2,%0), xops);
6925 #ifdef LOCAL_LABEL_PREFIX
6926 sprintf (buffer, \"%sLFFSHI%d:\",
6927 LOCAL_LABEL_PREFIX, ffshi_label_number);
6929 sprintf (buffer, \"%sLFFSHI%d:\",
6930 \"\", ffshi_label_number);
6932 output_asm_insn (buffer, xops);
6934 ffshi_label_number++;
6939 ;; These patterns match the binary 387 instructions for addM3, subM3,
6940 ;; mulM3 and divM3. There are three patterns for each of DFmode and
6941 ;; SFmode. The first is the normal insn, the second the same insn but
6942 ;; with one operand a conversion, and the third the same insn but with
6943 ;; the other operand a conversion. The conversion may be SFmode or
6944 ;; SImode if the target mode DFmode, but only SImode if the target mode
6948 [(set (match_operand:DF 0 "register_operand" "=f,f")
6949 (match_operator:DF 3 "binary_387_op"
6950 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
6951 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
6953 "* return output_387_binary_op (insn, operands);"
6955 (cond [(match_operand:DF 3 "is_mul" "")
6956 (const_string "fpmul")
6957 (match_operand:DF 3 "is_div" "")
6958 (const_string "fpdiv")
6960 (const_string "fpop")
6965 [(set (match_operand:DF 0 "register_operand" "=f")
6966 (match_operator:DF 3 "binary_387_op"
6967 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "rm"))
6968 (match_operand:DF 2 "register_operand" "0")]))]
6970 "* return output_387_binary_op (insn, operands);"
6972 (cond [(match_operand:DF 3 "is_mul" "")
6973 (const_string "fpmul")
6974 (match_operand:DF 3 "is_div" "")
6975 (const_string "fpdiv")
6977 (const_string "fpop")
6982 [(set (match_operand:XF 0 "register_operand" "=f,f")
6983 (match_operator:XF 3 "binary_387_op"
6984 [(match_operand:XF 1 "register_operand" "0,f")
6985 (match_operand:XF 2 "register_operand" "f,0")]))]
6987 "* return output_387_binary_op (insn, operands);"
6989 (cond [(match_operand:DF 3 "is_mul" "")
6990 (const_string "fpmul")
6991 (match_operand:DF 3 "is_div" "")
6992 (const_string "fpdiv")
6994 (const_string "fpop")
6999 [(set (match_operand:XF 0 "register_operand" "=f")
7000 (match_operator:XF 3 "binary_387_op"
7001 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "rm"))
7002 (match_operand:XF 2 "register_operand" "0")]))]
7004 "* return output_387_binary_op (insn, operands);"
7006 (cond [(match_operand:DF 3 "is_mul" "")
7007 (const_string "fpmul")
7008 (match_operand:DF 3 "is_div" "")
7009 (const_string "fpdiv")
7011 (const_string "fpop")
7016 [(set (match_operand:XF 0 "register_operand" "=f,f")
7017 (match_operator:XF 3 "binary_387_op"
7018 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7019 (match_operand:XF 2 "register_operand" "0,f")]))]
7021 "* return output_387_binary_op (insn, operands);"
7023 (cond [(match_operand:DF 3 "is_mul" "")
7024 (const_string "fpmul")
7025 (match_operand:DF 3 "is_div" "")
7026 (const_string "fpdiv")
7028 (const_string "fpop")
7033 [(set (match_operand:XF 0 "register_operand" "=f")
7034 (match_operator:XF 3 "binary_387_op"
7035 [(match_operand:XF 1 "register_operand" "0")
7036 (float:XF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
7038 "* return output_387_binary_op (insn, operands);"
7040 (cond [(match_operand:DF 3 "is_mul" "")
7041 (const_string "fpmul")
7042 (match_operand:DF 3 "is_div" "")
7043 (const_string "fpdiv")
7045 (const_string "fpop")
7050 [(set (match_operand:XF 0 "register_operand" "=f,f")
7051 (match_operator:XF 3 "binary_387_op"
7052 [(match_operand:XF 1 "register_operand" "0,f")
7054 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7056 "* return output_387_binary_op (insn, operands);"
7058 (cond [(match_operand:DF 3 "is_mul" "")
7059 (const_string "fpmul")
7060 (match_operand:DF 3 "is_div" "")
7061 (const_string "fpdiv")
7063 (const_string "fpop")
7068 [(set (match_operand:DF 0 "register_operand" "=f,f")
7069 (match_operator:DF 3 "binary_387_op"
7070 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7071 (match_operand:DF 2 "register_operand" "0,f")]))]
7073 "* return output_387_binary_op (insn, operands);"
7075 (cond [(match_operand:DF 3 "is_mul" "")
7076 (const_string "fpmul")
7077 (match_operand:DF 3 "is_div" "")
7078 (const_string "fpdiv")
7080 (const_string "fpop")
7085 [(set (match_operand:DF 0 "register_operand" "=f")
7086 (match_operator:DF 3 "binary_387_op"
7087 [(match_operand:DF 1 "register_operand" "0")
7088 (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
7090 "* return output_387_binary_op (insn, operands);"
7092 (cond [(match_operand:DF 3 "is_mul" "")
7093 (const_string "fpmul")
7094 (match_operand:DF 3 "is_div" "")
7095 (const_string "fpdiv")
7097 (const_string "fpop")
7102 [(set (match_operand:DF 0 "register_operand" "=f,f")
7103 (match_operator:DF 3 "binary_387_op"
7104 [(match_operand:DF 1 "register_operand" "0,f")
7106 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7108 "* return output_387_binary_op (insn, operands);"
7110 (cond [(match_operand:DF 3 "is_mul" "")
7111 (const_string "fpmul")
7112 (match_operand:DF 3 "is_div" "")
7113 (const_string "fpdiv")
7115 (const_string "fpop")
7120 [(set (match_operand:SF 0 "register_operand" "=f,f")
7121 (match_operator:SF 3 "binary_387_op"
7122 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
7123 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
7125 "* return output_387_binary_op (insn, operands);"
7127 (cond [(match_operand:DF 3 "is_mul" "")
7128 (const_string "fpmul")
7129 (match_operand:DF 3 "is_div" "")
7130 (const_string "fpdiv")
7132 (const_string "fpop")
7137 [(set (match_operand:SF 0 "register_operand" "=f")
7138 (match_operator:SF 3 "binary_387_op"
7139 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "rm"))
7140 (match_operand:SF 2 "register_operand" "0")]))]
7142 "* return output_387_binary_op (insn, operands);"
7144 (cond [(match_operand:DF 3 "is_mul" "")
7145 (const_string "fpmul")
7146 (match_operand:DF 3 "is_div" "")
7147 (const_string "fpdiv")
7149 (const_string "fpop")
7154 [(set (match_operand:SF 0 "register_operand" "=f")
7155 (match_operator:SF 3 "binary_387_op"
7156 [(match_operand:SF 1 "register_operand" "0")
7157 (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
7159 "* return output_387_binary_op (insn, operands);"
7161 (cond [(match_operand:DF 3 "is_mul" "")
7162 (const_string "fpmul")
7163 (match_operand:DF 3 "is_div" "")
7164 (const_string "fpdiv")
7166 (const_string "fpop")
7170 (define_expand "strlensi"
7171 [(parallel [(set (match_dup 4)
7172 (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
7173 (match_operand:QI 2 "immediate_operand" "")
7174 (match_operand:SI 3 "immediate_operand" "")] 0))
7175 (clobber (match_dup 1))])
7177 (not:SI (match_dup 4)))
7178 (set (match_operand:SI 0 "register_operand" "")
7179 (plus:SI (match_dup 5)
7184 if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1)
7189 /* well it seems that some optimizer does not combine a call like
7190 foo(strlen(bar), strlen(bar));
7191 when the move and the subtraction is done here. It does calculate
7192 the length just once when these instructions are done inside of
7193 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
7194 often used and I use one fewer register for the lifetime of
7195 output_strlen_unroll() this is better. */
7196 scratch = gen_reg_rtx (SImode);
7197 address = force_reg (SImode, XEXP (operands[1], 0));
7199 /* move address to scratch-register
7200 this is done here because the i586 can do the following and
7201 in the same cycle with the following move. */
7202 if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4)
7203 emit_insn (gen_movsi (scratch, address));
7205 emit_insn (gen_movsi (operands[0], address));
7207 if(TARGET_USE_Q_REG)
7208 emit_insn (gen_strlensi_unroll5 (operands[0],
7213 emit_insn (gen_strlensi_unroll4 (operands[0],
7218 /* gen_strlensi_unroll[45] returns the address of the zero
7219 at the end of the string, like memchr(), so compute the
7220 length by subtracting the startaddress. */
7221 emit_insn (gen_subsi3 (operands[0], operands[0], address));
7225 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7226 operands[4] = gen_reg_rtx (SImode);
7227 operands[5] = gen_reg_rtx (SImode);
7230 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7231 ;; But strength reduction might offset the MEM expression. So we let
7232 ;; reload put the address into %edi.
7235 [(set (match_operand:SI 0 "register_operand" "=&c")
7236 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
7237 (match_operand:QI 2 "immediate_operand" "a")
7238 (match_operand:SI 3 "immediate_operand" "i")] 0))
7239 (clobber (match_dup 1))]
7245 xops[0] = operands[0];
7246 xops[1] = constm1_rtx;
7247 output_asm_insn (\"cld\", operands);
7248 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
7249 return \"repnz\;scas%B2\";
7252 /* Conditional move define_insns. */
7254 (define_expand "movsicc"
7256 (parallel [(set (match_operand 0 "register_operand" "")
7257 (if_then_else:SI (match_operand 1 "comparison_operator" "")
7258 (match_operand:SI 2 "general_operand" "")
7259 (match_operand:SI 3 "general_operand" "")))
7260 (clobber (match_scratch:SI 4 "=&r"))])]
7264 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7267 (define_expand "movhicc"
7269 (parallel [(set (match_operand 0 "register_operand" "")
7270 (if_then_else:HI (match_operand 1 "comparison_operator" "")
7271 (match_operand:HI 2 "general_operand" "")
7272 (match_operand:HI 3 "general_operand" "")))
7273 (clobber (match_scratch:SI 4 "=&r"))])]
7277 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7280 (define_insn "movsicc_1"
7281 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,&r,rm")
7282 (if_then_else:SI (match_operator 1 "comparison_operator"
7283 [(cc0) (const_int 0)])
7284 (match_operand:SI 2 "general_operand" "rm,0,rm,g")
7285 (match_operand:SI 3 "general_operand" "0,rm,rm,g")))
7286 (clobber (match_scratch:SI 4 "X,X,X,=&r"))]
7290 if (which_alternative == 0)
7292 /* r <- cond ? arg : r */
7293 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7295 else if (which_alternative == 1)
7297 /* r <- cond ? r : arg */
7298 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7300 else if (which_alternative == 2)
7302 /* r <- cond ? arg1 : arg2 */
7303 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7304 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7306 else if (which_alternative == 3)
7308 /* r <- cond ? arg1 : arg2 */
7311 xops[0] = gen_label_rtx ();
7312 xops[1] = gen_label_rtx ();
7313 xops[2] = operands[1];
7315 output_asm_insn (\"j%c2 %l0\", xops);
7316 if (! rtx_equal_p (operands[0], operands[2]))
7317 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[2]) == MEM)
7319 output_asm_insn (AS2 (mov%z2,%2,%4), operands);
7320 output_asm_insn (AS2 (mov%z2,%4,%0), operands);
7323 output_asm_insn (AS2 (mov%z0,%2,%0), operands);
7324 output_asm_insn (\"jmp %l1\", xops);
7325 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
7326 if (! rtx_equal_p (operands[0], operands[3]))
7328 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[3]) == MEM)
7330 output_asm_insn (AS2 (mov%z2,%3,%4), operands);
7331 output_asm_insn (AS2 (mov%z2,%4,%0), operands);
7334 output_asm_insn (AS2 (mov%z0,%3,%0), operands);
7336 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
7341 (define_insn "movhicc_1"
7342 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,&r,rm")
7343 (if_then_else:HI (match_operator 1 "comparison_operator"
7344 [(cc0) (const_int 0)])
7345 (match_operand:HI 2 "general_operand" "rm,0,rm,g")
7346 (match_operand:HI 3 "general_operand" "0,rm,rm,g")))
7347 (clobber (match_scratch:SI 4 "X,X,X,=&r"))]
7351 if (which_alternative == 0)
7353 /* r <- cond ? arg : r */
7354 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7356 else if (which_alternative == 1)
7358 /* r <- cond ? r : arg */
7359 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7361 else if (which_alternative == 2)
7363 /* r <- cond ? arg1 : arg2 */
7364 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
7365 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
7367 else if (which_alternative == 3)
7369 /* r <- cond ? arg1 : arg2 */
7372 xops[0] = gen_label_rtx ();
7373 xops[1] = gen_label_rtx ();
7374 xops[2] = operands[1];
7376 output_asm_insn (\"j%c2 %l0\", xops);
7377 if (! rtx_equal_p (operands[0], operands[2]))
7378 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[2]) == MEM)
7380 output_asm_insn (AS2 (mov%z2,%2,%4), operands);
7381 output_asm_insn (AS2 (mov%z2,%4,%0), operands);
7384 output_asm_insn (AS2 (mov%z0,%2,%0), operands);
7385 output_asm_insn (\"jmp %l1\", xops);
7386 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
7387 if (! rtx_equal_p (operands[0], operands[3]))
7389 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[3]) == MEM)
7391 output_asm_insn (AS2 (mov%z2,%3,%4), operands);
7392 output_asm_insn (AS2 (mov%z2,%4,%0), operands);
7395 output_asm_insn (AS2 (mov%z0,%3,%0), operands);
7397 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
7402 (define_expand "movsfcc"
7404 (set (match_operand 0 "general_operand" "")
7405 (if_then_else:SF (match_operand 1 "comparison_operator" "")
7406 (match_operand:SF 2 "general_operand" "")
7407 (match_operand:SF 3 "general_operand" "")))]
7413 for (i = 2; i <= 3; i++)
7415 if ((reload_in_progress | reload_completed) == 0
7416 && CONSTANT_P (operands[i]))
7418 operands[i] = force_const_mem (SFmode, operands[i]);
7421 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7424 (define_expand "movdfcc"
7426 (set (match_operand 0 "register_operand" "t")
7427 (if_then_else:DF (match_operand 1 "comparison_operator" "")
7428 (match_operand:DF 2 "general_operand" "")
7429 (match_operand:DF 3 "general_operand" "")))]
7435 for (i = 2; i <= 3; i++)
7437 if ((reload_in_progress | reload_completed) == 0
7438 && CONSTANT_P (operands[i]))
7440 operands[i] = force_const_mem (DFmode, operands[i]);
7443 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7446 (define_expand "movxfcc"
7448 (set (match_operand 0 "register_operand" "t")
7449 (if_then_else:XF (match_operand 1 "comparison_operator" "")
7450 (match_operand:XF 2 "general_operand" "")
7451 (match_operand:XF 3 "general_operand" "")))]
7457 for (i = 2; i <= 3; i++)
7459 if ((reload_in_progress | reload_completed) == 0
7460 && CONSTANT_P (operands[i]))
7462 operands[i] = force_const_mem (XFmode, operands[i]);
7465 operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
7468 (define_insn "movsfcc_1"
7469 [(set (match_operand:SF 0 "general_operand" "=f,=f,=f,=f")
7470 (if_then_else:SF (match_operator 1 "comparison_operator"
7471 [(cc0) (const_int 0)])
7472 (match_operand:SF 2 "general_operand" "0,f,f,fFm")
7473 (match_operand:SF 3 "general_operand" "f,0,f,fFm")))]
7477 if (which_alternative == 0)
7479 /* r <- cond ? arg : r */
7480 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7482 else if (which_alternative == 1)
7484 /* r <- cond ? r : arg */
7485 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7487 else if (which_alternative == 2)
7489 /* r <- cond ? r : arg */
7490 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7491 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7493 else if (which_alternative == 3)
7495 /* r <- cond ? arg1 : arg2 */
7498 xops[0] = gen_label_rtx ();
7499 xops[1] = gen_label_rtx ();
7500 xops[2] = operands[1];
7502 output_asm_insn (\"j%f2 %l0\", xops);
7503 if (STACK_REG_P (operands[2]) || GET_CODE (operands[2]) == MEM)
7504 output_asm_insn (AS1 (fld%z2,%y2), operands);
7507 operands[2] = XEXP (operands[2], 0);
7508 output_asm_insn (AS1 (fld%z2,%y2), operands);
7510 output_asm_insn (\"jmp %l1\", xops);
7511 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
7512 if (STACK_REG_P (operands[3]) || GET_CODE (operands[0]) == MEM)
7513 output_asm_insn (AS1 (fld%z3,%y3), operands);
7516 operands[3] = XEXP (operands[3], 0);
7517 output_asm_insn (AS1 (fld%z3,%y3), operands);
7519 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
7524 (define_insn "movdfcc_1"
7525 [(set (match_operand:DF 0 "general_operand" "=f,=f,=f,=f")
7526 (if_then_else:DF (match_operator 1 "comparison_operator"
7527 [(cc0) (const_int 0)])
7528 (match_operand:DF 2 "general_operand" "0,f,f,fFm")
7529 (match_operand:DF 3 "general_operand" "f,0,f,fFm")))]
7533 if (which_alternative == 0)
7535 /* r <- cond ? arg : r */
7536 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7538 else if (which_alternative == 1)
7540 /* r <- cond ? r : arg */
7541 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7543 else if (which_alternative == 2)
7545 /* r <- cond ? r : arg */
7546 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7547 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7549 else if (which_alternative == 3)
7551 /* r <- cond ? arg1 : arg2 */
7554 xops[0] = gen_label_rtx ();
7555 xops[1] = gen_label_rtx ();
7556 xops[2] = operands[1];
7558 output_asm_insn (\"j%f2 %l0\", xops);
7559 if (STACK_REG_P (operands[2]) || GET_CODE (operands[2]) == MEM)
7560 output_asm_insn (AS1 (fld%z2,%y2), operands);
7563 operands[2] = XEXP (operands[2], 0);
7564 output_asm_insn (AS1 (fld%z2,%y2), operands);
7566 output_asm_insn (\"jmp %l1\", xops);
7567 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
7568 if (STACK_REG_P (operands[3]) || GET_CODE (operands[0]) == MEM)
7569 output_asm_insn (AS1 (fld%z3,%y3), operands);
7572 operands[3] = XEXP (operands[3], 0);
7573 output_asm_insn (AS1 (fld%z3,%y3), operands);
7575 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
7580 (define_insn "movxfcc_1"
7581 [(set (match_operand:XF 0 "register_operand" "=f,=f,=f,=f")
7582 (if_then_else:XF (match_operator 1 "comparison_operator"
7583 [(cc0) (const_int 0)])
7584 (match_operand:XF 2 "register_operand" "0,f,f,fFm")
7585 (match_operand:XF 3 "register_operand" "f,0,f,fFm")))]
7589 if (which_alternative == 0)
7591 /* r <- cond ? arg : r */
7592 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7594 else if (which_alternative == 1)
7596 /* r <- cond ? r : arg */
7597 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7599 else if (which_alternative == 2)
7601 /* r <- cond ? r : arg */
7602 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
7603 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
7605 else if (which_alternative == 3)
7607 /* r <- cond ? arg1 : arg2 */
7610 xops[0] = gen_label_rtx ();
7611 xops[1] = gen_label_rtx ();
7612 xops[2] = operands[1];
7614 output_asm_insn (\"j%f2 %l0\", xops);
7615 if (STACK_REG_P (operands[2]) || GET_CODE (operands[2]) == MEM)
7616 output_asm_insn (AS1 (fld%z2,%y2), operands);
7619 operands[2] = XEXP (operands[2], 0);
7620 output_asm_insn (AS1 (fld%z2,%y2), operands);
7622 output_asm_insn (\"jmp %l1\", xops);
7623 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
7624 if (STACK_REG_P (operands[3]) || GET_CODE (operands[0]) == MEM)
7625 output_asm_insn (AS1 (fld%z3,%y3), operands);
7628 operands[3] = XEXP (operands[3], 0);
7629 output_asm_insn (AS1 (fld%z3,%y3), operands);
7631 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
7636 (define_insn "strlensi_unroll"
7637 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
7638 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r"))
7639 (match_operand:SI 2 "immediate_operand" "i,i")] 0))
7640 (clobber (match_scratch:SI 3 "=&q,&r"))]
7642 "* return output_strlen_unroll (operands);")
7644 ;; the only difference between the following patterns is the register preference
7645 ;; on a pentium using a q-register saves one clock cycle per 4 characters
7647 (define_insn "strlensi_unroll4"
7648 [(set (match_operand:SI 0 "register_operand" "=r,r")
7649 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0"))
7650 (match_operand:SI 1 "immediate_operand" "i,i")
7651 (match_operand:SI 2 "register_operand" "+q,!r")] 0))
7652 (clobber (match_dup 2))]
7653 "(TARGET_USE_ANY_REG && optimize > 1)"
7654 "* return output_strlen_unroll (operands);")
7656 (define_insn "strlensi_unroll5"
7657 [(set (match_operand:SI 0 "register_operand" "=r")
7658 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0"))
7659 (match_operand:SI 1 "immediate_operand" "i")
7660 (match_operand:SI 2 "register_operand" "+q")] 0))
7661 (clobber (match_dup 2))]
7662 "(TARGET_USE_Q_REG && optimize > 1)"
7663 "* return output_strlen_unroll (operands);"
7666 (define_insn "allocate_stack_worker"
7667 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
7668 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
7669 (clobber (match_dup 0))]
7670 "TARGET_STACK_PROBE"
7671 "* return AS1(call,__alloca);")
7673 (define_expand "allocate_stack"
7674 [(set (match_operand:SI 0 "register_operand" "=r")
7675 (minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" "")))
7676 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))]
7677 "TARGET_STACK_PROBE"
7680 #ifdef CHECK_STACK_LIMIT
7681 if (GET_CODE (operands[1]) == CONST_INT
7682 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
7683 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
7687 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
7690 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
7694 (define_expand "nonlocal_goto_receiver"
7699 load_pic_register (1);