1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
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 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
65 (define_c_enum "unspec" [
66 ;; Relocation specifiers
77 UNSPEC_MACHOPIC_OFFSET
86 UNSPEC_MEMORY_BLOCKAGE
94 ;; Other random patterns
103 UNSPEC_LD_MPIC ; load_macho_picbase
106 ;; For SSE/MMX support:
124 UNSPEC_MS_TO_SYSV_CALL
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
183 ;; For SSE4.1 support
193 ;; For SSE4.2 support
199 UNSPEC_FMA4_INTRINSIC
202 UNSPEC_XOP_UNSIGNED_CMP
213 UNSPEC_AESKEYGENASSIST
215 ;; For PCLMUL support
231 (define_c_enum "unspecv" [
234 UNSPECV_PROBE_STACK_RANGE
253 UNSPECV_LLWP_INTRINSIC
254 UNSPECV_SLWP_INTRINSIC
255 UNSPECV_LWPVAL_INTRINSIC
256 UNSPECV_LWPINS_INTRINSIC
264 ;; Constants to represent pcomtrue/pcomfalse variants
274 ;; Constants used in the XOP pperm instruction
276 [(PPERM_SRC 0x00) /* copy source */
277 (PPERM_INVERT 0x20) /* invert source */
278 (PPERM_REVERSE 0x40) /* bit reverse source */
279 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
280 (PPERM_ZERO 0x80) /* all 0's */
281 (PPERM_ONES 0xa0) /* all 1's */
282 (PPERM_SIGN 0xc0) /* propagate sign bit */
283 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
284 (PPERM_SRC1 0x00) /* use first source byte */
285 (PPERM_SRC2 0x10) /* use second source byte */
288 ;; Registers by name.
341 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
344 ;; In C guard expressions, put expressions which may be compile-time
345 ;; constants first. This allows for better optimization. For
346 ;; example, write "TARGET_64BIT && reload_completed", not
347 ;; "reload_completed && TARGET_64BIT".
351 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
352 generic64,amdfam10,bdver1"
353 (const (symbol_ref "ix86_schedule")))
355 ;; A basic instruction type. Refinements due to arguments to be
356 ;; provided in other attributes.
359 alu,alu1,negnot,imov,imovx,lea,
360 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
361 icmp,test,ibr,setcc,icmov,
362 push,pop,call,callv,leave,
364 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
365 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
366 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
367 ssemuladd,sse4arg,lwp,
368 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
369 (const_string "other"))
371 ;; Main data type used by the insn
373 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
374 (const_string "unknown"))
376 ;; The CPU unit operations uses.
377 (define_attr "unit" "integer,i387,sse,mmx,unknown"
378 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
379 (const_string "i387")
380 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
381 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
382 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
384 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
386 (eq_attr "type" "other")
387 (const_string "unknown")]
388 (const_string "integer")))
390 ;; The (bounding maximum) length of an instruction immediate.
391 (define_attr "length_immediate" ""
392 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
395 (eq_attr "unit" "i387,sse,mmx")
397 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
399 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
400 (eq_attr "type" "imov,test")
401 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
402 (eq_attr "type" "call")
403 (if_then_else (match_operand 0 "constant_call_address_operand" "")
406 (eq_attr "type" "callv")
407 (if_then_else (match_operand 1 "constant_call_address_operand" "")
410 ;; We don't know the size before shorten_branches. Expect
411 ;; the instruction to fit for better scheduling.
412 (eq_attr "type" "ibr")
415 (symbol_ref "/* Update immediate_length and other attributes! */
416 gcc_unreachable (),1")))
418 ;; The (bounding maximum) length of an instruction address.
419 (define_attr "length_address" ""
420 (cond [(eq_attr "type" "str,other,multi,fxch")
422 (and (eq_attr "type" "call")
423 (match_operand 0 "constant_call_address_operand" ""))
425 (and (eq_attr "type" "callv")
426 (match_operand 1 "constant_call_address_operand" ""))
429 (symbol_ref "ix86_attr_length_address_default (insn)")))
431 ;; Set when length prefix is used.
432 (define_attr "prefix_data16" ""
433 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
435 (eq_attr "mode" "HI")
437 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
442 ;; Set when string REP prefix is used.
443 (define_attr "prefix_rep" ""
444 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
446 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
451 ;; Set when 0f opcode prefix is used.
452 (define_attr "prefix_0f" ""
454 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
455 (eq_attr "unit" "sse,mmx"))
459 ;; Set when REX opcode prefix is used.
460 (define_attr "prefix_rex" ""
461 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
463 (and (eq_attr "mode" "DI")
464 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
465 (eq_attr "unit" "!mmx")))
467 (and (eq_attr "mode" "QI")
468 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
471 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
474 (and (eq_attr "type" "imovx")
475 (match_operand:QI 1 "ext_QIreg_operand" ""))
480 ;; There are also additional prefixes in 3DNOW, SSSE3.
481 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
482 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
483 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
484 (define_attr "prefix_extra" ""
485 (cond [(eq_attr "type" "ssemuladd,sse4arg")
487 (eq_attr "type" "sseiadd1,ssecvt1")
492 ;; Prefix used: original, VEX or maybe VEX.
493 (define_attr "prefix" "orig,vex,maybe_vex"
494 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
496 (const_string "orig")))
498 ;; VEX W bit is used.
499 (define_attr "prefix_vex_w" "" (const_int 0))
501 ;; The length of VEX prefix
502 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
503 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
504 ;; still prefix_0f 1, with prefix_extra 1.
505 (define_attr "length_vex" ""
506 (if_then_else (and (eq_attr "prefix_0f" "1")
507 (eq_attr "prefix_extra" "0"))
508 (if_then_else (eq_attr "prefix_vex_w" "1")
509 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
510 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
511 (if_then_else (eq_attr "prefix_vex_w" "1")
512 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
513 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
515 ;; Set when modrm byte is used.
516 (define_attr "modrm" ""
517 (cond [(eq_attr "type" "str,leave")
519 (eq_attr "unit" "i387")
521 (and (eq_attr "type" "incdec")
522 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
523 (ior (match_operand:SI 1 "register_operand" "")
524 (match_operand:HI 1 "register_operand" ""))))
526 (and (eq_attr "type" "push")
527 (not (match_operand 1 "memory_operand" "")))
529 (and (eq_attr "type" "pop")
530 (not (match_operand 0 "memory_operand" "")))
532 (and (eq_attr "type" "imov")
533 (and (not (eq_attr "mode" "DI"))
534 (ior (and (match_operand 0 "register_operand" "")
535 (match_operand 1 "immediate_operand" ""))
536 (ior (and (match_operand 0 "ax_reg_operand" "")
537 (match_operand 1 "memory_displacement_only_operand" ""))
538 (and (match_operand 0 "memory_displacement_only_operand" "")
539 (match_operand 1 "ax_reg_operand" ""))))))
541 (and (eq_attr "type" "call")
542 (match_operand 0 "constant_call_address_operand" ""))
544 (and (eq_attr "type" "callv")
545 (match_operand 1 "constant_call_address_operand" ""))
547 (and (eq_attr "type" "alu,alu1,icmp,test")
548 (match_operand 0 "ax_reg_operand" ""))
549 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
553 ;; The (bounding maximum) length of an instruction in bytes.
554 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
555 ;; Later we may want to split them and compute proper length as for
557 (define_attr "length" ""
558 (cond [(eq_attr "type" "other,multi,fistp,frndint")
560 (eq_attr "type" "fcmp")
562 (eq_attr "unit" "i387")
564 (plus (attr "prefix_data16")
565 (attr "length_address")))
566 (ior (eq_attr "prefix" "vex")
567 (and (eq_attr "prefix" "maybe_vex")
568 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
569 (plus (attr "length_vex")
570 (plus (attr "length_immediate")
572 (attr "length_address"))))]
573 (plus (plus (attr "modrm")
574 (plus (attr "prefix_0f")
575 (plus (attr "prefix_rex")
576 (plus (attr "prefix_extra")
578 (plus (attr "prefix_rep")
579 (plus (attr "prefix_data16")
580 (plus (attr "length_immediate")
581 (attr "length_address")))))))
583 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
584 ;; `store' if there is a simple memory reference therein, or `unknown'
585 ;; if the instruction is complex.
587 (define_attr "memory" "none,load,store,both,unknown"
588 (cond [(eq_attr "type" "other,multi,str,lwp")
589 (const_string "unknown")
590 (eq_attr "type" "lea,fcmov,fpspc")
591 (const_string "none")
592 (eq_attr "type" "fistp,leave")
593 (const_string "both")
594 (eq_attr "type" "frndint")
595 (const_string "load")
596 (eq_attr "type" "push")
597 (if_then_else (match_operand 1 "memory_operand" "")
598 (const_string "both")
599 (const_string "store"))
600 (eq_attr "type" "pop")
601 (if_then_else (match_operand 0 "memory_operand" "")
602 (const_string "both")
603 (const_string "load"))
604 (eq_attr "type" "setcc")
605 (if_then_else (match_operand 0 "memory_operand" "")
606 (const_string "store")
607 (const_string "none"))
608 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
609 (if_then_else (ior (match_operand 0 "memory_operand" "")
610 (match_operand 1 "memory_operand" ""))
611 (const_string "load")
612 (const_string "none"))
613 (eq_attr "type" "ibr")
614 (if_then_else (match_operand 0 "memory_operand" "")
615 (const_string "load")
616 (const_string "none"))
617 (eq_attr "type" "call")
618 (if_then_else (match_operand 0 "constant_call_address_operand" "")
619 (const_string "none")
620 (const_string "load"))
621 (eq_attr "type" "callv")
622 (if_then_else (match_operand 1 "constant_call_address_operand" "")
623 (const_string "none")
624 (const_string "load"))
625 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
626 (match_operand 1 "memory_operand" ""))
627 (const_string "both")
628 (and (match_operand 0 "memory_operand" "")
629 (match_operand 1 "memory_operand" ""))
630 (const_string "both")
631 (match_operand 0 "memory_operand" "")
632 (const_string "store")
633 (match_operand 1 "memory_operand" "")
634 (const_string "load")
636 "!alu1,negnot,ishift1,
637 imov,imovx,icmp,test,bitmanip,
639 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
640 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
641 (match_operand 2 "memory_operand" ""))
642 (const_string "load")
643 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
644 (match_operand 3 "memory_operand" ""))
645 (const_string "load")
647 (const_string "none")))
649 ;; Indicates if an instruction has both an immediate and a displacement.
651 (define_attr "imm_disp" "false,true,unknown"
652 (cond [(eq_attr "type" "other,multi")
653 (const_string "unknown")
654 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
655 (and (match_operand 0 "memory_displacement_operand" "")
656 (match_operand 1 "immediate_operand" "")))
657 (const_string "true")
658 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
659 (and (match_operand 0 "memory_displacement_operand" "")
660 (match_operand 2 "immediate_operand" "")))
661 (const_string "true")
663 (const_string "false")))
665 ;; Indicates if an FP operation has an integer source.
667 (define_attr "fp_int_src" "false,true"
668 (const_string "false"))
670 ;; Defines rounding mode of an FP operation.
672 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
673 (const_string "any"))
675 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
676 (define_attr "use_carry" "0,1" (const_string "0"))
678 ;; Define attribute to indicate unaligned ssemov insns
679 (define_attr "movu" "0,1" (const_string "0"))
681 ;; Describe a user's asm statement.
682 (define_asm_attributes
683 [(set_attr "length" "128")
684 (set_attr "type" "multi")])
686 (define_code_iterator plusminus [plus minus])
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697 [(plus "add") (ss_plus "adds") (us_plus "addus")
698 (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (define_code_attr plusminus_carry_mnemonic
700 [(plus "adc") (minus "sbb")])
702 ;; Mark commutative operators as such in constraints.
703 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
704 (minus "") (ss_minus "") (us_minus "")])
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
712 ;; Mapping of signed/unsigned max and min
713 (define_code_iterator maxmin [smax smin umax umin])
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
717 (umax "maxu") (umin "minu")])
718 (define_code_attr maxmin_float [(smax "max") (smin "min")])
720 ;; Mapping of logic operators
721 (define_code_iterator any_logic [and ior xor])
722 (define_code_iterator any_or [ior xor])
724 ;; Base name for insn mnemonic.
725 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
727 ;; Mapping of shift-right operators
728 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730 ;; Base name for define_insn
731 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
733 ;; Base name for insn mnemonic.
734 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
736 ;; Mapping of rotate operators
737 (define_code_iterator any_rotate [rotate rotatert])
739 ;; Base name for define_insn
740 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
742 ;; Base name for insn mnemonic.
743 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
745 ;; Mapping of abs neg operators
746 (define_code_iterator absneg [abs neg])
748 ;; Base name for x87 insn mnemonic.
749 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
751 ;; Used in signed and unsigned widening multiplications.
752 (define_code_iterator any_extend [sign_extend zero_extend])
754 ;; Various insn prefixes for signed and unsigned operations.
755 (define_code_attr u [(sign_extend "") (zero_extend "u")
756 (div "") (udiv "u")])
757 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
759 ;; Used in signed and unsigned divisions.
760 (define_code_iterator any_div [div udiv])
762 ;; Instruction prefix for signed and unsigned operations.
763 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
764 (div "i") (udiv "")])
766 ;; 64bit single word integer modes.
767 (define_mode_iterator SWI1248x [QI HI SI DI])
769 ;; 64bit single word integer modes without QImode and HImode.
770 (define_mode_iterator SWI48x [SI DI])
772 ;; Single word integer modes.
773 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
775 ;; Single word integer modes without SImode and DImode.
776 (define_mode_iterator SWI12 [QI HI])
778 ;; Single word integer modes without DImode.
779 (define_mode_iterator SWI124 [QI HI SI])
781 ;; Single word integer modes without QImode and DImode.
782 (define_mode_iterator SWI24 [HI SI])
784 ;; Single word integer modes without QImode.
785 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
787 ;; Single word integer modes without QImode and HImode.
788 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
790 ;; All math-dependant single and double word integer modes.
791 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
792 (HI "TARGET_HIMODE_MATH")
793 SI DI (TI "TARGET_64BIT")])
795 ;; Math-dependant single word integer modes.
796 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
797 (HI "TARGET_HIMODE_MATH")
798 SI (DI "TARGET_64BIT")])
800 ;; Math-dependant single word integer modes without DImode.
801 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
802 (HI "TARGET_HIMODE_MATH")
805 ;; Math-dependant single word integer modes without QImode.
806 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
807 SI (DI "TARGET_64BIT")])
809 ;; Double word integer modes.
810 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
811 (TI "TARGET_64BIT")])
813 ;; Double word integer modes as mode attribute.
814 (define_mode_attr DWI [(SI "DI") (DI "TI")])
815 (define_mode_attr dwi [(SI "di") (DI "ti")])
817 ;; Half mode for double word integer modes.
818 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
819 (DI "TARGET_64BIT")])
821 ;; Instruction suffix for integer modes.
822 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
824 ;; Register class for integer modes.
825 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
827 ;; Immediate operand constraint for integer modes.
828 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
830 ;; General operand constraint for word modes.
831 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
833 ;; Immediate operand constraint for double integer modes.
834 (define_mode_attr di [(SI "iF") (DI "e")])
836 ;; Immediate operand constraint for shifts.
837 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
839 ;; General operand predicate for integer modes.
840 (define_mode_attr general_operand
841 [(QI "general_operand")
842 (HI "general_operand")
843 (SI "general_operand")
844 (DI "x86_64_general_operand")
845 (TI "x86_64_general_operand")])
847 ;; General sign/zero extend operand predicate for integer modes.
848 (define_mode_attr general_szext_operand
849 [(QI "general_operand")
850 (HI "general_operand")
851 (SI "general_operand")
852 (DI "x86_64_szext_general_operand")])
854 ;; Immediate operand predicate for integer modes.
855 (define_mode_attr immediate_operand
856 [(QI "immediate_operand")
857 (HI "immediate_operand")
858 (SI "immediate_operand")
859 (DI "x86_64_immediate_operand")])
861 ;; Operand predicate for shifts.
862 (define_mode_attr shift_operand
863 [(QI "nonimmediate_operand")
864 (HI "nonimmediate_operand")
865 (SI "nonimmediate_operand")
866 (DI "shiftdi_operand")
867 (TI "register_operand")])
869 ;; Operand predicate for shift argument.
870 (define_mode_attr shift_immediate_operand
871 [(QI "const_1_to_31_operand")
872 (HI "const_1_to_31_operand")
873 (SI "const_1_to_31_operand")
874 (DI "const_1_to_63_operand")])
876 ;; Input operand predicate for arithmetic left shifts.
877 (define_mode_attr ashl_input_operand
878 [(QI "nonimmediate_operand")
879 (HI "nonimmediate_operand")
880 (SI "nonimmediate_operand")
881 (DI "ashldi_input_operand")
882 (TI "reg_or_pm1_operand")])
884 ;; SSE and x87 SFmode and DFmode floating point modes
885 (define_mode_iterator MODEF [SF DF])
887 ;; All x87 floating point modes
888 (define_mode_iterator X87MODEF [SF DF XF])
890 ;; All integer modes handled by x87 fisttp operator.
891 (define_mode_iterator X87MODEI [HI SI DI])
893 ;; All integer modes handled by integer x87 operators.
894 (define_mode_iterator X87MODEI12 [HI SI])
896 ;; All integer modes handled by SSE cvtts?2si* operators.
897 (define_mode_iterator SSEMODEI24 [SI DI])
899 ;; SSE asm suffix for floating point modes
900 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
902 ;; SSE vector mode corresponding to a scalar mode
903 (define_mode_attr ssevecmode
904 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
906 ;; Instruction suffix for REX 64bit operators.
907 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
909 ;; This mode iterator allows :P to be used for patterns that operate on
910 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
911 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
913 ;; Scheduling descriptions
915 (include "pentium.md")
918 (include "athlon.md")
923 ;; Operand and operator predicates and constraints
925 (include "predicates.md")
926 (include "constraints.md")
929 ;; Compare and branch/compare and store instructions.
931 (define_expand "cbranch<mode>4"
932 [(set (reg:CC FLAGS_REG)
933 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
934 (match_operand:SDWIM 2 "<general_operand>" "")))
935 (set (pc) (if_then_else
936 (match_operator 0 "ordered_comparison_operator"
937 [(reg:CC FLAGS_REG) (const_int 0)])
938 (label_ref (match_operand 3 "" ""))
942 if (MEM_P (operands[1]) && MEM_P (operands[2]))
943 operands[1] = force_reg (<MODE>mode, operands[1]);
944 ix86_expand_branch (GET_CODE (operands[0]),
945 operands[1], operands[2], operands[3]);
949 (define_expand "cstore<mode>4"
950 [(set (reg:CC FLAGS_REG)
951 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
952 (match_operand:SWIM 3 "<general_operand>" "")))
953 (set (match_operand:QI 0 "register_operand" "")
954 (match_operator 1 "ordered_comparison_operator"
955 [(reg:CC FLAGS_REG) (const_int 0)]))]
958 if (MEM_P (operands[2]) && MEM_P (operands[3]))
959 operands[2] = force_reg (<MODE>mode, operands[2]);
960 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
961 operands[2], operands[3]);
965 (define_expand "cmp<mode>_1"
966 [(set (reg:CC FLAGS_REG)
967 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
968 (match_operand:SWI48 1 "<general_operand>" "")))]
972 (define_insn "*cmp<mode>_ccno_1"
973 [(set (reg FLAGS_REG)
974 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
975 (match_operand:SWI 1 "const0_operand" "")))]
976 "ix86_match_ccmode (insn, CCNOmode)"
978 test{<imodesuffix>}\t%0, %0
979 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
980 [(set_attr "type" "test,icmp")
981 (set_attr "length_immediate" "0,1")
982 (set_attr "mode" "<MODE>")])
984 (define_insn "*cmp<mode>_1"
985 [(set (reg FLAGS_REG)
986 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
987 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
988 "ix86_match_ccmode (insn, CCmode)"
989 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
990 [(set_attr "type" "icmp")
991 (set_attr "mode" "<MODE>")])
993 (define_insn "*cmp<mode>_minus_1"
994 [(set (reg FLAGS_REG)
996 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
997 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
999 "ix86_match_ccmode (insn, CCGOCmode)"
1000 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1001 [(set_attr "type" "icmp")
1002 (set_attr "mode" "<MODE>")])
1004 (define_insn "*cmpqi_ext_1"
1005 [(set (reg FLAGS_REG)
1007 (match_operand:QI 0 "general_operand" "Qm")
1010 (match_operand 1 "ext_register_operand" "Q")
1012 (const_int 8)) 0)))]
1013 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1014 "cmp{b}\t{%h1, %0|%0, %h1}"
1015 [(set_attr "type" "icmp")
1016 (set_attr "mode" "QI")])
1018 (define_insn "*cmpqi_ext_1_rex64"
1019 [(set (reg FLAGS_REG)
1021 (match_operand:QI 0 "register_operand" "Q")
1024 (match_operand 1 "ext_register_operand" "Q")
1026 (const_int 8)) 0)))]
1027 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1028 "cmp{b}\t{%h1, %0|%0, %h1}"
1029 [(set_attr "type" "icmp")
1030 (set_attr "mode" "QI")])
1032 (define_insn "*cmpqi_ext_2"
1033 [(set (reg FLAGS_REG)
1037 (match_operand 0 "ext_register_operand" "Q")
1040 (match_operand:QI 1 "const0_operand" "")))]
1041 "ix86_match_ccmode (insn, CCNOmode)"
1043 [(set_attr "type" "test")
1044 (set_attr "length_immediate" "0")
1045 (set_attr "mode" "QI")])
1047 (define_expand "cmpqi_ext_3"
1048 [(set (reg:CC FLAGS_REG)
1052 (match_operand 0 "ext_register_operand" "")
1055 (match_operand:QI 1 "immediate_operand" "")))]
1059 (define_insn "*cmpqi_ext_3_insn"
1060 [(set (reg FLAGS_REG)
1064 (match_operand 0 "ext_register_operand" "Q")
1067 (match_operand:QI 1 "general_operand" "Qmn")))]
1068 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1069 "cmp{b}\t{%1, %h0|%h0, %1}"
1070 [(set_attr "type" "icmp")
1071 (set_attr "modrm" "1")
1072 (set_attr "mode" "QI")])
1074 (define_insn "*cmpqi_ext_3_insn_rex64"
1075 [(set (reg FLAGS_REG)
1079 (match_operand 0 "ext_register_operand" "Q")
1082 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1083 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1084 "cmp{b}\t{%1, %h0|%h0, %1}"
1085 [(set_attr "type" "icmp")
1086 (set_attr "modrm" "1")
1087 (set_attr "mode" "QI")])
1089 (define_insn "*cmpqi_ext_4"
1090 [(set (reg FLAGS_REG)
1094 (match_operand 0 "ext_register_operand" "Q")
1099 (match_operand 1 "ext_register_operand" "Q")
1101 (const_int 8)) 0)))]
1102 "ix86_match_ccmode (insn, CCmode)"
1103 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1104 [(set_attr "type" "icmp")
1105 (set_attr "mode" "QI")])
1107 ;; These implement float point compares.
1108 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1109 ;; which would allow mix and match FP modes on the compares. Which is what
1110 ;; the old patterns did, but with many more of them.
1112 (define_expand "cbranchxf4"
1113 [(set (reg:CC FLAGS_REG)
1114 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1115 (match_operand:XF 2 "nonmemory_operand" "")))
1116 (set (pc) (if_then_else
1117 (match_operator 0 "ix86_fp_comparison_operator"
1120 (label_ref (match_operand 3 "" ""))
1124 ix86_expand_branch (GET_CODE (operands[0]),
1125 operands[1], operands[2], operands[3]);
1129 (define_expand "cstorexf4"
1130 [(set (reg:CC FLAGS_REG)
1131 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1132 (match_operand:XF 3 "nonmemory_operand" "")))
1133 (set (match_operand:QI 0 "register_operand" "")
1134 (match_operator 1 "ix86_fp_comparison_operator"
1139 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1140 operands[2], operands[3]);
1144 (define_expand "cbranch<mode>4"
1145 [(set (reg:CC FLAGS_REG)
1146 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1147 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1148 (set (pc) (if_then_else
1149 (match_operator 0 "ix86_fp_comparison_operator"
1152 (label_ref (match_operand 3 "" ""))
1154 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1156 ix86_expand_branch (GET_CODE (operands[0]),
1157 operands[1], operands[2], operands[3]);
1161 (define_expand "cstore<mode>4"
1162 [(set (reg:CC FLAGS_REG)
1163 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1164 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1165 (set (match_operand:QI 0 "register_operand" "")
1166 (match_operator 1 "ix86_fp_comparison_operator"
1169 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1171 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1172 operands[2], operands[3]);
1176 (define_expand "cbranchcc4"
1177 [(set (pc) (if_then_else
1178 (match_operator 0 "comparison_operator"
1179 [(match_operand 1 "flags_reg_operand" "")
1180 (match_operand 2 "const0_operand" "")])
1181 (label_ref (match_operand 3 "" ""))
1185 ix86_expand_branch (GET_CODE (operands[0]),
1186 operands[1], operands[2], operands[3]);
1190 (define_expand "cstorecc4"
1191 [(set (match_operand:QI 0 "register_operand" "")
1192 (match_operator 1 "comparison_operator"
1193 [(match_operand 2 "flags_reg_operand" "")
1194 (match_operand 3 "const0_operand" "")]))]
1197 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1198 operands[2], operands[3]);
1203 ;; FP compares, step 1:
1204 ;; Set the FP condition codes.
1206 ;; CCFPmode compare with exceptions
1207 ;; CCFPUmode compare with no exceptions
1209 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1210 ;; used to manage the reg stack popping would not be preserved.
1212 (define_insn "*cmpfp_0"
1213 [(set (match_operand:HI 0 "register_operand" "=a")
1216 (match_operand 1 "register_operand" "f")
1217 (match_operand 2 "const0_operand" ""))]
1219 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1220 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1221 "* return output_fp_compare (insn, operands, 0, 0);"
1222 [(set_attr "type" "multi")
1223 (set_attr "unit" "i387")
1225 (cond [(match_operand:SF 1 "" "")
1227 (match_operand:DF 1 "" "")
1230 (const_string "XF")))])
1232 (define_insn_and_split "*cmpfp_0_cc"
1233 [(set (reg:CCFP FLAGS_REG)
1235 (match_operand 1 "register_operand" "f")
1236 (match_operand 2 "const0_operand" "")))
1237 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1238 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1239 && TARGET_SAHF && !TARGET_CMOVE
1240 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1242 "&& reload_completed"
1245 [(compare:CCFP (match_dup 1)(match_dup 2))]
1247 (set (reg:CC FLAGS_REG)
1248 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1250 [(set_attr "type" "multi")
1251 (set_attr "unit" "i387")
1253 (cond [(match_operand:SF 1 "" "")
1255 (match_operand:DF 1 "" "")
1258 (const_string "XF")))])
1260 (define_insn "*cmpfp_xf"
1261 [(set (match_operand:HI 0 "register_operand" "=a")
1264 (match_operand:XF 1 "register_operand" "f")
1265 (match_operand:XF 2 "register_operand" "f"))]
1268 "* return output_fp_compare (insn, operands, 0, 0);"
1269 [(set_attr "type" "multi")
1270 (set_attr "unit" "i387")
1271 (set_attr "mode" "XF")])
1273 (define_insn_and_split "*cmpfp_xf_cc"
1274 [(set (reg:CCFP FLAGS_REG)
1276 (match_operand:XF 1 "register_operand" "f")
1277 (match_operand:XF 2 "register_operand" "f")))
1278 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1280 && TARGET_SAHF && !TARGET_CMOVE"
1282 "&& reload_completed"
1285 [(compare:CCFP (match_dup 1)(match_dup 2))]
1287 (set (reg:CC FLAGS_REG)
1288 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1290 [(set_attr "type" "multi")
1291 (set_attr "unit" "i387")
1292 (set_attr "mode" "XF")])
1294 (define_insn "*cmpfp_<mode>"
1295 [(set (match_operand:HI 0 "register_operand" "=a")
1298 (match_operand:MODEF 1 "register_operand" "f")
1299 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1302 "* return output_fp_compare (insn, operands, 0, 0);"
1303 [(set_attr "type" "multi")
1304 (set_attr "unit" "i387")
1305 (set_attr "mode" "<MODE>")])
1307 (define_insn_and_split "*cmpfp_<mode>_cc"
1308 [(set (reg:CCFP FLAGS_REG)
1310 (match_operand:MODEF 1 "register_operand" "f")
1311 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1312 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1314 && TARGET_SAHF && !TARGET_CMOVE"
1316 "&& reload_completed"
1319 [(compare:CCFP (match_dup 1)(match_dup 2))]
1321 (set (reg:CC FLAGS_REG)
1322 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1324 [(set_attr "type" "multi")
1325 (set_attr "unit" "i387")
1326 (set_attr "mode" "<MODE>")])
1328 (define_insn "*cmpfp_u"
1329 [(set (match_operand:HI 0 "register_operand" "=a")
1332 (match_operand 1 "register_operand" "f")
1333 (match_operand 2 "register_operand" "f"))]
1335 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1336 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1337 "* return output_fp_compare (insn, operands, 0, 1);"
1338 [(set_attr "type" "multi")
1339 (set_attr "unit" "i387")
1341 (cond [(match_operand:SF 1 "" "")
1343 (match_operand:DF 1 "" "")
1346 (const_string "XF")))])
1348 (define_insn_and_split "*cmpfp_u_cc"
1349 [(set (reg:CCFPU FLAGS_REG)
1351 (match_operand 1 "register_operand" "f")
1352 (match_operand 2 "register_operand" "f")))
1353 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1354 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1355 && TARGET_SAHF && !TARGET_CMOVE
1356 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1358 "&& reload_completed"
1361 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1363 (set (reg:CC FLAGS_REG)
1364 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1366 [(set_attr "type" "multi")
1367 (set_attr "unit" "i387")
1369 (cond [(match_operand:SF 1 "" "")
1371 (match_operand:DF 1 "" "")
1374 (const_string "XF")))])
1376 (define_insn "*cmpfp_<mode>"
1377 [(set (match_operand:HI 0 "register_operand" "=a")
1380 (match_operand 1 "register_operand" "f")
1381 (match_operator 3 "float_operator"
1382 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1384 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1385 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1386 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1387 "* return output_fp_compare (insn, operands, 0, 0);"
1388 [(set_attr "type" "multi")
1389 (set_attr "unit" "i387")
1390 (set_attr "fp_int_src" "true")
1391 (set_attr "mode" "<MODE>")])
1393 (define_insn_and_split "*cmpfp_<mode>_cc"
1394 [(set (reg:CCFP FLAGS_REG)
1396 (match_operand 1 "register_operand" "f")
1397 (match_operator 3 "float_operator"
1398 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1399 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1400 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1401 && TARGET_SAHF && !TARGET_CMOVE
1402 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1403 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1405 "&& reload_completed"
1410 (match_op_dup 3 [(match_dup 2)]))]
1412 (set (reg:CC FLAGS_REG)
1413 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1415 [(set_attr "type" "multi")
1416 (set_attr "unit" "i387")
1417 (set_attr "fp_int_src" "true")
1418 (set_attr "mode" "<MODE>")])
1420 ;; FP compares, step 2
1421 ;; Move the fpsw to ax.
1423 (define_insn "x86_fnstsw_1"
1424 [(set (match_operand:HI 0 "register_operand" "=a")
1425 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1428 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1429 (set_attr "mode" "SI")
1430 (set_attr "unit" "i387")])
1432 ;; FP compares, step 3
1433 ;; Get ax into flags, general case.
1435 (define_insn "x86_sahf_1"
1436 [(set (reg:CC FLAGS_REG)
1437 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1441 #ifndef HAVE_AS_IX86_SAHF
1443 return ASM_BYTE "0x9e";
1448 [(set_attr "length" "1")
1449 (set_attr "athlon_decode" "vector")
1450 (set_attr "amdfam10_decode" "direct")
1451 (set_attr "mode" "SI")])
1453 ;; Pentium Pro can do steps 1 through 3 in one go.
1454 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1455 (define_insn "*cmpfp_i_mixed"
1456 [(set (reg:CCFP FLAGS_REG)
1457 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1458 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1459 "TARGET_MIX_SSE_I387
1460 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1461 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1462 "* return output_fp_compare (insn, operands, 1, 0);"
1463 [(set_attr "type" "fcmp,ssecomi")
1464 (set_attr "prefix" "orig,maybe_vex")
1466 (if_then_else (match_operand:SF 1 "" "")
1468 (const_string "DF")))
1469 (set (attr "prefix_rep")
1470 (if_then_else (eq_attr "type" "ssecomi")
1472 (const_string "*")))
1473 (set (attr "prefix_data16")
1474 (cond [(eq_attr "type" "fcmp")
1476 (eq_attr "mode" "DF")
1479 (const_string "0")))
1480 (set_attr "athlon_decode" "vector")
1481 (set_attr "amdfam10_decode" "direct")])
1483 (define_insn "*cmpfp_i_sse"
1484 [(set (reg:CCFP FLAGS_REG)
1485 (compare:CCFP (match_operand 0 "register_operand" "x")
1486 (match_operand 1 "nonimmediate_operand" "xm")))]
1488 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1489 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1490 "* return output_fp_compare (insn, operands, 1, 0);"
1491 [(set_attr "type" "ssecomi")
1492 (set_attr "prefix" "maybe_vex")
1494 (if_then_else (match_operand:SF 1 "" "")
1496 (const_string "DF")))
1497 (set_attr "prefix_rep" "0")
1498 (set (attr "prefix_data16")
1499 (if_then_else (eq_attr "mode" "DF")
1501 (const_string "0")))
1502 (set_attr "athlon_decode" "vector")
1503 (set_attr "amdfam10_decode" "direct")])
1505 (define_insn "*cmpfp_i_i387"
1506 [(set (reg:CCFP FLAGS_REG)
1507 (compare:CCFP (match_operand 0 "register_operand" "f")
1508 (match_operand 1 "register_operand" "f")))]
1509 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1511 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1512 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1513 "* return output_fp_compare (insn, operands, 1, 0);"
1514 [(set_attr "type" "fcmp")
1516 (cond [(match_operand:SF 1 "" "")
1518 (match_operand:DF 1 "" "")
1521 (const_string "XF")))
1522 (set_attr "athlon_decode" "vector")
1523 (set_attr "amdfam10_decode" "direct")])
1525 (define_insn "*cmpfp_iu_mixed"
1526 [(set (reg:CCFPU FLAGS_REG)
1527 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1528 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1529 "TARGET_MIX_SSE_I387
1530 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532 "* return output_fp_compare (insn, operands, 1, 1);"
1533 [(set_attr "type" "fcmp,ssecomi")
1534 (set_attr "prefix" "orig,maybe_vex")
1536 (if_then_else (match_operand:SF 1 "" "")
1538 (const_string "DF")))
1539 (set (attr "prefix_rep")
1540 (if_then_else (eq_attr "type" "ssecomi")
1542 (const_string "*")))
1543 (set (attr "prefix_data16")
1544 (cond [(eq_attr "type" "fcmp")
1546 (eq_attr "mode" "DF")
1549 (const_string "0")))
1550 (set_attr "athlon_decode" "vector")
1551 (set_attr "amdfam10_decode" "direct")])
1553 (define_insn "*cmpfp_iu_sse"
1554 [(set (reg:CCFPU FLAGS_REG)
1555 (compare:CCFPU (match_operand 0 "register_operand" "x")
1556 (match_operand 1 "nonimmediate_operand" "xm")))]
1558 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1559 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560 "* return output_fp_compare (insn, operands, 1, 1);"
1561 [(set_attr "type" "ssecomi")
1562 (set_attr "prefix" "maybe_vex")
1564 (if_then_else (match_operand:SF 1 "" "")
1566 (const_string "DF")))
1567 (set_attr "prefix_rep" "0")
1568 (set (attr "prefix_data16")
1569 (if_then_else (eq_attr "mode" "DF")
1571 (const_string "0")))
1572 (set_attr "athlon_decode" "vector")
1573 (set_attr "amdfam10_decode" "direct")])
1575 (define_insn "*cmpfp_iu_387"
1576 [(set (reg:CCFPU FLAGS_REG)
1577 (compare:CCFPU (match_operand 0 "register_operand" "f")
1578 (match_operand 1 "register_operand" "f")))]
1579 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1581 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1582 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1583 "* return output_fp_compare (insn, operands, 1, 1);"
1584 [(set_attr "type" "fcmp")
1586 (cond [(match_operand:SF 1 "" "")
1588 (match_operand:DF 1 "" "")
1591 (const_string "XF")))
1592 (set_attr "athlon_decode" "vector")
1593 (set_attr "amdfam10_decode" "direct")])
1595 ;; Move instructions.
1597 (define_expand "movoi"
1598 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1599 (match_operand:OI 1 "general_operand" ""))]
1601 "ix86_expand_move (OImode, operands); DONE;")
1603 (define_expand "movti"
1604 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1605 (match_operand:TI 1 "nonimmediate_operand" ""))]
1606 "TARGET_64BIT || TARGET_SSE"
1609 ix86_expand_move (TImode, operands);
1610 else if (push_operand (operands[0], TImode))
1611 ix86_expand_push (TImode, operands[1]);
1613 ix86_expand_vector_move (TImode, operands);
1617 ;; This expands to what emit_move_complex would generate if we didn't
1618 ;; have a movti pattern. Having this avoids problems with reload on
1619 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1620 ;; to have around all the time.
1621 (define_expand "movcdi"
1622 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1623 (match_operand:CDI 1 "general_operand" ""))]
1626 if (push_operand (operands[0], CDImode))
1627 emit_move_complex_push (CDImode, operands[0], operands[1]);
1629 emit_move_complex_parts (operands[0], operands[1]);
1633 (define_expand "mov<mode>"
1634 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1635 (match_operand:SWI1248x 1 "general_operand" ""))]
1637 "ix86_expand_move (<MODE>mode, operands); DONE;")
1639 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1642 ;; %%% We don't use a post-inc memory reference because x86 is not a
1643 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1644 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1645 ;; targets without our curiosities, and it is just as easy to represent
1646 ;; this differently.
1648 (define_insn "*pushdi2_rex64"
1649 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1650 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1655 [(set_attr "type" "push,multi")
1656 (set_attr "mode" "DI")])
1658 ;; Convert impossible pushes of immediate to existing instructions.
1659 ;; First try to get scratch register and go through it. In case this
1660 ;; fails, push sign extended lower part first and then overwrite
1661 ;; upper part by 32bit move.
1663 [(match_scratch:DI 2 "r")
1664 (set (match_operand:DI 0 "push_operand" "")
1665 (match_operand:DI 1 "immediate_operand" ""))]
1666 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1667 && !x86_64_immediate_operand (operands[1], DImode)"
1668 [(set (match_dup 2) (match_dup 1))
1669 (set (match_dup 0) (match_dup 2))]
1672 ;; We need to define this as both peepholer and splitter for case
1673 ;; peephole2 pass is not run.
1674 ;; "&& 1" is needed to keep it from matching the previous pattern.
1676 [(set (match_operand:DI 0 "push_operand" "")
1677 (match_operand:DI 1 "immediate_operand" ""))]
1678 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1679 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1680 [(set (match_dup 0) (match_dup 1))
1681 (set (match_dup 2) (match_dup 3))]
1683 split_di (&operands[1], 1, &operands[2], &operands[3]);
1685 operands[1] = gen_lowpart (DImode, operands[2]);
1686 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1691 [(set (match_operand:DI 0 "push_operand" "")
1692 (match_operand:DI 1 "immediate_operand" ""))]
1693 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1694 ? epilogue_completed : reload_completed)
1695 && !symbolic_operand (operands[1], DImode)
1696 && !x86_64_immediate_operand (operands[1], DImode)"
1697 [(set (match_dup 0) (match_dup 1))
1698 (set (match_dup 2) (match_dup 3))]
1700 split_di (&operands[1], 1, &operands[2], &operands[3]);
1702 operands[1] = gen_lowpart (DImode, operands[2]);
1703 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1707 (define_insn "*pushdi2"
1708 [(set (match_operand:DI 0 "push_operand" "=<")
1709 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1714 [(set (match_operand:DI 0 "push_operand" "")
1715 (match_operand:DI 1 "general_operand" ""))]
1716 "!TARGET_64BIT && reload_completed
1717 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1719 "ix86_split_long_move (operands); DONE;")
1721 (define_insn "*pushsi2"
1722 [(set (match_operand:SI 0 "push_operand" "=<")
1723 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1726 [(set_attr "type" "push")
1727 (set_attr "mode" "SI")])
1729 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1730 ;; "push a byte/word". But actually we use pushl, which has the effect
1731 ;; of rounding the amount pushed up to a word.
1733 ;; For 64BIT abi we always round up to 8 bytes.
1734 (define_insn "*push<mode>2_rex64"
1735 [(set (match_operand:SWI124 0 "push_operand" "=X")
1736 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1739 [(set_attr "type" "push")
1740 (set_attr "mode" "DI")])
1742 (define_insn "*push<mode>2"
1743 [(set (match_operand:SWI12 0 "push_operand" "=X")
1744 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1747 [(set_attr "type" "push")
1748 (set_attr "mode" "SI")])
1750 (define_insn "*push<mode>2_prologue"
1751 [(set (match_operand:P 0 "push_operand" "=<")
1752 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1753 (clobber (mem:BLK (scratch)))]
1755 "push{<imodesuffix>}\t%1"
1756 [(set_attr "type" "push")
1757 (set_attr "mode" "<MODE>")])
1759 (define_insn "popdi1"
1760 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1761 (mem:DI (reg:DI SP_REG)))
1762 (set (reg:DI SP_REG)
1763 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1766 [(set_attr "type" "pop")
1767 (set_attr "mode" "DI")])
1769 (define_insn "popsi1"
1770 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1771 (mem:SI (reg:SI SP_REG)))
1772 (set (reg:SI SP_REG)
1773 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1776 [(set_attr "type" "pop")
1777 (set_attr "mode" "SI")])
1779 (define_insn "*popdi1_epilogue"
1780 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1781 (mem:DI (reg:DI SP_REG)))
1782 (set (reg:DI SP_REG)
1783 (plus:DI (reg:DI SP_REG) (const_int 8)))
1784 (clobber (mem:BLK (scratch)))]
1787 [(set_attr "type" "pop")
1788 (set_attr "mode" "DI")])
1790 (define_insn "*popsi1_epilogue"
1791 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1792 (mem:SI (reg:SI SP_REG)))
1793 (set (reg:SI SP_REG)
1794 (plus:SI (reg:SI SP_REG) (const_int 4)))
1795 (clobber (mem:BLK (scratch)))]
1798 [(set_attr "type" "pop")
1799 (set_attr "mode" "SI")])
1801 (define_insn "*mov<mode>_xor"
1802 [(set (match_operand:SWI48 0 "register_operand" "=r")
1803 (match_operand:SWI48 1 "const0_operand" ""))
1804 (clobber (reg:CC FLAGS_REG))]
1807 [(set_attr "type" "alu1")
1808 (set_attr "mode" "SI")
1809 (set_attr "length_immediate" "0")])
1811 (define_insn "*mov<mode>_or"
1812 [(set (match_operand:SWI48 0 "register_operand" "=r")
1813 (match_operand:SWI48 1 "const_int_operand" ""))
1814 (clobber (reg:CC FLAGS_REG))]
1816 && operands[1] == constm1_rtx"
1817 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1818 [(set_attr "type" "alu1")
1819 (set_attr "mode" "<MODE>")
1820 (set_attr "length_immediate" "1")])
1822 (define_insn "*movoi_internal_avx"
1823 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1824 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1825 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1827 switch (which_alternative)
1830 return "vxorps\t%0, %0, %0";
1833 if (misaligned_operand (operands[0], OImode)
1834 || misaligned_operand (operands[1], OImode))
1835 return "vmovdqu\t{%1, %0|%0, %1}";
1837 return "vmovdqa\t{%1, %0|%0, %1}";
1842 [(set_attr "type" "sselog1,ssemov,ssemov")
1843 (set_attr "prefix" "vex")
1844 (set_attr "mode" "OI")])
1846 (define_insn "*movti_internal_rex64"
1847 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1848 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1849 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1851 switch (which_alternative)
1857 if (get_attr_mode (insn) == MODE_V4SF)
1858 return "%vxorps\t%0, %d0";
1860 return "%vpxor\t%0, %d0";
1863 /* TDmode values are passed as TImode on the stack. Moving them
1864 to stack may result in unaligned memory access. */
1865 if (misaligned_operand (operands[0], TImode)
1866 || misaligned_operand (operands[1], TImode))
1868 if (get_attr_mode (insn) == MODE_V4SF)
1869 return "%vmovups\t{%1, %0|%0, %1}";
1871 return "%vmovdqu\t{%1, %0|%0, %1}";
1875 if (get_attr_mode (insn) == MODE_V4SF)
1876 return "%vmovaps\t{%1, %0|%0, %1}";
1878 return "%vmovdqa\t{%1, %0|%0, %1}";
1884 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1885 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1887 (cond [(eq_attr "alternative" "2,3")
1889 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1891 (const_string "V4SF")
1892 (const_string "TI"))
1893 (eq_attr "alternative" "4")
1895 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1897 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1899 (const_string "V4SF")
1900 (const_string "TI"))]
1901 (const_string "DI")))])
1904 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1905 (match_operand:TI 1 "general_operand" ""))]
1907 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1909 "ix86_split_long_move (operands); DONE;")
1911 (define_insn "*movti_internal_sse"
1912 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1913 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1914 "TARGET_SSE && !TARGET_64BIT
1915 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1917 switch (which_alternative)
1920 if (get_attr_mode (insn) == MODE_V4SF)
1921 return "%vxorps\t%0, %d0";
1923 return "%vpxor\t%0, %d0";
1926 /* TDmode values are passed as TImode on the stack. Moving them
1927 to stack may result in unaligned memory access. */
1928 if (misaligned_operand (operands[0], TImode)
1929 || misaligned_operand (operands[1], TImode))
1931 if (get_attr_mode (insn) == MODE_V4SF)
1932 return "%vmovups\t{%1, %0|%0, %1}";
1934 return "%vmovdqu\t{%1, %0|%0, %1}";
1938 if (get_attr_mode (insn) == MODE_V4SF)
1939 return "%vmovaps\t{%1, %0|%0, %1}";
1941 return "%vmovdqa\t{%1, %0|%0, %1}";
1947 [(set_attr "type" "sselog1,ssemov,ssemov")
1948 (set_attr "prefix" "maybe_vex")
1950 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1951 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1953 (const_string "V4SF")
1954 (and (eq_attr "alternative" "2")
1955 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1957 (const_string "V4SF")]
1958 (const_string "TI")))])
1960 (define_insn "*movdi_internal_rex64"
1961 [(set (match_operand:DI 0 "nonimmediate_operand"
1962 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1963 (match_operand:DI 1 "general_operand"
1964 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1965 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1967 switch (get_attr_type (insn))
1970 if (SSE_REG_P (operands[0]))
1971 return "movq2dq\t{%1, %0|%0, %1}";
1973 return "movdq2q\t{%1, %0|%0, %1}";
1978 if (get_attr_mode (insn) == MODE_TI)
1979 return "vmovdqa\t{%1, %0|%0, %1}";
1981 return "vmovq\t{%1, %0|%0, %1}";
1984 if (get_attr_mode (insn) == MODE_TI)
1985 return "movdqa\t{%1, %0|%0, %1}";
1989 /* Moves from and into integer register is done using movd
1990 opcode with REX prefix. */
1991 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1992 return "movd\t{%1, %0|%0, %1}";
1993 return "movq\t{%1, %0|%0, %1}";
1996 return "%vpxor\t%0, %d0";
1999 return "pxor\t%0, %0";
2005 return "lea{q}\t{%a1, %0|%0, %a1}";
2008 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2009 if (get_attr_mode (insn) == MODE_SI)
2010 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2011 else if (which_alternative == 2)
2012 return "movabs{q}\t{%1, %0|%0, %1}";
2014 return "mov{q}\t{%1, %0|%0, %1}";
2018 (cond [(eq_attr "alternative" "5")
2019 (const_string "mmx")
2020 (eq_attr "alternative" "6,7,8,9,10")
2021 (const_string "mmxmov")
2022 (eq_attr "alternative" "11")
2023 (const_string "sselog1")
2024 (eq_attr "alternative" "12,13,14,15,16")
2025 (const_string "ssemov")
2026 (eq_attr "alternative" "17,18")
2027 (const_string "ssecvt")
2028 (eq_attr "alternative" "4")
2029 (const_string "multi")
2030 (match_operand:DI 1 "pic_32bit_operand" "")
2031 (const_string "lea")
2033 (const_string "imov")))
2036 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2038 (const_string "*")))
2039 (set (attr "length_immediate")
2041 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2043 (const_string "*")))
2044 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2045 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2046 (set (attr "prefix")
2047 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2048 (const_string "maybe_vex")
2049 (const_string "orig")))
2050 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2052 ;; Convert impossible stores of immediate to existing instructions.
2053 ;; First try to get scratch register and go through it. In case this
2054 ;; fails, move by 32bit parts.
2056 [(match_scratch:DI 2 "r")
2057 (set (match_operand:DI 0 "memory_operand" "")
2058 (match_operand:DI 1 "immediate_operand" ""))]
2059 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2060 && !x86_64_immediate_operand (operands[1], DImode)"
2061 [(set (match_dup 2) (match_dup 1))
2062 (set (match_dup 0) (match_dup 2))]
2065 ;; We need to define this as both peepholer and splitter for case
2066 ;; peephole2 pass is not run.
2067 ;; "&& 1" is needed to keep it from matching the previous pattern.
2069 [(set (match_operand:DI 0 "memory_operand" "")
2070 (match_operand:DI 1 "immediate_operand" ""))]
2071 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2073 [(set (match_dup 2) (match_dup 3))
2074 (set (match_dup 4) (match_dup 5))]
2075 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2078 [(set (match_operand:DI 0 "memory_operand" "")
2079 (match_operand:DI 1 "immediate_operand" ""))]
2080 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2081 ? epilogue_completed : reload_completed)
2082 && !symbolic_operand (operands[1], DImode)
2083 && !x86_64_immediate_operand (operands[1], DImode)"
2084 [(set (match_dup 2) (match_dup 3))
2085 (set (match_dup 4) (match_dup 5))]
2086 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2088 (define_insn "*movdi_internal"
2089 [(set (match_operand:DI 0 "nonimmediate_operand"
2090 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2091 (match_operand:DI 1 "general_operand"
2092 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2093 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2098 movq\t{%1, %0|%0, %1}
2099 movq\t{%1, %0|%0, %1}
2101 %vmovq\t{%1, %0|%0, %1}
2102 %vmovdqa\t{%1, %0|%0, %1}
2103 %vmovq\t{%1, %0|%0, %1}
2105 movlps\t{%1, %0|%0, %1}
2106 movaps\t{%1, %0|%0, %1}
2107 movlps\t{%1, %0|%0, %1}"
2108 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2109 (set (attr "prefix")
2110 (if_then_else (eq_attr "alternative" "5,6,7,8")
2111 (const_string "vex")
2112 (const_string "orig")))
2113 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2116 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2117 (match_operand:DI 1 "general_operand" ""))]
2118 "!TARGET_64BIT && reload_completed
2119 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2120 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2122 "ix86_split_long_move (operands); DONE;")
2124 (define_insn "*movsi_internal"
2125 [(set (match_operand:SI 0 "nonimmediate_operand"
2126 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2127 (match_operand:SI 1 "general_operand"
2128 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2129 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2131 switch (get_attr_type (insn))
2134 if (get_attr_mode (insn) == MODE_TI)
2135 return "%vpxor\t%0, %d0";
2136 return "%vxorps\t%0, %d0";
2139 switch (get_attr_mode (insn))
2142 return "%vmovdqa\t{%1, %0|%0, %1}";
2144 return "%vmovaps\t{%1, %0|%0, %1}";
2146 return "%vmovd\t{%1, %0|%0, %1}";
2148 return "%vmovss\t{%1, %0|%0, %1}";
2154 return "pxor\t%0, %0";
2157 if (get_attr_mode (insn) == MODE_DI)
2158 return "movq\t{%1, %0|%0, %1}";
2159 return "movd\t{%1, %0|%0, %1}";
2162 return "lea{l}\t{%a1, %0|%0, %a1}";
2165 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2166 return "mov{l}\t{%1, %0|%0, %1}";
2170 (cond [(eq_attr "alternative" "2")
2171 (const_string "mmx")
2172 (eq_attr "alternative" "3,4,5")
2173 (const_string "mmxmov")
2174 (eq_attr "alternative" "6")
2175 (const_string "sselog1")
2176 (eq_attr "alternative" "7,8,9,10,11")
2177 (const_string "ssemov")
2178 (match_operand:DI 1 "pic_32bit_operand" "")
2179 (const_string "lea")
2181 (const_string "imov")))
2182 (set (attr "prefix")
2183 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2184 (const_string "orig")
2185 (const_string "maybe_vex")))
2186 (set (attr "prefix_data16")
2187 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2189 (const_string "*")))
2191 (cond [(eq_attr "alternative" "2,3")
2193 (eq_attr "alternative" "6,7")
2195 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2196 (const_string "V4SF")
2197 (const_string "TI"))
2198 (and (eq_attr "alternative" "8,9,10,11")
2199 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2202 (const_string "SI")))])
2204 (define_insn "*movhi_internal"
2205 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2206 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2207 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2209 switch (get_attr_type (insn))
2212 /* movzwl is faster than movw on p2 due to partial word stalls,
2213 though not as fast as an aligned movl. */
2214 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2216 if (get_attr_mode (insn) == MODE_SI)
2217 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2219 return "mov{w}\t{%1, %0|%0, %1}";
2223 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2225 (const_string "imov")
2226 (and (eq_attr "alternative" "0")
2227 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2229 (eq (symbol_ref "TARGET_HIMODE_MATH")
2231 (const_string "imov")
2232 (and (eq_attr "alternative" "1,2")
2233 (match_operand:HI 1 "aligned_operand" ""))
2234 (const_string "imov")
2235 (and (ne (symbol_ref "TARGET_MOVX")
2237 (eq_attr "alternative" "0,2"))
2238 (const_string "imovx")
2240 (const_string "imov")))
2242 (cond [(eq_attr "type" "imovx")
2244 (and (eq_attr "alternative" "1,2")
2245 (match_operand:HI 1 "aligned_operand" ""))
2247 (and (eq_attr "alternative" "0")
2248 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2250 (eq (symbol_ref "TARGET_HIMODE_MATH")
2254 (const_string "HI")))])
2256 ;; Situation is quite tricky about when to choose full sized (SImode) move
2257 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2258 ;; partial register dependency machines (such as AMD Athlon), where QImode
2259 ;; moves issue extra dependency and for partial register stalls machines
2260 ;; that don't use QImode patterns (and QImode move cause stall on the next
2263 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2264 ;; register stall machines with, where we use QImode instructions, since
2265 ;; partial register stall can be caused there. Then we use movzx.
2266 (define_insn "*movqi_internal"
2267 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2268 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2269 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2271 switch (get_attr_type (insn))
2274 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2275 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2277 if (get_attr_mode (insn) == MODE_SI)
2278 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2280 return "mov{b}\t{%1, %0|%0, %1}";
2284 (cond [(and (eq_attr "alternative" "5")
2285 (not (match_operand:QI 1 "aligned_operand" "")))
2286 (const_string "imovx")
2287 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2289 (const_string "imov")
2290 (and (eq_attr "alternative" "3")
2291 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2293 (eq (symbol_ref "TARGET_QIMODE_MATH")
2295 (const_string "imov")
2296 (eq_attr "alternative" "3,5")
2297 (const_string "imovx")
2298 (and (ne (symbol_ref "TARGET_MOVX")
2300 (eq_attr "alternative" "2"))
2301 (const_string "imovx")
2303 (const_string "imov")))
2305 (cond [(eq_attr "alternative" "3,4,5")
2307 (eq_attr "alternative" "6")
2309 (eq_attr "type" "imovx")
2311 (and (eq_attr "type" "imov")
2312 (and (eq_attr "alternative" "0,1")
2313 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2315 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2317 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2320 ;; Avoid partial register stalls when not using QImode arithmetic
2321 (and (eq_attr "type" "imov")
2322 (and (eq_attr "alternative" "0,1")
2323 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2325 (eq (symbol_ref "TARGET_QIMODE_MATH")
2329 (const_string "QI")))])
2331 ;; Stores and loads of ax to arbitrary constant address.
2332 ;; We fake an second form of instruction to force reload to load address
2333 ;; into register when rax is not available
2334 (define_insn "*movabs<mode>_1"
2335 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2336 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2337 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2339 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2340 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2341 [(set_attr "type" "imov")
2342 (set_attr "modrm" "0,*")
2343 (set_attr "length_address" "8,0")
2344 (set_attr "length_immediate" "0,*")
2345 (set_attr "memory" "store")
2346 (set_attr "mode" "<MODE>")])
2348 (define_insn "*movabs<mode>_2"
2349 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2350 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2351 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2353 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2354 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2355 [(set_attr "type" "imov")
2356 (set_attr "modrm" "0,*")
2357 (set_attr "length_address" "8,0")
2358 (set_attr "length_immediate" "0")
2359 (set_attr "memory" "load")
2360 (set_attr "mode" "<MODE>")])
2362 (define_insn "*swap<mode>"
2363 [(set (match_operand:SWI48 0 "register_operand" "+r")
2364 (match_operand:SWI48 1 "register_operand" "+r"))
2368 "xchg{<imodesuffix>}\t%1, %0"
2369 [(set_attr "type" "imov")
2370 (set_attr "mode" "<MODE>")
2371 (set_attr "pent_pair" "np")
2372 (set_attr "athlon_decode" "vector")
2373 (set_attr "amdfam10_decode" "double")])
2375 (define_insn "*swap<mode>_1"
2376 [(set (match_operand:SWI12 0 "register_operand" "+r")
2377 (match_operand:SWI12 1 "register_operand" "+r"))
2380 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2382 [(set_attr "type" "imov")
2383 (set_attr "mode" "SI")
2384 (set_attr "pent_pair" "np")
2385 (set_attr "athlon_decode" "vector")
2386 (set_attr "amdfam10_decode" "double")])
2388 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2389 ;; is disabled for AMDFAM10
2390 (define_insn "*swap<mode>_2"
2391 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2392 (match_operand:SWI12 1 "register_operand" "+<r>"))
2395 "TARGET_PARTIAL_REG_STALL"
2396 "xchg{<imodesuffix>}\t%1, %0"
2397 [(set_attr "type" "imov")
2398 (set_attr "mode" "<MODE>")
2399 (set_attr "pent_pair" "np")
2400 (set_attr "athlon_decode" "vector")])
2402 (define_expand "movstrict<mode>"
2403 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2404 (match_operand:SWI12 1 "general_operand" ""))]
2407 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2409 /* Don't generate memory->memory moves, go through a register */
2410 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2411 operands[1] = force_reg (<MODE>mode, operands[1]);
2414 (define_insn "*movstrict<mode>_1"
2415 [(set (strict_low_part
2416 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2417 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2418 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2419 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2420 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2421 [(set_attr "type" "imov")
2422 (set_attr "mode" "<MODE>")])
2424 (define_insn "*movstrict<mode>_xor"
2425 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2426 (match_operand:SWI12 1 "const0_operand" ""))
2427 (clobber (reg:CC FLAGS_REG))]
2429 "xor{<imodesuffix>}\t%0, %0"
2430 [(set_attr "type" "alu1")
2431 (set_attr "mode" "<MODE>")
2432 (set_attr "length_immediate" "0")])
2434 (define_insn "*mov<mode>_extv_1"
2435 [(set (match_operand:SWI24 0 "register_operand" "=R")
2436 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2440 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2441 [(set_attr "type" "imovx")
2442 (set_attr "mode" "SI")])
2444 (define_insn "*movqi_extv_1_rex64"
2445 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2446 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2451 switch (get_attr_type (insn))
2454 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2456 return "mov{b}\t{%h1, %0|%0, %h1}";
2460 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2461 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2462 (ne (symbol_ref "TARGET_MOVX")
2464 (const_string "imovx")
2465 (const_string "imov")))
2467 (if_then_else (eq_attr "type" "imovx")
2469 (const_string "QI")))])
2471 (define_insn "*movqi_extv_1"
2472 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2473 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2478 switch (get_attr_type (insn))
2481 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2483 return "mov{b}\t{%h1, %0|%0, %h1}";
2487 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2488 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2489 (ne (symbol_ref "TARGET_MOVX")
2491 (const_string "imovx")
2492 (const_string "imov")))
2494 (if_then_else (eq_attr "type" "imovx")
2496 (const_string "QI")))])
2498 (define_insn "*mov<mode>_extzv_1"
2499 [(set (match_operand:SWI48 0 "register_operand" "=R")
2500 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2504 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2505 [(set_attr "type" "imovx")
2506 (set_attr "mode" "SI")])
2508 (define_insn "*movqi_extzv_2_rex64"
2509 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2511 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2516 switch (get_attr_type (insn))
2519 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2521 return "mov{b}\t{%h1, %0|%0, %h1}";
2525 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2526 (ne (symbol_ref "TARGET_MOVX")
2528 (const_string "imovx")
2529 (const_string "imov")))
2531 (if_then_else (eq_attr "type" "imovx")
2533 (const_string "QI")))])
2535 (define_insn "*movqi_extzv_2"
2536 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2538 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2543 switch (get_attr_type (insn))
2546 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2548 return "mov{b}\t{%h1, %0|%0, %h1}";
2552 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2553 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2554 (ne (symbol_ref "TARGET_MOVX")
2556 (const_string "imovx")
2557 (const_string "imov")))
2559 (if_then_else (eq_attr "type" "imovx")
2561 (const_string "QI")))])
2563 (define_expand "mov<mode>_insv_1"
2564 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2567 (match_operand:SWI48 1 "nonmemory_operand" ""))]
2571 (define_insn "*mov<mode>_insv_1_rex64"
2572 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2575 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2577 "mov{b}\t{%b1, %h0|%h0, %b1}"
2578 [(set_attr "type" "imov")
2579 (set_attr "mode" "QI")])
2581 (define_insn "*movsi_insv_1"
2582 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2585 (match_operand:SI 1 "general_operand" "Qmn"))]
2587 "mov{b}\t{%b1, %h0|%h0, %b1}"
2588 [(set_attr "type" "imov")
2589 (set_attr "mode" "QI")])
2591 (define_insn "*movqi_insv_2"
2592 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2595 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2598 "mov{b}\t{%h1, %h0|%h0, %h1}"
2599 [(set_attr "type" "imov")
2600 (set_attr "mode" "QI")])
2602 ;; Floating point move instructions.
2604 (define_expand "movtf"
2605 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2606 (match_operand:TF 1 "nonimmediate_operand" ""))]
2609 ix86_expand_move (TFmode, operands);
2613 (define_expand "mov<mode>"
2614 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2615 (match_operand:X87MODEF 1 "general_operand" ""))]
2617 "ix86_expand_move (<MODE>mode, operands); DONE;")
2619 (define_insn "*pushtf"
2620 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2621 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2624 /* This insn should be already split before reg-stack. */
2627 [(set_attr "type" "multi")
2628 (set_attr "unit" "sse,*,*")
2629 (set_attr "mode" "TF,SI,SI")])
2632 [(set (match_operand:TF 0 "push_operand" "")
2633 (match_operand:TF 1 "general_operand" ""))]
2634 "TARGET_SSE2 && reload_completed
2635 && !SSE_REG_P (operands[1])"
2637 "ix86_split_long_move (operands); DONE;")
2640 [(set (match_operand:TF 0 "push_operand" "")
2641 (match_operand:TF 1 "any_fp_register_operand" ""))]
2643 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2644 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
2647 (define_insn "*pushxf"
2648 [(set (match_operand:XF 0 "push_operand" "=<,<")
2649 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2650 "optimize_function_for_speed_p (cfun)"
2652 /* This insn should be already split before reg-stack. */
2655 [(set_attr "type" "multi")
2656 (set_attr "unit" "i387,*")
2657 (set_attr "mode" "XF,SI")])
2659 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2660 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2661 ;; Pushing using integer instructions is longer except for constants
2662 ;; and direct memory references (assuming that any given constant is pushed
2663 ;; only once, but this ought to be handled elsewhere).
2665 (define_insn "*pushxf_nointeger"
2666 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2667 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2668 "optimize_function_for_size_p (cfun)"
2670 /* This insn should be already split before reg-stack. */
2673 [(set_attr "type" "multi")
2674 (set_attr "unit" "i387,*,*")
2675 (set_attr "mode" "XF,SI,SI")])
2678 [(set (match_operand:XF 0 "push_operand" "")
2679 (match_operand:XF 1 "any_fp_register_operand" ""))]
2681 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2682 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2683 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2686 [(set (match_operand:XF 0 "push_operand" "")
2687 (match_operand:XF 1 "general_operand" ""))]
2689 && !ANY_FP_REG_P (operands[1])"
2691 "ix86_split_long_move (operands); DONE;")
2693 (define_insn "*pushdf"
2694 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2695 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2696 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2698 /* This insn should be already split before reg-stack. */
2701 [(set_attr "type" "multi")
2702 (set_attr "unit" "i387,*,*")
2703 (set_attr "mode" "DF,SI,DF")])
2705 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2706 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2707 ;; On the average, pushdf using integers can be still shorter. Allow this
2708 ;; pattern for optimize_size too.
2710 (define_insn "*pushdf_nointeger"
2711 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2712 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2713 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2715 /* This insn should be already split before reg-stack. */
2718 [(set_attr "type" "multi")
2719 (set_attr "unit" "i387,*,*,*")
2720 (set_attr "mode" "DF,SI,SI,DF")])
2722 ;; %%% Kill this when call knows how to work this out.
2724 [(set (match_operand:DF 0 "push_operand" "")
2725 (match_operand:DF 1 "any_fp_register_operand" ""))]
2727 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2728 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2732 [(set (match_operand:DF 0 "push_operand" "")
2733 (match_operand:DF 1 "general_operand" ""))]
2735 && !ANY_FP_REG_P (operands[1])"
2737 "ix86_split_long_move (operands); DONE;")
2739 (define_insn "*pushsf_rex64"
2740 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2741 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2744 /* Anything else should be already split before reg-stack. */
2745 gcc_assert (which_alternative == 1);
2746 return "push{q}\t%q1";
2748 [(set_attr "type" "multi,push,multi")
2749 (set_attr "unit" "i387,*,*")
2750 (set_attr "mode" "SF,DI,SF")])
2752 (define_insn "*pushsf"
2753 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2754 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2757 /* Anything else should be already split before reg-stack. */
2758 gcc_assert (which_alternative == 1);
2759 return "push{l}\t%1";
2761 [(set_attr "type" "multi,push,multi")
2762 (set_attr "unit" "i387,*,*")
2763 (set_attr "mode" "SF,SI,SF")])
2766 [(set (match_operand:SF 0 "push_operand" "")
2767 (match_operand:SF 1 "memory_operand" ""))]
2769 && MEM_P (operands[1])
2770 && (operands[2] = find_constant_src (insn))"
2774 ;; %%% Kill this when call knows how to work this out.
2776 [(set (match_operand:SF 0 "push_operand" "")
2777 (match_operand:SF 1 "any_fp_register_operand" ""))]
2779 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2780 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2781 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2783 (define_insn "*movtf_internal"
2784 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2785 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2787 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2789 switch (which_alternative)
2793 if (get_attr_mode (insn) == MODE_V4SF)
2794 return "%vmovaps\t{%1, %0|%0, %1}";
2796 return "%vmovdqa\t{%1, %0|%0, %1}";
2798 if (get_attr_mode (insn) == MODE_V4SF)
2799 return "%vxorps\t%0, %d0";
2801 return "%vpxor\t%0, %d0";
2809 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2810 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2812 (cond [(eq_attr "alternative" "0,2")
2814 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2816 (const_string "V4SF")
2817 (const_string "TI"))
2818 (eq_attr "alternative" "1")
2820 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2822 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2824 (const_string "V4SF")
2825 (const_string "TI"))]
2826 (const_string "DI")))])
2829 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2830 (match_operand:TF 1 "general_operand" ""))]
2832 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2834 "ix86_split_long_move (operands); DONE;")
2836 (define_insn "*movxf_internal"
2837 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2838 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2839 "optimize_function_for_speed_p (cfun)
2840 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2841 && (reload_in_progress || reload_completed
2842 || GET_CODE (operands[1]) != CONST_DOUBLE
2843 || memory_operand (operands[0], XFmode))"
2845 switch (which_alternative)
2849 return output_387_reg_move (insn, operands);
2852 return standard_80387_constant_opcode (operands[1]);
2861 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2862 (set_attr "mode" "XF,XF,XF,SI,SI")])
2864 ;; Do not use integer registers when optimizing for size
2865 (define_insn "*movxf_internal_nointeger"
2866 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2867 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2868 "optimize_function_for_size_p (cfun)
2869 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2870 && (reload_in_progress || reload_completed
2871 || standard_80387_constant_p (operands[1])
2872 || GET_CODE (operands[1]) != CONST_DOUBLE
2873 || memory_operand (operands[0], XFmode))"
2875 switch (which_alternative)
2879 return output_387_reg_move (insn, operands);
2882 return standard_80387_constant_opcode (operands[1]);
2890 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2891 (set_attr "mode" "XF,XF,XF,SI,SI")])
2894 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2895 (match_operand:XF 1 "general_operand" ""))]
2897 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2898 && ! (ANY_FP_REG_P (operands[0]) ||
2899 (GET_CODE (operands[0]) == SUBREG
2900 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2901 && ! (ANY_FP_REG_P (operands[1]) ||
2902 (GET_CODE (operands[1]) == SUBREG
2903 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2905 "ix86_split_long_move (operands); DONE;")
2907 (define_insn "*movdf_internal_rex64"
2908 [(set (match_operand:DF 0 "nonimmediate_operand"
2909 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2910 (match_operand:DF 1 "general_operand"
2911 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2912 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2913 && (reload_in_progress || reload_completed
2914 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2915 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2916 && optimize_function_for_size_p (cfun)
2917 && standard_80387_constant_p (operands[1]))
2918 || GET_CODE (operands[1]) != CONST_DOUBLE
2919 || memory_operand (operands[0], DFmode))"
2921 switch (which_alternative)
2925 return output_387_reg_move (insn, operands);
2928 return standard_80387_constant_opcode (operands[1]);
2935 switch (get_attr_mode (insn))
2938 return "%vxorps\t%0, %d0";
2940 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2941 return "%vxorps\t%0, %d0";
2943 return "%vxorpd\t%0, %d0";
2945 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2946 return "%vxorps\t%0, %d0";
2948 return "%vpxor\t%0, %d0";
2955 switch (get_attr_mode (insn))
2958 return "%vmovaps\t{%1, %0|%0, %1}";
2960 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2961 return "%vmovaps\t{%1, %0|%0, %1}";
2963 return "%vmovapd\t{%1, %0|%0, %1}";
2965 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2966 return "%vmovaps\t{%1, %0|%0, %1}";
2968 return "%vmovdqa\t{%1, %0|%0, %1}";
2970 return "%vmovq\t{%1, %0|%0, %1}";
2974 if (REG_P (operands[0]) && REG_P (operands[1]))
2975 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2977 return "vmovsd\t{%1, %0|%0, %1}";
2980 return "movsd\t{%1, %0|%0, %1}";
2982 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2984 return "%vmovlps\t{%1, %d0|%d0, %1}";
2991 return "%vmovd\t{%1, %0|%0, %1}";
2997 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2998 (set (attr "prefix")
2999 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3000 (const_string "orig")
3001 (const_string "maybe_vex")))
3002 (set (attr "prefix_data16")
3003 (if_then_else (eq_attr "mode" "V1DF")
3005 (const_string "*")))
3007 (cond [(eq_attr "alternative" "0,1,2")
3009 (eq_attr "alternative" "3,4,9,10")
3012 /* For SSE1, we have many fewer alternatives. */
3013 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3014 (cond [(eq_attr "alternative" "5,6")
3015 (const_string "V4SF")
3017 (const_string "V2SF"))
3019 /* xorps is one byte shorter. */
3020 (eq_attr "alternative" "5")
3021 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3023 (const_string "V4SF")
3024 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3028 (const_string "V2DF"))
3030 /* For architectures resolving dependencies on
3031 whole SSE registers use APD move to break dependency
3032 chains, otherwise use short move to avoid extra work.
3034 movaps encodes one byte shorter. */
3035 (eq_attr "alternative" "6")
3037 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3039 (const_string "V4SF")
3040 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3042 (const_string "V2DF")
3044 (const_string "DF"))
3045 /* For architectures resolving dependencies on register
3046 parts we may avoid extra work to zero out upper part
3048 (eq_attr "alternative" "7")
3050 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3052 (const_string "V1DF")
3053 (const_string "DF"))
3055 (const_string "DF")))])
3057 (define_insn "*movdf_internal"
3058 [(set (match_operand:DF 0 "nonimmediate_operand"
3059 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3060 (match_operand:DF 1 "general_operand"
3061 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3062 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3063 && optimize_function_for_speed_p (cfun)
3064 && TARGET_INTEGER_DFMODE_MOVES
3065 && (reload_in_progress || reload_completed
3066 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3067 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3068 && optimize_function_for_size_p (cfun)
3069 && standard_80387_constant_p (operands[1]))
3070 || GET_CODE (operands[1]) != CONST_DOUBLE
3071 || memory_operand (operands[0], DFmode))"
3073 switch (which_alternative)
3077 return output_387_reg_move (insn, operands);
3080 return standard_80387_constant_opcode (operands[1]);
3087 switch (get_attr_mode (insn))
3090 return "xorps\t%0, %0";
3092 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093 return "xorps\t%0, %0";
3095 return "xorpd\t%0, %0";
3097 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3098 return "xorps\t%0, %0";
3100 return "pxor\t%0, %0";
3107 switch (get_attr_mode (insn))
3110 return "movaps\t{%1, %0|%0, %1}";
3112 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3113 return "movaps\t{%1, %0|%0, %1}";
3115 return "movapd\t{%1, %0|%0, %1}";
3117 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3118 return "movaps\t{%1, %0|%0, %1}";
3120 return "movdqa\t{%1, %0|%0, %1}";
3122 return "movq\t{%1, %0|%0, %1}";
3124 return "movsd\t{%1, %0|%0, %1}";
3126 return "movlpd\t{%1, %0|%0, %1}";
3128 return "movlps\t{%1, %0|%0, %1}";
3137 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3138 (set (attr "prefix_data16")
3139 (if_then_else (eq_attr "mode" "V1DF")
3141 (const_string "*")))
3143 (cond [(eq_attr "alternative" "0,1,2")
3145 (eq_attr "alternative" "3,4")
3148 /* For SSE1, we have many fewer alternatives. */
3149 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3150 (cond [(eq_attr "alternative" "5,6")
3151 (const_string "V4SF")
3153 (const_string "V2SF"))
3155 /* xorps is one byte shorter. */
3156 (eq_attr "alternative" "5")
3157 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3159 (const_string "V4SF")
3160 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3164 (const_string "V2DF"))
3166 /* For architectures resolving dependencies on
3167 whole SSE registers use APD move to break dependency
3168 chains, otherwise use short move to avoid extra work.
3170 movaps encodes one byte shorter. */
3171 (eq_attr "alternative" "6")
3173 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3175 (const_string "V4SF")
3176 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3178 (const_string "V2DF")
3180 (const_string "DF"))
3181 /* For architectures resolving dependencies on register
3182 parts we may avoid extra work to zero out upper part
3184 (eq_attr "alternative" "7")
3186 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3188 (const_string "V1DF")
3189 (const_string "DF"))
3191 (const_string "DF")))])
3193 ;; Moving is usually shorter when only FP registers are used. This separate
3194 ;; movdf pattern avoids the use of integer registers for FP operations
3195 ;; when optimizing for size.
3197 (define_insn "*movdf_internal_nointeger"
3198 [(set (match_operand:DF 0 "nonimmediate_operand"
3199 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3200 (match_operand:DF 1 "general_operand"
3201 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3202 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3203 && ((optimize_function_for_size_p (cfun)
3204 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3205 && (reload_in_progress || reload_completed
3206 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3207 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3208 && optimize_function_for_size_p (cfun)
3209 && !memory_operand (operands[0], DFmode)
3210 && standard_80387_constant_p (operands[1]))
3211 || GET_CODE (operands[1]) != CONST_DOUBLE
3212 || ((optimize_function_for_size_p (cfun)
3213 || !TARGET_MEMORY_MISMATCH_STALL
3214 || reload_in_progress || reload_completed)
3215 && memory_operand (operands[0], DFmode)))"
3217 switch (which_alternative)
3221 return output_387_reg_move (insn, operands);
3224 return standard_80387_constant_opcode (operands[1]);
3230 switch (get_attr_mode (insn))
3233 return "%vxorps\t%0, %d0";
3235 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3236 return "%vxorps\t%0, %d0";
3238 return "%vxorpd\t%0, %d0";
3240 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3241 return "%vxorps\t%0, %d0";
3243 return "%vpxor\t%0, %d0";
3250 switch (get_attr_mode (insn))
3253 return "%vmovaps\t{%1, %0|%0, %1}";
3255 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3256 return "%vmovaps\t{%1, %0|%0, %1}";
3258 return "%vmovapd\t{%1, %0|%0, %1}";
3260 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3261 return "%vmovaps\t{%1, %0|%0, %1}";
3263 return "%vmovdqa\t{%1, %0|%0, %1}";
3265 return "%vmovq\t{%1, %0|%0, %1}";
3269 if (REG_P (operands[0]) && REG_P (operands[1]))
3270 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3272 return "vmovsd\t{%1, %0|%0, %1}";
3275 return "movsd\t{%1, %0|%0, %1}";
3279 if (REG_P (operands[0]))
3280 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3282 return "vmovlpd\t{%1, %0|%0, %1}";
3285 return "movlpd\t{%1, %0|%0, %1}";
3289 if (REG_P (operands[0]))
3290 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3292 return "vmovlps\t{%1, %0|%0, %1}";
3295 return "movlps\t{%1, %0|%0, %1}";
3304 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3305 (set (attr "prefix")
3306 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3307 (const_string "orig")
3308 (const_string "maybe_vex")))
3309 (set (attr "prefix_data16")
3310 (if_then_else (eq_attr "mode" "V1DF")
3312 (const_string "*")))
3314 (cond [(eq_attr "alternative" "0,1,2")
3316 (eq_attr "alternative" "3,4")
3319 /* For SSE1, we have many fewer alternatives. */
3320 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3321 (cond [(eq_attr "alternative" "5,6")
3322 (const_string "V4SF")
3324 (const_string "V2SF"))
3326 /* xorps is one byte shorter. */
3327 (eq_attr "alternative" "5")
3328 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3330 (const_string "V4SF")
3331 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3335 (const_string "V2DF"))
3337 /* For architectures resolving dependencies on
3338 whole SSE registers use APD move to break dependency
3339 chains, otherwise use short move to avoid extra work.
3341 movaps encodes one byte shorter. */
3342 (eq_attr "alternative" "6")
3344 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3346 (const_string "V4SF")
3347 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3349 (const_string "V2DF")
3351 (const_string "DF"))
3352 /* For architectures resolving dependencies on register
3353 parts we may avoid extra work to zero out upper part
3355 (eq_attr "alternative" "7")
3357 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3359 (const_string "V1DF")
3360 (const_string "DF"))
3362 (const_string "DF")))])
3365 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3366 (match_operand:DF 1 "general_operand" ""))]
3368 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3369 && ! (ANY_FP_REG_P (operands[0]) ||
3370 (GET_CODE (operands[0]) == SUBREG
3371 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3372 && ! (ANY_FP_REG_P (operands[1]) ||
3373 (GET_CODE (operands[1]) == SUBREG
3374 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3376 "ix86_split_long_move (operands); DONE;")
3378 (define_insn "*movsf_internal"
3379 [(set (match_operand:SF 0 "nonimmediate_operand"
3380 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3381 (match_operand:SF 1 "general_operand"
3382 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3383 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3384 && (reload_in_progress || reload_completed
3385 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3386 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3387 && standard_80387_constant_p (operands[1]))
3388 || GET_CODE (operands[1]) != CONST_DOUBLE
3389 || memory_operand (operands[0], SFmode))"
3391 switch (which_alternative)
3395 return output_387_reg_move (insn, operands);
3398 return standard_80387_constant_opcode (operands[1]);
3402 return "mov{l}\t{%1, %0|%0, %1}";
3404 if (get_attr_mode (insn) == MODE_TI)
3405 return "%vpxor\t%0, %d0";
3407 return "%vxorps\t%0, %d0";
3409 if (get_attr_mode (insn) == MODE_V4SF)
3410 return "%vmovaps\t{%1, %0|%0, %1}";
3412 return "%vmovss\t{%1, %d0|%d0, %1}";
3415 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3416 : "vmovss\t{%1, %0|%0, %1}";
3418 return "movss\t{%1, %0|%0, %1}";
3420 return "%vmovss\t{%1, %0|%0, %1}";
3422 case 9: case 10: case 14: case 15:
3423 return "movd\t{%1, %0|%0, %1}";
3425 return "%vmovd\t{%1, %0|%0, %1}";
3428 return "movq\t{%1, %0|%0, %1}";
3434 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3435 (set (attr "prefix")
3436 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3437 (const_string "maybe_vex")
3438 (const_string "orig")))
3440 (cond [(eq_attr "alternative" "3,4,9,10")
3442 (eq_attr "alternative" "5")
3444 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3446 (ne (symbol_ref "TARGET_SSE2")
3448 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3451 (const_string "V4SF"))
3452 /* For architectures resolving dependencies on
3453 whole SSE registers use APS move to break dependency
3454 chains, otherwise use short move to avoid extra work.
3456 Do the same for architectures resolving dependencies on
3457 the parts. While in DF mode it is better to always handle
3458 just register parts, the SF mode is different due to lack
3459 of instructions to load just part of the register. It is
3460 better to maintain the whole registers in single format
3461 to avoid problems on using packed logical operations. */
3462 (eq_attr "alternative" "6")
3464 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3466 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3468 (const_string "V4SF")
3469 (const_string "SF"))
3470 (eq_attr "alternative" "11")
3471 (const_string "DI")]
3472 (const_string "SF")))])
3475 [(set (match_operand 0 "register_operand" "")
3476 (match_operand 1 "memory_operand" ""))]
3478 && MEM_P (operands[1])
3479 && (GET_MODE (operands[0]) == TFmode
3480 || GET_MODE (operands[0]) == XFmode
3481 || GET_MODE (operands[0]) == DFmode
3482 || GET_MODE (operands[0]) == SFmode)
3483 && (operands[2] = find_constant_src (insn))"
3484 [(set (match_dup 0) (match_dup 2))]
3486 rtx c = operands[2];
3487 rtx r = operands[0];
3489 if (GET_CODE (r) == SUBREG)
3494 if (!standard_sse_constant_p (c))
3497 else if (FP_REG_P (r))
3499 if (!standard_80387_constant_p (c))
3502 else if (MMX_REG_P (r))
3507 [(set (match_operand 0 "register_operand" "")
3508 (float_extend (match_operand 1 "memory_operand" "")))]
3510 && MEM_P (operands[1])
3511 && (GET_MODE (operands[0]) == TFmode
3512 || GET_MODE (operands[0]) == XFmode
3513 || GET_MODE (operands[0]) == DFmode
3514 || GET_MODE (operands[0]) == SFmode)
3515 && (operands[2] = find_constant_src (insn))"
3516 [(set (match_dup 0) (match_dup 2))]
3518 rtx c = operands[2];
3519 rtx r = operands[0];
3521 if (GET_CODE (r) == SUBREG)
3526 if (!standard_sse_constant_p (c))
3529 else if (FP_REG_P (r))
3531 if (!standard_80387_constant_p (c))
3534 else if (MMX_REG_P (r))
3538 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3540 [(set (match_operand:X87MODEF 0 "register_operand" "")
3541 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3542 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3543 && (standard_80387_constant_p (operands[1]) == 8
3544 || standard_80387_constant_p (operands[1]) == 9)"
3545 [(set (match_dup 0)(match_dup 1))
3547 (neg:X87MODEF (match_dup 0)))]
3551 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3552 if (real_isnegzero (&r))
3553 operands[1] = CONST0_RTX (<MODE>mode);
3555 operands[1] = CONST1_RTX (<MODE>mode);
3558 (define_insn "swapxf"
3559 [(set (match_operand:XF 0 "register_operand" "+f")
3560 (match_operand:XF 1 "register_operand" "+f"))
3565 if (STACK_TOP_P (operands[0]))
3570 [(set_attr "type" "fxch")
3571 (set_attr "mode" "XF")])
3573 (define_insn "*swap<mode>"
3574 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3575 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3578 "TARGET_80387 || reload_completed"
3580 if (STACK_TOP_P (operands[0]))
3585 [(set_attr "type" "fxch")
3586 (set_attr "mode" "<MODE>")])
3588 ;; Zero extension instructions
3590 (define_expand "zero_extendhisi2"
3591 [(set (match_operand:SI 0 "register_operand" "")
3592 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3595 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3597 operands[1] = force_reg (HImode, operands[1]);
3598 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3603 (define_insn "zero_extendhisi2_and"
3604 [(set (match_operand:SI 0 "register_operand" "=r")
3605 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3606 (clobber (reg:CC FLAGS_REG))]
3607 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3609 [(set_attr "type" "alu1")
3610 (set_attr "mode" "SI")])
3613 [(set (match_operand:SI 0 "register_operand" "")
3614 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3615 (clobber (reg:CC FLAGS_REG))]
3616 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3617 && optimize_function_for_speed_p (cfun)"
3618 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3619 (clobber (reg:CC FLAGS_REG))])]
3622 (define_insn "*zero_extendhisi2_movzwl"
3623 [(set (match_operand:SI 0 "register_operand" "=r")
3624 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3625 "!TARGET_ZERO_EXTEND_WITH_AND
3626 || optimize_function_for_size_p (cfun)"
3627 "movz{wl|x}\t{%1, %0|%0, %1}"
3628 [(set_attr "type" "imovx")
3629 (set_attr "mode" "SI")])
3631 (define_expand "zero_extendqihi2"
3633 [(set (match_operand:HI 0 "register_operand" "")
3634 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3635 (clobber (reg:CC FLAGS_REG))])]
3639 (define_insn "*zero_extendqihi2_and"
3640 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3641 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3642 (clobber (reg:CC FLAGS_REG))]
3643 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3645 [(set_attr "type" "alu1")
3646 (set_attr "mode" "HI")])
3648 (define_insn "*zero_extendqihi2_movzbw_and"
3649 [(set (match_operand:HI 0 "register_operand" "=r,r")
3650 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3651 (clobber (reg:CC FLAGS_REG))]
3652 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3654 [(set_attr "type" "imovx,alu1")
3655 (set_attr "mode" "HI")])
3657 ; zero extend to SImode here to avoid partial register stalls
3658 (define_insn "*zero_extendqihi2_movzbl"
3659 [(set (match_operand:HI 0 "register_operand" "=r")
3660 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3661 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3662 && reload_completed"
3663 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3664 [(set_attr "type" "imovx")
3665 (set_attr "mode" "SI")])
3667 ;; For the movzbw case strip only the clobber
3669 [(set (match_operand:HI 0 "register_operand" "")
3670 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3671 (clobber (reg:CC FLAGS_REG))]
3673 && (!TARGET_ZERO_EXTEND_WITH_AND
3674 || optimize_function_for_size_p (cfun))
3675 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3676 [(set (match_operand:HI 0 "register_operand" "")
3677 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3679 ;; When source and destination does not overlap, clear destination
3680 ;; first and then do the movb
3682 [(set (match_operand:HI 0 "register_operand" "")
3683 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3684 (clobber (reg:CC FLAGS_REG))]
3686 && ANY_QI_REG_P (operands[0])
3687 && (TARGET_ZERO_EXTEND_WITH_AND
3688 && optimize_function_for_speed_p (cfun))
3689 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3690 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3692 operands[2] = gen_lowpart (QImode, operands[0]);
3693 ix86_expand_clear (operands[0]);
3696 ;; Rest is handled by single and.
3698 [(set (match_operand:HI 0 "register_operand" "")
3699 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3700 (clobber (reg:CC FLAGS_REG))]
3702 && true_regnum (operands[0]) == true_regnum (operands[1])"
3703 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3704 (clobber (reg:CC FLAGS_REG))])]
3707 (define_expand "zero_extendqisi2"
3709 [(set (match_operand:SI 0 "register_operand" "")
3710 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3711 (clobber (reg:CC FLAGS_REG))])]
3715 (define_insn "*zero_extendqisi2_and"
3716 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3717 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3718 (clobber (reg:CC FLAGS_REG))]
3719 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3721 [(set_attr "type" "alu1")
3722 (set_attr "mode" "SI")])
3724 (define_insn "*zero_extendqisi2_movzbl_and"
3725 [(set (match_operand:SI 0 "register_operand" "=r,r")
3726 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3727 (clobber (reg:CC FLAGS_REG))]
3728 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3730 [(set_attr "type" "imovx,alu1")
3731 (set_attr "mode" "SI")])
3733 (define_insn "*zero_extendqisi2_movzbl"
3734 [(set (match_operand:SI 0 "register_operand" "=r")
3735 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3736 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3737 && reload_completed"
3738 "movz{bl|x}\t{%1, %0|%0, %1}"
3739 [(set_attr "type" "imovx")
3740 (set_attr "mode" "SI")])
3742 ;; For the movzbl case strip only the clobber
3744 [(set (match_operand:SI 0 "register_operand" "")
3745 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3746 (clobber (reg:CC FLAGS_REG))]
3748 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3749 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3751 (zero_extend:SI (match_dup 1)))])
3753 ;; When source and destination does not overlap, clear destination
3754 ;; first and then do the movb
3756 [(set (match_operand:SI 0 "register_operand" "")
3757 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3758 (clobber (reg:CC FLAGS_REG))]
3760 && ANY_QI_REG_P (operands[0])
3761 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3762 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3763 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3764 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3766 operands[2] = gen_lowpart (QImode, operands[0]);
3767 ix86_expand_clear (operands[0]);
3770 ;; Rest is handled by single and.
3772 [(set (match_operand:SI 0 "register_operand" "")
3773 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3774 (clobber (reg:CC FLAGS_REG))]
3776 && true_regnum (operands[0]) == true_regnum (operands[1])"
3777 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3778 (clobber (reg:CC FLAGS_REG))])]
3781 ;; %%% Kill me once multi-word ops are sane.
3782 (define_expand "zero_extendsidi2"
3783 [(set (match_operand:DI 0 "register_operand" "")
3784 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3789 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3794 (define_insn "zero_extendsidi2_32"
3795 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3797 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3798 (clobber (reg:CC FLAGS_REG))]
3804 movd\t{%1, %0|%0, %1}
3805 movd\t{%1, %0|%0, %1}
3806 %vmovd\t{%1, %0|%0, %1}
3807 %vmovd\t{%1, %0|%0, %1}"
3808 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3809 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3810 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3812 (define_insn "zero_extendsidi2_rex64"
3813 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3815 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3818 mov\t{%k1, %k0|%k0, %k1}
3820 movd\t{%1, %0|%0, %1}
3821 movd\t{%1, %0|%0, %1}
3822 %vmovd\t{%1, %0|%0, %1}
3823 %vmovd\t{%1, %0|%0, %1}"
3824 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3825 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3826 (set_attr "prefix_0f" "0,*,*,*,*,*")
3827 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3830 [(set (match_operand:DI 0 "memory_operand" "")
3831 (zero_extend:DI (match_dup 0)))]
3833 [(set (match_dup 4) (const_int 0))]
3834 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3837 [(set (match_operand:DI 0 "register_operand" "")
3838 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3839 (clobber (reg:CC FLAGS_REG))]
3840 "!TARGET_64BIT && reload_completed
3841 && true_regnum (operands[0]) == true_regnum (operands[1])"
3842 [(set (match_dup 4) (const_int 0))]
3843 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3846 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3847 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3848 (clobber (reg:CC FLAGS_REG))]
3849 "!TARGET_64BIT && reload_completed
3850 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3851 [(set (match_dup 3) (match_dup 1))
3852 (set (match_dup 4) (const_int 0))]
3853 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3855 (define_insn "zero_extendhidi2"
3856 [(set (match_operand:DI 0 "register_operand" "=r")
3857 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3859 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3860 [(set_attr "type" "imovx")
3861 (set_attr "mode" "SI")])
3863 (define_insn "zero_extendqidi2"
3864 [(set (match_operand:DI 0 "register_operand" "=r")
3865 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3867 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3868 [(set_attr "type" "imovx")
3869 (set_attr "mode" "SI")])
3871 ;; Sign extension instructions
3873 (define_expand "extendsidi2"
3874 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3875 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3876 (clobber (reg:CC FLAGS_REG))
3877 (clobber (match_scratch:SI 2 ""))])]
3882 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3887 (define_insn "*extendsidi2_1"
3888 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3889 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3890 (clobber (reg:CC FLAGS_REG))
3891 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3895 (define_insn "extendsidi2_rex64"
3896 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3897 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3901 movs{lq|x}\t{%1, %0|%0, %1}"
3902 [(set_attr "type" "imovx")
3903 (set_attr "mode" "DI")
3904 (set_attr "prefix_0f" "0")
3905 (set_attr "modrm" "0,1")])
3907 (define_insn "extendhidi2"
3908 [(set (match_operand:DI 0 "register_operand" "=r")
3909 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3911 "movs{wq|x}\t{%1, %0|%0, %1}"
3912 [(set_attr "type" "imovx")
3913 (set_attr "mode" "DI")])
3915 (define_insn "extendqidi2"
3916 [(set (match_operand:DI 0 "register_operand" "=r")
3917 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3919 "movs{bq|x}\t{%1, %0|%0, %1}"
3920 [(set_attr "type" "imovx")
3921 (set_attr "mode" "DI")])
3923 ;; Extend to memory case when source register does die.
3925 [(set (match_operand:DI 0 "memory_operand" "")
3926 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3927 (clobber (reg:CC FLAGS_REG))
3928 (clobber (match_operand:SI 2 "register_operand" ""))]
3930 && dead_or_set_p (insn, operands[1])
3931 && !reg_mentioned_p (operands[1], operands[0]))"
3932 [(set (match_dup 3) (match_dup 1))
3933 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3934 (clobber (reg:CC FLAGS_REG))])
3935 (set (match_dup 4) (match_dup 1))]
3936 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3938 ;; Extend to memory case when source register does not die.
3940 [(set (match_operand:DI 0 "memory_operand" "")
3941 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3942 (clobber (reg:CC FLAGS_REG))
3943 (clobber (match_operand:SI 2 "register_operand" ""))]
3947 split_di (&operands[0], 1, &operands[3], &operands[4]);
3949 emit_move_insn (operands[3], operands[1]);
3951 /* Generate a cltd if possible and doing so it profitable. */
3952 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3953 && true_regnum (operands[1]) == AX_REG
3954 && true_regnum (operands[2]) == DX_REG)
3956 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3960 emit_move_insn (operands[2], operands[1]);
3961 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3963 emit_move_insn (operands[4], operands[2]);
3967 ;; Extend to register case. Optimize case where source and destination
3968 ;; registers match and cases where we can use cltd.
3970 [(set (match_operand:DI 0 "register_operand" "")
3971 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3972 (clobber (reg:CC FLAGS_REG))
3973 (clobber (match_scratch:SI 2 ""))]
3977 split_di (&operands[0], 1, &operands[3], &operands[4]);
3979 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3980 emit_move_insn (operands[3], operands[1]);
3982 /* Generate a cltd if possible and doing so it profitable. */
3983 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3984 && true_regnum (operands[3]) == AX_REG
3985 && true_regnum (operands[4]) == DX_REG)
3987 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3991 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3992 emit_move_insn (operands[4], operands[1]);
3994 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3998 (define_insn "extendhisi2"
3999 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4000 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4003 switch (get_attr_prefix_0f (insn))
4006 return "{cwtl|cwde}";
4008 return "movs{wl|x}\t{%1, %0|%0, %1}";
4011 [(set_attr "type" "imovx")
4012 (set_attr "mode" "SI")
4013 (set (attr "prefix_0f")
4014 ;; movsx is short decodable while cwtl is vector decoded.
4015 (if_then_else (and (eq_attr "cpu" "!k6")
4016 (eq_attr "alternative" "0"))
4018 (const_string "1")))
4020 (if_then_else (eq_attr "prefix_0f" "0")
4022 (const_string "1")))])
4024 (define_insn "*extendhisi2_zext"
4025 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4027 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4030 switch (get_attr_prefix_0f (insn))
4033 return "{cwtl|cwde}";
4035 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4038 [(set_attr "type" "imovx")
4039 (set_attr "mode" "SI")
4040 (set (attr "prefix_0f")
4041 ;; movsx is short decodable while cwtl is vector decoded.
4042 (if_then_else (and (eq_attr "cpu" "!k6")
4043 (eq_attr "alternative" "0"))
4045 (const_string "1")))
4047 (if_then_else (eq_attr "prefix_0f" "0")
4049 (const_string "1")))])
4051 (define_insn "extendqihi2"
4052 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4053 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4056 switch (get_attr_prefix_0f (insn))
4059 return "{cbtw|cbw}";
4061 return "movs{bw|x}\t{%1, %0|%0, %1}";
4064 [(set_attr "type" "imovx")
4065 (set_attr "mode" "HI")
4066 (set (attr "prefix_0f")
4067 ;; movsx is short decodable while cwtl is vector decoded.
4068 (if_then_else (and (eq_attr "cpu" "!k6")
4069 (eq_attr "alternative" "0"))
4071 (const_string "1")))
4073 (if_then_else (eq_attr "prefix_0f" "0")
4075 (const_string "1")))])
4077 (define_insn "extendqisi2"
4078 [(set (match_operand:SI 0 "register_operand" "=r")
4079 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4081 "movs{bl|x}\t{%1, %0|%0, %1}"
4082 [(set_attr "type" "imovx")
4083 (set_attr "mode" "SI")])
4085 (define_insn "*extendqisi2_zext"
4086 [(set (match_operand:DI 0 "register_operand" "=r")
4088 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4090 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4091 [(set_attr "type" "imovx")
4092 (set_attr "mode" "SI")])
4094 ;; Conversions between float and double.
4096 ;; These are all no-ops in the model used for the 80387. So just
4099 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4100 (define_insn "*dummy_extendsfdf2"
4101 [(set (match_operand:DF 0 "push_operand" "=<")
4102 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4107 [(set (match_operand:DF 0 "push_operand" "")
4108 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4110 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4111 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4113 (define_insn "*dummy_extendsfxf2"
4114 [(set (match_operand:XF 0 "push_operand" "=<")
4115 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4120 [(set (match_operand:XF 0 "push_operand" "")
4121 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4123 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4124 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4125 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4128 [(set (match_operand:XF 0 "push_operand" "")
4129 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4131 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4132 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4133 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4135 (define_expand "extendsfdf2"
4136 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4137 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4138 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4140 /* ??? Needed for compress_float_constant since all fp constants
4141 are LEGITIMATE_CONSTANT_P. */
4142 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4144 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4145 && standard_80387_constant_p (operands[1]) > 0)
4147 operands[1] = simplify_const_unary_operation
4148 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4149 emit_move_insn_1 (operands[0], operands[1]);
4152 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4156 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4158 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4160 We do the conversion post reload to avoid producing of 128bit spills
4161 that might lead to ICE on 32bit target. The sequence unlikely combine
4164 [(set (match_operand:DF 0 "register_operand" "")
4166 (match_operand:SF 1 "nonimmediate_operand" "")))]
4167 "TARGET_USE_VECTOR_FP_CONVERTS
4168 && optimize_insn_for_speed_p ()
4169 && reload_completed && SSE_REG_P (operands[0])"
4174 (parallel [(const_int 0) (const_int 1)]))))]
4176 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4177 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4178 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4179 Try to avoid move when unpacking can be done in source. */
4180 if (REG_P (operands[1]))
4182 /* If it is unsafe to overwrite upper half of source, we need
4183 to move to destination and unpack there. */
4184 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4185 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4186 && true_regnum (operands[0]) != true_regnum (operands[1]))
4188 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4189 emit_move_insn (tmp, operands[1]);
4192 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4193 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4197 emit_insn (gen_vec_setv4sf_0 (operands[3],
4198 CONST0_RTX (V4SFmode), operands[1]));
4201 (define_insn "*extendsfdf2_mixed"
4202 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4204 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4205 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4207 switch (which_alternative)
4211 return output_387_reg_move (insn, operands);
4214 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4220 [(set_attr "type" "fmov,fmov,ssecvt")
4221 (set_attr "prefix" "orig,orig,maybe_vex")
4222 (set_attr "mode" "SF,XF,DF")])
4224 (define_insn "*extendsfdf2_sse"
4225 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4226 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4227 "TARGET_SSE2 && TARGET_SSE_MATH"
4228 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4229 [(set_attr "type" "ssecvt")
4230 (set_attr "prefix" "maybe_vex")
4231 (set_attr "mode" "DF")])
4233 (define_insn "*extendsfdf2_i387"
4234 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4235 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4237 "* return output_387_reg_move (insn, operands);"
4238 [(set_attr "type" "fmov")
4239 (set_attr "mode" "SF,XF")])
4241 (define_expand "extend<mode>xf2"
4242 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4243 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4246 /* ??? Needed for compress_float_constant since all fp constants
4247 are LEGITIMATE_CONSTANT_P. */
4248 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4250 if (standard_80387_constant_p (operands[1]) > 0)
4252 operands[1] = simplify_const_unary_operation
4253 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4254 emit_move_insn_1 (operands[0], operands[1]);
4257 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4261 (define_insn "*extend<mode>xf2_i387"
4262 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4264 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4266 "* return output_387_reg_move (insn, operands);"
4267 [(set_attr "type" "fmov")
4268 (set_attr "mode" "<MODE>,XF")])
4270 ;; %%% This seems bad bad news.
4271 ;; This cannot output into an f-reg because there is no way to be sure
4272 ;; of truncating in that case. Otherwise this is just like a simple move
4273 ;; insn. So we pretend we can output to a reg in order to get better
4274 ;; register preferencing, but we really use a stack slot.
4276 ;; Conversion from DFmode to SFmode.
4278 (define_expand "truncdfsf2"
4279 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4281 (match_operand:DF 1 "nonimmediate_operand" "")))]
4282 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4284 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4286 else if (flag_unsafe_math_optimizations)
4290 enum ix86_stack_slot slot = (virtuals_instantiated
4293 rtx temp = assign_386_stack_local (SFmode, slot);
4294 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4299 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4301 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4303 We do the conversion post reload to avoid producing of 128bit spills
4304 that might lead to ICE on 32bit target. The sequence unlikely combine
4307 [(set (match_operand:SF 0 "register_operand" "")
4309 (match_operand:DF 1 "nonimmediate_operand" "")))]
4310 "TARGET_USE_VECTOR_FP_CONVERTS
4311 && optimize_insn_for_speed_p ()
4312 && reload_completed && SSE_REG_P (operands[0])"
4315 (float_truncate:V2SF
4319 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4320 operands[3] = CONST0_RTX (V2SFmode);
4321 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4322 /* Use movsd for loading from memory, unpcklpd for registers.
4323 Try to avoid move when unpacking can be done in source, or SSE3
4324 movddup is available. */
4325 if (REG_P (operands[1]))
4328 && true_regnum (operands[0]) != true_regnum (operands[1])
4329 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4330 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4332 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4333 emit_move_insn (tmp, operands[1]);
4336 else if (!TARGET_SSE3)
4337 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4338 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4341 emit_insn (gen_sse2_loadlpd (operands[4],
4342 CONST0_RTX (V2DFmode), operands[1]));
4345 (define_expand "truncdfsf2_with_temp"
4346 [(parallel [(set (match_operand:SF 0 "" "")
4347 (float_truncate:SF (match_operand:DF 1 "" "")))
4348 (clobber (match_operand:SF 2 "" ""))])]
4351 (define_insn "*truncdfsf_fast_mixed"
4352 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4354 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4355 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4357 switch (which_alternative)
4360 return output_387_reg_move (insn, operands);
4362 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4367 [(set_attr "type" "fmov,ssecvt")
4368 (set_attr "prefix" "orig,maybe_vex")
4369 (set_attr "mode" "SF")])
4371 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4372 ;; because nothing we do here is unsafe.
4373 (define_insn "*truncdfsf_fast_sse"
4374 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4376 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4377 "TARGET_SSE2 && TARGET_SSE_MATH"
4378 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4379 [(set_attr "type" "ssecvt")
4380 (set_attr "prefix" "maybe_vex")
4381 (set_attr "mode" "SF")])
4383 (define_insn "*truncdfsf_fast_i387"
4384 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4386 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4387 "TARGET_80387 && flag_unsafe_math_optimizations"
4388 "* return output_387_reg_move (insn, operands);"
4389 [(set_attr "type" "fmov")
4390 (set_attr "mode" "SF")])
4392 (define_insn "*truncdfsf_mixed"
4393 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4395 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4396 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4397 "TARGET_MIX_SSE_I387"
4399 switch (which_alternative)
4402 return output_387_reg_move (insn, operands);
4404 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4410 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4411 (set_attr "unit" "*,*,i387,i387,i387")
4412 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4413 (set_attr "mode" "SF")])
4415 (define_insn "*truncdfsf_i387"
4416 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4418 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4419 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4422 switch (which_alternative)
4425 return output_387_reg_move (insn, operands);
4431 [(set_attr "type" "fmov,multi,multi,multi")
4432 (set_attr "unit" "*,i387,i387,i387")
4433 (set_attr "mode" "SF")])
4435 (define_insn "*truncdfsf2_i387_1"
4436 [(set (match_operand:SF 0 "memory_operand" "=m")
4438 (match_operand:DF 1 "register_operand" "f")))]
4440 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4441 && !TARGET_MIX_SSE_I387"
4442 "* return output_387_reg_move (insn, operands);"
4443 [(set_attr "type" "fmov")
4444 (set_attr "mode" "SF")])
4447 [(set (match_operand:SF 0 "register_operand" "")
4449 (match_operand:DF 1 "fp_register_operand" "")))
4450 (clobber (match_operand 2 "" ""))]
4452 [(set (match_dup 2) (match_dup 1))
4453 (set (match_dup 0) (match_dup 2))]
4455 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4458 ;; Conversion from XFmode to {SF,DF}mode
4460 (define_expand "truncxf<mode>2"
4461 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4462 (float_truncate:MODEF
4463 (match_operand:XF 1 "register_operand" "")))
4464 (clobber (match_dup 2))])]
4467 if (flag_unsafe_math_optimizations)
4469 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4470 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4471 if (reg != operands[0])
4472 emit_move_insn (operands[0], reg);
4477 enum ix86_stack_slot slot = (virtuals_instantiated
4480 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4484 (define_insn "*truncxfsf2_mixed"
4485 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4487 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4488 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4491 gcc_assert (!which_alternative);
4492 return output_387_reg_move (insn, operands);
4494 [(set_attr "type" "fmov,multi,multi,multi")
4495 (set_attr "unit" "*,i387,i387,i387")
4496 (set_attr "mode" "SF")])
4498 (define_insn "*truncxfdf2_mixed"
4499 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4501 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4502 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4505 gcc_assert (!which_alternative);
4506 return output_387_reg_move (insn, operands);
4508 [(set_attr "type" "fmov,multi,multi,multi")
4509 (set_attr "unit" "*,i387,i387,i387")
4510 (set_attr "mode" "DF")])
4512 (define_insn "truncxf<mode>2_i387_noop"
4513 [(set (match_operand:MODEF 0 "register_operand" "=f")
4514 (float_truncate:MODEF
4515 (match_operand:XF 1 "register_operand" "f")))]
4516 "TARGET_80387 && flag_unsafe_math_optimizations"
4517 "* return output_387_reg_move (insn, operands);"
4518 [(set_attr "type" "fmov")
4519 (set_attr "mode" "<MODE>")])
4521 (define_insn "*truncxf<mode>2_i387"
4522 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4523 (float_truncate:MODEF
4524 (match_operand:XF 1 "register_operand" "f")))]
4526 "* return output_387_reg_move (insn, operands);"
4527 [(set_attr "type" "fmov")
4528 (set_attr "mode" "<MODE>")])
4531 [(set (match_operand:MODEF 0 "register_operand" "")
4532 (float_truncate:MODEF
4533 (match_operand:XF 1 "register_operand" "")))
4534 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4535 "TARGET_80387 && reload_completed"
4536 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4537 (set (match_dup 0) (match_dup 2))]
4541 [(set (match_operand:MODEF 0 "memory_operand" "")
4542 (float_truncate:MODEF
4543 (match_operand:XF 1 "register_operand" "")))
4544 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4546 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4549 ;; Signed conversion to DImode.
4551 (define_expand "fix_truncxfdi2"
4552 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4553 (fix:DI (match_operand:XF 1 "register_operand" "")))
4554 (clobber (reg:CC FLAGS_REG))])]
4559 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4564 (define_expand "fix_trunc<mode>di2"
4565 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4566 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4567 (clobber (reg:CC FLAGS_REG))])]
4568 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4571 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4573 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4576 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4578 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4579 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4580 if (out != operands[0])
4581 emit_move_insn (operands[0], out);
4586 ;; Signed conversion to SImode.
4588 (define_expand "fix_truncxfsi2"
4589 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4590 (fix:SI (match_operand:XF 1 "register_operand" "")))
4591 (clobber (reg:CC FLAGS_REG))])]
4596 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4601 (define_expand "fix_trunc<mode>si2"
4602 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4603 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4604 (clobber (reg:CC FLAGS_REG))])]
4605 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4608 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4610 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4613 if (SSE_FLOAT_MODE_P (<MODE>mode))
4615 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4616 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4617 if (out != operands[0])
4618 emit_move_insn (operands[0], out);
4623 ;; Signed conversion to HImode.
4625 (define_expand "fix_trunc<mode>hi2"
4626 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4627 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4628 (clobber (reg:CC FLAGS_REG))])]
4630 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4634 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4639 ;; Unsigned conversion to SImode.
4641 (define_expand "fixuns_trunc<mode>si2"
4643 [(set (match_operand:SI 0 "register_operand" "")
4645 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4647 (clobber (match_scratch:<ssevecmode> 3 ""))
4648 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4649 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4651 enum machine_mode mode = <MODE>mode;
4652 enum machine_mode vecmode = <ssevecmode>mode;
4653 REAL_VALUE_TYPE TWO31r;
4656 if (optimize_insn_for_size_p ())
4659 real_ldexp (&TWO31r, &dconst1, 31);
4660 two31 = const_double_from_real_value (TWO31r, mode);
4661 two31 = ix86_build_const_vector (mode, true, two31);
4662 operands[2] = force_reg (vecmode, two31);
4665 (define_insn_and_split "*fixuns_trunc<mode>_1"
4666 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4668 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4669 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4670 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4671 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4672 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4673 && optimize_function_for_speed_p (cfun)"
4675 "&& reload_completed"
4678 ix86_split_convert_uns_si_sse (operands);
4682 ;; Unsigned conversion to HImode.
4683 ;; Without these patterns, we'll try the unsigned SI conversion which
4684 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4686 (define_expand "fixuns_trunc<mode>hi2"
4688 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4689 (set (match_operand:HI 0 "nonimmediate_operand" "")
4690 (subreg:HI (match_dup 2) 0))]
4691 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4692 "operands[2] = gen_reg_rtx (SImode);")
4694 ;; When SSE is available, it is always faster to use it!
4695 (define_insn "fix_trunc<mode>di_sse"
4696 [(set (match_operand:DI 0 "register_operand" "=r,r")
4697 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4698 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4699 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4700 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4701 [(set_attr "type" "sseicvt")
4702 (set_attr "prefix" "maybe_vex")
4703 (set_attr "prefix_rex" "1")
4704 (set_attr "mode" "<MODE>")
4705 (set_attr "athlon_decode" "double,vector")
4706 (set_attr "amdfam10_decode" "double,double")])
4708 (define_insn "fix_trunc<mode>si_sse"
4709 [(set (match_operand:SI 0 "register_operand" "=r,r")
4710 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4711 "SSE_FLOAT_MODE_P (<MODE>mode)
4712 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4713 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4714 [(set_attr "type" "sseicvt")
4715 (set_attr "prefix" "maybe_vex")
4716 (set_attr "mode" "<MODE>")
4717 (set_attr "athlon_decode" "double,vector")
4718 (set_attr "amdfam10_decode" "double,double")])
4720 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4722 [(set (match_operand:MODEF 0 "register_operand" "")
4723 (match_operand:MODEF 1 "memory_operand" ""))
4724 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4725 (fix:SSEMODEI24 (match_dup 0)))]
4726 "TARGET_SHORTEN_X87_SSE
4727 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4728 && peep2_reg_dead_p (2, operands[0])"
4729 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4732 ;; Avoid vector decoded forms of the instruction.
4734 [(match_scratch:DF 2 "Y2")
4735 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4736 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4737 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4738 [(set (match_dup 2) (match_dup 1))
4739 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4743 [(match_scratch:SF 2 "x")
4744 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4745 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4746 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4747 [(set (match_dup 2) (match_dup 1))
4748 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4751 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4752 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4753 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4754 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4756 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4757 && (TARGET_64BIT || <MODE>mode != DImode))
4759 && can_create_pseudo_p ()"
4764 if (memory_operand (operands[0], VOIDmode))
4765 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4768 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4769 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4775 [(set_attr "type" "fisttp")
4776 (set_attr "mode" "<MODE>")])
4778 (define_insn "fix_trunc<mode>_i387_fisttp"
4779 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4780 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4781 (clobber (match_scratch:XF 2 "=&1f"))]
4782 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4784 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4785 && (TARGET_64BIT || <MODE>mode != DImode))
4786 && TARGET_SSE_MATH)"
4787 "* return output_fix_trunc (insn, operands, 1);"
4788 [(set_attr "type" "fisttp")
4789 (set_attr "mode" "<MODE>")])
4791 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4792 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4793 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4794 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4795 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4796 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4798 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4799 && (TARGET_64BIT || <MODE>mode != DImode))
4800 && TARGET_SSE_MATH)"
4802 [(set_attr "type" "fisttp")
4803 (set_attr "mode" "<MODE>")])
4806 [(set (match_operand:X87MODEI 0 "register_operand" "")
4807 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4808 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4809 (clobber (match_scratch 3 ""))]
4811 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4812 (clobber (match_dup 3))])
4813 (set (match_dup 0) (match_dup 2))]
4817 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4818 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4819 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4820 (clobber (match_scratch 3 ""))]
4822 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4823 (clobber (match_dup 3))])]
4826 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4827 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4828 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4829 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4830 ;; function in i386.c.
4831 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4832 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4833 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4834 (clobber (reg:CC FLAGS_REG))]
4835 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4837 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4838 && (TARGET_64BIT || <MODE>mode != DImode))
4839 && can_create_pseudo_p ()"
4844 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4846 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4847 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4848 if (memory_operand (operands[0], VOIDmode))
4849 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4850 operands[2], operands[3]));
4853 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4854 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4855 operands[2], operands[3],
4860 [(set_attr "type" "fistp")
4861 (set_attr "i387_cw" "trunc")
4862 (set_attr "mode" "<MODE>")])
4864 (define_insn "fix_truncdi_i387"
4865 [(set (match_operand:DI 0 "memory_operand" "=m")
4866 (fix:DI (match_operand 1 "register_operand" "f")))
4867 (use (match_operand:HI 2 "memory_operand" "m"))
4868 (use (match_operand:HI 3 "memory_operand" "m"))
4869 (clobber (match_scratch:XF 4 "=&1f"))]
4870 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4872 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4873 "* return output_fix_trunc (insn, operands, 0);"
4874 [(set_attr "type" "fistp")
4875 (set_attr "i387_cw" "trunc")
4876 (set_attr "mode" "DI")])
4878 (define_insn "fix_truncdi_i387_with_temp"
4879 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4880 (fix:DI (match_operand 1 "register_operand" "f,f")))
4881 (use (match_operand:HI 2 "memory_operand" "m,m"))
4882 (use (match_operand:HI 3 "memory_operand" "m,m"))
4883 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4884 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4885 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4887 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4889 [(set_attr "type" "fistp")
4890 (set_attr "i387_cw" "trunc")
4891 (set_attr "mode" "DI")])
4894 [(set (match_operand:DI 0 "register_operand" "")
4895 (fix:DI (match_operand 1 "register_operand" "")))
4896 (use (match_operand:HI 2 "memory_operand" ""))
4897 (use (match_operand:HI 3 "memory_operand" ""))
4898 (clobber (match_operand:DI 4 "memory_operand" ""))
4899 (clobber (match_scratch 5 ""))]
4901 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4904 (clobber (match_dup 5))])
4905 (set (match_dup 0) (match_dup 4))]
4909 [(set (match_operand:DI 0 "memory_operand" "")
4910 (fix:DI (match_operand 1 "register_operand" "")))
4911 (use (match_operand:HI 2 "memory_operand" ""))
4912 (use (match_operand:HI 3 "memory_operand" ""))
4913 (clobber (match_operand:DI 4 "memory_operand" ""))
4914 (clobber (match_scratch 5 ""))]
4916 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4919 (clobber (match_dup 5))])]
4922 (define_insn "fix_trunc<mode>_i387"
4923 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4924 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4925 (use (match_operand:HI 2 "memory_operand" "m"))
4926 (use (match_operand:HI 3 "memory_operand" "m"))]
4927 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4929 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4930 "* return output_fix_trunc (insn, operands, 0);"
4931 [(set_attr "type" "fistp")
4932 (set_attr "i387_cw" "trunc")
4933 (set_attr "mode" "<MODE>")])
4935 (define_insn "fix_trunc<mode>_i387_with_temp"
4936 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4937 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4938 (use (match_operand:HI 2 "memory_operand" "m,m"))
4939 (use (match_operand:HI 3 "memory_operand" "m,m"))
4940 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4941 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4943 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4945 [(set_attr "type" "fistp")
4946 (set_attr "i387_cw" "trunc")
4947 (set_attr "mode" "<MODE>")])
4950 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4951 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4952 (use (match_operand:HI 2 "memory_operand" ""))
4953 (use (match_operand:HI 3 "memory_operand" ""))
4954 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4956 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4958 (use (match_dup 3))])
4959 (set (match_dup 0) (match_dup 4))]
4963 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4964 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4965 (use (match_operand:HI 2 "memory_operand" ""))
4966 (use (match_operand:HI 3 "memory_operand" ""))
4967 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4969 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4971 (use (match_dup 3))])]
4974 (define_insn "x86_fnstcw_1"
4975 [(set (match_operand:HI 0 "memory_operand" "=m")
4976 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4979 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4980 (set_attr "mode" "HI")
4981 (set_attr "unit" "i387")])
4983 (define_insn "x86_fldcw_1"
4984 [(set (reg:HI FPCR_REG)
4985 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4988 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4989 (set_attr "mode" "HI")
4990 (set_attr "unit" "i387")
4991 (set_attr "athlon_decode" "vector")
4992 (set_attr "amdfam10_decode" "vector")])
4994 ;; Conversion between fixed point and floating point.
4996 ;; Even though we only accept memory inputs, the backend _really_
4997 ;; wants to be able to do this between registers.
4999 (define_expand "floathi<mode>2"
5000 [(set (match_operand:X87MODEF 0 "register_operand" "")
5001 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5003 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5004 || TARGET_MIX_SSE_I387)"
5007 ;; Pre-reload splitter to add memory clobber to the pattern.
5008 (define_insn_and_split "*floathi<mode>2_1"
5009 [(set (match_operand:X87MODEF 0 "register_operand" "")
5010 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5012 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5013 || TARGET_MIX_SSE_I387)
5014 && can_create_pseudo_p ()"
5017 [(parallel [(set (match_dup 0)
5018 (float:X87MODEF (match_dup 1)))
5019 (clobber (match_dup 2))])]
5020 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5022 (define_insn "*floathi<mode>2_i387_with_temp"
5023 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5024 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5025 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5027 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5028 || TARGET_MIX_SSE_I387)"
5030 [(set_attr "type" "fmov,multi")
5031 (set_attr "mode" "<MODE>")
5032 (set_attr "unit" "*,i387")
5033 (set_attr "fp_int_src" "true")])
5035 (define_insn "*floathi<mode>2_i387"
5036 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5037 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5040 || TARGET_MIX_SSE_I387)"
5042 [(set_attr "type" "fmov")
5043 (set_attr "mode" "<MODE>")
5044 (set_attr "fp_int_src" "true")])
5047 [(set (match_operand:X87MODEF 0 "register_operand" "")
5048 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5049 (clobber (match_operand:HI 2 "memory_operand" ""))]
5051 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5052 || TARGET_MIX_SSE_I387)
5053 && reload_completed"
5054 [(set (match_dup 2) (match_dup 1))
5055 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5059 [(set (match_operand:X87MODEF 0 "register_operand" "")
5060 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5061 (clobber (match_operand:HI 2 "memory_operand" ""))]
5063 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5064 || TARGET_MIX_SSE_I387)
5065 && reload_completed"
5066 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5069 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5070 [(set (match_operand:X87MODEF 0 "register_operand" "")
5072 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5074 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5075 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5077 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5078 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5079 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5081 rtx reg = gen_reg_rtx (XFmode);
5084 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5086 if (<X87MODEF:MODE>mode == SFmode)
5087 insn = gen_truncxfsf2 (operands[0], reg);
5088 else if (<X87MODEF:MODE>mode == DFmode)
5089 insn = gen_truncxfdf2 (operands[0], reg);
5098 ;; Pre-reload splitter to add memory clobber to the pattern.
5099 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5100 [(set (match_operand:X87MODEF 0 "register_operand" "")
5101 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5103 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5104 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5105 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5106 || TARGET_MIX_SSE_I387))
5107 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5108 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5109 && ((<SSEMODEI24:MODE>mode == SImode
5110 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5111 && optimize_function_for_speed_p (cfun)
5112 && flag_trapping_math)
5113 || !(TARGET_INTER_UNIT_CONVERSIONS
5114 || optimize_function_for_size_p (cfun)))))
5115 && can_create_pseudo_p ()"
5118 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5119 (clobber (match_dup 2))])]
5121 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5123 /* Avoid store forwarding (partial memory) stall penalty
5124 by passing DImode value through XMM registers. */
5125 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5126 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5127 && optimize_function_for_speed_p (cfun))
5129 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5136 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5137 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5139 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5140 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5141 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5142 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5144 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5145 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5146 (set_attr "unit" "*,i387,*,*,*")
5147 (set_attr "athlon_decode" "*,*,double,direct,double")
5148 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5149 (set_attr "fp_int_src" "true")])
5151 (define_insn "*floatsi<mode>2_vector_mixed"
5152 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5153 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5154 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5155 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5159 [(set_attr "type" "fmov,sseicvt")
5160 (set_attr "mode" "<MODE>,<ssevecmode>")
5161 (set_attr "unit" "i387,*")
5162 (set_attr "athlon_decode" "*,direct")
5163 (set_attr "amdfam10_decode" "*,double")
5164 (set_attr "fp_int_src" "true")])
5166 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5167 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5169 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5170 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5171 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5172 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5174 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5175 (set_attr "mode" "<MODEF:MODE>")
5176 (set_attr "unit" "*,i387,*,*")
5177 (set_attr "athlon_decode" "*,*,double,direct")
5178 (set_attr "amdfam10_decode" "*,*,vector,double")
5179 (set_attr "fp_int_src" "true")])
5182 [(set (match_operand:MODEF 0 "register_operand" "")
5183 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5184 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5185 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5186 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5187 && TARGET_INTER_UNIT_CONVERSIONS
5189 && (SSE_REG_P (operands[0])
5190 || (GET_CODE (operands[0]) == SUBREG
5191 && SSE_REG_P (operands[0])))"
5192 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5196 [(set (match_operand:MODEF 0 "register_operand" "")
5197 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5198 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5199 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5200 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5201 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5203 && (SSE_REG_P (operands[0])
5204 || (GET_CODE (operands[0]) == SUBREG
5205 && SSE_REG_P (operands[0])))"
5206 [(set (match_dup 2) (match_dup 1))
5207 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5210 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5211 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5213 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5214 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5215 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5216 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5219 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5220 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5221 [(set_attr "type" "fmov,sseicvt,sseicvt")
5222 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5223 (set_attr "mode" "<MODEF:MODE>")
5224 (set (attr "prefix_rex")
5226 (and (eq_attr "prefix" "maybe_vex")
5227 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5229 (const_string "*")))
5230 (set_attr "unit" "i387,*,*")
5231 (set_attr "athlon_decode" "*,double,direct")
5232 (set_attr "amdfam10_decode" "*,vector,double")
5233 (set_attr "fp_int_src" "true")])
5235 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5236 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5238 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5239 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5240 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5241 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5244 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5245 [(set_attr "type" "fmov,sseicvt")
5246 (set_attr "prefix" "orig,maybe_vex")
5247 (set_attr "mode" "<MODEF:MODE>")
5248 (set (attr "prefix_rex")
5250 (and (eq_attr "prefix" "maybe_vex")
5251 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5253 (const_string "*")))
5254 (set_attr "athlon_decode" "*,direct")
5255 (set_attr "amdfam10_decode" "*,double")
5256 (set_attr "fp_int_src" "true")])
5258 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5259 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5261 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5262 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5263 "TARGET_SSE2 && TARGET_SSE_MATH
5264 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5266 [(set_attr "type" "sseicvt")
5267 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5268 (set_attr "athlon_decode" "double,direct,double")
5269 (set_attr "amdfam10_decode" "vector,double,double")
5270 (set_attr "fp_int_src" "true")])
5272 (define_insn "*floatsi<mode>2_vector_sse"
5273 [(set (match_operand:MODEF 0 "register_operand" "=x")
5274 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5275 "TARGET_SSE2 && TARGET_SSE_MATH
5276 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5278 [(set_attr "type" "sseicvt")
5279 (set_attr "mode" "<MODE>")
5280 (set_attr "athlon_decode" "direct")
5281 (set_attr "amdfam10_decode" "double")
5282 (set_attr "fp_int_src" "true")])
5285 [(set (match_operand:MODEF 0 "register_operand" "")
5286 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5287 (clobber (match_operand:SI 2 "memory_operand" ""))]
5288 "TARGET_SSE2 && TARGET_SSE_MATH
5289 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5291 && (SSE_REG_P (operands[0])
5292 || (GET_CODE (operands[0]) == SUBREG
5293 && SSE_REG_P (operands[0])))"
5296 rtx op1 = operands[1];
5298 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5300 if (GET_CODE (op1) == SUBREG)
5301 op1 = SUBREG_REG (op1);
5303 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5305 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5306 emit_insn (gen_sse2_loadld (operands[4],
5307 CONST0_RTX (V4SImode), operands[1]));
5309 /* We can ignore possible trapping value in the
5310 high part of SSE register for non-trapping math. */
5311 else if (SSE_REG_P (op1) && !flag_trapping_math)
5312 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5315 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5316 emit_move_insn (operands[2], operands[1]);
5317 emit_insn (gen_sse2_loadld (operands[4],
5318 CONST0_RTX (V4SImode), operands[2]));
5321 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5326 [(set (match_operand:MODEF 0 "register_operand" "")
5327 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5328 (clobber (match_operand:SI 2 "memory_operand" ""))]
5329 "TARGET_SSE2 && TARGET_SSE_MATH
5330 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5332 && (SSE_REG_P (operands[0])
5333 || (GET_CODE (operands[0]) == SUBREG
5334 && SSE_REG_P (operands[0])))"
5337 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5339 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5341 emit_insn (gen_sse2_loadld (operands[4],
5342 CONST0_RTX (V4SImode), operands[1]));
5344 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5349 [(set (match_operand:MODEF 0 "register_operand" "")
5350 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5351 "TARGET_SSE2 && TARGET_SSE_MATH
5352 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5354 && (SSE_REG_P (operands[0])
5355 || (GET_CODE (operands[0]) == SUBREG
5356 && SSE_REG_P (operands[0])))"
5359 rtx op1 = operands[1];
5361 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5363 if (GET_CODE (op1) == SUBREG)
5364 op1 = SUBREG_REG (op1);
5366 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5368 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5369 emit_insn (gen_sse2_loadld (operands[4],
5370 CONST0_RTX (V4SImode), operands[1]));
5372 /* We can ignore possible trapping value in the
5373 high part of SSE register for non-trapping math. */
5374 else if (SSE_REG_P (op1) && !flag_trapping_math)
5375 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5379 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5384 [(set (match_operand:MODEF 0 "register_operand" "")
5385 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5386 "TARGET_SSE2 && TARGET_SSE_MATH
5387 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5389 && (SSE_REG_P (operands[0])
5390 || (GET_CODE (operands[0]) == SUBREG
5391 && SSE_REG_P (operands[0])))"
5394 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5396 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5398 emit_insn (gen_sse2_loadld (operands[4],
5399 CONST0_RTX (V4SImode), operands[1]));
5401 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5405 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5406 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5408 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5409 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5410 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5411 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5413 [(set_attr "type" "sseicvt")
5414 (set_attr "mode" "<MODEF:MODE>")
5415 (set_attr "athlon_decode" "double,direct")
5416 (set_attr "amdfam10_decode" "vector,double")
5417 (set_attr "fp_int_src" "true")])
5419 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5420 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5422 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5423 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5424 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5425 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5426 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5427 [(set_attr "type" "sseicvt")
5428 (set_attr "prefix" "maybe_vex")
5429 (set_attr "mode" "<MODEF:MODE>")
5430 (set (attr "prefix_rex")
5432 (and (eq_attr "prefix" "maybe_vex")
5433 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5435 (const_string "*")))
5436 (set_attr "athlon_decode" "double,direct")
5437 (set_attr "amdfam10_decode" "vector,double")
5438 (set_attr "fp_int_src" "true")])
5441 [(set (match_operand:MODEF 0 "register_operand" "")
5442 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5443 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5444 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5445 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5446 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5448 && (SSE_REG_P (operands[0])
5449 || (GET_CODE (operands[0]) == SUBREG
5450 && SSE_REG_P (operands[0])))"
5451 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5454 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5455 [(set (match_operand:MODEF 0 "register_operand" "=x")
5457 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5458 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5459 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5460 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5461 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5462 [(set_attr "type" "sseicvt")
5463 (set_attr "prefix" "maybe_vex")
5464 (set_attr "mode" "<MODEF:MODE>")
5465 (set (attr "prefix_rex")
5467 (and (eq_attr "prefix" "maybe_vex")
5468 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5470 (const_string "*")))
5471 (set_attr "athlon_decode" "direct")
5472 (set_attr "amdfam10_decode" "double")
5473 (set_attr "fp_int_src" "true")])
5476 [(set (match_operand:MODEF 0 "register_operand" "")
5477 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5478 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5479 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5480 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5481 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5483 && (SSE_REG_P (operands[0])
5484 || (GET_CODE (operands[0]) == SUBREG
5485 && SSE_REG_P (operands[0])))"
5486 [(set (match_dup 2) (match_dup 1))
5487 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5491 [(set (match_operand:MODEF 0 "register_operand" "")
5492 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5493 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5494 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5495 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5497 && (SSE_REG_P (operands[0])
5498 || (GET_CODE (operands[0]) == SUBREG
5499 && SSE_REG_P (operands[0])))"
5500 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5503 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5504 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5506 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5507 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5509 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5513 [(set_attr "type" "fmov,multi")
5514 (set_attr "mode" "<X87MODEF:MODE>")
5515 (set_attr "unit" "*,i387")
5516 (set_attr "fp_int_src" "true")])
5518 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5519 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5521 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5523 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5525 [(set_attr "type" "fmov")
5526 (set_attr "mode" "<X87MODEF:MODE>")
5527 (set_attr "fp_int_src" "true")])
5530 [(set (match_operand:X87MODEF 0 "register_operand" "")
5531 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5532 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5534 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5536 && FP_REG_P (operands[0])"
5537 [(set (match_dup 2) (match_dup 1))
5538 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5542 [(set (match_operand:X87MODEF 0 "register_operand" "")
5543 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5544 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5546 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5548 && FP_REG_P (operands[0])"
5549 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5552 ;; Avoid store forwarding (partial memory) stall penalty
5553 ;; by passing DImode value through XMM registers. */
5555 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5556 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5558 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5559 (clobber (match_scratch:V4SI 3 "=X,x"))
5560 (clobber (match_scratch:V4SI 4 "=X,x"))
5561 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5562 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5563 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5564 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5566 [(set_attr "type" "multi")
5567 (set_attr "mode" "<X87MODEF:MODE>")
5568 (set_attr "unit" "i387")
5569 (set_attr "fp_int_src" "true")])
5572 [(set (match_operand:X87MODEF 0 "register_operand" "")
5573 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5574 (clobber (match_scratch:V4SI 3 ""))
5575 (clobber (match_scratch:V4SI 4 ""))
5576 (clobber (match_operand:DI 2 "memory_operand" ""))]
5577 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5578 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5579 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5581 && FP_REG_P (operands[0])"
5582 [(set (match_dup 2) (match_dup 3))
5583 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5585 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5586 Assemble the 64-bit DImode value in an xmm register. */
5587 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5588 gen_rtx_SUBREG (SImode, operands[1], 0)));
5589 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5590 gen_rtx_SUBREG (SImode, operands[1], 4)));
5591 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5594 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5598 [(set (match_operand:X87MODEF 0 "register_operand" "")
5599 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5600 (clobber (match_scratch:V4SI 3 ""))
5601 (clobber (match_scratch:V4SI 4 ""))
5602 (clobber (match_operand:DI 2 "memory_operand" ""))]
5603 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5604 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5605 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5607 && FP_REG_P (operands[0])"
5608 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5611 ;; Avoid store forwarding (partial memory) stall penalty by extending
5612 ;; SImode value to DImode through XMM register instead of pushing two
5613 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5614 ;; targets benefit from this optimization. Also note that fild
5615 ;; loads from memory only.
5617 (define_insn "*floatunssi<mode>2_1"
5618 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5619 (unsigned_float:X87MODEF
5620 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5621 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5622 (clobber (match_scratch:SI 3 "=X,x"))]
5624 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5627 [(set_attr "type" "multi")
5628 (set_attr "mode" "<MODE>")])
5631 [(set (match_operand:X87MODEF 0 "register_operand" "")
5632 (unsigned_float:X87MODEF
5633 (match_operand:SI 1 "register_operand" "")))
5634 (clobber (match_operand:DI 2 "memory_operand" ""))
5635 (clobber (match_scratch:SI 3 ""))]
5637 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5639 && reload_completed"
5640 [(set (match_dup 2) (match_dup 1))
5642 (float:X87MODEF (match_dup 2)))]
5643 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5646 [(set (match_operand:X87MODEF 0 "register_operand" "")
5647 (unsigned_float:X87MODEF
5648 (match_operand:SI 1 "memory_operand" "")))
5649 (clobber (match_operand:DI 2 "memory_operand" ""))
5650 (clobber (match_scratch:SI 3 ""))]
5652 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5654 && reload_completed"
5655 [(set (match_dup 2) (match_dup 3))
5657 (float:X87MODEF (match_dup 2)))]
5659 emit_move_insn (operands[3], operands[1]);
5660 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5663 (define_expand "floatunssi<mode>2"
5665 [(set (match_operand:X87MODEF 0 "register_operand" "")
5666 (unsigned_float:X87MODEF
5667 (match_operand:SI 1 "nonimmediate_operand" "")))
5668 (clobber (match_dup 2))
5669 (clobber (match_scratch:SI 3 ""))])]
5671 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5673 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5675 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5677 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5682 enum ix86_stack_slot slot = (virtuals_instantiated
5685 operands[2] = assign_386_stack_local (DImode, slot);
5689 (define_expand "floatunsdisf2"
5690 [(use (match_operand:SF 0 "register_operand" ""))
5691 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5692 "TARGET_64BIT && TARGET_SSE_MATH"
5693 "x86_emit_floatuns (operands); DONE;")
5695 (define_expand "floatunsdidf2"
5696 [(use (match_operand:DF 0 "register_operand" ""))
5697 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5698 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5699 && TARGET_SSE2 && TARGET_SSE_MATH"
5702 x86_emit_floatuns (operands);
5704 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5710 (define_expand "add<mode>3"
5711 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5712 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5713 (match_operand:SDWIM 2 "<general_operand>" "")))]
5715 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5717 (define_insn_and_split "*add<dwi>3_doubleword"
5718 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5720 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5721 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5722 (clobber (reg:CC FLAGS_REG))]
5723 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5726 [(parallel [(set (reg:CC FLAGS_REG)
5727 (unspec:CC [(match_dup 1) (match_dup 2)]
5730 (plus:DWIH (match_dup 1) (match_dup 2)))])
5731 (parallel [(set (match_dup 3)
5735 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5737 (clobber (reg:CC FLAGS_REG))])]
5738 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5740 (define_insn "*add<mode>3_cc"
5741 [(set (reg:CC FLAGS_REG)
5743 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5744 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5746 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5747 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5748 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5749 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5750 [(set_attr "type" "alu")
5751 (set_attr "mode" "<MODE>")])
5753 (define_insn "addqi3_cc"
5754 [(set (reg:CC FLAGS_REG)
5756 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5757 (match_operand:QI 2 "general_operand" "qn,qm")]
5759 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5760 (plus:QI (match_dup 1) (match_dup 2)))]
5761 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5762 "add{b}\t{%2, %0|%0, %2}"
5763 [(set_attr "type" "alu")
5764 (set_attr "mode" "QI")])
5766 (define_insn "*lea_1"
5767 [(set (match_operand:DWIH 0 "register_operand" "=r")
5768 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5770 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5771 [(set_attr "type" "lea")
5772 (set_attr "mode" "<MODE>")])
5774 (define_insn "*lea_2"
5775 [(set (match_operand:SI 0 "register_operand" "=r")
5776 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5778 "lea{l}\t{%a1, %0|%0, %a1}"
5779 [(set_attr "type" "lea")
5780 (set_attr "mode" "SI")])
5782 (define_insn "*lea_2_zext"
5783 [(set (match_operand:DI 0 "register_operand" "=r")
5785 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5787 "lea{l}\t{%a1, %k0|%k0, %a1}"
5788 [(set_attr "type" "lea")
5789 (set_attr "mode" "SI")])
5791 (define_insn "*add<mode>_1"
5792 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5794 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5795 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5796 (clobber (reg:CC FLAGS_REG))]
5797 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5799 switch (get_attr_type (insn))
5805 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5806 if (operands[2] == const1_rtx)
5807 return "inc{<imodesuffix>}\t%0";
5810 gcc_assert (operands[2] == constm1_rtx);
5811 return "dec{<imodesuffix>}\t%0";
5815 /* For most processors, ADD is faster than LEA. This alternative
5816 was added to use ADD as much as possible. */
5817 if (which_alternative == 2)
5820 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5823 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5824 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5825 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5827 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5831 (cond [(eq_attr "alternative" "3")
5832 (const_string "lea")
5833 (match_operand:SWI48 2 "incdec_operand" "")
5834 (const_string "incdec")
5836 (const_string "alu")))
5837 (set (attr "length_immediate")
5839 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5841 (const_string "*")))
5842 (set_attr "mode" "<MODE>")])
5844 ;; It may seem that nonimmediate operand is proper one for operand 1.
5845 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5846 ;; we take care in ix86_binary_operator_ok to not allow two memory
5847 ;; operands so proper swapping will be done in reload. This allow
5848 ;; patterns constructed from addsi_1 to match.
5850 (define_insn "*addsi_1_zext"
5851 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5853 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5854 (match_operand:SI 2 "general_operand" "g,0,li"))))
5855 (clobber (reg:CC FLAGS_REG))]
5856 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5858 switch (get_attr_type (insn))
5864 if (operands[2] == const1_rtx)
5865 return "inc{l}\t%k0";
5868 gcc_assert (operands[2] == constm1_rtx);
5869 return "dec{l}\t%k0";
5873 /* For most processors, ADD is faster than LEA. This alternative
5874 was added to use ADD as much as possible. */
5875 if (which_alternative == 1)
5878 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5881 if (x86_maybe_negate_const_int (&operands[2], SImode))
5882 return "sub{l}\t{%2, %k0|%k0, %2}";
5884 return "add{l}\t{%2, %k0|%k0, %2}";
5888 (cond [(eq_attr "alternative" "2")
5889 (const_string "lea")
5890 (match_operand:SI 2 "incdec_operand" "")
5891 (const_string "incdec")
5893 (const_string "alu")))
5894 (set (attr "length_immediate")
5896 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5898 (const_string "*")))
5899 (set_attr "mode" "SI")])
5901 (define_insn "*addhi_1"
5902 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5903 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5904 (match_operand:HI 2 "general_operand" "rn,rm")))
5905 (clobber (reg:CC FLAGS_REG))]
5906 "TARGET_PARTIAL_REG_STALL
5907 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5909 switch (get_attr_type (insn))
5912 if (operands[2] == const1_rtx)
5913 return "inc{w}\t%0";
5916 gcc_assert (operands[2] == constm1_rtx);
5917 return "dec{w}\t%0";
5921 if (x86_maybe_negate_const_int (&operands[2], HImode))
5922 return "sub{w}\t{%2, %0|%0, %2}";
5924 return "add{w}\t{%2, %0|%0, %2}";
5928 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5929 (const_string "incdec")
5930 (const_string "alu")))
5931 (set (attr "length_immediate")
5933 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5935 (const_string "*")))
5936 (set_attr "mode" "HI")])
5938 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5939 ;; type optimizations enabled by define-splits. This is not important
5940 ;; for PII, and in fact harmful because of partial register stalls.
5942 (define_insn "*addhi_1_lea"
5943 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5944 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5945 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5946 (clobber (reg:CC FLAGS_REG))]
5947 "!TARGET_PARTIAL_REG_STALL
5948 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5950 switch (get_attr_type (insn))
5956 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5957 if (operands[2] == const1_rtx)
5958 return "inc{w}\t%0";
5961 gcc_assert (operands[2] == constm1_rtx);
5962 return "dec{w}\t%0";
5966 /* For most processors, ADD is faster than LEA. This alternative
5967 was added to use ADD as much as possible. */
5968 if (which_alternative == 2)
5971 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5974 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5975 if (x86_maybe_negate_const_int (&operands[2], HImode))
5976 return "sub{w}\t{%2, %0|%0, %2}";
5978 return "add{w}\t{%2, %0|%0, %2}";
5982 (cond [(eq_attr "alternative" "3")
5983 (const_string "lea")
5984 (match_operand:HI 2 "incdec_operand" "")
5985 (const_string "incdec")
5987 (const_string "alu")))
5988 (set (attr "length_immediate")
5990 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5992 (const_string "*")))
5993 (set_attr "mode" "HI,HI,HI,SI")])
5995 ;; %%% Potential partial reg stall on alternative 2. What to do?
5996 (define_insn "*addqi_1"
5997 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5998 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5999 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6000 (clobber (reg:CC FLAGS_REG))]
6001 "TARGET_PARTIAL_REG_STALL
6002 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6004 int widen = (which_alternative == 2);
6005 switch (get_attr_type (insn))
6008 if (operands[2] == const1_rtx)
6009 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6012 gcc_assert (operands[2] == constm1_rtx);
6013 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6017 if (x86_maybe_negate_const_int (&operands[2], QImode))
6020 return "sub{l}\t{%2, %k0|%k0, %2}";
6022 return "sub{b}\t{%2, %0|%0, %2}";
6025 return "add{l}\t{%k2, %k0|%k0, %k2}";
6027 return "add{b}\t{%2, %0|%0, %2}";
6031 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6032 (const_string "incdec")
6033 (const_string "alu")))
6034 (set (attr "length_immediate")
6036 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6038 (const_string "*")))
6039 (set_attr "mode" "QI,QI,SI")])
6041 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
6042 (define_insn "*addqi_1_lea"
6043 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
6044 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
6045 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
6046 (clobber (reg:CC FLAGS_REG))]
6047 "!TARGET_PARTIAL_REG_STALL
6048 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6050 int widen = (which_alternative == 3 || which_alternative == 4);
6052 switch (get_attr_type (insn))
6058 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6059 if (operands[2] == const1_rtx)
6060 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6063 gcc_assert (operands[2] == constm1_rtx);
6064 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6068 /* For most processors, ADD is faster than LEA. These alternatives
6069 were added to use ADD as much as possible. */
6070 if (which_alternative == 2 || which_alternative == 4)
6073 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6076 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6077 if (x86_maybe_negate_const_int (&operands[2], QImode))
6080 return "sub{l}\t{%2, %k0|%k0, %2}";
6082 return "sub{b}\t{%2, %0|%0, %2}";
6085 return "add{l}\t{%k2, %k0|%k0, %k2}";
6087 return "add{b}\t{%2, %0|%0, %2}";
6091 (cond [(eq_attr "alternative" "5")
6092 (const_string "lea")
6093 (match_operand:QI 2 "incdec_operand" "")
6094 (const_string "incdec")
6096 (const_string "alu")))
6097 (set (attr "length_immediate")
6099 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6101 (const_string "*")))
6102 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
6104 (define_insn "*addqi_1_slp"
6105 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6106 (plus:QI (match_dup 0)
6107 (match_operand:QI 1 "general_operand" "qn,qnm")))
6108 (clobber (reg:CC FLAGS_REG))]
6109 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6110 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6112 switch (get_attr_type (insn))
6115 if (operands[1] == const1_rtx)
6116 return "inc{b}\t%0";
6119 gcc_assert (operands[1] == constm1_rtx);
6120 return "dec{b}\t%0";
6124 if (x86_maybe_negate_const_int (&operands[1], QImode))
6125 return "sub{b}\t{%1, %0|%0, %1}";
6127 return "add{b}\t{%1, %0|%0, %1}";
6131 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6132 (const_string "incdec")
6133 (const_string "alu1")))
6134 (set (attr "memory")
6135 (if_then_else (match_operand 1 "memory_operand" "")
6136 (const_string "load")
6137 (const_string "none")))
6138 (set_attr "mode" "QI")])
6140 (define_insn "*add<mode>_2"
6141 [(set (reg FLAGS_REG)
6144 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6145 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6147 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6148 (plus:SWI (match_dup 1) (match_dup 2)))]
6149 "ix86_match_ccmode (insn, CCGOCmode)
6150 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6152 switch (get_attr_type (insn))
6155 if (operands[2] == const1_rtx)
6156 return "inc{<imodesuffix>}\t%0";
6159 gcc_assert (operands[2] == constm1_rtx);
6160 return "dec{<imodesuffix>}\t%0";
6164 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6165 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6167 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6171 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6172 (const_string "incdec")
6173 (const_string "alu")))
6174 (set (attr "length_immediate")
6176 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6178 (const_string "*")))
6179 (set_attr "mode" "<MODE>")])
6181 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6182 (define_insn "*addsi_2_zext"
6183 [(set (reg FLAGS_REG)
6185 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6186 (match_operand:SI 2 "general_operand" "g"))
6188 (set (match_operand:DI 0 "register_operand" "=r")
6189 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6190 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6191 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6193 switch (get_attr_type (insn))
6196 if (operands[2] == const1_rtx)
6197 return "inc{l}\t%k0";
6200 gcc_assert (operands[2] == constm1_rtx);
6201 return "dec{l}\t%k0";
6205 if (x86_maybe_negate_const_int (&operands[2], SImode))
6206 return "sub{l}\t{%2, %k0|%k0, %2}";
6208 return "add{l}\t{%2, %k0|%k0, %2}";
6212 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6213 (const_string "incdec")
6214 (const_string "alu")))
6215 (set (attr "length_immediate")
6217 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6219 (const_string "*")))
6220 (set_attr "mode" "SI")])
6222 (define_insn "*add<mode>_3"
6223 [(set (reg FLAGS_REG)
6225 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6226 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6227 (clobber (match_scratch:SWI 0 "=<r>"))]
6228 "ix86_match_ccmode (insn, CCZmode)
6229 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6231 switch (get_attr_type (insn))
6234 if (operands[2] == const1_rtx)
6235 return "inc{<imodesuffix>}\t%0";
6238 gcc_assert (operands[2] == constm1_rtx);
6239 return "dec{<imodesuffix>}\t%0";
6243 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6244 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6246 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6250 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6251 (const_string "incdec")
6252 (const_string "alu")))
6253 (set (attr "length_immediate")
6255 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6257 (const_string "*")))
6258 (set_attr "mode" "<MODE>")])
6260 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6261 (define_insn "*addsi_3_zext"
6262 [(set (reg FLAGS_REG)
6264 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6265 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6266 (set (match_operand:DI 0 "register_operand" "=r")
6267 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6268 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6269 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6271 switch (get_attr_type (insn))
6274 if (operands[2] == const1_rtx)
6275 return "inc{l}\t%k0";
6278 gcc_assert (operands[2] == constm1_rtx);
6279 return "dec{l}\t%k0";
6283 if (x86_maybe_negate_const_int (&operands[2], SImode))
6284 return "sub{l}\t{%2, %k0|%k0, %2}";
6286 return "add{l}\t{%2, %k0|%k0, %2}";
6290 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6291 (const_string "incdec")
6292 (const_string "alu")))
6293 (set (attr "length_immediate")
6295 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6297 (const_string "*")))
6298 (set_attr "mode" "SI")])
6300 ; For comparisons against 1, -1 and 128, we may generate better code
6301 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6302 ; is matched then. We can't accept general immediate, because for
6303 ; case of overflows, the result is messed up.
6304 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6305 ; only for comparisons not depending on it.
6307 (define_insn "*adddi_4"
6308 [(set (reg FLAGS_REG)
6310 (match_operand:DI 1 "nonimmediate_operand" "0")
6311 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6312 (clobber (match_scratch:DI 0 "=rm"))]
6314 && ix86_match_ccmode (insn, CCGCmode)"
6316 switch (get_attr_type (insn))
6319 if (operands[2] == constm1_rtx)
6320 return "inc{q}\t%0";
6323 gcc_assert (operands[2] == const1_rtx);
6324 return "dec{q}\t%0";
6328 if (x86_maybe_negate_const_int (&operands[2], DImode))
6329 return "add{q}\t{%2, %0|%0, %2}";
6331 return "sub{q}\t{%2, %0|%0, %2}";
6335 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6336 (const_string "incdec")
6337 (const_string "alu")))
6338 (set (attr "length_immediate")
6340 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6342 (const_string "*")))
6343 (set_attr "mode" "DI")])
6345 ; For comparisons against 1, -1 and 128, we may generate better code
6346 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6347 ; is matched then. We can't accept general immediate, because for
6348 ; case of overflows, the result is messed up.
6349 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6350 ; only for comparisons not depending on it.
6352 (define_insn "*add<mode>_4"
6353 [(set (reg FLAGS_REG)
6355 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6356 (match_operand:SWI124 2 "const_int_operand" "n")))
6357 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6358 "ix86_match_ccmode (insn, CCGCmode)"
6360 switch (get_attr_type (insn))
6363 if (operands[2] == constm1_rtx)
6364 return "inc{<imodesuffix>}\t%0";
6367 gcc_assert (operands[2] == const1_rtx);
6368 return "dec{<imodesuffix>}\t%0";
6372 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6373 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6375 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6379 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6380 (const_string "incdec")
6381 (const_string "alu")))
6382 (set (attr "length_immediate")
6384 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6386 (const_string "*")))
6387 (set_attr "mode" "<MODE>")])
6389 (define_insn "*add<mode>_5"
6390 [(set (reg FLAGS_REG)
6393 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6394 (match_operand:SWI 2 "<general_operand>" "<g>"))
6396 (clobber (match_scratch:SWI 0 "=<r>"))]
6397 "ix86_match_ccmode (insn, CCGOCmode)
6398 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6400 switch (get_attr_type (insn))
6403 if (operands[2] == const1_rtx)
6404 return "inc{<imodesuffix>}\t%0";
6407 gcc_assert (operands[2] == constm1_rtx);
6408 return "dec{<imodesuffix>}\t%0";
6412 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6413 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6415 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6419 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6420 (const_string "incdec")
6421 (const_string "alu")))
6422 (set (attr "length_immediate")
6424 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6426 (const_string "*")))
6427 (set_attr "mode" "<MODE>")])
6429 (define_insn "*addqi_ext_1_rex64"
6430 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6435 (match_operand 1 "ext_register_operand" "0")
6438 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6439 (clobber (reg:CC FLAGS_REG))]
6442 switch (get_attr_type (insn))
6445 if (operands[2] == const1_rtx)
6446 return "inc{b}\t%h0";
6449 gcc_assert (operands[2] == constm1_rtx);
6450 return "dec{b}\t%h0";
6454 return "add{b}\t{%2, %h0|%h0, %2}";
6458 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6459 (const_string "incdec")
6460 (const_string "alu")))
6461 (set_attr "modrm" "1")
6462 (set_attr "mode" "QI")])
6464 (define_insn "addqi_ext_1"
6465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6470 (match_operand 1 "ext_register_operand" "0")
6473 (match_operand:QI 2 "general_operand" "Qmn")))
6474 (clobber (reg:CC FLAGS_REG))]
6477 switch (get_attr_type (insn))
6480 if (operands[2] == const1_rtx)
6481 return "inc{b}\t%h0";
6484 gcc_assert (operands[2] == constm1_rtx);
6485 return "dec{b}\t%h0";
6489 return "add{b}\t{%2, %h0|%h0, %2}";
6493 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6494 (const_string "incdec")
6495 (const_string "alu")))
6496 (set_attr "modrm" "1")
6497 (set_attr "mode" "QI")])
6499 (define_insn "*addqi_ext_2"
6500 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6505 (match_operand 1 "ext_register_operand" "%0")
6509 (match_operand 2 "ext_register_operand" "Q")
6512 (clobber (reg:CC FLAGS_REG))]
6514 "add{b}\t{%h2, %h0|%h0, %h2}"
6515 [(set_attr "type" "alu")
6516 (set_attr "mode" "QI")])
6518 ;; The lea patterns for non-Pmodes needs to be matched by
6519 ;; several insns converted to real lea by splitters.
6521 (define_insn_and_split "*lea_general_1"
6522 [(set (match_operand 0 "register_operand" "=r")
6523 (plus (plus (match_operand 1 "index_register_operand" "l")
6524 (match_operand 2 "register_operand" "r"))
6525 (match_operand 3 "immediate_operand" "i")))]
6526 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6527 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6528 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6529 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6530 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6531 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6532 || GET_MODE (operands[3]) == VOIDmode)"
6534 "&& reload_completed"
6538 operands[0] = gen_lowpart (SImode, operands[0]);
6539 operands[1] = gen_lowpart (Pmode, operands[1]);
6540 operands[2] = gen_lowpart (Pmode, operands[2]);
6541 operands[3] = gen_lowpart (Pmode, operands[3]);
6542 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6544 if (Pmode != SImode)
6545 pat = gen_rtx_SUBREG (SImode, pat, 0);
6546 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6549 [(set_attr "type" "lea")
6550 (set_attr "mode" "SI")])
6552 (define_insn_and_split "*lea_general_1_zext"
6553 [(set (match_operand:DI 0 "register_operand" "=r")
6556 (match_operand:SI 1 "index_register_operand" "l")
6557 (match_operand:SI 2 "register_operand" "r"))
6558 (match_operand:SI 3 "immediate_operand" "i"))))]
6561 "&& reload_completed"
6563 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6565 (match_dup 3)) 0)))]
6567 operands[1] = gen_lowpart (Pmode, operands[1]);
6568 operands[2] = gen_lowpart (Pmode, operands[2]);
6569 operands[3] = gen_lowpart (Pmode, operands[3]);
6571 [(set_attr "type" "lea")
6572 (set_attr "mode" "SI")])
6574 (define_insn_and_split "*lea_general_2"
6575 [(set (match_operand 0 "register_operand" "=r")
6576 (plus (mult (match_operand 1 "index_register_operand" "l")
6577 (match_operand 2 "const248_operand" "i"))
6578 (match_operand 3 "nonmemory_operand" "ri")))]
6579 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6580 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6581 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6582 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6583 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6584 || GET_MODE (operands[3]) == VOIDmode)"
6586 "&& reload_completed"
6590 operands[0] = gen_lowpart (SImode, operands[0]);
6591 operands[1] = gen_lowpart (Pmode, operands[1]);
6592 operands[3] = gen_lowpart (Pmode, operands[3]);
6593 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6595 if (Pmode != SImode)
6596 pat = gen_rtx_SUBREG (SImode, pat, 0);
6597 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6600 [(set_attr "type" "lea")
6601 (set_attr "mode" "SI")])
6603 (define_insn_and_split "*lea_general_2_zext"
6604 [(set (match_operand:DI 0 "register_operand" "=r")
6607 (match_operand:SI 1 "index_register_operand" "l")
6608 (match_operand:SI 2 "const248_operand" "n"))
6609 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6612 "&& reload_completed"
6614 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6616 (match_dup 3)) 0)))]
6618 operands[1] = gen_lowpart (Pmode, operands[1]);
6619 operands[3] = gen_lowpart (Pmode, operands[3]);
6621 [(set_attr "type" "lea")
6622 (set_attr "mode" "SI")])
6624 (define_insn_and_split "*lea_general_3"
6625 [(set (match_operand 0 "register_operand" "=r")
6626 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6627 (match_operand 2 "const248_operand" "i"))
6628 (match_operand 3 "register_operand" "r"))
6629 (match_operand 4 "immediate_operand" "i")))]
6630 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6631 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6632 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6633 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6634 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6636 "&& reload_completed"
6640 operands[0] = gen_lowpart (SImode, operands[0]);
6641 operands[1] = gen_lowpart (Pmode, operands[1]);
6642 operands[3] = gen_lowpart (Pmode, operands[3]);
6643 operands[4] = gen_lowpart (Pmode, operands[4]);
6644 pat = gen_rtx_PLUS (Pmode,
6645 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6649 if (Pmode != SImode)
6650 pat = gen_rtx_SUBREG (SImode, pat, 0);
6651 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6654 [(set_attr "type" "lea")
6655 (set_attr "mode" "SI")])
6657 (define_insn_and_split "*lea_general_3_zext"
6658 [(set (match_operand:DI 0 "register_operand" "=r")
6662 (match_operand:SI 1 "index_register_operand" "l")
6663 (match_operand:SI 2 "const248_operand" "n"))
6664 (match_operand:SI 3 "register_operand" "r"))
6665 (match_operand:SI 4 "immediate_operand" "i"))))]
6668 "&& reload_completed"
6670 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6673 (match_dup 4)) 0)))]
6675 operands[1] = gen_lowpart (Pmode, operands[1]);
6676 operands[3] = gen_lowpart (Pmode, operands[3]);
6677 operands[4] = gen_lowpart (Pmode, operands[4]);
6679 [(set_attr "type" "lea")
6680 (set_attr "mode" "SI")])
6682 ;; Convert lea to the lea pattern to avoid flags dependency.
6684 [(set (match_operand:DI 0 "register_operand" "")
6685 (plus:DI (match_operand:DI 1 "register_operand" "")
6686 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6687 (clobber (reg:CC FLAGS_REG))]
6688 "TARGET_64BIT && reload_completed
6689 && ix86_lea_for_add_ok (insn, operands)"
6691 (plus:DI (match_dup 1)
6695 ;; Convert lea to the lea pattern to avoid flags dependency.
6697 [(set (match_operand 0 "register_operand" "")
6698 (plus (match_operand 1 "register_operand" "")
6699 (match_operand 2 "nonmemory_operand" "")))
6700 (clobber (reg:CC FLAGS_REG))]
6701 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6705 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6706 may confuse gen_lowpart. */
6707 if (GET_MODE (operands[0]) != Pmode)
6709 operands[1] = gen_lowpart (Pmode, operands[1]);
6710 operands[2] = gen_lowpart (Pmode, operands[2]);
6712 operands[0] = gen_lowpart (SImode, operands[0]);
6713 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6714 if (Pmode != SImode)
6715 pat = gen_rtx_SUBREG (SImode, pat, 0);
6716 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6720 ;; Convert lea to the lea pattern to avoid flags dependency.
6722 [(set (match_operand:DI 0 "register_operand" "")
6724 (plus:SI (match_operand:SI 1 "register_operand" "")
6725 (match_operand:SI 2 "nonmemory_operand" ""))))
6726 (clobber (reg:CC FLAGS_REG))]
6727 "TARGET_64BIT && reload_completed
6728 && true_regnum (operands[0]) != true_regnum (operands[1])"
6730 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6732 operands[1] = gen_lowpart (Pmode, operands[1]);
6733 operands[2] = gen_lowpart (Pmode, operands[2]);
6736 ;; Subtract instructions
6738 (define_expand "sub<mode>3"
6739 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6740 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6741 (match_operand:SDWIM 2 "<general_operand>" "")))]
6743 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6745 (define_insn_and_split "*sub<dwi>3_doubleword"
6746 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6748 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6749 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6750 (clobber (reg:CC FLAGS_REG))]
6751 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6754 [(parallel [(set (reg:CC FLAGS_REG)
6755 (compare:CC (match_dup 1) (match_dup 2)))
6757 (minus:DWIH (match_dup 1) (match_dup 2)))])
6758 (parallel [(set (match_dup 3)
6762 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6764 (clobber (reg:CC FLAGS_REG))])]
6765 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6767 (define_insn "*sub<mode>_1"
6768 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6770 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6771 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6772 (clobber (reg:CC FLAGS_REG))]
6773 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6774 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6775 [(set_attr "type" "alu")
6776 (set_attr "mode" "<MODE>")])
6778 (define_insn "*subsi_1_zext"
6779 [(set (match_operand:DI 0 "register_operand" "=r")
6781 (minus:SI (match_operand:SI 1 "register_operand" "0")
6782 (match_operand:SI 2 "general_operand" "g"))))
6783 (clobber (reg:CC FLAGS_REG))]
6784 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6785 "sub{l}\t{%2, %k0|%k0, %2}"
6786 [(set_attr "type" "alu")
6787 (set_attr "mode" "SI")])
6789 (define_insn "*subqi_1_slp"
6790 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6791 (minus:QI (match_dup 0)
6792 (match_operand:QI 1 "general_operand" "qn,qm")))
6793 (clobber (reg:CC FLAGS_REG))]
6794 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6795 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6796 "sub{b}\t{%1, %0|%0, %1}"
6797 [(set_attr "type" "alu1")
6798 (set_attr "mode" "QI")])
6800 (define_insn "*sub<mode>_2"
6801 [(set (reg FLAGS_REG)
6804 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6805 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6807 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6808 (minus:SWI (match_dup 1) (match_dup 2)))]
6809 "ix86_match_ccmode (insn, CCGOCmode)
6810 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6811 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6812 [(set_attr "type" "alu")
6813 (set_attr "mode" "<MODE>")])
6815 (define_insn "*subsi_2_zext"
6816 [(set (reg FLAGS_REG)
6818 (minus:SI (match_operand:SI 1 "register_operand" "0")
6819 (match_operand:SI 2 "general_operand" "g"))
6821 (set (match_operand:DI 0 "register_operand" "=r")
6823 (minus:SI (match_dup 1)
6825 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6826 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6827 "sub{l}\t{%2, %k0|%k0, %2}"
6828 [(set_attr "type" "alu")
6829 (set_attr "mode" "SI")])
6831 (define_insn "*sub<mode>_3"
6832 [(set (reg FLAGS_REG)
6833 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6834 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6835 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6836 (minus:SWI (match_dup 1) (match_dup 2)))]
6837 "ix86_match_ccmode (insn, CCmode)
6838 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6839 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6840 [(set_attr "type" "alu")
6841 (set_attr "mode" "<MODE>")])
6843 (define_insn "*subsi_3_zext"
6844 [(set (reg FLAGS_REG)
6845 (compare (match_operand:SI 1 "register_operand" "0")
6846 (match_operand:SI 2 "general_operand" "g")))
6847 (set (match_operand:DI 0 "register_operand" "=r")
6849 (minus:SI (match_dup 1)
6851 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6852 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6853 "sub{l}\t{%2, %1|%1, %2}"
6854 [(set_attr "type" "alu")
6855 (set_attr "mode" "SI")])
6857 ;; Add with carry and subtract with borrow
6859 (define_expand "<plusminus_insn><mode>3_carry"
6861 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6863 (match_operand:SWI 1 "nonimmediate_operand" "")
6864 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6865 [(match_operand 3 "flags_reg_operand" "")
6867 (match_operand:SWI 2 "<general_operand>" ""))))
6868 (clobber (reg:CC FLAGS_REG))])]
6869 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6872 (define_insn "*<plusminus_insn><mode>3_carry"
6873 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6875 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6877 (match_operator 3 "ix86_carry_flag_operator"
6878 [(reg FLAGS_REG) (const_int 0)])
6879 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6880 (clobber (reg:CC FLAGS_REG))]
6881 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6882 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6883 [(set_attr "type" "alu")
6884 (set_attr "use_carry" "1")
6885 (set_attr "pent_pair" "pu")
6886 (set_attr "mode" "<MODE>")])
6888 (define_insn "*addsi3_carry_zext"
6889 [(set (match_operand:DI 0 "register_operand" "=r")
6891 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6892 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6893 [(reg FLAGS_REG) (const_int 0)])
6894 (match_operand:SI 2 "general_operand" "g")))))
6895 (clobber (reg:CC FLAGS_REG))]
6896 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6897 "adc{l}\t{%2, %k0|%k0, %2}"
6898 [(set_attr "type" "alu")
6899 (set_attr "use_carry" "1")
6900 (set_attr "pent_pair" "pu")
6901 (set_attr "mode" "SI")])
6903 (define_insn "*subsi3_carry_zext"
6904 [(set (match_operand:DI 0 "register_operand" "=r")
6906 (minus:SI (match_operand:SI 1 "register_operand" "0")
6907 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6908 [(reg FLAGS_REG) (const_int 0)])
6909 (match_operand:SI 2 "general_operand" "g")))))
6910 (clobber (reg:CC FLAGS_REG))]
6911 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6912 "sbb{l}\t{%2, %k0|%k0, %2}"
6913 [(set_attr "type" "alu")
6914 (set_attr "pent_pair" "pu")
6915 (set_attr "mode" "SI")])
6917 ;; Overflow setting add and subtract instructions
6919 (define_insn "*add<mode>3_cconly_overflow"
6920 [(set (reg:CCC FLAGS_REG)
6923 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6924 (match_operand:SWI 2 "<general_operand>" "<g>"))
6926 (clobber (match_scratch:SWI 0 "=<r>"))]
6927 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6928 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6929 [(set_attr "type" "alu")
6930 (set_attr "mode" "<MODE>")])
6932 (define_insn "*sub<mode>3_cconly_overflow"
6933 [(set (reg:CCC FLAGS_REG)
6936 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6937 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6940 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6941 [(set_attr "type" "icmp")
6942 (set_attr "mode" "<MODE>")])
6944 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6945 [(set (reg:CCC FLAGS_REG)
6948 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6949 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6951 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6952 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6953 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6954 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6955 [(set_attr "type" "alu")
6956 (set_attr "mode" "<MODE>")])
6958 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6959 [(set (reg:CCC FLAGS_REG)
6962 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6963 (match_operand:SI 2 "general_operand" "g"))
6965 (set (match_operand:DI 0 "register_operand" "=r")
6966 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6967 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6968 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6969 [(set_attr "type" "alu")
6970 (set_attr "mode" "SI")])
6972 ;; The patterns that match these are at the end of this file.
6974 (define_expand "<plusminus_insn>xf3"
6975 [(set (match_operand:XF 0 "register_operand" "")
6977 (match_operand:XF 1 "register_operand" "")
6978 (match_operand:XF 2 "register_operand" "")))]
6982 (define_expand "<plusminus_insn><mode>3"
6983 [(set (match_operand:MODEF 0 "register_operand" "")
6985 (match_operand:MODEF 1 "register_operand" "")
6986 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6987 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6988 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6991 ;; Multiply instructions
6993 (define_expand "mul<mode>3"
6994 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6996 (match_operand:SWIM248 1 "register_operand" "")
6997 (match_operand:SWIM248 2 "<general_operand>" "")))
6998 (clobber (reg:CC FLAGS_REG))])]
7002 (define_expand "mulqi3"
7003 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7005 (match_operand:QI 1 "register_operand" "")
7006 (match_operand:QI 2 "nonimmediate_operand" "")))
7007 (clobber (reg:CC FLAGS_REG))])]
7008 "TARGET_QIMODE_MATH"
7012 ;; IMUL reg32/64, reg32/64, imm8 Direct
7013 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7014 ;; IMUL reg32/64, reg32/64, imm32 Direct
7015 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7016 ;; IMUL reg32/64, reg32/64 Direct
7017 ;; IMUL reg32/64, mem32/64 Direct
7019 (define_insn "*mul<mode>3_1"
7020 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7022 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7023 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7024 (clobber (reg:CC FLAGS_REG))]
7025 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7027 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7028 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7029 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7030 [(set_attr "type" "imul")
7031 (set_attr "prefix_0f" "0,0,1")
7032 (set (attr "athlon_decode")
7033 (cond [(eq_attr "cpu" "athlon")
7034 (const_string "vector")
7035 (eq_attr "alternative" "1")
7036 (const_string "vector")
7037 (and (eq_attr "alternative" "2")
7038 (match_operand 1 "memory_operand" ""))
7039 (const_string "vector")]
7040 (const_string "direct")))
7041 (set (attr "amdfam10_decode")
7042 (cond [(and (eq_attr "alternative" "0,1")
7043 (match_operand 1 "memory_operand" ""))
7044 (const_string "vector")]
7045 (const_string "direct")))
7046 (set_attr "mode" "<MODE>")])
7048 (define_insn "*mulsi3_1_zext"
7049 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7051 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7052 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7053 (clobber (reg:CC FLAGS_REG))]
7055 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7057 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7058 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7059 imul{l}\t{%2, %k0|%k0, %2}"
7060 [(set_attr "type" "imul")
7061 (set_attr "prefix_0f" "0,0,1")
7062 (set (attr "athlon_decode")
7063 (cond [(eq_attr "cpu" "athlon")
7064 (const_string "vector")
7065 (eq_attr "alternative" "1")
7066 (const_string "vector")
7067 (and (eq_attr "alternative" "2")
7068 (match_operand 1 "memory_operand" ""))
7069 (const_string "vector")]
7070 (const_string "direct")))
7071 (set (attr "amdfam10_decode")
7072 (cond [(and (eq_attr "alternative" "0,1")
7073 (match_operand 1 "memory_operand" ""))
7074 (const_string "vector")]
7075 (const_string "direct")))
7076 (set_attr "mode" "SI")])
7079 ;; IMUL reg16, reg16, imm8 VectorPath
7080 ;; IMUL reg16, mem16, imm8 VectorPath
7081 ;; IMUL reg16, reg16, imm16 VectorPath
7082 ;; IMUL reg16, mem16, imm16 VectorPath
7083 ;; IMUL reg16, reg16 Direct
7084 ;; IMUL reg16, mem16 Direct
7086 (define_insn "*mulhi3_1"
7087 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7088 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7089 (match_operand:HI 2 "general_operand" "K,n,mr")))
7090 (clobber (reg:CC FLAGS_REG))]
7092 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7094 imul{w}\t{%2, %1, %0|%0, %1, %2}
7095 imul{w}\t{%2, %1, %0|%0, %1, %2}
7096 imul{w}\t{%2, %0|%0, %2}"
7097 [(set_attr "type" "imul")
7098 (set_attr "prefix_0f" "0,0,1")
7099 (set (attr "athlon_decode")
7100 (cond [(eq_attr "cpu" "athlon")
7101 (const_string "vector")
7102 (eq_attr "alternative" "1,2")
7103 (const_string "vector")]
7104 (const_string "direct")))
7105 (set (attr "amdfam10_decode")
7106 (cond [(eq_attr "alternative" "0,1")
7107 (const_string "vector")]
7108 (const_string "direct")))
7109 (set_attr "mode" "HI")])
7115 (define_insn "*mulqi3_1"
7116 [(set (match_operand:QI 0 "register_operand" "=a")
7117 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7118 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7119 (clobber (reg:CC FLAGS_REG))]
7121 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7123 [(set_attr "type" "imul")
7124 (set_attr "length_immediate" "0")
7125 (set (attr "athlon_decode")
7126 (if_then_else (eq_attr "cpu" "athlon")
7127 (const_string "vector")
7128 (const_string "direct")))
7129 (set_attr "amdfam10_decode" "direct")
7130 (set_attr "mode" "QI")])
7132 (define_expand "<u>mul<mode><dwi>3"
7133 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7136 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7138 (match_operand:DWIH 2 "register_operand" ""))))
7139 (clobber (reg:CC FLAGS_REG))])]
7143 (define_expand "<u>mulqihi3"
7144 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7147 (match_operand:QI 1 "nonimmediate_operand" ""))
7149 (match_operand:QI 2 "register_operand" ""))))
7150 (clobber (reg:CC FLAGS_REG))])]
7151 "TARGET_QIMODE_MATH"
7154 (define_insn "*<u>mul<mode><dwi>3_1"
7155 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7158 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7160 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7161 (clobber (reg:CC FLAGS_REG))]
7162 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7163 "<sgnprefix>mul{<imodesuffix>}\t%2"
7164 [(set_attr "type" "imul")
7165 (set_attr "length_immediate" "0")
7166 (set (attr "athlon_decode")
7167 (if_then_else (eq_attr "cpu" "athlon")
7168 (const_string "vector")
7169 (const_string "double")))
7170 (set_attr "amdfam10_decode" "double")
7171 (set_attr "mode" "<MODE>")])
7173 (define_insn "*<u>mulqihi3_1"
7174 [(set (match_operand:HI 0 "register_operand" "=a")
7177 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7179 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7180 (clobber (reg:CC FLAGS_REG))]
7182 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7183 "<sgnprefix>mul{b}\t%2"
7184 [(set_attr "type" "imul")
7185 (set_attr "length_immediate" "0")
7186 (set (attr "athlon_decode")
7187 (if_then_else (eq_attr "cpu" "athlon")
7188 (const_string "vector")
7189 (const_string "direct")))
7190 (set_attr "amdfam10_decode" "direct")
7191 (set_attr "mode" "QI")])
7193 (define_expand "<s>mul<mode>3_highpart"
7194 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7199 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7201 (match_operand:SWI48 2 "register_operand" "")))
7203 (clobber (match_scratch:SWI48 3 ""))
7204 (clobber (reg:CC FLAGS_REG))])]
7206 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7208 (define_insn "*<s>muldi3_highpart_1"
7209 [(set (match_operand:DI 0 "register_operand" "=d")
7214 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7216 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7218 (clobber (match_scratch:DI 3 "=1"))
7219 (clobber (reg:CC FLAGS_REG))]
7221 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7222 "<sgnprefix>mul{q}\t%2"
7223 [(set_attr "type" "imul")
7224 (set_attr "length_immediate" "0")
7225 (set (attr "athlon_decode")
7226 (if_then_else (eq_attr "cpu" "athlon")
7227 (const_string "vector")
7228 (const_string "double")))
7229 (set_attr "amdfam10_decode" "double")
7230 (set_attr "mode" "DI")])
7232 (define_insn "*<s>mulsi3_highpart_1"
7233 [(set (match_operand:SI 0 "register_operand" "=d")
7238 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7240 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7242 (clobber (match_scratch:SI 3 "=1"))
7243 (clobber (reg:CC FLAGS_REG))]
7244 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7245 "<sgnprefix>mul{l}\t%2"
7246 [(set_attr "type" "imul")
7247 (set_attr "length_immediate" "0")
7248 (set (attr "athlon_decode")
7249 (if_then_else (eq_attr "cpu" "athlon")
7250 (const_string "vector")
7251 (const_string "double")))
7252 (set_attr "amdfam10_decode" "double")
7253 (set_attr "mode" "SI")])
7255 (define_insn "*<s>mulsi3_highpart_zext"
7256 [(set (match_operand:DI 0 "register_operand" "=d")
7257 (zero_extend:DI (truncate:SI
7259 (mult:DI (any_extend:DI
7260 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7262 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7264 (clobber (match_scratch:SI 3 "=1"))
7265 (clobber (reg:CC FLAGS_REG))]
7267 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7268 "<sgnprefix>mul{l}\t%2"
7269 [(set_attr "type" "imul")
7270 (set_attr "length_immediate" "0")
7271 (set (attr "athlon_decode")
7272 (if_then_else (eq_attr "cpu" "athlon")
7273 (const_string "vector")
7274 (const_string "double")))
7275 (set_attr "amdfam10_decode" "double")
7276 (set_attr "mode" "SI")])
7278 ;; The patterns that match these are at the end of this file.
7280 (define_expand "mulxf3"
7281 [(set (match_operand:XF 0 "register_operand" "")
7282 (mult:XF (match_operand:XF 1 "register_operand" "")
7283 (match_operand:XF 2 "register_operand" "")))]
7287 (define_expand "mul<mode>3"
7288 [(set (match_operand:MODEF 0 "register_operand" "")
7289 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7290 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7291 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7292 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7295 ;; Divide instructions
7297 ;; The patterns that match these are at the end of this file.
7299 (define_expand "divxf3"
7300 [(set (match_operand:XF 0 "register_operand" "")
7301 (div:XF (match_operand:XF 1 "register_operand" "")
7302 (match_operand:XF 2 "register_operand" "")))]
7306 (define_expand "divdf3"
7307 [(set (match_operand:DF 0 "register_operand" "")
7308 (div:DF (match_operand:DF 1 "register_operand" "")
7309 (match_operand:DF 2 "nonimmediate_operand" "")))]
7310 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7311 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7314 (define_expand "divsf3"
7315 [(set (match_operand:SF 0 "register_operand" "")
7316 (div:SF (match_operand:SF 1 "register_operand" "")
7317 (match_operand:SF 2 "nonimmediate_operand" "")))]
7318 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7321 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7322 && flag_finite_math_only && !flag_trapping_math
7323 && flag_unsafe_math_optimizations)
7325 ix86_emit_swdivsf (operands[0], operands[1],
7326 operands[2], SFmode);
7331 ;; Divmod instructions.
7333 (define_expand "divmodqi4"
7334 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7336 (match_operand:QI 1 "register_operand" "")
7337 (match_operand:QI 2 "nonimmediate_operand" "")))
7338 (set (match_operand:QI 3 "register_operand" "")
7339 (mod:QI (match_dup 1) (match_dup 2)))
7340 (clobber (reg:CC FLAGS_REG))])]
7341 "TARGET_QIMODE_MATH"
7346 tmp0 = gen_reg_rtx (HImode);
7347 tmp1 = gen_reg_rtx (HImode);
7349 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7351 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7352 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7354 /* Extract remainder from AH. */
7355 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7356 insn = emit_move_insn (operands[3], tmp1);
7358 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7359 set_unique_reg_note (insn, REG_EQUAL, mod);
7361 /* Extract quotient from AL. */
7362 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7364 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7365 set_unique_reg_note (insn, REG_EQUAL, div);
7370 (define_expand "udivmodqi4"
7371 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7373 (match_operand:QI 1 "register_operand" "")
7374 (match_operand:QI 2 "nonimmediate_operand" "")))
7375 (set (match_operand:QI 3 "register_operand" "")
7376 (umod:QI (match_dup 1) (match_dup 2)))
7377 (clobber (reg:CC FLAGS_REG))])]
7378 "TARGET_QIMODE_MATH"
7383 tmp0 = gen_reg_rtx (HImode);
7384 tmp1 = gen_reg_rtx (HImode);
7386 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7388 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7389 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7391 /* Extract remainder from AH. */
7392 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7393 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7394 insn = emit_move_insn (operands[3], tmp1);
7396 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7397 set_unique_reg_note (insn, REG_EQUAL, mod);
7399 /* Extract quotient from AL. */
7400 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7402 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7403 set_unique_reg_note (insn, REG_EQUAL, div);
7408 ;; Divide AX by r/m8, with result stored in
7411 ;; Change div/mod to HImode and extend the second argument to HImode
7412 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7413 ;; combine may fail.
7414 (define_insn "divmodhiqi3"
7415 [(set (match_operand:HI 0 "register_operand" "=a")
7420 (mod:HI (match_operand:HI 1 "register_operand" "0")
7422 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7426 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7427 (clobber (reg:CC FLAGS_REG))]
7428 "TARGET_QIMODE_MATH"
7430 [(set_attr "type" "idiv")
7431 (set_attr "mode" "QI")])
7433 (define_insn "udivmodhiqi3"
7434 [(set (match_operand:HI 0 "register_operand" "=a")
7439 (mod:HI (match_operand:HI 1 "register_operand" "0")
7441 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7445 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7446 (clobber (reg:CC FLAGS_REG))]
7447 "TARGET_QIMODE_MATH"
7449 [(set_attr "type" "idiv")
7450 (set_attr "mode" "QI")])
7452 (define_expand "divmod<mode>4"
7453 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7455 (match_operand:SWIM248 1 "register_operand" "")
7456 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7457 (set (match_operand:SWIM248 3 "register_operand" "")
7458 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7459 (clobber (reg:CC FLAGS_REG))])]
7463 (define_insn_and_split "*divmod<mode>4"
7464 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7465 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7466 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7467 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7468 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7469 (clobber (reg:CC FLAGS_REG))]
7473 [(parallel [(set (match_dup 1)
7474 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7475 (clobber (reg:CC FLAGS_REG))])
7476 (parallel [(set (match_dup 0)
7477 (div:SWIM248 (match_dup 2) (match_dup 3)))
7479 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7481 (clobber (reg:CC FLAGS_REG))])]
7483 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7485 if (<MODE>mode != HImode
7486 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7487 operands[4] = operands[2];
7490 /* Avoid use of cltd in favor of a mov+shift. */
7491 emit_move_insn (operands[1], operands[2]);
7492 operands[4] = operands[1];
7495 [(set_attr "type" "multi")
7496 (set_attr "mode" "<MODE>")])
7498 (define_insn "*divmod<mode>4_noext"
7499 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7500 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7501 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7502 (set (match_operand:SWIM248 1 "register_operand" "=d")
7503 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7504 (use (match_operand:SWIM248 4 "register_operand" "1"))
7505 (clobber (reg:CC FLAGS_REG))]
7507 "idiv{<imodesuffix>}\t%3"
7508 [(set_attr "type" "idiv")
7509 (set_attr "mode" "<MODE>")])
7511 (define_expand "udivmod<mode>4"
7512 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7514 (match_operand:SWIM248 1 "register_operand" "")
7515 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7516 (set (match_operand:SWIM248 3 "register_operand" "")
7517 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7518 (clobber (reg:CC FLAGS_REG))])]
7522 (define_insn_and_split "*udivmod<mode>4"
7523 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7524 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7525 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7526 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7527 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7528 (clobber (reg:CC FLAGS_REG))]
7532 [(set (match_dup 1) (const_int 0))
7533 (parallel [(set (match_dup 0)
7534 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7536 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7538 (clobber (reg:CC FLAGS_REG))])]
7540 [(set_attr "type" "multi")
7541 (set_attr "mode" "<MODE>")])
7543 (define_insn "*udivmod<mode>4_noext"
7544 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7545 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7546 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7547 (set (match_operand:SWIM248 1 "register_operand" "=d")
7548 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7549 (use (match_operand:SWIM248 4 "register_operand" "1"))
7550 (clobber (reg:CC FLAGS_REG))]
7552 "div{<imodesuffix>}\t%3"
7553 [(set_attr "type" "idiv")
7554 (set_attr "mode" "<MODE>")])
7556 ;; We cannot use div/idiv for double division, because it causes
7557 ;; "division by zero" on the overflow and that's not what we expect
7558 ;; from truncate. Because true (non truncating) double division is
7559 ;; never generated, we can't create this insn anyway.
7562 ; [(set (match_operand:SI 0 "register_operand" "=a")
7564 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7566 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7567 ; (set (match_operand:SI 3 "register_operand" "=d")
7569 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7570 ; (clobber (reg:CC FLAGS_REG))]
7572 ; "div{l}\t{%2, %0|%0, %2}"
7573 ; [(set_attr "type" "idiv")])
7575 ;;- Logical AND instructions
7577 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7578 ;; Note that this excludes ah.
7580 (define_expand "testsi_ccno_1"
7581 [(set (reg:CCNO FLAGS_REG)
7583 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7584 (match_operand:SI 1 "nonmemory_operand" ""))
7589 (define_expand "testqi_ccz_1"
7590 [(set (reg:CCZ FLAGS_REG)
7591 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7592 (match_operand:QI 1 "nonmemory_operand" ""))
7597 (define_insn "*testdi_1"
7598 [(set (reg FLAGS_REG)
7601 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7602 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7604 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7605 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7607 test{l}\t{%k1, %k0|%k0, %k1}
7608 test{l}\t{%k1, %k0|%k0, %k1}
7609 test{q}\t{%1, %0|%0, %1}
7610 test{q}\t{%1, %0|%0, %1}
7611 test{q}\t{%1, %0|%0, %1}"
7612 [(set_attr "type" "test")
7613 (set_attr "modrm" "0,1,0,1,1")
7614 (set_attr "mode" "SI,SI,DI,DI,DI")])
7616 (define_insn "*testqi_1_maybe_si"
7617 [(set (reg FLAGS_REG)
7620 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7621 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7623 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7624 && ix86_match_ccmode (insn,
7625 CONST_INT_P (operands[1])
7626 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7628 if (which_alternative == 3)
7630 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7631 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7632 return "test{l}\t{%1, %k0|%k0, %1}";
7634 return "test{b}\t{%1, %0|%0, %1}";
7636 [(set_attr "type" "test")
7637 (set_attr "modrm" "0,1,1,1")
7638 (set_attr "mode" "QI,QI,QI,SI")
7639 (set_attr "pent_pair" "uv,np,uv,np")])
7641 (define_insn "*test<mode>_1"
7642 [(set (reg FLAGS_REG)
7645 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7646 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7648 "ix86_match_ccmode (insn, CCNOmode)
7649 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7650 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7651 [(set_attr "type" "test")
7652 (set_attr "modrm" "0,1,1")
7653 (set_attr "mode" "<MODE>")
7654 (set_attr "pent_pair" "uv,np,uv")])
7656 (define_expand "testqi_ext_ccno_0"
7657 [(set (reg:CCNO FLAGS_REG)
7661 (match_operand 0 "ext_register_operand" "")
7664 (match_operand 1 "const_int_operand" ""))
7669 (define_insn "*testqi_ext_0"
7670 [(set (reg FLAGS_REG)
7674 (match_operand 0 "ext_register_operand" "Q")
7677 (match_operand 1 "const_int_operand" "n"))
7679 "ix86_match_ccmode (insn, CCNOmode)"
7680 "test{b}\t{%1, %h0|%h0, %1}"
7681 [(set_attr "type" "test")
7682 (set_attr "mode" "QI")
7683 (set_attr "length_immediate" "1")
7684 (set_attr "modrm" "1")
7685 (set_attr "pent_pair" "np")])
7687 (define_insn "*testqi_ext_1_rex64"
7688 [(set (reg FLAGS_REG)
7692 (match_operand 0 "ext_register_operand" "Q")
7696 (match_operand:QI 1 "register_operand" "Q")))
7698 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7699 "test{b}\t{%1, %h0|%h0, %1}"
7700 [(set_attr "type" "test")
7701 (set_attr "mode" "QI")])
7703 (define_insn "*testqi_ext_1"
7704 [(set (reg FLAGS_REG)
7708 (match_operand 0 "ext_register_operand" "Q")
7712 (match_operand:QI 1 "general_operand" "Qm")))
7714 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7715 "test{b}\t{%1, %h0|%h0, %1}"
7716 [(set_attr "type" "test")
7717 (set_attr "mode" "QI")])
7719 (define_insn "*testqi_ext_2"
7720 [(set (reg FLAGS_REG)
7724 (match_operand 0 "ext_register_operand" "Q")
7728 (match_operand 1 "ext_register_operand" "Q")
7732 "ix86_match_ccmode (insn, CCNOmode)"
7733 "test{b}\t{%h1, %h0|%h0, %h1}"
7734 [(set_attr "type" "test")
7735 (set_attr "mode" "QI")])
7737 (define_insn "*testqi_ext_3_rex64"
7738 [(set (reg FLAGS_REG)
7739 (compare (zero_extract:DI
7740 (match_operand 0 "nonimmediate_operand" "rm")
7741 (match_operand:DI 1 "const_int_operand" "")
7742 (match_operand:DI 2 "const_int_operand" ""))
7745 && ix86_match_ccmode (insn, CCNOmode)
7746 && INTVAL (operands[1]) > 0
7747 && INTVAL (operands[2]) >= 0
7748 /* Ensure that resulting mask is zero or sign extended operand. */
7749 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7750 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7751 && INTVAL (operands[1]) > 32))
7752 && (GET_MODE (operands[0]) == SImode
7753 || GET_MODE (operands[0]) == DImode
7754 || GET_MODE (operands[0]) == HImode
7755 || GET_MODE (operands[0]) == QImode)"
7758 ;; Combine likes to form bit extractions for some tests. Humor it.
7759 (define_insn "*testqi_ext_3"
7760 [(set (reg FLAGS_REG)
7761 (compare (zero_extract:SI
7762 (match_operand 0 "nonimmediate_operand" "rm")
7763 (match_operand:SI 1 "const_int_operand" "")
7764 (match_operand:SI 2 "const_int_operand" ""))
7766 "ix86_match_ccmode (insn, CCNOmode)
7767 && INTVAL (operands[1]) > 0
7768 && INTVAL (operands[2]) >= 0
7769 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7770 && (GET_MODE (operands[0]) == SImode
7771 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7772 || GET_MODE (operands[0]) == HImode
7773 || GET_MODE (operands[0]) == QImode)"
7777 [(set (match_operand 0 "flags_reg_operand" "")
7778 (match_operator 1 "compare_operator"
7780 (match_operand 2 "nonimmediate_operand" "")
7781 (match_operand 3 "const_int_operand" "")
7782 (match_operand 4 "const_int_operand" ""))
7784 "ix86_match_ccmode (insn, CCNOmode)"
7785 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7787 rtx val = operands[2];
7788 HOST_WIDE_INT len = INTVAL (operands[3]);
7789 HOST_WIDE_INT pos = INTVAL (operands[4]);
7791 enum machine_mode mode, submode;
7793 mode = GET_MODE (val);
7796 /* ??? Combine likes to put non-volatile mem extractions in QImode
7797 no matter the size of the test. So find a mode that works. */
7798 if (! MEM_VOLATILE_P (val))
7800 mode = smallest_mode_for_size (pos + len, MODE_INT);
7801 val = adjust_address (val, mode, 0);
7804 else if (GET_CODE (val) == SUBREG
7805 && (submode = GET_MODE (SUBREG_REG (val)),
7806 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7807 && pos + len <= GET_MODE_BITSIZE (submode)
7808 && GET_MODE_CLASS (submode) == MODE_INT)
7810 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7812 val = SUBREG_REG (val);
7814 else if (mode == HImode && pos + len <= 8)
7816 /* Small HImode tests can be converted to QImode. */
7818 val = gen_lowpart (QImode, val);
7821 if (len == HOST_BITS_PER_WIDE_INT)
7824 mask = ((HOST_WIDE_INT)1 << len) - 1;
7827 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7830 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7831 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7832 ;; this is relatively important trick.
7833 ;; Do the conversion only post-reload to avoid limiting of the register class
7836 [(set (match_operand 0 "flags_reg_operand" "")
7837 (match_operator 1 "compare_operator"
7838 [(and (match_operand 2 "register_operand" "")
7839 (match_operand 3 "const_int_operand" ""))
7842 && QI_REG_P (operands[2])
7843 && GET_MODE (operands[2]) != QImode
7844 && ((ix86_match_ccmode (insn, CCZmode)
7845 && !(INTVAL (operands[3]) & ~(255 << 8)))
7846 || (ix86_match_ccmode (insn, CCNOmode)
7847 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7850 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7853 "operands[2] = gen_lowpart (SImode, operands[2]);
7854 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7857 [(set (match_operand 0 "flags_reg_operand" "")
7858 (match_operator 1 "compare_operator"
7859 [(and (match_operand 2 "nonimmediate_operand" "")
7860 (match_operand 3 "const_int_operand" ""))
7863 && GET_MODE (operands[2]) != QImode
7864 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7865 && ((ix86_match_ccmode (insn, CCZmode)
7866 && !(INTVAL (operands[3]) & ~255))
7867 || (ix86_match_ccmode (insn, CCNOmode)
7868 && !(INTVAL (operands[3]) & ~127)))"
7870 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7872 "operands[2] = gen_lowpart (QImode, operands[2]);
7873 operands[3] = gen_lowpart (QImode, operands[3]);")
7875 ;; %%% This used to optimize known byte-wide and operations to memory,
7876 ;; and sometimes to QImode registers. If this is considered useful,
7877 ;; it should be done with splitters.
7879 (define_expand "and<mode>3"
7880 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7881 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7882 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7884 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7886 (define_insn "*anddi_1"
7887 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7889 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7890 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7891 (clobber (reg:CC FLAGS_REG))]
7892 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7894 switch (get_attr_type (insn))
7898 enum machine_mode mode;
7900 gcc_assert (CONST_INT_P (operands[2]));
7901 if (INTVAL (operands[2]) == 0xff)
7905 gcc_assert (INTVAL (operands[2]) == 0xffff);
7909 operands[1] = gen_lowpart (mode, operands[1]);
7911 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7913 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7917 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7918 if (get_attr_mode (insn) == MODE_SI)
7919 return "and{l}\t{%k2, %k0|%k0, %k2}";
7921 return "and{q}\t{%2, %0|%0, %2}";
7924 [(set_attr "type" "alu,alu,alu,imovx")
7925 (set_attr "length_immediate" "*,*,*,0")
7926 (set (attr "prefix_rex")
7928 (and (eq_attr "type" "imovx")
7929 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7930 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7932 (const_string "*")))
7933 (set_attr "mode" "SI,DI,DI,SI")])
7935 (define_insn "*andsi_1"
7936 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7937 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7938 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7939 (clobber (reg:CC FLAGS_REG))]
7940 "ix86_binary_operator_ok (AND, SImode, operands)"
7942 switch (get_attr_type (insn))
7946 enum machine_mode mode;
7948 gcc_assert (CONST_INT_P (operands[2]));
7949 if (INTVAL (operands[2]) == 0xff)
7953 gcc_assert (INTVAL (operands[2]) == 0xffff);
7957 operands[1] = gen_lowpart (mode, operands[1]);
7959 return "movz{bl|x}\t{%1, %0|%0, %1}";
7961 return "movz{wl|x}\t{%1, %0|%0, %1}";
7965 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7966 return "and{l}\t{%2, %0|%0, %2}";
7969 [(set_attr "type" "alu,alu,imovx")
7970 (set (attr "prefix_rex")
7972 (and (eq_attr "type" "imovx")
7973 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7974 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7976 (const_string "*")))
7977 (set_attr "length_immediate" "*,*,0")
7978 (set_attr "mode" "SI")])
7980 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7981 (define_insn "*andsi_1_zext"
7982 [(set (match_operand:DI 0 "register_operand" "=r")
7984 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7985 (match_operand:SI 2 "general_operand" "g"))))
7986 (clobber (reg:CC FLAGS_REG))]
7987 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7988 "and{l}\t{%2, %k0|%k0, %2}"
7989 [(set_attr "type" "alu")
7990 (set_attr "mode" "SI")])
7992 (define_insn "*andhi_1"
7993 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7994 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7995 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7996 (clobber (reg:CC FLAGS_REG))]
7997 "ix86_binary_operator_ok (AND, HImode, operands)"
7999 switch (get_attr_type (insn))
8002 gcc_assert (CONST_INT_P (operands[2]));
8003 gcc_assert (INTVAL (operands[2]) == 0xff);
8004 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8007 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8009 return "and{w}\t{%2, %0|%0, %2}";
8012 [(set_attr "type" "alu,alu,imovx")
8013 (set_attr "length_immediate" "*,*,0")
8014 (set (attr "prefix_rex")
8016 (and (eq_attr "type" "imovx")
8017 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8019 (const_string "*")))
8020 (set_attr "mode" "HI,HI,SI")])
8022 ;; %%% Potential partial reg stall on alternative 2. What to do?
8023 (define_insn "*andqi_1"
8024 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8025 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8026 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8027 (clobber (reg:CC FLAGS_REG))]
8028 "ix86_binary_operator_ok (AND, QImode, operands)"
8030 and{b}\t{%2, %0|%0, %2}
8031 and{b}\t{%2, %0|%0, %2}
8032 and{l}\t{%k2, %k0|%k0, %k2}"
8033 [(set_attr "type" "alu")
8034 (set_attr "mode" "QI,QI,SI")])
8036 (define_insn "*andqi_1_slp"
8037 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8038 (and:QI (match_dup 0)
8039 (match_operand:QI 1 "general_operand" "qn,qmn")))
8040 (clobber (reg:CC FLAGS_REG))]
8041 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8042 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8043 "and{b}\t{%1, %0|%0, %1}"
8044 [(set_attr "type" "alu1")
8045 (set_attr "mode" "QI")])
8048 [(set (match_operand 0 "register_operand" "")
8050 (const_int -65536)))
8051 (clobber (reg:CC FLAGS_REG))]
8052 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8053 || optimize_function_for_size_p (cfun)"
8054 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8055 "operands[1] = gen_lowpart (HImode, operands[0]);")
8058 [(set (match_operand 0 "ext_register_operand" "")
8061 (clobber (reg:CC FLAGS_REG))]
8062 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8063 && reload_completed"
8064 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8065 "operands[1] = gen_lowpart (QImode, operands[0]);")
8068 [(set (match_operand 0 "ext_register_operand" "")
8070 (const_int -65281)))
8071 (clobber (reg:CC FLAGS_REG))]
8072 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8073 && reload_completed"
8074 [(parallel [(set (zero_extract:SI (match_dup 0)
8078 (zero_extract:SI (match_dup 0)
8081 (zero_extract:SI (match_dup 0)
8084 (clobber (reg:CC FLAGS_REG))])]
8085 "operands[0] = gen_lowpart (SImode, operands[0]);")
8087 (define_insn "*anddi_2"
8088 [(set (reg FLAGS_REG)
8091 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8092 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8094 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8095 (and:DI (match_dup 1) (match_dup 2)))]
8096 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8097 && ix86_binary_operator_ok (AND, DImode, operands)"
8099 and{l}\t{%k2, %k0|%k0, %k2}
8100 and{q}\t{%2, %0|%0, %2}
8101 and{q}\t{%2, %0|%0, %2}"
8102 [(set_attr "type" "alu")
8103 (set_attr "mode" "SI,DI,DI")])
8105 (define_insn "*andqi_2_maybe_si"
8106 [(set (reg FLAGS_REG)
8108 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8109 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8111 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8112 (and:QI (match_dup 1) (match_dup 2)))]
8113 "ix86_binary_operator_ok (AND, QImode, operands)
8114 && ix86_match_ccmode (insn,
8115 CONST_INT_P (operands[2])
8116 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8118 if (which_alternative == 2)
8120 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8121 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8122 return "and{l}\t{%2, %k0|%k0, %2}";
8124 return "and{b}\t{%2, %0|%0, %2}";
8126 [(set_attr "type" "alu")
8127 (set_attr "mode" "QI,QI,SI")])
8129 (define_insn "*and<mode>_2"
8130 [(set (reg FLAGS_REG)
8131 (compare (and:SWI124
8132 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8133 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8135 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8136 (and:SWI124 (match_dup 1) (match_dup 2)))]
8137 "ix86_match_ccmode (insn, CCNOmode)
8138 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8139 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8140 [(set_attr "type" "alu")
8141 (set_attr "mode" "<MODE>")])
8143 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8144 (define_insn "*andsi_2_zext"
8145 [(set (reg FLAGS_REG)
8147 (match_operand:SI 1 "nonimmediate_operand" "%0")
8148 (match_operand:SI 2 "general_operand" "g"))
8150 (set (match_operand:DI 0 "register_operand" "=r")
8151 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8152 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8153 && ix86_binary_operator_ok (AND, SImode, operands)"
8154 "and{l}\t{%2, %k0|%k0, %2}"
8155 [(set_attr "type" "alu")
8156 (set_attr "mode" "SI")])
8158 (define_insn "*andqi_2_slp"
8159 [(set (reg FLAGS_REG)
8161 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8162 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8164 (set (strict_low_part (match_dup 0))
8165 (and:QI (match_dup 0) (match_dup 1)))]
8166 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8167 && ix86_match_ccmode (insn, CCNOmode)
8168 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8169 "and{b}\t{%1, %0|%0, %1}"
8170 [(set_attr "type" "alu1")
8171 (set_attr "mode" "QI")])
8173 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8174 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8175 ;; for a QImode operand, which of course failed.
8176 (define_insn "andqi_ext_0"
8177 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8182 (match_operand 1 "ext_register_operand" "0")
8185 (match_operand 2 "const_int_operand" "n")))
8186 (clobber (reg:CC FLAGS_REG))]
8188 "and{b}\t{%2, %h0|%h0, %2}"
8189 [(set_attr "type" "alu")
8190 (set_attr "length_immediate" "1")
8191 (set_attr "modrm" "1")
8192 (set_attr "mode" "QI")])
8194 ;; Generated by peephole translating test to and. This shows up
8195 ;; often in fp comparisons.
8196 (define_insn "*andqi_ext_0_cc"
8197 [(set (reg FLAGS_REG)
8201 (match_operand 1 "ext_register_operand" "0")
8204 (match_operand 2 "const_int_operand" "n"))
8206 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8215 "ix86_match_ccmode (insn, CCNOmode)"
8216 "and{b}\t{%2, %h0|%h0, %2}"
8217 [(set_attr "type" "alu")
8218 (set_attr "length_immediate" "1")
8219 (set_attr "modrm" "1")
8220 (set_attr "mode" "QI")])
8222 (define_insn "*andqi_ext_1_rex64"
8223 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8228 (match_operand 1 "ext_register_operand" "0")
8232 (match_operand 2 "ext_register_operand" "Q"))))
8233 (clobber (reg:CC FLAGS_REG))]
8235 "and{b}\t{%2, %h0|%h0, %2}"
8236 [(set_attr "type" "alu")
8237 (set_attr "length_immediate" "0")
8238 (set_attr "mode" "QI")])
8240 (define_insn "*andqi_ext_1"
8241 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8246 (match_operand 1 "ext_register_operand" "0")
8250 (match_operand:QI 2 "general_operand" "Qm"))))
8251 (clobber (reg:CC FLAGS_REG))]
8253 "and{b}\t{%2, %h0|%h0, %2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "length_immediate" "0")
8256 (set_attr "mode" "QI")])
8258 (define_insn "*andqi_ext_2"
8259 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8264 (match_operand 1 "ext_register_operand" "%0")
8268 (match_operand 2 "ext_register_operand" "Q")
8271 (clobber (reg:CC FLAGS_REG))]
8273 "and{b}\t{%h2, %h0|%h0, %h2}"
8274 [(set_attr "type" "alu")
8275 (set_attr "length_immediate" "0")
8276 (set_attr "mode" "QI")])
8278 ;; Convert wide AND instructions with immediate operand to shorter QImode
8279 ;; equivalents when possible.
8280 ;; Don't do the splitting with memory operands, since it introduces risk
8281 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8282 ;; for size, but that can (should?) be handled by generic code instead.
8284 [(set (match_operand 0 "register_operand" "")
8285 (and (match_operand 1 "register_operand" "")
8286 (match_operand 2 "const_int_operand" "")))
8287 (clobber (reg:CC FLAGS_REG))]
8289 && QI_REG_P (operands[0])
8290 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8291 && !(~INTVAL (operands[2]) & ~(255 << 8))
8292 && GET_MODE (operands[0]) != QImode"
8293 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8294 (and:SI (zero_extract:SI (match_dup 1)
8295 (const_int 8) (const_int 8))
8297 (clobber (reg:CC FLAGS_REG))])]
8298 "operands[0] = gen_lowpart (SImode, operands[0]);
8299 operands[1] = gen_lowpart (SImode, operands[1]);
8300 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8302 ;; Since AND can be encoded with sign extended immediate, this is only
8303 ;; profitable when 7th bit is not set.
8305 [(set (match_operand 0 "register_operand" "")
8306 (and (match_operand 1 "general_operand" "")
8307 (match_operand 2 "const_int_operand" "")))
8308 (clobber (reg:CC FLAGS_REG))]
8310 && ANY_QI_REG_P (operands[0])
8311 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8312 && !(~INTVAL (operands[2]) & ~255)
8313 && !(INTVAL (operands[2]) & 128)
8314 && GET_MODE (operands[0]) != QImode"
8315 [(parallel [(set (strict_low_part (match_dup 0))
8316 (and:QI (match_dup 1)
8318 (clobber (reg:CC FLAGS_REG))])]
8319 "operands[0] = gen_lowpart (QImode, operands[0]);
8320 operands[1] = gen_lowpart (QImode, operands[1]);
8321 operands[2] = gen_lowpart (QImode, operands[2]);")
8323 ;; Logical inclusive and exclusive OR instructions
8325 ;; %%% This used to optimize known byte-wide and operations to memory.
8326 ;; If this is considered useful, it should be done with splitters.
8328 (define_expand "<code><mode>3"
8329 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8330 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8331 (match_operand:SWIM 2 "<general_operand>" "")))]
8333 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8335 (define_insn "*<code><mode>_1"
8336 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8338 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8339 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8340 (clobber (reg:CC FLAGS_REG))]
8341 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8342 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8343 [(set_attr "type" "alu")
8344 (set_attr "mode" "<MODE>")])
8346 ;; %%% Potential partial reg stall on alternative 2. What to do?
8347 (define_insn "*<code>qi_1"
8348 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8349 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8350 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8351 (clobber (reg:CC FLAGS_REG))]
8352 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8354 <logic>{b}\t{%2, %0|%0, %2}
8355 <logic>{b}\t{%2, %0|%0, %2}
8356 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8357 [(set_attr "type" "alu")
8358 (set_attr "mode" "QI,QI,SI")])
8360 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8361 (define_insn "*<code>si_1_zext"
8362 [(set (match_operand:DI 0 "register_operand" "=r")
8364 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8365 (match_operand:SI 2 "general_operand" "g"))))
8366 (clobber (reg:CC FLAGS_REG))]
8367 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8368 "<logic>{l}\t{%2, %k0|%k0, %2}"
8369 [(set_attr "type" "alu")
8370 (set_attr "mode" "SI")])
8372 (define_insn "*<code>si_1_zext_imm"
8373 [(set (match_operand:DI 0 "register_operand" "=r")
8375 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8376 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8377 (clobber (reg:CC FLAGS_REG))]
8378 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8379 "<logic>{l}\t{%2, %k0|%k0, %2}"
8380 [(set_attr "type" "alu")
8381 (set_attr "mode" "SI")])
8383 (define_insn "*<code>qi_1_slp"
8384 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8385 (any_or:QI (match_dup 0)
8386 (match_operand:QI 1 "general_operand" "qmn,qn")))
8387 (clobber (reg:CC FLAGS_REG))]
8388 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8389 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8390 "<logic>{b}\t{%1, %0|%0, %1}"
8391 [(set_attr "type" "alu1")
8392 (set_attr "mode" "QI")])
8394 (define_insn "*<code><mode>_2"
8395 [(set (reg FLAGS_REG)
8396 (compare (any_or:SWI
8397 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8398 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8400 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8401 (any_or:SWI (match_dup 1) (match_dup 2)))]
8402 "ix86_match_ccmode (insn, CCNOmode)
8403 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8404 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8405 [(set_attr "type" "alu")
8406 (set_attr "mode" "<MODE>")])
8408 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8409 ;; ??? Special case for immediate operand is missing - it is tricky.
8410 (define_insn "*<code>si_2_zext"
8411 [(set (reg FLAGS_REG)
8412 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8413 (match_operand:SI 2 "general_operand" "g"))
8415 (set (match_operand:DI 0 "register_operand" "=r")
8416 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8417 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8418 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8419 "<logic>{l}\t{%2, %k0|%k0, %2}"
8420 [(set_attr "type" "alu")
8421 (set_attr "mode" "SI")])
8423 (define_insn "*<code>si_2_zext_imm"
8424 [(set (reg FLAGS_REG)
8426 (match_operand:SI 1 "nonimmediate_operand" "%0")
8427 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8429 (set (match_operand:DI 0 "register_operand" "=r")
8430 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8431 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8432 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8433 "<logic>{l}\t{%2, %k0|%k0, %2}"
8434 [(set_attr "type" "alu")
8435 (set_attr "mode" "SI")])
8437 (define_insn "*<code>qi_2_slp"
8438 [(set (reg FLAGS_REG)
8439 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8440 (match_operand:QI 1 "general_operand" "qmn,qn"))
8442 (set (strict_low_part (match_dup 0))
8443 (any_or:QI (match_dup 0) (match_dup 1)))]
8444 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8445 && ix86_match_ccmode (insn, CCNOmode)
8446 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8447 "<logic>{b}\t{%1, %0|%0, %1}"
8448 [(set_attr "type" "alu1")
8449 (set_attr "mode" "QI")])
8451 (define_insn "*<code><mode>_3"
8452 [(set (reg FLAGS_REG)
8453 (compare (any_or:SWI
8454 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8455 (match_operand:SWI 2 "<general_operand>" "<g>"))
8457 (clobber (match_scratch:SWI 0 "=<r>"))]
8458 "ix86_match_ccmode (insn, CCNOmode)
8459 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8460 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8461 [(set_attr "type" "alu")
8462 (set_attr "mode" "<MODE>")])
8464 (define_insn "*<code>qi_ext_0"
8465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8470 (match_operand 1 "ext_register_operand" "0")
8473 (match_operand 2 "const_int_operand" "n")))
8474 (clobber (reg:CC FLAGS_REG))]
8475 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8476 "<logic>{b}\t{%2, %h0|%h0, %2}"
8477 [(set_attr "type" "alu")
8478 (set_attr "length_immediate" "1")
8479 (set_attr "modrm" "1")
8480 (set_attr "mode" "QI")])
8482 (define_insn "*<code>qi_ext_1_rex64"
8483 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8488 (match_operand 1 "ext_register_operand" "0")
8492 (match_operand 2 "ext_register_operand" "Q"))))
8493 (clobber (reg:CC FLAGS_REG))]
8495 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8496 "<logic>{b}\t{%2, %h0|%h0, %2}"
8497 [(set_attr "type" "alu")
8498 (set_attr "length_immediate" "0")
8499 (set_attr "mode" "QI")])
8501 (define_insn "*<code>qi_ext_1"
8502 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8507 (match_operand 1 "ext_register_operand" "0")
8511 (match_operand:QI 2 "general_operand" "Qm"))))
8512 (clobber (reg:CC FLAGS_REG))]
8514 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8515 "<logic>{b}\t{%2, %h0|%h0, %2}"
8516 [(set_attr "type" "alu")
8517 (set_attr "length_immediate" "0")
8518 (set_attr "mode" "QI")])
8520 (define_insn "*<code>qi_ext_2"
8521 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8525 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8528 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8531 (clobber (reg:CC FLAGS_REG))]
8532 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8533 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8534 [(set_attr "type" "alu")
8535 (set_attr "length_immediate" "0")
8536 (set_attr "mode" "QI")])
8539 [(set (match_operand 0 "register_operand" "")
8540 (any_or (match_operand 1 "register_operand" "")
8541 (match_operand 2 "const_int_operand" "")))
8542 (clobber (reg:CC FLAGS_REG))]
8544 && QI_REG_P (operands[0])
8545 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8546 && !(INTVAL (operands[2]) & ~(255 << 8))
8547 && GET_MODE (operands[0]) != QImode"
8548 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8549 (any_or:SI (zero_extract:SI (match_dup 1)
8550 (const_int 8) (const_int 8))
8552 (clobber (reg:CC FLAGS_REG))])]
8553 "operands[0] = gen_lowpart (SImode, operands[0]);
8554 operands[1] = gen_lowpart (SImode, operands[1]);
8555 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8557 ;; Since OR can be encoded with sign extended immediate, this is only
8558 ;; profitable when 7th bit is set.
8560 [(set (match_operand 0 "register_operand" "")
8561 (any_or (match_operand 1 "general_operand" "")
8562 (match_operand 2 "const_int_operand" "")))
8563 (clobber (reg:CC FLAGS_REG))]
8565 && ANY_QI_REG_P (operands[0])
8566 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8567 && !(INTVAL (operands[2]) & ~255)
8568 && (INTVAL (operands[2]) & 128)
8569 && GET_MODE (operands[0]) != QImode"
8570 [(parallel [(set (strict_low_part (match_dup 0))
8571 (any_or:QI (match_dup 1)
8573 (clobber (reg:CC FLAGS_REG))])]
8574 "operands[0] = gen_lowpart (QImode, operands[0]);
8575 operands[1] = gen_lowpart (QImode, operands[1]);
8576 operands[2] = gen_lowpart (QImode, operands[2]);")
8578 (define_expand "xorqi_cc_ext_1"
8580 (set (reg:CCNO FLAGS_REG)
8584 (match_operand 1 "ext_register_operand" "")
8587 (match_operand:QI 2 "general_operand" ""))
8589 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8601 (define_insn "*xorqi_cc_ext_1_rex64"
8602 [(set (reg FLAGS_REG)
8606 (match_operand 1 "ext_register_operand" "0")
8609 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8611 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8620 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8621 "xor{b}\t{%2, %h0|%h0, %2}"
8622 [(set_attr "type" "alu")
8623 (set_attr "modrm" "1")
8624 (set_attr "mode" "QI")])
8626 (define_insn "*xorqi_cc_ext_1"
8627 [(set (reg FLAGS_REG)
8631 (match_operand 1 "ext_register_operand" "0")
8634 (match_operand:QI 2 "general_operand" "qmn"))
8636 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8645 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8646 "xor{b}\t{%2, %h0|%h0, %2}"
8647 [(set_attr "type" "alu")
8648 (set_attr "modrm" "1")
8649 (set_attr "mode" "QI")])
8651 ;; Negation instructions
8653 (define_expand "neg<mode>2"
8654 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8655 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8657 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8659 (define_insn_and_split "*neg<dwi>2_doubleword"
8660 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8661 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8662 (clobber (reg:CC FLAGS_REG))]
8663 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8667 [(set (reg:CCZ FLAGS_REG)
8668 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8669 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8672 (plus:DWIH (match_dup 3)
8673 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8675 (clobber (reg:CC FLAGS_REG))])
8678 (neg:DWIH (match_dup 2)))
8679 (clobber (reg:CC FLAGS_REG))])]
8680 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8682 (define_insn "*neg<mode>2_1"
8683 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8684 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8685 (clobber (reg:CC FLAGS_REG))]
8686 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8687 "neg{<imodesuffix>}\t%0"
8688 [(set_attr "type" "negnot")
8689 (set_attr "mode" "<MODE>")])
8691 ;; Combine is quite creative about this pattern.
8692 (define_insn "*negsi2_1_zext"
8693 [(set (match_operand:DI 0 "register_operand" "=r")
8695 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8698 (clobber (reg:CC FLAGS_REG))]
8699 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8701 [(set_attr "type" "negnot")
8702 (set_attr "mode" "SI")])
8704 ;; The problem with neg is that it does not perform (compare x 0),
8705 ;; it really performs (compare 0 x), which leaves us with the zero
8706 ;; flag being the only useful item.
8708 (define_insn "*neg<mode>2_cmpz"
8709 [(set (reg:CCZ FLAGS_REG)
8711 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8713 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8714 (neg:SWI (match_dup 1)))]
8715 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8716 "neg{<imodesuffix>}\t%0"
8717 [(set_attr "type" "negnot")
8718 (set_attr "mode" "<MODE>")])
8720 (define_insn "*negsi2_cmpz_zext"
8721 [(set (reg:CCZ FLAGS_REG)
8725 (match_operand:DI 1 "register_operand" "0")
8729 (set (match_operand:DI 0 "register_operand" "=r")
8730 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8733 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8735 [(set_attr "type" "negnot")
8736 (set_attr "mode" "SI")])
8738 ;; Changing of sign for FP values is doable using integer unit too.
8740 (define_expand "<code><mode>2"
8741 [(set (match_operand:X87MODEF 0 "register_operand" "")
8742 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8743 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8744 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8746 (define_insn "*absneg<mode>2_mixed"
8747 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8748 (match_operator:MODEF 3 "absneg_operator"
8749 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8750 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8751 (clobber (reg:CC FLAGS_REG))]
8752 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8755 (define_insn "*absneg<mode>2_sse"
8756 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8757 (match_operator:MODEF 3 "absneg_operator"
8758 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8759 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8760 (clobber (reg:CC FLAGS_REG))]
8761 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8764 (define_insn "*absneg<mode>2_i387"
8765 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8766 (match_operator:X87MODEF 3 "absneg_operator"
8767 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8768 (use (match_operand 2 "" ""))
8769 (clobber (reg:CC FLAGS_REG))]
8770 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8773 (define_expand "<code>tf2"
8774 [(set (match_operand:TF 0 "register_operand" "")
8775 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8777 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8779 (define_insn "*absnegtf2_sse"
8780 [(set (match_operand:TF 0 "register_operand" "=x,x")
8781 (match_operator:TF 3 "absneg_operator"
8782 [(match_operand:TF 1 "register_operand" "0,x")]))
8783 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8784 (clobber (reg:CC FLAGS_REG))]
8788 ;; Splitters for fp abs and neg.
8791 [(set (match_operand 0 "fp_register_operand" "")
8792 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8793 (use (match_operand 2 "" ""))
8794 (clobber (reg:CC FLAGS_REG))]
8796 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8799 [(set (match_operand 0 "register_operand" "")
8800 (match_operator 3 "absneg_operator"
8801 [(match_operand 1 "register_operand" "")]))
8802 (use (match_operand 2 "nonimmediate_operand" ""))
8803 (clobber (reg:CC FLAGS_REG))]
8804 "reload_completed && SSE_REG_P (operands[0])"
8805 [(set (match_dup 0) (match_dup 3))]
8807 enum machine_mode mode = GET_MODE (operands[0]);
8808 enum machine_mode vmode = GET_MODE (operands[2]);
8811 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8812 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8813 if (operands_match_p (operands[0], operands[2]))
8816 operands[1] = operands[2];
8819 if (GET_CODE (operands[3]) == ABS)
8820 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8822 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8827 [(set (match_operand:SF 0 "register_operand" "")
8828 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8829 (use (match_operand:V4SF 2 "" ""))
8830 (clobber (reg:CC FLAGS_REG))]
8832 [(parallel [(set (match_dup 0) (match_dup 1))
8833 (clobber (reg:CC FLAGS_REG))])]
8836 operands[0] = gen_lowpart (SImode, operands[0]);
8837 if (GET_CODE (operands[1]) == ABS)
8839 tmp = gen_int_mode (0x7fffffff, SImode);
8840 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8844 tmp = gen_int_mode (0x80000000, SImode);
8845 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8851 [(set (match_operand:DF 0 "register_operand" "")
8852 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8853 (use (match_operand 2 "" ""))
8854 (clobber (reg:CC FLAGS_REG))]
8856 [(parallel [(set (match_dup 0) (match_dup 1))
8857 (clobber (reg:CC FLAGS_REG))])]
8862 tmp = gen_lowpart (DImode, operands[0]);
8863 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8866 if (GET_CODE (operands[1]) == ABS)
8869 tmp = gen_rtx_NOT (DImode, tmp);
8873 operands[0] = gen_highpart (SImode, operands[0]);
8874 if (GET_CODE (operands[1]) == ABS)
8876 tmp = gen_int_mode (0x7fffffff, SImode);
8877 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8881 tmp = gen_int_mode (0x80000000, SImode);
8882 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8889 [(set (match_operand:XF 0 "register_operand" "")
8890 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8891 (use (match_operand 2 "" ""))
8892 (clobber (reg:CC FLAGS_REG))]
8894 [(parallel [(set (match_dup 0) (match_dup 1))
8895 (clobber (reg:CC FLAGS_REG))])]
8898 operands[0] = gen_rtx_REG (SImode,
8899 true_regnum (operands[0])
8900 + (TARGET_64BIT ? 1 : 2));
8901 if (GET_CODE (operands[1]) == ABS)
8903 tmp = GEN_INT (0x7fff);
8904 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8908 tmp = GEN_INT (0x8000);
8909 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8914 ;; Conditionalize these after reload. If they match before reload, we
8915 ;; lose the clobber and ability to use integer instructions.
8917 (define_insn "*<code><mode>2_1"
8918 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8919 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8921 && (reload_completed
8922 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8923 "f<absneg_mnemonic>"
8924 [(set_attr "type" "fsgn")
8925 (set_attr "mode" "<MODE>")])
8927 (define_insn "*<code>extendsfdf2"
8928 [(set (match_operand:DF 0 "register_operand" "=f")
8929 (absneg:DF (float_extend:DF
8930 (match_operand:SF 1 "register_operand" "0"))))]
8931 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8932 "f<absneg_mnemonic>"
8933 [(set_attr "type" "fsgn")
8934 (set_attr "mode" "DF")])
8936 (define_insn "*<code>extendsfxf2"
8937 [(set (match_operand:XF 0 "register_operand" "=f")
8938 (absneg:XF (float_extend:XF
8939 (match_operand:SF 1 "register_operand" "0"))))]
8941 "f<absneg_mnemonic>"
8942 [(set_attr "type" "fsgn")
8943 (set_attr "mode" "XF")])
8945 (define_insn "*<code>extenddfxf2"
8946 [(set (match_operand:XF 0 "register_operand" "=f")
8947 (absneg:XF (float_extend:XF
8948 (match_operand:DF 1 "register_operand" "0"))))]
8950 "f<absneg_mnemonic>"
8951 [(set_attr "type" "fsgn")
8952 (set_attr "mode" "XF")])
8954 ;; Copysign instructions
8956 (define_mode_iterator CSGNMODE [SF DF TF])
8957 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8959 (define_expand "copysign<mode>3"
8960 [(match_operand:CSGNMODE 0 "register_operand" "")
8961 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8962 (match_operand:CSGNMODE 2 "register_operand" "")]
8963 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8964 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8966 ix86_expand_copysign (operands);
8970 (define_insn_and_split "copysign<mode>3_const"
8971 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8973 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8974 (match_operand:CSGNMODE 2 "register_operand" "0")
8975 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8977 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8978 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8980 "&& reload_completed"
8983 ix86_split_copysign_const (operands);
8987 (define_insn "copysign<mode>3_var"
8988 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8990 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8991 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8992 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8993 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8995 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8996 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8997 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9001 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9003 [(match_operand:CSGNMODE 2 "register_operand" "")
9004 (match_operand:CSGNMODE 3 "register_operand" "")
9005 (match_operand:<CSGNVMODE> 4 "" "")
9006 (match_operand:<CSGNVMODE> 5 "" "")]
9008 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9009 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9010 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9011 && reload_completed"
9014 ix86_split_copysign_var (operands);
9018 ;; One complement instructions
9020 (define_expand "one_cmpl<mode>2"
9021 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9022 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9024 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9026 (define_insn "*one_cmpl<mode>2_1"
9027 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9028 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9029 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9030 "not{<imodesuffix>}\t%0"
9031 [(set_attr "type" "negnot")
9032 (set_attr "mode" "<MODE>")])
9034 ;; %%% Potential partial reg stall on alternative 1. What to do?
9035 (define_insn "*one_cmplqi2_1"
9036 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9037 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9038 "ix86_unary_operator_ok (NOT, QImode, operands)"
9042 [(set_attr "type" "negnot")
9043 (set_attr "mode" "QI,SI")])
9045 ;; ??? Currently never generated - xor is used instead.
9046 (define_insn "*one_cmplsi2_1_zext"
9047 [(set (match_operand:DI 0 "register_operand" "=r")
9049 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9050 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9052 [(set_attr "type" "negnot")
9053 (set_attr "mode" "SI")])
9055 (define_insn "*one_cmpl<mode>2_2"
9056 [(set (reg FLAGS_REG)
9057 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9059 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9060 (not:SWI (match_dup 1)))]
9061 "ix86_match_ccmode (insn, CCNOmode)
9062 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9064 [(set_attr "type" "alu1")
9065 (set_attr "mode" "<MODE>")])
9068 [(set (match_operand 0 "flags_reg_operand" "")
9069 (match_operator 2 "compare_operator"
9070 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9072 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9073 (not:SWI (match_dup 3)))]
9074 "ix86_match_ccmode (insn, CCNOmode)"
9075 [(parallel [(set (match_dup 0)
9076 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9079 (xor:SWI (match_dup 3) (const_int -1)))])]
9082 ;; ??? Currently never generated - xor is used instead.
9083 (define_insn "*one_cmplsi2_2_zext"
9084 [(set (reg FLAGS_REG)
9085 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9087 (set (match_operand:DI 0 "register_operand" "=r")
9088 (zero_extend:DI (not:SI (match_dup 1))))]
9089 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9090 && ix86_unary_operator_ok (NOT, SImode, operands)"
9092 [(set_attr "type" "alu1")
9093 (set_attr "mode" "SI")])
9096 [(set (match_operand 0 "flags_reg_operand" "")
9097 (match_operator 2 "compare_operator"
9098 [(not:SI (match_operand:SI 3 "register_operand" ""))
9100 (set (match_operand:DI 1 "register_operand" "")
9101 (zero_extend:DI (not:SI (match_dup 3))))]
9102 "ix86_match_ccmode (insn, CCNOmode)"
9103 [(parallel [(set (match_dup 0)
9104 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9107 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9110 ;; Shift instructions
9112 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9113 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9114 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9115 ;; from the assembler input.
9117 ;; This instruction shifts the target reg/mem as usual, but instead of
9118 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9119 ;; is a left shift double, bits are taken from the high order bits of
9120 ;; reg, else if the insn is a shift right double, bits are taken from the
9121 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9122 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9124 ;; Since sh[lr]d does not change the `reg' operand, that is done
9125 ;; separately, making all shifts emit pairs of shift double and normal
9126 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9127 ;; support a 63 bit shift, each shift where the count is in a reg expands
9128 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9130 ;; If the shift count is a constant, we need never emit more than one
9131 ;; shift pair, instead using moves and sign extension for counts greater
9134 (define_expand "ashl<mode>3"
9135 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9136 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9137 (match_operand:QI 2 "nonmemory_operand" "")))]
9139 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9141 (define_insn "*ashl<mode>3_doubleword"
9142 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9143 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9144 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9145 (clobber (reg:CC FLAGS_REG))]
9148 [(set_attr "type" "multi")])
9151 [(set (match_operand:DWI 0 "register_operand" "")
9152 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9153 (match_operand:QI 2 "nonmemory_operand" "")))
9154 (clobber (reg:CC FLAGS_REG))]
9155 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9157 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9159 ;; By default we don't ask for a scratch register, because when DWImode
9160 ;; values are manipulated, registers are already at a premium. But if
9161 ;; we have one handy, we won't turn it away.
9164 [(match_scratch:DWIH 3 "r")
9165 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9167 (match_operand:<DWI> 1 "nonmemory_operand" "")
9168 (match_operand:QI 2 "nonmemory_operand" "")))
9169 (clobber (reg:CC FLAGS_REG))])
9173 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9175 (define_insn "x86_64_shld"
9176 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9177 (ior:DI (ashift:DI (match_dup 0)
9178 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9179 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9180 (minus:QI (const_int 64) (match_dup 2)))))
9181 (clobber (reg:CC FLAGS_REG))]
9183 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9184 [(set_attr "type" "ishift")
9185 (set_attr "prefix_0f" "1")
9186 (set_attr "mode" "DI")
9187 (set_attr "athlon_decode" "vector")
9188 (set_attr "amdfam10_decode" "vector")])
9190 (define_insn "x86_shld"
9191 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9192 (ior:SI (ashift:SI (match_dup 0)
9193 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9194 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9195 (minus:QI (const_int 32) (match_dup 2)))))
9196 (clobber (reg:CC FLAGS_REG))]
9198 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9199 [(set_attr "type" "ishift")
9200 (set_attr "prefix_0f" "1")
9201 (set_attr "mode" "SI")
9202 (set_attr "pent_pair" "np")
9203 (set_attr "athlon_decode" "vector")
9204 (set_attr "amdfam10_decode" "vector")])
9206 (define_expand "x86_shift<mode>_adj_1"
9207 [(set (reg:CCZ FLAGS_REG)
9208 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9211 (set (match_operand:SWI48 0 "register_operand" "")
9212 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9213 (match_operand:SWI48 1 "register_operand" "")
9216 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9217 (match_operand:SWI48 3 "register_operand" "r")
9220 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9222 (define_expand "x86_shift<mode>_adj_2"
9223 [(use (match_operand:SWI48 0 "register_operand" ""))
9224 (use (match_operand:SWI48 1 "register_operand" ""))
9225 (use (match_operand:QI 2 "register_operand" ""))]
9228 rtx label = gen_label_rtx ();
9231 emit_insn (gen_testqi_ccz_1 (operands[2],
9232 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9234 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9235 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9236 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9237 gen_rtx_LABEL_REF (VOIDmode, label),
9239 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9240 JUMP_LABEL (tmp) = label;
9242 emit_move_insn (operands[0], operands[1]);
9243 ix86_expand_clear (operands[1]);
9246 LABEL_NUSES (label) = 1;
9251 (define_insn "*ashl<mode>3_1"
9252 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9253 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9254 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9255 (clobber (reg:CC FLAGS_REG))]
9256 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9258 switch (get_attr_type (insn))
9264 gcc_assert (operands[2] == const1_rtx);
9265 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9266 return "add{<imodesuffix>}\t%0, %0";
9269 if (operands[2] == const1_rtx
9270 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9271 return "sal{<imodesuffix>}\t%0";
9273 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9277 (cond [(eq_attr "alternative" "1")
9278 (const_string "lea")
9279 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9281 (match_operand 0 "register_operand" ""))
9282 (match_operand 2 "const1_operand" ""))
9283 (const_string "alu")
9285 (const_string "ishift")))
9286 (set (attr "length_immediate")
9288 (ior (eq_attr "type" "alu")
9289 (and (eq_attr "type" "ishift")
9290 (and (match_operand 2 "const1_operand" "")
9291 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9294 (const_string "*")))
9295 (set_attr "mode" "<MODE>")])
9297 (define_insn "*ashlsi3_1_zext"
9298 [(set (match_operand:DI 0 "register_operand" "=r,r")
9300 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9301 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9302 (clobber (reg:CC FLAGS_REG))]
9303 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9305 switch (get_attr_type (insn))
9311 gcc_assert (operands[2] == const1_rtx);
9312 return "add{l}\t%k0, %k0";
9315 if (operands[2] == const1_rtx
9316 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9317 return "sal{l}\t%k0";
9319 return "sal{l}\t{%2, %k0|%k0, %2}";
9323 (cond [(eq_attr "alternative" "1")
9324 (const_string "lea")
9325 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9327 (match_operand 2 "const1_operand" ""))
9328 (const_string "alu")
9330 (const_string "ishift")))
9331 (set (attr "length_immediate")
9333 (ior (eq_attr "type" "alu")
9334 (and (eq_attr "type" "ishift")
9335 (and (match_operand 2 "const1_operand" "")
9336 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9339 (const_string "*")))
9340 (set_attr "mode" "SI")])
9342 (define_insn "*ashlhi3_1"
9343 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9344 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9345 (match_operand:QI 2 "nonmemory_operand" "cI")))
9346 (clobber (reg:CC FLAGS_REG))]
9347 "TARGET_PARTIAL_REG_STALL
9348 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9350 switch (get_attr_type (insn))
9353 gcc_assert (operands[2] == const1_rtx);
9354 return "add{w}\t%0, %0";
9357 if (operands[2] == const1_rtx
9358 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9359 return "sal{w}\t%0";
9361 return "sal{w}\t{%2, %0|%0, %2}";
9365 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9367 (match_operand 0 "register_operand" ""))
9368 (match_operand 2 "const1_operand" ""))
9369 (const_string "alu")
9371 (const_string "ishift")))
9372 (set (attr "length_immediate")
9374 (ior (eq_attr "type" "alu")
9375 (and (eq_attr "type" "ishift")
9376 (and (match_operand 2 "const1_operand" "")
9377 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9380 (const_string "*")))
9381 (set_attr "mode" "HI")])
9383 (define_insn "*ashlhi3_1_lea"
9384 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9385 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9386 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9387 (clobber (reg:CC FLAGS_REG))]
9388 "!TARGET_PARTIAL_REG_STALL
9389 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9391 switch (get_attr_type (insn))
9397 gcc_assert (operands[2] == const1_rtx);
9398 return "add{w}\t%0, %0";
9401 if (operands[2] == const1_rtx
9402 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9403 return "sal{w}\t%0";
9405 return "sal{w}\t{%2, %0|%0, %2}";
9409 (cond [(eq_attr "alternative" "1")
9410 (const_string "lea")
9411 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9413 (match_operand 0 "register_operand" ""))
9414 (match_operand 2 "const1_operand" ""))
9415 (const_string "alu")
9417 (const_string "ishift")))
9418 (set (attr "length_immediate")
9420 (ior (eq_attr "type" "alu")
9421 (and (eq_attr "type" "ishift")
9422 (and (match_operand 2 "const1_operand" "")
9423 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9426 (const_string "*")))
9427 (set_attr "mode" "HI,SI")])
9429 (define_insn "*ashlqi3_1"
9430 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9431 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9432 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9433 (clobber (reg:CC FLAGS_REG))]
9434 "TARGET_PARTIAL_REG_STALL
9435 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9437 switch (get_attr_type (insn))
9440 gcc_assert (operands[2] == const1_rtx);
9441 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9442 return "add{l}\t%k0, %k0";
9444 return "add{b}\t%0, %0";
9447 if (operands[2] == const1_rtx
9448 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9450 if (get_attr_mode (insn) == MODE_SI)
9451 return "sal{l}\t%k0";
9453 return "sal{b}\t%0";
9457 if (get_attr_mode (insn) == MODE_SI)
9458 return "sal{l}\t{%2, %k0|%k0, %2}";
9460 return "sal{b}\t{%2, %0|%0, %2}";
9465 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9467 (match_operand 0 "register_operand" ""))
9468 (match_operand 2 "const1_operand" ""))
9469 (const_string "alu")
9471 (const_string "ishift")))
9472 (set (attr "length_immediate")
9474 (ior (eq_attr "type" "alu")
9475 (and (eq_attr "type" "ishift")
9476 (and (match_operand 2 "const1_operand" "")
9477 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9480 (const_string "*")))
9481 (set_attr "mode" "QI,SI")])
9483 ;; %%% Potential partial reg stall on alternative 2. What to do?
9484 (define_insn "*ashlqi3_1_lea"
9485 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9486 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9487 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9488 (clobber (reg:CC FLAGS_REG))]
9489 "!TARGET_PARTIAL_REG_STALL
9490 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9492 switch (get_attr_type (insn))
9498 gcc_assert (operands[2] == const1_rtx);
9499 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9500 return "add{l}\t%k0, %k0";
9502 return "add{b}\t%0, %0";
9505 if (operands[2] == const1_rtx
9506 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9508 if (get_attr_mode (insn) == MODE_SI)
9509 return "sal{l}\t%k0";
9511 return "sal{b}\t%0";
9515 if (get_attr_mode (insn) == MODE_SI)
9516 return "sal{l}\t{%2, %k0|%k0, %2}";
9518 return "sal{b}\t{%2, %0|%0, %2}";
9523 (cond [(eq_attr "alternative" "2")
9524 (const_string "lea")
9525 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9527 (match_operand 0 "register_operand" ""))
9528 (match_operand 2 "const1_operand" ""))
9529 (const_string "alu")
9531 (const_string "ishift")))
9532 (set (attr "length_immediate")
9534 (ior (eq_attr "type" "alu")
9535 (and (eq_attr "type" "ishift")
9536 (and (match_operand 2 "const1_operand" "")
9537 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9540 (const_string "*")))
9541 (set_attr "mode" "QI,SI,SI")])
9543 (define_insn "*ashlqi3_1_slp"
9544 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9545 (ashift:QI (match_dup 0)
9546 (match_operand:QI 1 "nonmemory_operand" "cI")))
9547 (clobber (reg:CC FLAGS_REG))]
9548 "(optimize_function_for_size_p (cfun)
9549 || !TARGET_PARTIAL_FLAG_REG_STALL
9550 || (operands[1] == const1_rtx
9552 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9554 switch (get_attr_type (insn))
9557 gcc_assert (operands[1] == const1_rtx);
9558 return "add{b}\t%0, %0";
9561 if (operands[1] == const1_rtx
9562 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9563 return "sal{b}\t%0";
9565 return "sal{b}\t{%1, %0|%0, %1}";
9569 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9571 (match_operand 0 "register_operand" ""))
9572 (match_operand 1 "const1_operand" ""))
9573 (const_string "alu")
9575 (const_string "ishift1")))
9576 (set (attr "length_immediate")
9578 (ior (eq_attr "type" "alu")
9579 (and (eq_attr "type" "ishift1")
9580 (and (match_operand 1 "const1_operand" "")
9581 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9584 (const_string "*")))
9585 (set_attr "mode" "QI")])
9587 ;; Convert lea to the lea pattern to avoid flags dependency.
9589 [(set (match_operand:DI 0 "register_operand" "")
9590 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9591 (match_operand:QI 2 "const_int_operand" "")))
9592 (clobber (reg:CC FLAGS_REG))]
9593 "TARGET_64BIT && reload_completed
9594 && true_regnum (operands[0]) != true_regnum (operands[1])"
9596 (mult:DI (match_dup 1)
9598 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9600 ;; Convert lea to the lea pattern to avoid flags dependency.
9602 [(set (match_operand 0 "register_operand" "")
9603 (ashift (match_operand 1 "index_register_operand" "")
9604 (match_operand:QI 2 "const_int_operand" "")))
9605 (clobber (reg:CC FLAGS_REG))]
9607 && true_regnum (operands[0]) != true_regnum (operands[1])
9608 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9612 enum machine_mode mode = GET_MODE (operands[0]);
9614 if (GET_MODE_SIZE (mode) < 4)
9615 operands[0] = gen_lowpart (SImode, operands[0]);
9617 operands[1] = gen_lowpart (Pmode, operands[1]);
9618 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9620 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9621 if (Pmode != SImode)
9622 pat = gen_rtx_SUBREG (SImode, pat, 0);
9623 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9627 ;; Rare case of shifting RSP is handled by generating move and shift
9629 [(set (match_operand 0 "register_operand" "")
9630 (ashift (match_operand 1 "register_operand" "")
9631 (match_operand:QI 2 "const_int_operand" "")))
9632 (clobber (reg:CC FLAGS_REG))]
9634 && true_regnum (operands[0]) != true_regnum (operands[1])"
9638 emit_move_insn (operands[0], operands[1]);
9639 pat = gen_rtx_SET (VOIDmode, operands[0],
9640 gen_rtx_ASHIFT (GET_MODE (operands[0]),
9641 operands[0], operands[2]));
9642 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9643 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9647 ;; Convert lea to the lea pattern to avoid flags dependency.
9649 [(set (match_operand:DI 0 "register_operand" "")
9651 (ashift:SI (match_operand:SI 1 "register_operand" "")
9652 (match_operand:QI 2 "const_int_operand" ""))))
9653 (clobber (reg:CC FLAGS_REG))]
9654 "TARGET_64BIT && reload_completed
9655 && true_regnum (operands[0]) != true_regnum (operands[1])"
9657 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9659 operands[1] = gen_lowpart (Pmode, operands[1]);
9660 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9663 ;; This pattern can't accept a variable shift count, since shifts by
9664 ;; zero don't affect the flags. We assume that shifts by constant
9665 ;; zero are optimized away.
9666 (define_insn "*ashl<mode>3_cmp"
9667 [(set (reg FLAGS_REG)
9669 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9670 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9672 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9673 (ashift:SWI (match_dup 1) (match_dup 2)))]
9674 "(optimize_function_for_size_p (cfun)
9675 || !TARGET_PARTIAL_FLAG_REG_STALL
9676 || (operands[2] == const1_rtx
9678 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9679 && ix86_match_ccmode (insn, CCGOCmode)
9680 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9682 switch (get_attr_type (insn))
9685 gcc_assert (operands[2] == const1_rtx);
9686 return "add{<imodesuffix>}\t%0, %0";
9689 if (operands[2] == const1_rtx
9690 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9691 return "sal{<imodesuffix>}\t%0";
9693 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9697 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9699 (match_operand 0 "register_operand" ""))
9700 (match_operand 2 "const1_operand" ""))
9701 (const_string "alu")
9703 (const_string "ishift")))
9704 (set (attr "length_immediate")
9706 (ior (eq_attr "type" "alu")
9707 (and (eq_attr "type" "ishift")
9708 (and (match_operand 2 "const1_operand" "")
9709 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9712 (const_string "*")))
9713 (set_attr "mode" "<MODE>")])
9715 (define_insn "*ashlsi3_cmp_zext"
9716 [(set (reg FLAGS_REG)
9718 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9719 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9721 (set (match_operand:DI 0 "register_operand" "=r")
9722 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9724 && (optimize_function_for_size_p (cfun)
9725 || !TARGET_PARTIAL_FLAG_REG_STALL
9726 || (operands[2] == const1_rtx
9728 || TARGET_DOUBLE_WITH_ADD)))
9729 && ix86_match_ccmode (insn, CCGOCmode)
9730 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9732 switch (get_attr_type (insn))
9735 gcc_assert (operands[2] == const1_rtx);
9736 return "add{l}\t%k0, %k0";
9739 if (operands[2] == const1_rtx
9740 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9741 return "sal{l}\t%k0";
9743 return "sal{l}\t{%2, %k0|%k0, %2}";
9747 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9749 (match_operand 2 "const1_operand" ""))
9750 (const_string "alu")
9752 (const_string "ishift")))
9753 (set (attr "length_immediate")
9755 (ior (eq_attr "type" "alu")
9756 (and (eq_attr "type" "ishift")
9757 (and (match_operand 2 "const1_operand" "")
9758 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9761 (const_string "*")))
9762 (set_attr "mode" "SI")])
9764 (define_insn "*ashl<mode>3_cconly"
9765 [(set (reg FLAGS_REG)
9767 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9768 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9770 (clobber (match_scratch:SWI 0 "=<r>"))]
9771 "(optimize_function_for_size_p (cfun)
9772 || !TARGET_PARTIAL_FLAG_REG_STALL
9773 || (operands[2] == const1_rtx
9775 || TARGET_DOUBLE_WITH_ADD)))
9776 && ix86_match_ccmode (insn, CCGOCmode)
9777 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9779 switch (get_attr_type (insn))
9782 gcc_assert (operands[2] == const1_rtx);
9783 return "add{<imodesuffix>}\t%0, %0";
9786 if (operands[2] == const1_rtx
9787 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9788 return "sal{<imodesuffix>}\t%0";
9790 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9794 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9796 (match_operand 0 "register_operand" ""))
9797 (match_operand 2 "const1_operand" ""))
9798 (const_string "alu")
9800 (const_string "ishift")))
9801 (set (attr "length_immediate")
9803 (ior (eq_attr "type" "alu")
9804 (and (eq_attr "type" "ishift")
9805 (and (match_operand 2 "const1_operand" "")
9806 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9809 (const_string "*")))
9810 (set_attr "mode" "<MODE>")])
9812 ;; See comment above `ashl<mode>3' about how this works.
9814 (define_expand "<shiftrt_insn><mode>3"
9815 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9816 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9817 (match_operand:QI 2 "nonmemory_operand" "")))]
9819 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9821 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9822 [(set (match_operand:DWI 0 "register_operand" "=r")
9823 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9824 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9825 (clobber (reg:CC FLAGS_REG))]
9828 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9830 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9831 [(set_attr "type" "multi")])
9833 ;; By default we don't ask for a scratch register, because when DWImode
9834 ;; values are manipulated, registers are already at a premium. But if
9835 ;; we have one handy, we won't turn it away.
9838 [(match_scratch:DWIH 3 "r")
9839 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9841 (match_operand:<DWI> 1 "register_operand" "")
9842 (match_operand:QI 2 "nonmemory_operand" "")))
9843 (clobber (reg:CC FLAGS_REG))])
9847 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9849 (define_insn "x86_64_shrd"
9850 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9851 (ior:DI (ashiftrt:DI (match_dup 0)
9852 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9853 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9854 (minus:QI (const_int 64) (match_dup 2)))))
9855 (clobber (reg:CC FLAGS_REG))]
9857 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9858 [(set_attr "type" "ishift")
9859 (set_attr "prefix_0f" "1")
9860 (set_attr "mode" "DI")
9861 (set_attr "athlon_decode" "vector")
9862 (set_attr "amdfam10_decode" "vector")])
9864 (define_insn "x86_shrd"
9865 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9866 (ior:SI (ashiftrt:SI (match_dup 0)
9867 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9868 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9869 (minus:QI (const_int 32) (match_dup 2)))))
9870 (clobber (reg:CC FLAGS_REG))]
9872 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9873 [(set_attr "type" "ishift")
9874 (set_attr "prefix_0f" "1")
9875 (set_attr "mode" "SI")
9876 (set_attr "pent_pair" "np")
9877 (set_attr "athlon_decode" "vector")
9878 (set_attr "amdfam10_decode" "vector")])
9880 (define_insn "ashrdi3_cvt"
9881 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9882 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9883 (match_operand:QI 2 "const_int_operand" "")))
9884 (clobber (reg:CC FLAGS_REG))]
9885 "TARGET_64BIT && INTVAL (operands[2]) == 63
9886 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9887 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9890 sar{q}\t{%2, %0|%0, %2}"
9891 [(set_attr "type" "imovx,ishift")
9892 (set_attr "prefix_0f" "0,*")
9893 (set_attr "length_immediate" "0,*")
9894 (set_attr "modrm" "0,1")
9895 (set_attr "mode" "DI")])
9897 (define_insn "ashrsi3_cvt"
9898 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9899 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9900 (match_operand:QI 2 "const_int_operand" "")))
9901 (clobber (reg:CC FLAGS_REG))]
9902 "INTVAL (operands[2]) == 31
9903 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9904 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9907 sar{l}\t{%2, %0|%0, %2}"
9908 [(set_attr "type" "imovx,ishift")
9909 (set_attr "prefix_0f" "0,*")
9910 (set_attr "length_immediate" "0,*")
9911 (set_attr "modrm" "0,1")
9912 (set_attr "mode" "SI")])
9914 (define_insn "*ashrsi3_cvt_zext"
9915 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9917 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9918 (match_operand:QI 2 "const_int_operand" ""))))
9919 (clobber (reg:CC FLAGS_REG))]
9920 "TARGET_64BIT && INTVAL (operands[2]) == 31
9921 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9922 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9925 sar{l}\t{%2, %k0|%k0, %2}"
9926 [(set_attr "type" "imovx,ishift")
9927 (set_attr "prefix_0f" "0,*")
9928 (set_attr "length_immediate" "0,*")
9929 (set_attr "modrm" "0,1")
9930 (set_attr "mode" "SI")])
9932 (define_expand "x86_shift<mode>_adj_3"
9933 [(use (match_operand:SWI48 0 "register_operand" ""))
9934 (use (match_operand:SWI48 1 "register_operand" ""))
9935 (use (match_operand:QI 2 "register_operand" ""))]
9938 rtx label = gen_label_rtx ();
9941 emit_insn (gen_testqi_ccz_1 (operands[2],
9942 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9944 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9945 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9946 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9947 gen_rtx_LABEL_REF (VOIDmode, label),
9949 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9950 JUMP_LABEL (tmp) = label;
9952 emit_move_insn (operands[0], operands[1]);
9953 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9954 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9956 LABEL_NUSES (label) = 1;
9961 (define_insn "*<shiftrt_insn><mode>3_1"
9962 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9963 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9964 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9965 (clobber (reg:CC FLAGS_REG))]
9966 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9968 if (operands[2] == const1_rtx
9969 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9970 return "<shiftrt>{<imodesuffix>}\t%0";
9972 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9974 [(set_attr "type" "ishift")
9975 (set (attr "length_immediate")
9977 (and (match_operand 2 "const1_operand" "")
9978 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9981 (const_string "*")))
9982 (set_attr "mode" "<MODE>")])
9984 (define_insn "*<shiftrt_insn>si3_1_zext"
9985 [(set (match_operand:DI 0 "register_operand" "=r")
9987 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9988 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9989 (clobber (reg:CC FLAGS_REG))]
9990 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9992 if (operands[2] == const1_rtx
9993 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9994 return "<shiftrt>{l}\t%k0";
9996 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9998 [(set_attr "type" "ishift")
9999 (set (attr "length_immediate")
10001 (and (match_operand 2 "const1_operand" "")
10002 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10005 (const_string "*")))
10006 (set_attr "mode" "SI")])
10008 (define_insn "*<shiftrt_insn>qi3_1_slp"
10009 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10010 (any_shiftrt:QI (match_dup 0)
10011 (match_operand:QI 1 "nonmemory_operand" "cI")))
10012 (clobber (reg:CC FLAGS_REG))]
10013 "(optimize_function_for_size_p (cfun)
10014 || !TARGET_PARTIAL_REG_STALL
10015 || (operands[1] == const1_rtx
10016 && TARGET_SHIFT1))"
10018 if (operands[1] == const1_rtx
10019 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10020 return "<shiftrt>{b}\t%0";
10022 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10024 [(set_attr "type" "ishift1")
10025 (set (attr "length_immediate")
10027 (and (match_operand 1 "const1_operand" "")
10028 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10031 (const_string "*")))
10032 (set_attr "mode" "QI")])
10034 ;; This pattern can't accept a variable shift count, since shifts by
10035 ;; zero don't affect the flags. We assume that shifts by constant
10036 ;; zero are optimized away.
10037 (define_insn "*<shiftrt_insn><mode>3_cmp"
10038 [(set (reg FLAGS_REG)
10041 (match_operand:SWI 1 "nonimmediate_operand" "0")
10042 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10044 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10045 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10046 "(optimize_function_for_size_p (cfun)
10047 || !TARGET_PARTIAL_FLAG_REG_STALL
10048 || (operands[2] == const1_rtx
10050 && ix86_match_ccmode (insn, CCGOCmode)
10051 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10053 if (operands[2] == const1_rtx
10054 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10055 return "<shiftrt>{<imodesuffix>}\t%0";
10057 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10059 [(set_attr "type" "ishift")
10060 (set (attr "length_immediate")
10062 (and (match_operand 2 "const1_operand" "")
10063 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10066 (const_string "*")))
10067 (set_attr "mode" "<MODE>")])
10069 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10070 [(set (reg FLAGS_REG)
10072 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10073 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10075 (set (match_operand:DI 0 "register_operand" "=r")
10076 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10078 && (optimize_function_for_size_p (cfun)
10079 || !TARGET_PARTIAL_FLAG_REG_STALL
10080 || (operands[2] == const1_rtx
10082 && ix86_match_ccmode (insn, CCGOCmode)
10083 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10085 if (operands[2] == const1_rtx
10086 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10087 return "<shiftrt>{l}\t%k0";
10089 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10091 [(set_attr "type" "ishift")
10092 (set (attr "length_immediate")
10094 (and (match_operand 2 "const1_operand" "")
10095 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10098 (const_string "*")))
10099 (set_attr "mode" "SI")])
10101 (define_insn "*<shiftrt_insn><mode>3_cconly"
10102 [(set (reg FLAGS_REG)
10105 (match_operand:SWI 1 "nonimmediate_operand" "0")
10106 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10108 (clobber (match_scratch:SWI 0 "=<r>"))]
10109 "(optimize_function_for_size_p (cfun)
10110 || !TARGET_PARTIAL_FLAG_REG_STALL
10111 || (operands[2] == const1_rtx
10113 && ix86_match_ccmode (insn, CCGOCmode)
10114 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10116 if (operands[2] == const1_rtx
10117 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10118 return "<shiftrt>{<imodesuffix>}\t%0";
10120 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10122 [(set_attr "type" "ishift")
10123 (set (attr "length_immediate")
10125 (and (match_operand 2 "const1_operand" "")
10126 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10129 (const_string "*")))
10130 (set_attr "mode" "<MODE>")])
10132 ;; Rotate instructions
10134 (define_expand "<rotate_insn>ti3"
10135 [(set (match_operand:TI 0 "register_operand" "")
10136 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10137 (match_operand:QI 2 "nonmemory_operand" "")))]
10140 if (const_1_to_63_operand (operands[2], VOIDmode))
10141 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10142 (operands[0], operands[1], operands[2]));
10149 (define_expand "<rotate_insn>di3"
10150 [(set (match_operand:DI 0 "shiftdi_operand" "")
10151 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10152 (match_operand:QI 2 "nonmemory_operand" "")))]
10156 ix86_expand_binary_operator (<CODE>, DImode, operands);
10157 else if (const_1_to_31_operand (operands[2], VOIDmode))
10158 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10159 (operands[0], operands[1], operands[2]));
10166 (define_expand "<rotate_insn><mode>3"
10167 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10168 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10169 (match_operand:QI 2 "nonmemory_operand" "")))]
10171 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10173 ;; Implement rotation using two double-precision
10174 ;; shift instructions and a scratch register.
10176 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10177 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10178 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10179 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10180 (clobber (reg:CC FLAGS_REG))
10181 (clobber (match_scratch:DWIH 3 "=&r"))]
10185 [(set (match_dup 3) (match_dup 4))
10187 [(set (match_dup 4)
10188 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10189 (lshiftrt:DWIH (match_dup 5)
10190 (minus:QI (match_dup 6) (match_dup 2)))))
10191 (clobber (reg:CC FLAGS_REG))])
10193 [(set (match_dup 5)
10194 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10195 (lshiftrt:DWIH (match_dup 3)
10196 (minus:QI (match_dup 6) (match_dup 2)))))
10197 (clobber (reg:CC FLAGS_REG))])]
10199 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10201 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10204 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10205 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10206 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10207 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10208 (clobber (reg:CC FLAGS_REG))
10209 (clobber (match_scratch:DWIH 3 "=&r"))]
10213 [(set (match_dup 3) (match_dup 4))
10215 [(set (match_dup 4)
10216 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10217 (ashift:DWIH (match_dup 5)
10218 (minus:QI (match_dup 6) (match_dup 2)))))
10219 (clobber (reg:CC FLAGS_REG))])
10221 [(set (match_dup 5)
10222 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10223 (ashift:DWIH (match_dup 3)
10224 (minus:QI (match_dup 6) (match_dup 2)))))
10225 (clobber (reg:CC FLAGS_REG))])]
10227 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10229 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10232 (define_insn "*<rotate_insn><mode>3_1"
10233 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10234 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10235 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10236 (clobber (reg:CC FLAGS_REG))]
10237 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10239 if (operands[2] == const1_rtx
10240 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10241 return "<rotate>{<imodesuffix>}\t%0";
10243 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10245 [(set_attr "type" "rotate")
10246 (set (attr "length_immediate")
10248 (and (match_operand 2 "const1_operand" "")
10249 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10252 (const_string "*")))
10253 (set_attr "mode" "<MODE>")])
10255 (define_insn "*<rotate_insn>si3_1_zext"
10256 [(set (match_operand:DI 0 "register_operand" "=r")
10258 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10259 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10260 (clobber (reg:CC FLAGS_REG))]
10261 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10263 if (operands[2] == const1_rtx
10264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10265 return "<rotate>{l}\t%k0";
10267 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10269 [(set_attr "type" "rotate")
10270 (set (attr "length_immediate")
10272 (and (match_operand 2 "const1_operand" "")
10273 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10276 (const_string "*")))
10277 (set_attr "mode" "SI")])
10279 (define_insn "*<rotate_insn>qi3_1_slp"
10280 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10281 (any_rotate:QI (match_dup 0)
10282 (match_operand:QI 1 "nonmemory_operand" "cI")))
10283 (clobber (reg:CC FLAGS_REG))]
10284 "(optimize_function_for_size_p (cfun)
10285 || !TARGET_PARTIAL_REG_STALL
10286 || (operands[1] == const1_rtx
10287 && TARGET_SHIFT1))"
10289 if (operands[1] == const1_rtx
10290 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10291 return "<rotate>{b}\t%0";
10293 return "<rotate>{b}\t{%1, %0|%0, %1}";
10295 [(set_attr "type" "rotate1")
10296 (set (attr "length_immediate")
10298 (and (match_operand 1 "const1_operand" "")
10299 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10302 (const_string "*")))
10303 (set_attr "mode" "QI")])
10306 [(set (match_operand:HI 0 "register_operand" "")
10307 (any_rotate:HI (match_dup 0) (const_int 8)))
10308 (clobber (reg:CC FLAGS_REG))]
10310 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10311 [(parallel [(set (strict_low_part (match_dup 0))
10312 (bswap:HI (match_dup 0)))
10313 (clobber (reg:CC FLAGS_REG))])]
10316 ;; Bit set / bit test instructions
10318 (define_expand "extv"
10319 [(set (match_operand:SI 0 "register_operand" "")
10320 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10321 (match_operand:SI 2 "const8_operand" "")
10322 (match_operand:SI 3 "const8_operand" "")))]
10325 /* Handle extractions from %ah et al. */
10326 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10329 /* From mips.md: extract_bit_field doesn't verify that our source
10330 matches the predicate, so check it again here. */
10331 if (! ext_register_operand (operands[1], VOIDmode))
10335 (define_expand "extzv"
10336 [(set (match_operand:SI 0 "register_operand" "")
10337 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10338 (match_operand:SI 2 "const8_operand" "")
10339 (match_operand:SI 3 "const8_operand" "")))]
10342 /* Handle extractions from %ah et al. */
10343 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10346 /* From mips.md: extract_bit_field doesn't verify that our source
10347 matches the predicate, so check it again here. */
10348 if (! ext_register_operand (operands[1], VOIDmode))
10352 (define_expand "insv"
10353 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10354 (match_operand 1 "const8_operand" "")
10355 (match_operand 2 "const8_operand" ""))
10356 (match_operand 3 "register_operand" ""))]
10359 rtx (*gen_mov_insv_1) (rtx, rtx);
10361 /* Handle insertions to %ah et al. */
10362 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10365 /* From mips.md: insert_bit_field doesn't verify that our source
10366 matches the predicate, so check it again here. */
10367 if (! ext_register_operand (operands[0], VOIDmode))
10370 gen_mov_insv_1 = (TARGET_64BIT
10371 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10373 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10377 ;; %%% bts, btr, btc, bt.
10378 ;; In general these instructions are *slow* when applied to memory,
10379 ;; since they enforce atomic operation. When applied to registers,
10380 ;; it depends on the cpu implementation. They're never faster than
10381 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10382 ;; no point. But in 64-bit, we can't hold the relevant immediates
10383 ;; within the instruction itself, so operating on bits in the high
10384 ;; 32-bits of a register becomes easier.
10386 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10387 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10388 ;; negdf respectively, so they can never be disabled entirely.
10390 (define_insn "*btsq"
10391 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10393 (match_operand:DI 1 "const_0_to_63_operand" ""))
10395 (clobber (reg:CC FLAGS_REG))]
10396 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10397 "bts{q}\t{%1, %0|%0, %1}"
10398 [(set_attr "type" "alu1")
10399 (set_attr "prefix_0f" "1")
10400 (set_attr "mode" "DI")])
10402 (define_insn "*btrq"
10403 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10405 (match_operand:DI 1 "const_0_to_63_operand" ""))
10407 (clobber (reg:CC FLAGS_REG))]
10408 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10409 "btr{q}\t{%1, %0|%0, %1}"
10410 [(set_attr "type" "alu1")
10411 (set_attr "prefix_0f" "1")
10412 (set_attr "mode" "DI")])
10414 (define_insn "*btcq"
10415 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10417 (match_operand:DI 1 "const_0_to_63_operand" ""))
10418 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10421 "btc{q}\t{%1, %0|%0, %1}"
10422 [(set_attr "type" "alu1")
10423 (set_attr "prefix_0f" "1")
10424 (set_attr "mode" "DI")])
10426 ;; Allow Nocona to avoid these instructions if a register is available.
10429 [(match_scratch:DI 2 "r")
10430 (parallel [(set (zero_extract:DI
10431 (match_operand:DI 0 "register_operand" "")
10433 (match_operand:DI 1 "const_0_to_63_operand" ""))
10435 (clobber (reg:CC FLAGS_REG))])]
10436 "TARGET_64BIT && !TARGET_USE_BT"
10439 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10442 if (HOST_BITS_PER_WIDE_INT >= 64)
10443 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10444 else if (i < HOST_BITS_PER_WIDE_INT)
10445 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10447 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10449 op1 = immed_double_const (lo, hi, DImode);
10452 emit_move_insn (operands[2], op1);
10456 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10461 [(match_scratch:DI 2 "r")
10462 (parallel [(set (zero_extract:DI
10463 (match_operand:DI 0 "register_operand" "")
10465 (match_operand:DI 1 "const_0_to_63_operand" ""))
10467 (clobber (reg:CC FLAGS_REG))])]
10468 "TARGET_64BIT && !TARGET_USE_BT"
10471 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10474 if (HOST_BITS_PER_WIDE_INT >= 64)
10475 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10476 else if (i < HOST_BITS_PER_WIDE_INT)
10477 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10479 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10481 op1 = immed_double_const (~lo, ~hi, DImode);
10484 emit_move_insn (operands[2], op1);
10488 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10493 [(match_scratch:DI 2 "r")
10494 (parallel [(set (zero_extract:DI
10495 (match_operand:DI 0 "register_operand" "")
10497 (match_operand:DI 1 "const_0_to_63_operand" ""))
10498 (not:DI (zero_extract:DI
10499 (match_dup 0) (const_int 1) (match_dup 1))))
10500 (clobber (reg:CC FLAGS_REG))])]
10501 "TARGET_64BIT && !TARGET_USE_BT"
10504 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10507 if (HOST_BITS_PER_WIDE_INT >= 64)
10508 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10509 else if (i < HOST_BITS_PER_WIDE_INT)
10510 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10512 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10514 op1 = immed_double_const (lo, hi, DImode);
10517 emit_move_insn (operands[2], op1);
10521 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10525 (define_insn "*bt<mode>"
10526 [(set (reg:CCC FLAGS_REG)
10528 (zero_extract:SWI48
10529 (match_operand:SWI48 0 "register_operand" "r")
10531 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10533 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10534 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10535 [(set_attr "type" "alu1")
10536 (set_attr "prefix_0f" "1")
10537 (set_attr "mode" "<MODE>")])
10539 ;; Store-flag instructions.
10541 ;; For all sCOND expanders, also expand the compare or test insn that
10542 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10544 (define_insn_and_split "*setcc_di_1"
10545 [(set (match_operand:DI 0 "register_operand" "=q")
10546 (match_operator:DI 1 "ix86_comparison_operator"
10547 [(reg FLAGS_REG) (const_int 0)]))]
10548 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10550 "&& reload_completed"
10551 [(set (match_dup 2) (match_dup 1))
10552 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10554 PUT_MODE (operands[1], QImode);
10555 operands[2] = gen_lowpart (QImode, operands[0]);
10558 (define_insn_and_split "*setcc_si_1_and"
10559 [(set (match_operand:SI 0 "register_operand" "=q")
10560 (match_operator:SI 1 "ix86_comparison_operator"
10561 [(reg FLAGS_REG) (const_int 0)]))
10562 (clobber (reg:CC FLAGS_REG))]
10563 "!TARGET_PARTIAL_REG_STALL
10564 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10566 "&& reload_completed"
10567 [(set (match_dup 2) (match_dup 1))
10568 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10569 (clobber (reg:CC FLAGS_REG))])]
10571 PUT_MODE (operands[1], QImode);
10572 operands[2] = gen_lowpart (QImode, operands[0]);
10575 (define_insn_and_split "*setcc_si_1_movzbl"
10576 [(set (match_operand:SI 0 "register_operand" "=q")
10577 (match_operator:SI 1 "ix86_comparison_operator"
10578 [(reg FLAGS_REG) (const_int 0)]))]
10579 "!TARGET_PARTIAL_REG_STALL
10580 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10582 "&& reload_completed"
10583 [(set (match_dup 2) (match_dup 1))
10584 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10586 PUT_MODE (operands[1], QImode);
10587 operands[2] = gen_lowpart (QImode, operands[0]);
10590 (define_insn "*setcc_qi"
10591 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10592 (match_operator:QI 1 "ix86_comparison_operator"
10593 [(reg FLAGS_REG) (const_int 0)]))]
10596 [(set_attr "type" "setcc")
10597 (set_attr "mode" "QI")])
10599 (define_insn "*setcc_qi_slp"
10600 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10601 (match_operator:QI 1 "ix86_comparison_operator"
10602 [(reg FLAGS_REG) (const_int 0)]))]
10605 [(set_attr "type" "setcc")
10606 (set_attr "mode" "QI")])
10608 ;; In general it is not safe to assume too much about CCmode registers,
10609 ;; so simplify-rtx stops when it sees a second one. Under certain
10610 ;; conditions this is safe on x86, so help combine not create
10617 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10618 (ne:QI (match_operator 1 "ix86_comparison_operator"
10619 [(reg FLAGS_REG) (const_int 0)])
10622 [(set (match_dup 0) (match_dup 1))]
10624 PUT_MODE (operands[1], QImode);
10628 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10629 (ne:QI (match_operator 1 "ix86_comparison_operator"
10630 [(reg FLAGS_REG) (const_int 0)])
10633 [(set (match_dup 0) (match_dup 1))]
10635 PUT_MODE (operands[1], QImode);
10639 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10640 (eq:QI (match_operator 1 "ix86_comparison_operator"
10641 [(reg FLAGS_REG) (const_int 0)])
10644 [(set (match_dup 0) (match_dup 1))]
10646 rtx new_op1 = copy_rtx (operands[1]);
10647 operands[1] = new_op1;
10648 PUT_MODE (new_op1, QImode);
10649 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10650 GET_MODE (XEXP (new_op1, 0))));
10652 /* Make sure that (a) the CCmode we have for the flags is strong
10653 enough for the reversed compare or (b) we have a valid FP compare. */
10654 if (! ix86_comparison_operator (new_op1, VOIDmode))
10659 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10660 (eq:QI (match_operator 1 "ix86_comparison_operator"
10661 [(reg FLAGS_REG) (const_int 0)])
10664 [(set (match_dup 0) (match_dup 1))]
10666 rtx new_op1 = copy_rtx (operands[1]);
10667 operands[1] = new_op1;
10668 PUT_MODE (new_op1, QImode);
10669 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10670 GET_MODE (XEXP (new_op1, 0))));
10672 /* Make sure that (a) the CCmode we have for the flags is strong
10673 enough for the reversed compare or (b) we have a valid FP compare. */
10674 if (! ix86_comparison_operator (new_op1, VOIDmode))
10678 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10679 ;; subsequent logical operations are used to imitate conditional moves.
10680 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10683 (define_insn "*avx_setcc<mode>"
10684 [(set (match_operand:MODEF 0 "register_operand" "=x")
10685 (match_operator:MODEF 1 "avx_comparison_float_operator"
10686 [(match_operand:MODEF 2 "register_operand" "x")
10687 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10689 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10690 [(set_attr "type" "ssecmp")
10691 (set_attr "prefix" "vex")
10692 (set_attr "length_immediate" "1")
10693 (set_attr "mode" "<MODE>")])
10695 (define_insn "*sse_setcc<mode>"
10696 [(set (match_operand:MODEF 0 "register_operand" "=x")
10697 (match_operator:MODEF 1 "sse_comparison_operator"
10698 [(match_operand:MODEF 2 "register_operand" "0")
10699 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10700 "SSE_FLOAT_MODE_P (<MODE>mode)"
10701 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10702 [(set_attr "type" "ssecmp")
10703 (set_attr "length_immediate" "1")
10704 (set_attr "mode" "<MODE>")])
10706 ;; Basic conditional jump instructions.
10707 ;; We ignore the overflow flag for signed branch instructions.
10709 (define_insn "*jcc_1"
10711 (if_then_else (match_operator 1 "ix86_comparison_operator"
10712 [(reg FLAGS_REG) (const_int 0)])
10713 (label_ref (match_operand 0 "" ""))
10717 [(set_attr "type" "ibr")
10718 (set_attr "modrm" "0")
10719 (set (attr "length")
10720 (if_then_else (and (ge (minus (match_dup 0) (pc))
10722 (lt (minus (match_dup 0) (pc))
10727 (define_insn "*jcc_2"
10729 (if_then_else (match_operator 1 "ix86_comparison_operator"
10730 [(reg FLAGS_REG) (const_int 0)])
10732 (label_ref (match_operand 0 "" ""))))]
10735 [(set_attr "type" "ibr")
10736 (set_attr "modrm" "0")
10737 (set (attr "length")
10738 (if_then_else (and (ge (minus (match_dup 0) (pc))
10740 (lt (minus (match_dup 0) (pc))
10745 ;; In general it is not safe to assume too much about CCmode registers,
10746 ;; so simplify-rtx stops when it sees a second one. Under certain
10747 ;; conditions this is safe on x86, so help combine not create
10755 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10756 [(reg FLAGS_REG) (const_int 0)])
10758 (label_ref (match_operand 1 "" ""))
10762 (if_then_else (match_dup 0)
10763 (label_ref (match_dup 1))
10766 PUT_MODE (operands[0], VOIDmode);
10771 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10772 [(reg FLAGS_REG) (const_int 0)])
10774 (label_ref (match_operand 1 "" ""))
10778 (if_then_else (match_dup 0)
10779 (label_ref (match_dup 1))
10782 rtx new_op0 = copy_rtx (operands[0]);
10783 operands[0] = new_op0;
10784 PUT_MODE (new_op0, VOIDmode);
10785 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10786 GET_MODE (XEXP (new_op0, 0))));
10788 /* Make sure that (a) the CCmode we have for the flags is strong
10789 enough for the reversed compare or (b) we have a valid FP compare. */
10790 if (! ix86_comparison_operator (new_op0, VOIDmode))
10794 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10795 ;; pass generates from shift insn with QImode operand. Actually, the mode
10796 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10797 ;; appropriate modulo of the bit offset value.
10799 (define_insn_and_split "*jcc_bt<mode>"
10801 (if_then_else (match_operator 0 "bt_comparison_operator"
10802 [(zero_extract:SWI48
10803 (match_operand:SWI48 1 "register_operand" "r")
10806 (match_operand:QI 2 "register_operand" "r")))
10808 (label_ref (match_operand 3 "" ""))
10810 (clobber (reg:CC FLAGS_REG))]
10811 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10814 [(set (reg:CCC FLAGS_REG)
10816 (zero_extract:SWI48
10822 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10823 (label_ref (match_dup 3))
10826 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10828 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10831 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10832 ;; also for DImode, this is what combine produces.
10833 (define_insn_and_split "*jcc_bt<mode>_mask"
10835 (if_then_else (match_operator 0 "bt_comparison_operator"
10836 [(zero_extract:SWI48
10837 (match_operand:SWI48 1 "register_operand" "r")
10840 (match_operand:SI 2 "register_operand" "r")
10841 (match_operand:SI 3 "const_int_operand" "n")))])
10842 (label_ref (match_operand 4 "" ""))
10844 (clobber (reg:CC FLAGS_REG))]
10845 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10846 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10847 == GET_MODE_BITSIZE (<MODE>mode)-1"
10850 [(set (reg:CCC FLAGS_REG)
10852 (zero_extract:SWI48
10858 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10859 (label_ref (match_dup 4))
10862 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10864 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10867 (define_insn_and_split "*jcc_btsi_1"
10869 (if_then_else (match_operator 0 "bt_comparison_operator"
10872 (match_operand:SI 1 "register_operand" "r")
10873 (match_operand:QI 2 "register_operand" "r"))
10876 (label_ref (match_operand 3 "" ""))
10878 (clobber (reg:CC FLAGS_REG))]
10879 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10882 [(set (reg:CCC FLAGS_REG)
10890 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10891 (label_ref (match_dup 3))
10894 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10896 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10899 ;; avoid useless masking of bit offset operand
10900 (define_insn_and_split "*jcc_btsi_mask_1"
10903 (match_operator 0 "bt_comparison_operator"
10906 (match_operand:SI 1 "register_operand" "r")
10909 (match_operand:SI 2 "register_operand" "r")
10910 (match_operand:SI 3 "const_int_operand" "n")) 0))
10913 (label_ref (match_operand 4 "" ""))
10915 (clobber (reg:CC FLAGS_REG))]
10916 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10917 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10920 [(set (reg:CCC FLAGS_REG)
10928 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10929 (label_ref (match_dup 4))
10931 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10933 ;; Define combination compare-and-branch fp compare instructions to help
10936 (define_insn "*fp_jcc_1_387"
10938 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10939 [(match_operand 1 "register_operand" "f")
10940 (match_operand 2 "nonimmediate_operand" "fm")])
10941 (label_ref (match_operand 3 "" ""))
10943 (clobber (reg:CCFP FPSR_REG))
10944 (clobber (reg:CCFP FLAGS_REG))
10945 (clobber (match_scratch:HI 4 "=a"))]
10947 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10948 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10949 && SELECT_CC_MODE (GET_CODE (operands[0]),
10950 operands[1], operands[2]) == CCFPmode
10954 (define_insn "*fp_jcc_1r_387"
10956 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10957 [(match_operand 1 "register_operand" "f")
10958 (match_operand 2 "nonimmediate_operand" "fm")])
10960 (label_ref (match_operand 3 "" ""))))
10961 (clobber (reg:CCFP FPSR_REG))
10962 (clobber (reg:CCFP FLAGS_REG))
10963 (clobber (match_scratch:HI 4 "=a"))]
10965 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10966 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10967 && SELECT_CC_MODE (GET_CODE (operands[0]),
10968 operands[1], operands[2]) == CCFPmode
10972 (define_insn "*fp_jcc_2_387"
10974 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10975 [(match_operand 1 "register_operand" "f")
10976 (match_operand 2 "register_operand" "f")])
10977 (label_ref (match_operand 3 "" ""))
10979 (clobber (reg:CCFP FPSR_REG))
10980 (clobber (reg:CCFP FLAGS_REG))
10981 (clobber (match_scratch:HI 4 "=a"))]
10982 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10983 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10987 (define_insn "*fp_jcc_2r_387"
10989 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10990 [(match_operand 1 "register_operand" "f")
10991 (match_operand 2 "register_operand" "f")])
10993 (label_ref (match_operand 3 "" ""))))
10994 (clobber (reg:CCFP FPSR_REG))
10995 (clobber (reg:CCFP FLAGS_REG))
10996 (clobber (match_scratch:HI 4 "=a"))]
10997 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10998 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11002 (define_insn "*fp_jcc_3_387"
11004 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11005 [(match_operand 1 "register_operand" "f")
11006 (match_operand 2 "const0_operand" "")])
11007 (label_ref (match_operand 3 "" ""))
11009 (clobber (reg:CCFP FPSR_REG))
11010 (clobber (reg:CCFP FLAGS_REG))
11011 (clobber (match_scratch:HI 4 "=a"))]
11012 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11013 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11014 && SELECT_CC_MODE (GET_CODE (operands[0]),
11015 operands[1], operands[2]) == CCFPmode
11021 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11022 [(match_operand 1 "register_operand" "")
11023 (match_operand 2 "nonimmediate_operand" "")])
11024 (match_operand 3 "" "")
11025 (match_operand 4 "" "")))
11026 (clobber (reg:CCFP FPSR_REG))
11027 (clobber (reg:CCFP FLAGS_REG))]
11031 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11032 operands[3], operands[4], NULL_RTX, NULL_RTX);
11038 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11039 [(match_operand 1 "register_operand" "")
11040 (match_operand 2 "general_operand" "")])
11041 (match_operand 3 "" "")
11042 (match_operand 4 "" "")))
11043 (clobber (reg:CCFP FPSR_REG))
11044 (clobber (reg:CCFP FLAGS_REG))
11045 (clobber (match_scratch:HI 5 "=a"))]
11049 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11050 operands[3], operands[4], operands[5], NULL_RTX);
11054 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11055 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11056 ;; with a precedence over other operators and is always put in the first
11057 ;; place. Swap condition and operands to match ficom instruction.
11059 (define_insn "*fp_jcc_4_<mode>_387"
11062 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11063 [(match_operator 1 "float_operator"
11064 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11065 (match_operand 3 "register_operand" "f,f")])
11066 (label_ref (match_operand 4 "" ""))
11068 (clobber (reg:CCFP FPSR_REG))
11069 (clobber (reg:CCFP FLAGS_REG))
11070 (clobber (match_scratch:HI 5 "=a,a"))]
11071 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11072 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11073 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11074 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11081 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11082 [(match_operator 1 "float_operator"
11083 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11084 (match_operand 3 "register_operand" "")])
11085 (match_operand 4 "" "")
11086 (match_operand 5 "" "")))
11087 (clobber (reg:CCFP FPSR_REG))
11088 (clobber (reg:CCFP FLAGS_REG))
11089 (clobber (match_scratch:HI 6 "=a"))]
11093 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11095 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11096 operands[3], operands[7],
11097 operands[4], operands[5], operands[6], NULL_RTX);
11101 ;; %%% Kill this when reload knows how to do it.
11105 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11106 [(match_operator 1 "float_operator"
11107 [(match_operand:X87MODEI12 2 "register_operand" "")])
11108 (match_operand 3 "register_operand" "")])
11109 (match_operand 4 "" "")
11110 (match_operand 5 "" "")))
11111 (clobber (reg:CCFP FPSR_REG))
11112 (clobber (reg:CCFP FLAGS_REG))
11113 (clobber (match_scratch:HI 6 "=a"))]
11117 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11118 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11120 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11121 operands[3], operands[7],
11122 operands[4], operands[5], operands[6], operands[2]);
11126 ;; Unconditional and other jump instructions
11128 (define_insn "jump"
11130 (label_ref (match_operand 0 "" "")))]
11133 [(set_attr "type" "ibr")
11134 (set (attr "length")
11135 (if_then_else (and (ge (minus (match_dup 0) (pc))
11137 (lt (minus (match_dup 0) (pc))
11141 (set_attr "modrm" "0")])
11143 (define_expand "indirect_jump"
11144 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11148 (define_insn "*indirect_jump"
11149 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11152 [(set_attr "type" "ibr")
11153 (set_attr "length_immediate" "0")])
11155 (define_expand "tablejump"
11156 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11157 (use (label_ref (match_operand 1 "" "")))])]
11160 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11161 relative. Convert the relative address to an absolute address. */
11165 enum rtx_code code;
11167 /* We can't use @GOTOFF for text labels on VxWorks;
11168 see gotoff_operand. */
11169 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11173 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11175 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11179 op1 = pic_offset_table_rtx;
11184 op0 = pic_offset_table_rtx;
11188 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11193 (define_insn "*tablejump_1"
11194 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11195 (use (label_ref (match_operand 1 "" "")))]
11198 [(set_attr "type" "ibr")
11199 (set_attr "length_immediate" "0")])
11201 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11204 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11205 (set (match_operand:QI 1 "register_operand" "")
11206 (match_operator:QI 2 "ix86_comparison_operator"
11207 [(reg FLAGS_REG) (const_int 0)]))
11208 (set (match_operand 3 "q_regs_operand" "")
11209 (zero_extend (match_dup 1)))]
11210 "(peep2_reg_dead_p (3, operands[1])
11211 || operands_match_p (operands[1], operands[3]))
11212 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11213 [(set (match_dup 4) (match_dup 0))
11214 (set (strict_low_part (match_dup 5))
11217 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11218 operands[5] = gen_lowpart (QImode, operands[3]);
11219 ix86_expand_clear (operands[3]);
11222 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11225 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11226 (set (match_operand:QI 1 "register_operand" "")
11227 (match_operator:QI 2 "ix86_comparison_operator"
11228 [(reg FLAGS_REG) (const_int 0)]))
11229 (parallel [(set (match_operand 3 "q_regs_operand" "")
11230 (zero_extend (match_dup 1)))
11231 (clobber (reg:CC FLAGS_REG))])]
11232 "(peep2_reg_dead_p (3, operands[1])
11233 || operands_match_p (operands[1], operands[3]))
11234 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11235 [(set (match_dup 4) (match_dup 0))
11236 (set (strict_low_part (match_dup 5))
11239 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11240 operands[5] = gen_lowpart (QImode, operands[3]);
11241 ix86_expand_clear (operands[3]);
11244 ;; Call instructions.
11246 ;; The predicates normally associated with named expanders are not properly
11247 ;; checked for calls. This is a bug in the generic code, but it isn't that
11248 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11250 ;; P6 processors will jump to the address after the decrement when %esp
11251 ;; is used as a call operand, so they will execute return address as a code.
11252 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11254 ;; Call subroutine returning no value.
11256 (define_expand "call_pop"
11257 [(parallel [(call (match_operand:QI 0 "" "")
11258 (match_operand:SI 1 "" ""))
11259 (set (reg:SI SP_REG)
11260 (plus:SI (reg:SI SP_REG)
11261 (match_operand:SI 3 "" "")))])]
11264 ix86_expand_call (NULL, operands[0], operands[1],
11265 operands[2], operands[3], 0);
11269 (define_insn "*call_pop_0"
11270 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11271 (match_operand:SI 1 "" ""))
11272 (set (reg:SI SP_REG)
11273 (plus:SI (reg:SI SP_REG)
11274 (match_operand:SI 2 "immediate_operand" "")))]
11277 if (SIBLING_CALL_P (insn))
11280 return "call\t%P0";
11282 [(set_attr "type" "call")])
11284 (define_insn "*call_pop_1"
11285 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11286 (match_operand:SI 1 "" ""))
11287 (set (reg:SI SP_REG)
11288 (plus:SI (reg:SI SP_REG)
11289 (match_operand:SI 2 "immediate_operand" "i")))]
11290 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11292 if (constant_call_address_operand (operands[0], Pmode))
11293 return "call\t%P0";
11294 return "call\t%A0";
11296 [(set_attr "type" "call")])
11298 (define_insn "*sibcall_pop_1"
11299 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11300 (match_operand:SI 1 "" ""))
11301 (set (reg:SI SP_REG)
11302 (plus:SI (reg:SI SP_REG)
11303 (match_operand:SI 2 "immediate_operand" "i,i")))]
11304 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11308 [(set_attr "type" "call")])
11310 (define_expand "call"
11311 [(call (match_operand:QI 0 "" "")
11312 (match_operand 1 "" ""))
11313 (use (match_operand 2 "" ""))]
11316 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11320 (define_expand "sibcall"
11321 [(call (match_operand:QI 0 "" "")
11322 (match_operand 1 "" ""))
11323 (use (match_operand 2 "" ""))]
11326 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11330 (define_insn "*call_0"
11331 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11332 (match_operand 1 "" ""))]
11335 if (SIBLING_CALL_P (insn))
11338 return "call\t%P0";
11340 [(set_attr "type" "call")])
11342 (define_insn "*call_1"
11343 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11344 (match_operand 1 "" ""))]
11345 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11347 if (constant_call_address_operand (operands[0], Pmode))
11348 return "call\t%P0";
11349 return "call\t%A0";
11351 [(set_attr "type" "call")])
11353 (define_insn "*sibcall_1"
11354 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11355 (match_operand 1 "" ""))]
11356 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11360 [(set_attr "type" "call")])
11362 (define_insn "*call_1_rex64"
11363 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11364 (match_operand 1 "" ""))]
11365 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11366 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11368 if (constant_call_address_operand (operands[0], Pmode))
11369 return "call\t%P0";
11370 return "call\t%A0";
11372 [(set_attr "type" "call")])
11374 (define_insn "*call_1_rex64_ms_sysv"
11375 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11376 (match_operand 1 "" ""))
11377 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11378 (clobber (reg:TI XMM6_REG))
11379 (clobber (reg:TI XMM7_REG))
11380 (clobber (reg:TI XMM8_REG))
11381 (clobber (reg:TI XMM9_REG))
11382 (clobber (reg:TI XMM10_REG))
11383 (clobber (reg:TI XMM11_REG))
11384 (clobber (reg:TI XMM12_REG))
11385 (clobber (reg:TI XMM13_REG))
11386 (clobber (reg:TI XMM14_REG))
11387 (clobber (reg:TI XMM15_REG))
11388 (clobber (reg:DI SI_REG))
11389 (clobber (reg:DI DI_REG))]
11390 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11392 if (constant_call_address_operand (operands[0], Pmode))
11393 return "call\t%P0";
11394 return "call\t%A0";
11396 [(set_attr "type" "call")])
11398 (define_insn "*call_1_rex64_large"
11399 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11400 (match_operand 1 "" ""))]
11401 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11403 [(set_attr "type" "call")])
11405 (define_insn "*sibcall_1_rex64"
11406 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11407 (match_operand 1 "" ""))]
11408 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11412 [(set_attr "type" "call")])
11414 ;; Call subroutine, returning value in operand 0
11415 (define_expand "call_value_pop"
11416 [(parallel [(set (match_operand 0 "" "")
11417 (call (match_operand:QI 1 "" "")
11418 (match_operand:SI 2 "" "")))
11419 (set (reg:SI SP_REG)
11420 (plus:SI (reg:SI SP_REG)
11421 (match_operand:SI 4 "" "")))])]
11424 ix86_expand_call (operands[0], operands[1], operands[2],
11425 operands[3], operands[4], 0);
11429 (define_expand "call_value"
11430 [(set (match_operand 0 "" "")
11431 (call (match_operand:QI 1 "" "")
11432 (match_operand:SI 2 "" "")))
11433 (use (match_operand:SI 3 "" ""))]
11434 ;; Operand 3 is not used on the i386.
11437 ix86_expand_call (operands[0], operands[1], operands[2],
11438 operands[3], NULL, 0);
11442 (define_expand "sibcall_value"
11443 [(set (match_operand 0 "" "")
11444 (call (match_operand:QI 1 "" "")
11445 (match_operand:SI 2 "" "")))
11446 (use (match_operand:SI 3 "" ""))]
11447 ;; Operand 3 is not used on the i386.
11450 ix86_expand_call (operands[0], operands[1], operands[2],
11451 operands[3], NULL, 1);
11455 ;; Call subroutine returning any type.
11457 (define_expand "untyped_call"
11458 [(parallel [(call (match_operand 0 "" "")
11460 (match_operand 1 "" "")
11461 (match_operand 2 "" "")])]
11466 /* In order to give reg-stack an easier job in validating two
11467 coprocessor registers as containing a possible return value,
11468 simply pretend the untyped call returns a complex long double
11471 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11472 and should have the default ABI. */
11474 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11475 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11476 operands[0], const0_rtx,
11477 GEN_INT ((TARGET_64BIT
11478 ? (ix86_abi == SYSV_ABI
11479 ? X86_64_SSE_REGPARM_MAX
11480 : X86_64_MS_SSE_REGPARM_MAX)
11481 : X86_32_SSE_REGPARM_MAX)
11485 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11487 rtx set = XVECEXP (operands[2], 0, i);
11488 emit_move_insn (SET_DEST (set), SET_SRC (set));
11491 /* The optimizer does not know that the call sets the function value
11492 registers we stored in the result block. We avoid problems by
11493 claiming that all hard registers are used and clobbered at this
11495 emit_insn (gen_blockage ());
11500 ;; Prologue and epilogue instructions
11502 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11503 ;; all of memory. This blocks insns from being moved across this point.
11505 (define_insn "blockage"
11506 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11509 [(set_attr "length" "0")])
11511 ;; Do not schedule instructions accessing memory across this point.
11513 (define_expand "memory_blockage"
11514 [(set (match_dup 0)
11515 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11518 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11519 MEM_VOLATILE_P (operands[0]) = 1;
11522 (define_insn "*memory_blockage"
11523 [(set (match_operand:BLK 0 "" "")
11524 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11527 [(set_attr "length" "0")])
11529 ;; As USE insns aren't meaningful after reload, this is used instead
11530 ;; to prevent deleting instructions setting registers for PIC code
11531 (define_insn "prologue_use"
11532 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11535 [(set_attr "length" "0")])
11537 ;; Insn emitted into the body of a function to return from a function.
11538 ;; This is only done if the function's epilogue is known to be simple.
11539 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11541 (define_expand "return"
11543 "ix86_can_use_return_insn_p ()"
11545 if (crtl->args.pops_args)
11547 rtx popc = GEN_INT (crtl->args.pops_args);
11548 emit_jump_insn (gen_return_pop_internal (popc));
11553 (define_insn "return_internal"
11557 [(set_attr "length" "1")
11558 (set_attr "atom_unit" "jeu")
11559 (set_attr "length_immediate" "0")
11560 (set_attr "modrm" "0")])
11562 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11563 ;; instruction Athlon and K8 have.
11565 (define_insn "return_internal_long"
11567 (unspec [(const_int 0)] UNSPEC_REP)]
11570 [(set_attr "length" "2")
11571 (set_attr "atom_unit" "jeu")
11572 (set_attr "length_immediate" "0")
11573 (set_attr "prefix_rep" "1")
11574 (set_attr "modrm" "0")])
11576 (define_insn "return_pop_internal"
11578 (use (match_operand:SI 0 "const_int_operand" ""))]
11581 [(set_attr "length" "3")
11582 (set_attr "atom_unit" "jeu")
11583 (set_attr "length_immediate" "2")
11584 (set_attr "modrm" "0")])
11586 (define_insn "return_indirect_internal"
11588 (use (match_operand:SI 0 "register_operand" "r"))]
11591 [(set_attr "type" "ibr")
11592 (set_attr "length_immediate" "0")])
11598 [(set_attr "length" "1")
11599 (set_attr "length_immediate" "0")
11600 (set_attr "modrm" "0")])
11602 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11603 ;; branch prediction penalty for the third jump in a 16-byte
11607 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11610 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11611 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11613 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11614 The align insn is used to avoid 3 jump instructions in the row to improve
11615 branch prediction and the benefits hardly outweigh the cost of extra 8
11616 nops on the average inserted by full alignment pseudo operation. */
11620 [(set_attr "length" "16")])
11622 (define_expand "prologue"
11625 "ix86_expand_prologue (); DONE;")
11627 (define_insn "set_got"
11628 [(set (match_operand:SI 0 "register_operand" "=r")
11629 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11630 (clobber (reg:CC FLAGS_REG))]
11632 { return output_set_got (operands[0], NULL_RTX); }
11633 [(set_attr "type" "multi")
11634 (set_attr "length" "12")])
11636 (define_insn "set_got_labelled"
11637 [(set (match_operand:SI 0 "register_operand" "=r")
11638 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11640 (clobber (reg:CC FLAGS_REG))]
11642 { return output_set_got (operands[0], operands[1]); }
11643 [(set_attr "type" "multi")
11644 (set_attr "length" "12")])
11646 (define_insn "set_got_rex64"
11647 [(set (match_operand:DI 0 "register_operand" "=r")
11648 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11650 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11651 [(set_attr "type" "lea")
11652 (set_attr "length_address" "4")
11653 (set_attr "mode" "DI")])
11655 (define_insn "set_rip_rex64"
11656 [(set (match_operand:DI 0 "register_operand" "=r")
11657 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11659 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11660 [(set_attr "type" "lea")
11661 (set_attr "length_address" "4")
11662 (set_attr "mode" "DI")])
11664 (define_insn "set_got_offset_rex64"
11665 [(set (match_operand:DI 0 "register_operand" "=r")
11667 [(label_ref (match_operand 1 "" ""))]
11668 UNSPEC_SET_GOT_OFFSET))]
11670 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11671 [(set_attr "type" "imov")
11672 (set_attr "length_immediate" "0")
11673 (set_attr "length_address" "8")
11674 (set_attr "mode" "DI")])
11676 (define_expand "epilogue"
11679 "ix86_expand_epilogue (1); DONE;")
11681 (define_expand "sibcall_epilogue"
11684 "ix86_expand_epilogue (0); DONE;")
11686 (define_expand "eh_return"
11687 [(use (match_operand 0 "register_operand" ""))]
11690 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11692 /* Tricky bit: we write the address of the handler to which we will
11693 be returning into someone else's stack frame, one word below the
11694 stack address we wish to restore. */
11695 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11696 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11697 tmp = gen_rtx_MEM (Pmode, tmp);
11698 emit_move_insn (tmp, ra);
11700 emit_jump_insn (gen_eh_return_internal ());
11705 (define_insn_and_split "eh_return_internal"
11709 "epilogue_completed"
11711 "ix86_expand_epilogue (2); DONE;")
11713 (define_insn "leave"
11714 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11715 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11716 (clobber (mem:BLK (scratch)))]
11719 [(set_attr "type" "leave")])
11721 (define_insn "leave_rex64"
11722 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11723 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11724 (clobber (mem:BLK (scratch)))]
11727 [(set_attr "type" "leave")])
11729 ;; Bit manipulation instructions.
11731 (define_expand "ffs<mode>2"
11732 [(set (match_dup 2) (const_int -1))
11733 (parallel [(set (reg:CCZ FLAGS_REG)
11735 (match_operand:SWI48 1 "nonimmediate_operand" "")
11737 (set (match_operand:SWI48 0 "register_operand" "")
11738 (ctz:SWI48 (match_dup 1)))])
11739 (set (match_dup 0) (if_then_else:SWI48
11740 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11743 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11744 (clobber (reg:CC FLAGS_REG))])]
11747 if (<MODE>mode == SImode && !TARGET_CMOVE)
11749 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11752 operands[2] = gen_reg_rtx (<MODE>mode);
11755 (define_insn_and_split "ffssi2_no_cmove"
11756 [(set (match_operand:SI 0 "register_operand" "=r")
11757 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11758 (clobber (match_scratch:SI 2 "=&q"))
11759 (clobber (reg:CC FLAGS_REG))]
11762 "&& reload_completed"
11763 [(parallel [(set (reg:CCZ FLAGS_REG)
11764 (compare:CCZ (match_dup 1) (const_int 0)))
11765 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11766 (set (strict_low_part (match_dup 3))
11767 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11768 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11769 (clobber (reg:CC FLAGS_REG))])
11770 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11771 (clobber (reg:CC FLAGS_REG))])
11772 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11773 (clobber (reg:CC FLAGS_REG))])]
11775 operands[3] = gen_lowpart (QImode, operands[2]);
11776 ix86_expand_clear (operands[2]);
11779 (define_insn "*ffs<mode>_1"
11780 [(set (reg:CCZ FLAGS_REG)
11781 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11783 (set (match_operand:SWI48 0 "register_operand" "=r")
11784 (ctz:SWI48 (match_dup 1)))]
11786 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11787 [(set_attr "type" "alu1")
11788 (set_attr "prefix_0f" "1")
11789 (set_attr "mode" "<MODE>")])
11791 (define_insn "ctz<mode>2"
11792 [(set (match_operand:SWI48 0 "register_operand" "=r")
11793 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11794 (clobber (reg:CC FLAGS_REG))]
11796 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11797 [(set_attr "type" "alu1")
11798 (set_attr "prefix_0f" "1")
11799 (set_attr "mode" "<MODE>")])
11801 (define_expand "clz<mode>2"
11803 [(set (match_operand:SWI248 0 "register_operand" "")
11806 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11807 (clobber (reg:CC FLAGS_REG))])
11809 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11810 (clobber (reg:CC FLAGS_REG))])]
11815 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11818 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11821 (define_insn "clz<mode>2_abm"
11822 [(set (match_operand:SWI248 0 "register_operand" "=r")
11823 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11824 (clobber (reg:CC FLAGS_REG))]
11826 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11827 [(set_attr "prefix_rep" "1")
11828 (set_attr "type" "bitmanip")
11829 (set_attr "mode" "<MODE>")])
11831 (define_insn "bsr_rex64"
11832 [(set (match_operand:DI 0 "register_operand" "=r")
11833 (minus:DI (const_int 63)
11834 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11835 (clobber (reg:CC FLAGS_REG))]
11837 "bsr{q}\t{%1, %0|%0, %1}"
11838 [(set_attr "type" "alu1")
11839 (set_attr "prefix_0f" "1")
11840 (set_attr "mode" "DI")])
11843 [(set (match_operand:SI 0 "register_operand" "=r")
11844 (minus:SI (const_int 31)
11845 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11846 (clobber (reg:CC FLAGS_REG))]
11848 "bsr{l}\t{%1, %0|%0, %1}"
11849 [(set_attr "type" "alu1")
11850 (set_attr "prefix_0f" "1")
11851 (set_attr "mode" "SI")])
11853 (define_insn "*bsrhi"
11854 [(set (match_operand:HI 0 "register_operand" "=r")
11855 (minus:HI (const_int 15)
11856 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11857 (clobber (reg:CC FLAGS_REG))]
11859 "bsr{w}\t{%1, %0|%0, %1}"
11860 [(set_attr "type" "alu1")
11861 (set_attr "prefix_0f" "1")
11862 (set_attr "mode" "HI")])
11864 (define_insn "popcount<mode>2"
11865 [(set (match_operand:SWI248 0 "register_operand" "=r")
11867 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11868 (clobber (reg:CC FLAGS_REG))]
11872 return "popcnt\t{%1, %0|%0, %1}";
11874 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11877 [(set_attr "prefix_rep" "1")
11878 (set_attr "type" "bitmanip")
11879 (set_attr "mode" "<MODE>")])
11881 (define_insn "*popcount<mode>2_cmp"
11882 [(set (reg FLAGS_REG)
11885 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11887 (set (match_operand:SWI248 0 "register_operand" "=r")
11888 (popcount:SWI248 (match_dup 1)))]
11889 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11892 return "popcnt\t{%1, %0|%0, %1}";
11894 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11897 [(set_attr "prefix_rep" "1")
11898 (set_attr "type" "bitmanip")
11899 (set_attr "mode" "<MODE>")])
11901 (define_insn "*popcountsi2_cmp_zext"
11902 [(set (reg FLAGS_REG)
11904 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11906 (set (match_operand:DI 0 "register_operand" "=r")
11907 (zero_extend:DI(popcount:SI (match_dup 1))))]
11908 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11911 return "popcnt\t{%1, %0|%0, %1}";
11913 return "popcnt{l}\t{%1, %0|%0, %1}";
11916 [(set_attr "prefix_rep" "1")
11917 (set_attr "type" "bitmanip")
11918 (set_attr "mode" "SI")])
11920 (define_expand "bswap<mode>2"
11921 [(set (match_operand:SWI48 0 "register_operand" "")
11922 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11925 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11927 rtx x = operands[0];
11929 emit_move_insn (x, operands[1]);
11930 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11931 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11932 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11937 (define_insn "*bswap<mode>2_movbe"
11938 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11939 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11941 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11944 movbe\t{%1, %0|%0, %1}
11945 movbe\t{%1, %0|%0, %1}"
11946 [(set_attr "type" "bitmanip,imov,imov")
11947 (set_attr "modrm" "0,1,1")
11948 (set_attr "prefix_0f" "*,1,1")
11949 (set_attr "prefix_extra" "*,1,1")
11950 (set_attr "mode" "<MODE>")])
11952 (define_insn "*bswap<mode>2_1"
11953 [(set (match_operand:SWI48 0 "register_operand" "=r")
11954 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11957 [(set_attr "type" "bitmanip")
11958 (set_attr "modrm" "0")
11959 (set_attr "mode" "<MODE>")])
11961 (define_insn "*bswaphi_lowpart_1"
11962 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11963 (bswap:HI (match_dup 0)))
11964 (clobber (reg:CC FLAGS_REG))]
11965 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11967 xchg{b}\t{%h0, %b0|%b0, %h0}
11968 rol{w}\t{$8, %0|%0, 8}"
11969 [(set_attr "length" "2,4")
11970 (set_attr "mode" "QI,HI")])
11972 (define_insn "bswaphi_lowpart"
11973 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11974 (bswap:HI (match_dup 0)))
11975 (clobber (reg:CC FLAGS_REG))]
11977 "rol{w}\t{$8, %0|%0, 8}"
11978 [(set_attr "length" "4")
11979 (set_attr "mode" "HI")])
11981 (define_expand "paritydi2"
11982 [(set (match_operand:DI 0 "register_operand" "")
11983 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11986 rtx scratch = gen_reg_rtx (QImode);
11989 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11990 NULL_RTX, operands[1]));
11992 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11993 gen_rtx_REG (CCmode, FLAGS_REG),
11995 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11998 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12001 rtx tmp = gen_reg_rtx (SImode);
12003 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12004 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12009 (define_expand "paritysi2"
12010 [(set (match_operand:SI 0 "register_operand" "")
12011 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12014 rtx scratch = gen_reg_rtx (QImode);
12017 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12019 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12020 gen_rtx_REG (CCmode, FLAGS_REG),
12022 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12024 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12028 (define_insn_and_split "paritydi2_cmp"
12029 [(set (reg:CC FLAGS_REG)
12030 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12032 (clobber (match_scratch:DI 0 "=r"))
12033 (clobber (match_scratch:SI 1 "=&r"))
12034 (clobber (match_scratch:HI 2 "=Q"))]
12037 "&& reload_completed"
12039 [(set (match_dup 1)
12040 (xor:SI (match_dup 1) (match_dup 4)))
12041 (clobber (reg:CC FLAGS_REG))])
12043 [(set (reg:CC FLAGS_REG)
12044 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12045 (clobber (match_dup 1))
12046 (clobber (match_dup 2))])]
12048 operands[4] = gen_lowpart (SImode, operands[3]);
12052 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12053 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12056 operands[1] = gen_highpart (SImode, operands[3]);
12059 (define_insn_and_split "paritysi2_cmp"
12060 [(set (reg:CC FLAGS_REG)
12061 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12063 (clobber (match_scratch:SI 0 "=r"))
12064 (clobber (match_scratch:HI 1 "=&Q"))]
12067 "&& reload_completed"
12069 [(set (match_dup 1)
12070 (xor:HI (match_dup 1) (match_dup 3)))
12071 (clobber (reg:CC FLAGS_REG))])
12073 [(set (reg:CC FLAGS_REG)
12074 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12075 (clobber (match_dup 1))])]
12077 operands[3] = gen_lowpart (HImode, operands[2]);
12079 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12080 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12083 (define_insn "*parityhi2_cmp"
12084 [(set (reg:CC FLAGS_REG)
12085 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12087 (clobber (match_scratch:HI 0 "=Q"))]
12089 "xor{b}\t{%h0, %b0|%b0, %h0}"
12090 [(set_attr "length" "2")
12091 (set_attr "mode" "HI")])
12093 ;; Thread-local storage patterns for ELF.
12095 ;; Note that these code sequences must appear exactly as shown
12096 ;; in order to allow linker relaxation.
12098 (define_insn "*tls_global_dynamic_32_gnu"
12099 [(set (match_operand:SI 0 "register_operand" "=a")
12100 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12101 (match_operand:SI 2 "tls_symbolic_operand" "")
12102 (match_operand:SI 3 "call_insn_operand" "")]
12104 (clobber (match_scratch:SI 4 "=d"))
12105 (clobber (match_scratch:SI 5 "=c"))
12106 (clobber (reg:CC FLAGS_REG))]
12107 "!TARGET_64BIT && TARGET_GNU_TLS"
12108 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12109 [(set_attr "type" "multi")
12110 (set_attr "length" "12")])
12112 (define_expand "tls_global_dynamic_32"
12113 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12116 (match_operand:SI 1 "tls_symbolic_operand" "")
12119 (clobber (match_scratch:SI 4 ""))
12120 (clobber (match_scratch:SI 5 ""))
12121 (clobber (reg:CC FLAGS_REG))])]
12125 operands[2] = pic_offset_table_rtx;
12128 operands[2] = gen_reg_rtx (Pmode);
12129 emit_insn (gen_set_got (operands[2]));
12131 if (TARGET_GNU2_TLS)
12133 emit_insn (gen_tls_dynamic_gnu2_32
12134 (operands[0], operands[1], operands[2]));
12137 operands[3] = ix86_tls_get_addr ();
12140 (define_insn "*tls_global_dynamic_64"
12141 [(set (match_operand:DI 0 "register_operand" "=a")
12142 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12143 (match_operand:DI 3 "" "")))
12144 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12147 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12148 [(set_attr "type" "multi")
12149 (set_attr "length" "16")])
12151 (define_expand "tls_global_dynamic_64"
12152 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12153 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12154 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12158 if (TARGET_GNU2_TLS)
12160 emit_insn (gen_tls_dynamic_gnu2_64
12161 (operands[0], operands[1]));
12164 operands[2] = ix86_tls_get_addr ();
12167 (define_insn "*tls_local_dynamic_base_32_gnu"
12168 [(set (match_operand:SI 0 "register_operand" "=a")
12169 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12170 (match_operand:SI 2 "call_insn_operand" "")]
12171 UNSPEC_TLS_LD_BASE))
12172 (clobber (match_scratch:SI 3 "=d"))
12173 (clobber (match_scratch:SI 4 "=c"))
12174 (clobber (reg:CC FLAGS_REG))]
12175 "!TARGET_64BIT && TARGET_GNU_TLS"
12176 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12177 [(set_attr "type" "multi")
12178 (set_attr "length" "11")])
12180 (define_expand "tls_local_dynamic_base_32"
12181 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12182 (unspec:SI [(match_dup 1) (match_dup 2)]
12183 UNSPEC_TLS_LD_BASE))
12184 (clobber (match_scratch:SI 3 ""))
12185 (clobber (match_scratch:SI 4 ""))
12186 (clobber (reg:CC FLAGS_REG))])]
12190 operands[1] = pic_offset_table_rtx;
12193 operands[1] = gen_reg_rtx (Pmode);
12194 emit_insn (gen_set_got (operands[1]));
12196 if (TARGET_GNU2_TLS)
12198 emit_insn (gen_tls_dynamic_gnu2_32
12199 (operands[0], ix86_tls_module_base (), operands[1]));
12202 operands[2] = ix86_tls_get_addr ();
12205 (define_insn "*tls_local_dynamic_base_64"
12206 [(set (match_operand:DI 0 "register_operand" "=a")
12207 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12208 (match_operand:DI 2 "" "")))
12209 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12211 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12212 [(set_attr "type" "multi")
12213 (set_attr "length" "12")])
12215 (define_expand "tls_local_dynamic_base_64"
12216 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12217 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12218 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12221 if (TARGET_GNU2_TLS)
12223 emit_insn (gen_tls_dynamic_gnu2_64
12224 (operands[0], ix86_tls_module_base ()));
12227 operands[1] = ix86_tls_get_addr ();
12230 ;; Local dynamic of a single variable is a lose. Show combine how
12231 ;; to convert that back to global dynamic.
12233 (define_insn_and_split "*tls_local_dynamic_32_once"
12234 [(set (match_operand:SI 0 "register_operand" "=a")
12235 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12236 (match_operand:SI 2 "call_insn_operand" "")]
12237 UNSPEC_TLS_LD_BASE)
12238 (const:SI (unspec:SI
12239 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12241 (clobber (match_scratch:SI 4 "=d"))
12242 (clobber (match_scratch:SI 5 "=c"))
12243 (clobber (reg:CC FLAGS_REG))]
12247 [(parallel [(set (match_dup 0)
12248 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12250 (clobber (match_dup 4))
12251 (clobber (match_dup 5))
12252 (clobber (reg:CC FLAGS_REG))])]
12255 ;; Load and add the thread base pointer from %gs:0.
12257 (define_insn "*load_tp_si"
12258 [(set (match_operand:SI 0 "register_operand" "=r")
12259 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12261 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12262 [(set_attr "type" "imov")
12263 (set_attr "modrm" "0")
12264 (set_attr "length" "7")
12265 (set_attr "memory" "load")
12266 (set_attr "imm_disp" "false")])
12268 (define_insn "*add_tp_si"
12269 [(set (match_operand:SI 0 "register_operand" "=r")
12270 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12271 (match_operand:SI 1 "register_operand" "0")))
12272 (clobber (reg:CC FLAGS_REG))]
12274 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12275 [(set_attr "type" "alu")
12276 (set_attr "modrm" "0")
12277 (set_attr "length" "7")
12278 (set_attr "memory" "load")
12279 (set_attr "imm_disp" "false")])
12281 (define_insn "*load_tp_di"
12282 [(set (match_operand:DI 0 "register_operand" "=r")
12283 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12285 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12286 [(set_attr "type" "imov")
12287 (set_attr "modrm" "0")
12288 (set_attr "length" "7")
12289 (set_attr "memory" "load")
12290 (set_attr "imm_disp" "false")])
12292 (define_insn "*add_tp_di"
12293 [(set (match_operand:DI 0 "register_operand" "=r")
12294 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12295 (match_operand:DI 1 "register_operand" "0")))
12296 (clobber (reg:CC FLAGS_REG))]
12298 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12299 [(set_attr "type" "alu")
12300 (set_attr "modrm" "0")
12301 (set_attr "length" "7")
12302 (set_attr "memory" "load")
12303 (set_attr "imm_disp" "false")])
12305 ;; GNU2 TLS patterns can be split.
12307 (define_expand "tls_dynamic_gnu2_32"
12308 [(set (match_dup 3)
12309 (plus:SI (match_operand:SI 2 "register_operand" "")
12311 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12314 [(set (match_operand:SI 0 "register_operand" "")
12315 (unspec:SI [(match_dup 1) (match_dup 3)
12316 (match_dup 2) (reg:SI SP_REG)]
12318 (clobber (reg:CC FLAGS_REG))])]
12319 "!TARGET_64BIT && TARGET_GNU2_TLS"
12321 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12322 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12325 (define_insn "*tls_dynamic_lea_32"
12326 [(set (match_operand:SI 0 "register_operand" "=r")
12327 (plus:SI (match_operand:SI 1 "register_operand" "b")
12329 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12330 UNSPEC_TLSDESC))))]
12331 "!TARGET_64BIT && TARGET_GNU2_TLS"
12332 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12333 [(set_attr "type" "lea")
12334 (set_attr "mode" "SI")
12335 (set_attr "length" "6")
12336 (set_attr "length_address" "4")])
12338 (define_insn "*tls_dynamic_call_32"
12339 [(set (match_operand:SI 0 "register_operand" "=a")
12340 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12341 (match_operand:SI 2 "register_operand" "0")
12342 ;; we have to make sure %ebx still points to the GOT
12343 (match_operand:SI 3 "register_operand" "b")
12346 (clobber (reg:CC FLAGS_REG))]
12347 "!TARGET_64BIT && TARGET_GNU2_TLS"
12348 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12349 [(set_attr "type" "call")
12350 (set_attr "length" "2")
12351 (set_attr "length_address" "0")])
12353 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12354 [(set (match_operand:SI 0 "register_operand" "=&a")
12356 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12357 (match_operand:SI 4 "" "")
12358 (match_operand:SI 2 "register_operand" "b")
12361 (const:SI (unspec:SI
12362 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12364 (clobber (reg:CC FLAGS_REG))]
12365 "!TARGET_64BIT && TARGET_GNU2_TLS"
12368 [(set (match_dup 0) (match_dup 5))]
12370 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12371 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12374 (define_expand "tls_dynamic_gnu2_64"
12375 [(set (match_dup 2)
12376 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12379 [(set (match_operand:DI 0 "register_operand" "")
12380 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12382 (clobber (reg:CC FLAGS_REG))])]
12383 "TARGET_64BIT && TARGET_GNU2_TLS"
12385 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12386 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12389 (define_insn "*tls_dynamic_lea_64"
12390 [(set (match_operand:DI 0 "register_operand" "=r")
12391 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12393 "TARGET_64BIT && TARGET_GNU2_TLS"
12394 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12395 [(set_attr "type" "lea")
12396 (set_attr "mode" "DI")
12397 (set_attr "length" "7")
12398 (set_attr "length_address" "4")])
12400 (define_insn "*tls_dynamic_call_64"
12401 [(set (match_operand:DI 0 "register_operand" "=a")
12402 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12403 (match_operand:DI 2 "register_operand" "0")
12406 (clobber (reg:CC FLAGS_REG))]
12407 "TARGET_64BIT && TARGET_GNU2_TLS"
12408 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12409 [(set_attr "type" "call")
12410 (set_attr "length" "2")
12411 (set_attr "length_address" "0")])
12413 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12414 [(set (match_operand:DI 0 "register_operand" "=&a")
12416 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12417 (match_operand:DI 3 "" "")
12420 (const:DI (unspec:DI
12421 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12423 (clobber (reg:CC FLAGS_REG))]
12424 "TARGET_64BIT && TARGET_GNU2_TLS"
12427 [(set (match_dup 0) (match_dup 4))]
12429 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12430 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12435 ;; These patterns match the binary 387 instructions for addM3, subM3,
12436 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12437 ;; SFmode. The first is the normal insn, the second the same insn but
12438 ;; with one operand a conversion, and the third the same insn but with
12439 ;; the other operand a conversion. The conversion may be SFmode or
12440 ;; SImode if the target mode DFmode, but only SImode if the target mode
12443 ;; Gcc is slightly more smart about handling normal two address instructions
12444 ;; so use special patterns for add and mull.
12446 (define_insn "*fop_<mode>_comm_mixed_avx"
12447 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12448 (match_operator:MODEF 3 "binary_fp_operator"
12449 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12450 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12451 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12452 && COMMUTATIVE_ARITH_P (operands[3])
12453 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12454 "* return output_387_binary_op (insn, operands);"
12455 [(set (attr "type")
12456 (if_then_else (eq_attr "alternative" "1")
12457 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12458 (const_string "ssemul")
12459 (const_string "sseadd"))
12460 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12461 (const_string "fmul")
12462 (const_string "fop"))))
12463 (set_attr "prefix" "orig,maybe_vex")
12464 (set_attr "mode" "<MODE>")])
12466 (define_insn "*fop_<mode>_comm_mixed"
12467 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12468 (match_operator:MODEF 3 "binary_fp_operator"
12469 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12470 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12471 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12472 && COMMUTATIVE_ARITH_P (operands[3])
12473 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12474 "* return output_387_binary_op (insn, operands);"
12475 [(set (attr "type")
12476 (if_then_else (eq_attr "alternative" "1")
12477 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12478 (const_string "ssemul")
12479 (const_string "sseadd"))
12480 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12481 (const_string "fmul")
12482 (const_string "fop"))))
12483 (set_attr "mode" "<MODE>")])
12485 (define_insn "*fop_<mode>_comm_avx"
12486 [(set (match_operand:MODEF 0 "register_operand" "=x")
12487 (match_operator:MODEF 3 "binary_fp_operator"
12488 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12489 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12490 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12491 && COMMUTATIVE_ARITH_P (operands[3])
12492 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12493 "* return output_387_binary_op (insn, operands);"
12494 [(set (attr "type")
12495 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12496 (const_string "ssemul")
12497 (const_string "sseadd")))
12498 (set_attr "prefix" "vex")
12499 (set_attr "mode" "<MODE>")])
12501 (define_insn "*fop_<mode>_comm_sse"
12502 [(set (match_operand:MODEF 0 "register_operand" "=x")
12503 (match_operator:MODEF 3 "binary_fp_operator"
12504 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12505 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12506 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12507 && COMMUTATIVE_ARITH_P (operands[3])
12508 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12509 "* return output_387_binary_op (insn, operands);"
12510 [(set (attr "type")
12511 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12512 (const_string "ssemul")
12513 (const_string "sseadd")))
12514 (set_attr "mode" "<MODE>")])
12516 (define_insn "*fop_<mode>_comm_i387"
12517 [(set (match_operand:MODEF 0 "register_operand" "=f")
12518 (match_operator:MODEF 3 "binary_fp_operator"
12519 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12520 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12521 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12522 && COMMUTATIVE_ARITH_P (operands[3])
12523 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12524 "* return output_387_binary_op (insn, operands);"
12525 [(set (attr "type")
12526 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12527 (const_string "fmul")
12528 (const_string "fop")))
12529 (set_attr "mode" "<MODE>")])
12531 (define_insn "*fop_<mode>_1_mixed_avx"
12532 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12533 (match_operator:MODEF 3 "binary_fp_operator"
12534 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12535 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12536 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12537 && !COMMUTATIVE_ARITH_P (operands[3])
12538 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12539 "* return output_387_binary_op (insn, operands);"
12540 [(set (attr "type")
12541 (cond [(and (eq_attr "alternative" "2")
12542 (match_operand:MODEF 3 "mult_operator" ""))
12543 (const_string "ssemul")
12544 (and (eq_attr "alternative" "2")
12545 (match_operand:MODEF 3 "div_operator" ""))
12546 (const_string "ssediv")
12547 (eq_attr "alternative" "2")
12548 (const_string "sseadd")
12549 (match_operand:MODEF 3 "mult_operator" "")
12550 (const_string "fmul")
12551 (match_operand:MODEF 3 "div_operator" "")
12552 (const_string "fdiv")
12554 (const_string "fop")))
12555 (set_attr "prefix" "orig,orig,maybe_vex")
12556 (set_attr "mode" "<MODE>")])
12558 (define_insn "*fop_<mode>_1_mixed"
12559 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12560 (match_operator:MODEF 3 "binary_fp_operator"
12561 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12562 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12563 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12564 && !COMMUTATIVE_ARITH_P (operands[3])
12565 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12566 "* return output_387_binary_op (insn, operands);"
12567 [(set (attr "type")
12568 (cond [(and (eq_attr "alternative" "2")
12569 (match_operand:MODEF 3 "mult_operator" ""))
12570 (const_string "ssemul")
12571 (and (eq_attr "alternative" "2")
12572 (match_operand:MODEF 3 "div_operator" ""))
12573 (const_string "ssediv")
12574 (eq_attr "alternative" "2")
12575 (const_string "sseadd")
12576 (match_operand:MODEF 3 "mult_operator" "")
12577 (const_string "fmul")
12578 (match_operand:MODEF 3 "div_operator" "")
12579 (const_string "fdiv")
12581 (const_string "fop")))
12582 (set_attr "mode" "<MODE>")])
12584 (define_insn "*rcpsf2_sse"
12585 [(set (match_operand:SF 0 "register_operand" "=x")
12586 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12589 "%vrcpss\t{%1, %d0|%d0, %1}"
12590 [(set_attr "type" "sse")
12591 (set_attr "atom_sse_attr" "rcp")
12592 (set_attr "prefix" "maybe_vex")
12593 (set_attr "mode" "SF")])
12595 (define_insn "*fop_<mode>_1_avx"
12596 [(set (match_operand:MODEF 0 "register_operand" "=x")
12597 (match_operator:MODEF 3 "binary_fp_operator"
12598 [(match_operand:MODEF 1 "register_operand" "x")
12599 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12600 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12601 && !COMMUTATIVE_ARITH_P (operands[3])"
12602 "* return output_387_binary_op (insn, operands);"
12603 [(set (attr "type")
12604 (cond [(match_operand:MODEF 3 "mult_operator" "")
12605 (const_string "ssemul")
12606 (match_operand:MODEF 3 "div_operator" "")
12607 (const_string "ssediv")
12609 (const_string "sseadd")))
12610 (set_attr "prefix" "vex")
12611 (set_attr "mode" "<MODE>")])
12613 (define_insn "*fop_<mode>_1_sse"
12614 [(set (match_operand:MODEF 0 "register_operand" "=x")
12615 (match_operator:MODEF 3 "binary_fp_operator"
12616 [(match_operand:MODEF 1 "register_operand" "0")
12617 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12618 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12619 && !COMMUTATIVE_ARITH_P (operands[3])"
12620 "* return output_387_binary_op (insn, operands);"
12621 [(set (attr "type")
12622 (cond [(match_operand:MODEF 3 "mult_operator" "")
12623 (const_string "ssemul")
12624 (match_operand:MODEF 3 "div_operator" "")
12625 (const_string "ssediv")
12627 (const_string "sseadd")))
12628 (set_attr "mode" "<MODE>")])
12630 ;; This pattern is not fully shadowed by the pattern above.
12631 (define_insn "*fop_<mode>_1_i387"
12632 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12633 (match_operator:MODEF 3 "binary_fp_operator"
12634 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12635 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12636 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12637 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12638 && !COMMUTATIVE_ARITH_P (operands[3])
12639 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12640 "* return output_387_binary_op (insn, operands);"
12641 [(set (attr "type")
12642 (cond [(match_operand:MODEF 3 "mult_operator" "")
12643 (const_string "fmul")
12644 (match_operand:MODEF 3 "div_operator" "")
12645 (const_string "fdiv")
12647 (const_string "fop")))
12648 (set_attr "mode" "<MODE>")])
12650 ;; ??? Add SSE splitters for these!
12651 (define_insn "*fop_<MODEF:mode>_2_i387"
12652 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12653 (match_operator:MODEF 3 "binary_fp_operator"
12655 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12656 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12657 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12658 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12659 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12660 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12661 [(set (attr "type")
12662 (cond [(match_operand:MODEF 3 "mult_operator" "")
12663 (const_string "fmul")
12664 (match_operand:MODEF 3 "div_operator" "")
12665 (const_string "fdiv")
12667 (const_string "fop")))
12668 (set_attr "fp_int_src" "true")
12669 (set_attr "mode" "<X87MODEI12:MODE>")])
12671 (define_insn "*fop_<MODEF:mode>_3_i387"
12672 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12673 (match_operator:MODEF 3 "binary_fp_operator"
12674 [(match_operand:MODEF 1 "register_operand" "0,0")
12676 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12677 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12678 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12679 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12680 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12681 [(set (attr "type")
12682 (cond [(match_operand:MODEF 3 "mult_operator" "")
12683 (const_string "fmul")
12684 (match_operand:MODEF 3 "div_operator" "")
12685 (const_string "fdiv")
12687 (const_string "fop")))
12688 (set_attr "fp_int_src" "true")
12689 (set_attr "mode" "<MODE>")])
12691 (define_insn "*fop_df_4_i387"
12692 [(set (match_operand:DF 0 "register_operand" "=f,f")
12693 (match_operator:DF 3 "binary_fp_operator"
12695 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12696 (match_operand:DF 2 "register_operand" "0,f")]))]
12697 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12698 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12699 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12700 "* return output_387_binary_op (insn, operands);"
12701 [(set (attr "type")
12702 (cond [(match_operand:DF 3 "mult_operator" "")
12703 (const_string "fmul")
12704 (match_operand:DF 3 "div_operator" "")
12705 (const_string "fdiv")
12707 (const_string "fop")))
12708 (set_attr "mode" "SF")])
12710 (define_insn "*fop_df_5_i387"
12711 [(set (match_operand:DF 0 "register_operand" "=f,f")
12712 (match_operator:DF 3 "binary_fp_operator"
12713 [(match_operand:DF 1 "register_operand" "0,f")
12715 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12716 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12717 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12718 "* return output_387_binary_op (insn, operands);"
12719 [(set (attr "type")
12720 (cond [(match_operand:DF 3 "mult_operator" "")
12721 (const_string "fmul")
12722 (match_operand:DF 3 "div_operator" "")
12723 (const_string "fdiv")
12725 (const_string "fop")))
12726 (set_attr "mode" "SF")])
12728 (define_insn "*fop_df_6_i387"
12729 [(set (match_operand:DF 0 "register_operand" "=f,f")
12730 (match_operator:DF 3 "binary_fp_operator"
12732 (match_operand:SF 1 "register_operand" "0,f"))
12734 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12735 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12736 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12737 "* return output_387_binary_op (insn, operands);"
12738 [(set (attr "type")
12739 (cond [(match_operand:DF 3 "mult_operator" "")
12740 (const_string "fmul")
12741 (match_operand:DF 3 "div_operator" "")
12742 (const_string "fdiv")
12744 (const_string "fop")))
12745 (set_attr "mode" "SF")])
12747 (define_insn "*fop_xf_comm_i387"
12748 [(set (match_operand:XF 0 "register_operand" "=f")
12749 (match_operator:XF 3 "binary_fp_operator"
12750 [(match_operand:XF 1 "register_operand" "%0")
12751 (match_operand:XF 2 "register_operand" "f")]))]
12753 && COMMUTATIVE_ARITH_P (operands[3])"
12754 "* return output_387_binary_op (insn, operands);"
12755 [(set (attr "type")
12756 (if_then_else (match_operand:XF 3 "mult_operator" "")
12757 (const_string "fmul")
12758 (const_string "fop")))
12759 (set_attr "mode" "XF")])
12761 (define_insn "*fop_xf_1_i387"
12762 [(set (match_operand:XF 0 "register_operand" "=f,f")
12763 (match_operator:XF 3 "binary_fp_operator"
12764 [(match_operand:XF 1 "register_operand" "0,f")
12765 (match_operand:XF 2 "register_operand" "f,0")]))]
12767 && !COMMUTATIVE_ARITH_P (operands[3])"
12768 "* return output_387_binary_op (insn, operands);"
12769 [(set (attr "type")
12770 (cond [(match_operand:XF 3 "mult_operator" "")
12771 (const_string "fmul")
12772 (match_operand:XF 3 "div_operator" "")
12773 (const_string "fdiv")
12775 (const_string "fop")))
12776 (set_attr "mode" "XF")])
12778 (define_insn "*fop_xf_2_i387"
12779 [(set (match_operand:XF 0 "register_operand" "=f,f")
12780 (match_operator:XF 3 "binary_fp_operator"
12782 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12783 (match_operand:XF 2 "register_operand" "0,0")]))]
12784 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12785 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12786 [(set (attr "type")
12787 (cond [(match_operand:XF 3 "mult_operator" "")
12788 (const_string "fmul")
12789 (match_operand:XF 3 "div_operator" "")
12790 (const_string "fdiv")
12792 (const_string "fop")))
12793 (set_attr "fp_int_src" "true")
12794 (set_attr "mode" "<MODE>")])
12796 (define_insn "*fop_xf_3_i387"
12797 [(set (match_operand:XF 0 "register_operand" "=f,f")
12798 (match_operator:XF 3 "binary_fp_operator"
12799 [(match_operand:XF 1 "register_operand" "0,0")
12801 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12802 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12803 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12804 [(set (attr "type")
12805 (cond [(match_operand:XF 3 "mult_operator" "")
12806 (const_string "fmul")
12807 (match_operand:XF 3 "div_operator" "")
12808 (const_string "fdiv")
12810 (const_string "fop")))
12811 (set_attr "fp_int_src" "true")
12812 (set_attr "mode" "<MODE>")])
12814 (define_insn "*fop_xf_4_i387"
12815 [(set (match_operand:XF 0 "register_operand" "=f,f")
12816 (match_operator:XF 3 "binary_fp_operator"
12818 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12819 (match_operand:XF 2 "register_operand" "0,f")]))]
12821 "* return output_387_binary_op (insn, operands);"
12822 [(set (attr "type")
12823 (cond [(match_operand:XF 3 "mult_operator" "")
12824 (const_string "fmul")
12825 (match_operand:XF 3 "div_operator" "")
12826 (const_string "fdiv")
12828 (const_string "fop")))
12829 (set_attr "mode" "<MODE>")])
12831 (define_insn "*fop_xf_5_i387"
12832 [(set (match_operand:XF 0 "register_operand" "=f,f")
12833 (match_operator:XF 3 "binary_fp_operator"
12834 [(match_operand:XF 1 "register_operand" "0,f")
12836 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12838 "* return output_387_binary_op (insn, operands);"
12839 [(set (attr "type")
12840 (cond [(match_operand:XF 3 "mult_operator" "")
12841 (const_string "fmul")
12842 (match_operand:XF 3 "div_operator" "")
12843 (const_string "fdiv")
12845 (const_string "fop")))
12846 (set_attr "mode" "<MODE>")])
12848 (define_insn "*fop_xf_6_i387"
12849 [(set (match_operand:XF 0 "register_operand" "=f,f")
12850 (match_operator:XF 3 "binary_fp_operator"
12852 (match_operand:MODEF 1 "register_operand" "0,f"))
12854 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12856 "* return output_387_binary_op (insn, operands);"
12857 [(set (attr "type")
12858 (cond [(match_operand:XF 3 "mult_operator" "")
12859 (const_string "fmul")
12860 (match_operand:XF 3 "div_operator" "")
12861 (const_string "fdiv")
12863 (const_string "fop")))
12864 (set_attr "mode" "<MODE>")])
12867 [(set (match_operand 0 "register_operand" "")
12868 (match_operator 3 "binary_fp_operator"
12869 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12870 (match_operand 2 "register_operand" "")]))]
12872 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12873 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12876 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12877 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12878 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12879 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12880 GET_MODE (operands[3]),
12883 ix86_free_from_memory (GET_MODE (operands[1]));
12888 [(set (match_operand 0 "register_operand" "")
12889 (match_operator 3 "binary_fp_operator"
12890 [(match_operand 1 "register_operand" "")
12891 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12893 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12894 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12897 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12898 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12899 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12900 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12901 GET_MODE (operands[3]),
12904 ix86_free_from_memory (GET_MODE (operands[2]));
12908 ;; FPU special functions.
12910 ;; This pattern implements a no-op XFmode truncation for
12911 ;; all fancy i386 XFmode math functions.
12913 (define_insn "truncxf<mode>2_i387_noop_unspec"
12914 [(set (match_operand:MODEF 0 "register_operand" "=f")
12915 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12916 UNSPEC_TRUNC_NOOP))]
12917 "TARGET_USE_FANCY_MATH_387"
12918 "* return output_387_reg_move (insn, operands);"
12919 [(set_attr "type" "fmov")
12920 (set_attr "mode" "<MODE>")])
12922 (define_insn "sqrtxf2"
12923 [(set (match_operand:XF 0 "register_operand" "=f")
12924 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12925 "TARGET_USE_FANCY_MATH_387"
12927 [(set_attr "type" "fpspc")
12928 (set_attr "mode" "XF")
12929 (set_attr "athlon_decode" "direct")
12930 (set_attr "amdfam10_decode" "direct")])
12932 (define_insn "sqrt_extend<mode>xf2_i387"
12933 [(set (match_operand:XF 0 "register_operand" "=f")
12936 (match_operand:MODEF 1 "register_operand" "0"))))]
12937 "TARGET_USE_FANCY_MATH_387"
12939 [(set_attr "type" "fpspc")
12940 (set_attr "mode" "XF")
12941 (set_attr "athlon_decode" "direct")
12942 (set_attr "amdfam10_decode" "direct")])
12944 (define_insn "*rsqrtsf2_sse"
12945 [(set (match_operand:SF 0 "register_operand" "=x")
12946 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12949 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12950 [(set_attr "type" "sse")
12951 (set_attr "atom_sse_attr" "rcp")
12952 (set_attr "prefix" "maybe_vex")
12953 (set_attr "mode" "SF")])
12955 (define_expand "rsqrtsf2"
12956 [(set (match_operand:SF 0 "register_operand" "")
12957 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12961 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12965 (define_insn "*sqrt<mode>2_sse"
12966 [(set (match_operand:MODEF 0 "register_operand" "=x")
12968 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12969 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12970 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12971 [(set_attr "type" "sse")
12972 (set_attr "atom_sse_attr" "sqrt")
12973 (set_attr "prefix" "maybe_vex")
12974 (set_attr "mode" "<MODE>")
12975 (set_attr "athlon_decode" "*")
12976 (set_attr "amdfam10_decode" "*")])
12978 (define_expand "sqrt<mode>2"
12979 [(set (match_operand:MODEF 0 "register_operand" "")
12981 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12982 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12983 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12985 if (<MODE>mode == SFmode
12986 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12987 && flag_finite_math_only && !flag_trapping_math
12988 && flag_unsafe_math_optimizations)
12990 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12994 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12996 rtx op0 = gen_reg_rtx (XFmode);
12997 rtx op1 = force_reg (<MODE>mode, operands[1]);
12999 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13000 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13005 (define_insn "fpremxf4_i387"
13006 [(set (match_operand:XF 0 "register_operand" "=f")
13007 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13008 (match_operand:XF 3 "register_operand" "1")]
13010 (set (match_operand:XF 1 "register_operand" "=u")
13011 (unspec:XF [(match_dup 2) (match_dup 3)]
13013 (set (reg:CCFP FPSR_REG)
13014 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13016 "TARGET_USE_FANCY_MATH_387"
13018 [(set_attr "type" "fpspc")
13019 (set_attr "mode" "XF")])
13021 (define_expand "fmodxf3"
13022 [(use (match_operand:XF 0 "register_operand" ""))
13023 (use (match_operand:XF 1 "general_operand" ""))
13024 (use (match_operand:XF 2 "general_operand" ""))]
13025 "TARGET_USE_FANCY_MATH_387"
13027 rtx label = gen_label_rtx ();
13029 rtx op1 = gen_reg_rtx (XFmode);
13030 rtx op2 = gen_reg_rtx (XFmode);
13032 emit_move_insn (op2, operands[2]);
13033 emit_move_insn (op1, operands[1]);
13035 emit_label (label);
13036 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13037 ix86_emit_fp_unordered_jump (label);
13038 LABEL_NUSES (label) = 1;
13040 emit_move_insn (operands[0], op1);
13044 (define_expand "fmod<mode>3"
13045 [(use (match_operand:MODEF 0 "register_operand" ""))
13046 (use (match_operand:MODEF 1 "general_operand" ""))
13047 (use (match_operand:MODEF 2 "general_operand" ""))]
13048 "TARGET_USE_FANCY_MATH_387"
13050 rtx (*gen_truncxf) (rtx, rtx);
13052 rtx label = gen_label_rtx ();
13054 rtx op1 = gen_reg_rtx (XFmode);
13055 rtx op2 = gen_reg_rtx (XFmode);
13057 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13058 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13060 emit_label (label);
13061 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13062 ix86_emit_fp_unordered_jump (label);
13063 LABEL_NUSES (label) = 1;
13065 /* Truncate the result properly for strict SSE math. */
13066 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13067 && !TARGET_MIX_SSE_I387)
13068 gen_truncxf = gen_truncxf<mode>2;
13070 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13072 emit_insn (gen_truncxf (operands[0], op1));
13076 (define_insn "fprem1xf4_i387"
13077 [(set (match_operand:XF 0 "register_operand" "=f")
13078 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13079 (match_operand:XF 3 "register_operand" "1")]
13081 (set (match_operand:XF 1 "register_operand" "=u")
13082 (unspec:XF [(match_dup 2) (match_dup 3)]
13084 (set (reg:CCFP FPSR_REG)
13085 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13087 "TARGET_USE_FANCY_MATH_387"
13089 [(set_attr "type" "fpspc")
13090 (set_attr "mode" "XF")])
13092 (define_expand "remainderxf3"
13093 [(use (match_operand:XF 0 "register_operand" ""))
13094 (use (match_operand:XF 1 "general_operand" ""))
13095 (use (match_operand:XF 2 "general_operand" ""))]
13096 "TARGET_USE_FANCY_MATH_387"
13098 rtx label = gen_label_rtx ();
13100 rtx op1 = gen_reg_rtx (XFmode);
13101 rtx op2 = gen_reg_rtx (XFmode);
13103 emit_move_insn (op2, operands[2]);
13104 emit_move_insn (op1, operands[1]);
13106 emit_label (label);
13107 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13108 ix86_emit_fp_unordered_jump (label);
13109 LABEL_NUSES (label) = 1;
13111 emit_move_insn (operands[0], op1);
13115 (define_expand "remainder<mode>3"
13116 [(use (match_operand:MODEF 0 "register_operand" ""))
13117 (use (match_operand:MODEF 1 "general_operand" ""))
13118 (use (match_operand:MODEF 2 "general_operand" ""))]
13119 "TARGET_USE_FANCY_MATH_387"
13121 rtx (*gen_truncxf) (rtx, rtx);
13123 rtx label = gen_label_rtx ();
13125 rtx op1 = gen_reg_rtx (XFmode);
13126 rtx op2 = gen_reg_rtx (XFmode);
13128 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13129 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13131 emit_label (label);
13133 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13134 ix86_emit_fp_unordered_jump (label);
13135 LABEL_NUSES (label) = 1;
13137 /* Truncate the result properly for strict SSE math. */
13138 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13139 && !TARGET_MIX_SSE_I387)
13140 gen_truncxf = gen_truncxf<mode>2;
13142 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13144 emit_insn (gen_truncxf (operands[0], op1));
13148 (define_insn "*sinxf2_i387"
13149 [(set (match_operand:XF 0 "register_operand" "=f")
13150 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13151 "TARGET_USE_FANCY_MATH_387
13152 && flag_unsafe_math_optimizations"
13154 [(set_attr "type" "fpspc")
13155 (set_attr "mode" "XF")])
13157 (define_insn "*sin_extend<mode>xf2_i387"
13158 [(set (match_operand:XF 0 "register_operand" "=f")
13159 (unspec:XF [(float_extend:XF
13160 (match_operand:MODEF 1 "register_operand" "0"))]
13162 "TARGET_USE_FANCY_MATH_387
13163 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13164 || TARGET_MIX_SSE_I387)
13165 && flag_unsafe_math_optimizations"
13167 [(set_attr "type" "fpspc")
13168 (set_attr "mode" "XF")])
13170 (define_insn "*cosxf2_i387"
13171 [(set (match_operand:XF 0 "register_operand" "=f")
13172 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13173 "TARGET_USE_FANCY_MATH_387
13174 && flag_unsafe_math_optimizations"
13176 [(set_attr "type" "fpspc")
13177 (set_attr "mode" "XF")])
13179 (define_insn "*cos_extend<mode>xf2_i387"
13180 [(set (match_operand:XF 0 "register_operand" "=f")
13181 (unspec:XF [(float_extend:XF
13182 (match_operand:MODEF 1 "register_operand" "0"))]
13184 "TARGET_USE_FANCY_MATH_387
13185 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13186 || TARGET_MIX_SSE_I387)
13187 && flag_unsafe_math_optimizations"
13189 [(set_attr "type" "fpspc")
13190 (set_attr "mode" "XF")])
13192 ;; When sincos pattern is defined, sin and cos builtin functions will be
13193 ;; expanded to sincos pattern with one of its outputs left unused.
13194 ;; CSE pass will figure out if two sincos patterns can be combined,
13195 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13196 ;; depending on the unused output.
13198 (define_insn "sincosxf3"
13199 [(set (match_operand:XF 0 "register_operand" "=f")
13200 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13201 UNSPEC_SINCOS_COS))
13202 (set (match_operand:XF 1 "register_operand" "=u")
13203 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13204 "TARGET_USE_FANCY_MATH_387
13205 && flag_unsafe_math_optimizations"
13207 [(set_attr "type" "fpspc")
13208 (set_attr "mode" "XF")])
13211 [(set (match_operand:XF 0 "register_operand" "")
13212 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13213 UNSPEC_SINCOS_COS))
13214 (set (match_operand:XF 1 "register_operand" "")
13215 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13216 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13217 && !(reload_completed || reload_in_progress)"
13218 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13222 [(set (match_operand:XF 0 "register_operand" "")
13223 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13224 UNSPEC_SINCOS_COS))
13225 (set (match_operand:XF 1 "register_operand" "")
13226 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13227 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13228 && !(reload_completed || reload_in_progress)"
13229 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13232 (define_insn "sincos_extend<mode>xf3_i387"
13233 [(set (match_operand:XF 0 "register_operand" "=f")
13234 (unspec:XF [(float_extend:XF
13235 (match_operand:MODEF 2 "register_operand" "0"))]
13236 UNSPEC_SINCOS_COS))
13237 (set (match_operand:XF 1 "register_operand" "=u")
13238 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13239 "TARGET_USE_FANCY_MATH_387
13240 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13241 || TARGET_MIX_SSE_I387)
13242 && flag_unsafe_math_optimizations"
13244 [(set_attr "type" "fpspc")
13245 (set_attr "mode" "XF")])
13248 [(set (match_operand:XF 0 "register_operand" "")
13249 (unspec:XF [(float_extend:XF
13250 (match_operand:MODEF 2 "register_operand" ""))]
13251 UNSPEC_SINCOS_COS))
13252 (set (match_operand:XF 1 "register_operand" "")
13253 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13254 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13255 && !(reload_completed || reload_in_progress)"
13256 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13260 [(set (match_operand:XF 0 "register_operand" "")
13261 (unspec:XF [(float_extend:XF
13262 (match_operand:MODEF 2 "register_operand" ""))]
13263 UNSPEC_SINCOS_COS))
13264 (set (match_operand:XF 1 "register_operand" "")
13265 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13266 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13267 && !(reload_completed || reload_in_progress)"
13268 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13271 (define_expand "sincos<mode>3"
13272 [(use (match_operand:MODEF 0 "register_operand" ""))
13273 (use (match_operand:MODEF 1 "register_operand" ""))
13274 (use (match_operand:MODEF 2 "register_operand" ""))]
13275 "TARGET_USE_FANCY_MATH_387
13276 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13277 || TARGET_MIX_SSE_I387)
13278 && flag_unsafe_math_optimizations"
13280 rtx op0 = gen_reg_rtx (XFmode);
13281 rtx op1 = gen_reg_rtx (XFmode);
13283 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13284 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13285 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13289 (define_insn "fptanxf4_i387"
13290 [(set (match_operand:XF 0 "register_operand" "=f")
13291 (match_operand:XF 3 "const_double_operand" "F"))
13292 (set (match_operand:XF 1 "register_operand" "=u")
13293 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13295 "TARGET_USE_FANCY_MATH_387
13296 && flag_unsafe_math_optimizations
13297 && standard_80387_constant_p (operands[3]) == 2"
13299 [(set_attr "type" "fpspc")
13300 (set_attr "mode" "XF")])
13302 (define_insn "fptan_extend<mode>xf4_i387"
13303 [(set (match_operand:MODEF 0 "register_operand" "=f")
13304 (match_operand:MODEF 3 "const_double_operand" "F"))
13305 (set (match_operand:XF 1 "register_operand" "=u")
13306 (unspec:XF [(float_extend:XF
13307 (match_operand:MODEF 2 "register_operand" "0"))]
13309 "TARGET_USE_FANCY_MATH_387
13310 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13311 || TARGET_MIX_SSE_I387)
13312 && flag_unsafe_math_optimizations
13313 && standard_80387_constant_p (operands[3]) == 2"
13315 [(set_attr "type" "fpspc")
13316 (set_attr "mode" "XF")])
13318 (define_expand "tanxf2"
13319 [(use (match_operand:XF 0 "register_operand" ""))
13320 (use (match_operand:XF 1 "register_operand" ""))]
13321 "TARGET_USE_FANCY_MATH_387
13322 && flag_unsafe_math_optimizations"
13324 rtx one = gen_reg_rtx (XFmode);
13325 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13327 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13331 (define_expand "tan<mode>2"
13332 [(use (match_operand:MODEF 0 "register_operand" ""))
13333 (use (match_operand:MODEF 1 "register_operand" ""))]
13334 "TARGET_USE_FANCY_MATH_387
13335 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13336 || TARGET_MIX_SSE_I387)
13337 && flag_unsafe_math_optimizations"
13339 rtx op0 = gen_reg_rtx (XFmode);
13341 rtx one = gen_reg_rtx (<MODE>mode);
13342 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13344 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13345 operands[1], op2));
13346 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13350 (define_insn "*fpatanxf3_i387"
13351 [(set (match_operand:XF 0 "register_operand" "=f")
13352 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13353 (match_operand:XF 2 "register_operand" "u")]
13355 (clobber (match_scratch:XF 3 "=2"))]
13356 "TARGET_USE_FANCY_MATH_387
13357 && flag_unsafe_math_optimizations"
13359 [(set_attr "type" "fpspc")
13360 (set_attr "mode" "XF")])
13362 (define_insn "fpatan_extend<mode>xf3_i387"
13363 [(set (match_operand:XF 0 "register_operand" "=f")
13364 (unspec:XF [(float_extend:XF
13365 (match_operand:MODEF 1 "register_operand" "0"))
13367 (match_operand:MODEF 2 "register_operand" "u"))]
13369 (clobber (match_scratch:XF 3 "=2"))]
13370 "TARGET_USE_FANCY_MATH_387
13371 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13372 || TARGET_MIX_SSE_I387)
13373 && flag_unsafe_math_optimizations"
13375 [(set_attr "type" "fpspc")
13376 (set_attr "mode" "XF")])
13378 (define_expand "atan2xf3"
13379 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13380 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13381 (match_operand:XF 1 "register_operand" "")]
13383 (clobber (match_scratch:XF 3 ""))])]
13384 "TARGET_USE_FANCY_MATH_387
13385 && flag_unsafe_math_optimizations"
13388 (define_expand "atan2<mode>3"
13389 [(use (match_operand:MODEF 0 "register_operand" ""))
13390 (use (match_operand:MODEF 1 "register_operand" ""))
13391 (use (match_operand:MODEF 2 "register_operand" ""))]
13392 "TARGET_USE_FANCY_MATH_387
13393 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13394 || TARGET_MIX_SSE_I387)
13395 && flag_unsafe_math_optimizations"
13397 rtx op0 = gen_reg_rtx (XFmode);
13399 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13400 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13404 (define_expand "atanxf2"
13405 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13406 (unspec:XF [(match_dup 2)
13407 (match_operand:XF 1 "register_operand" "")]
13409 (clobber (match_scratch:XF 3 ""))])]
13410 "TARGET_USE_FANCY_MATH_387
13411 && flag_unsafe_math_optimizations"
13413 operands[2] = gen_reg_rtx (XFmode);
13414 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13417 (define_expand "atan<mode>2"
13418 [(use (match_operand:MODEF 0 "register_operand" ""))
13419 (use (match_operand:MODEF 1 "register_operand" ""))]
13420 "TARGET_USE_FANCY_MATH_387
13421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13422 || TARGET_MIX_SSE_I387)
13423 && flag_unsafe_math_optimizations"
13425 rtx op0 = gen_reg_rtx (XFmode);
13427 rtx op2 = gen_reg_rtx (<MODE>mode);
13428 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13430 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13431 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13435 (define_expand "asinxf2"
13436 [(set (match_dup 2)
13437 (mult:XF (match_operand:XF 1 "register_operand" "")
13439 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13440 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13441 (parallel [(set (match_operand:XF 0 "register_operand" "")
13442 (unspec:XF [(match_dup 5) (match_dup 1)]
13444 (clobber (match_scratch:XF 6 ""))])]
13445 "TARGET_USE_FANCY_MATH_387
13446 && flag_unsafe_math_optimizations"
13450 if (optimize_insn_for_size_p ())
13453 for (i = 2; i < 6; i++)
13454 operands[i] = gen_reg_rtx (XFmode);
13456 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13459 (define_expand "asin<mode>2"
13460 [(use (match_operand:MODEF 0 "register_operand" ""))
13461 (use (match_operand:MODEF 1 "general_operand" ""))]
13462 "TARGET_USE_FANCY_MATH_387
13463 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13464 || TARGET_MIX_SSE_I387)
13465 && flag_unsafe_math_optimizations"
13467 rtx op0 = gen_reg_rtx (XFmode);
13468 rtx op1 = gen_reg_rtx (XFmode);
13470 if (optimize_insn_for_size_p ())
13473 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13474 emit_insn (gen_asinxf2 (op0, op1));
13475 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13479 (define_expand "acosxf2"
13480 [(set (match_dup 2)
13481 (mult:XF (match_operand:XF 1 "register_operand" "")
13483 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13484 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13485 (parallel [(set (match_operand:XF 0 "register_operand" "")
13486 (unspec:XF [(match_dup 1) (match_dup 5)]
13488 (clobber (match_scratch:XF 6 ""))])]
13489 "TARGET_USE_FANCY_MATH_387
13490 && flag_unsafe_math_optimizations"
13494 if (optimize_insn_for_size_p ())
13497 for (i = 2; i < 6; i++)
13498 operands[i] = gen_reg_rtx (XFmode);
13500 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13503 (define_expand "acos<mode>2"
13504 [(use (match_operand:MODEF 0 "register_operand" ""))
13505 (use (match_operand:MODEF 1 "general_operand" ""))]
13506 "TARGET_USE_FANCY_MATH_387
13507 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13508 || TARGET_MIX_SSE_I387)
13509 && flag_unsafe_math_optimizations"
13511 rtx op0 = gen_reg_rtx (XFmode);
13512 rtx op1 = gen_reg_rtx (XFmode);
13514 if (optimize_insn_for_size_p ())
13517 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13518 emit_insn (gen_acosxf2 (op0, op1));
13519 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13523 (define_insn "fyl2xxf3_i387"
13524 [(set (match_operand:XF 0 "register_operand" "=f")
13525 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13526 (match_operand:XF 2 "register_operand" "u")]
13528 (clobber (match_scratch:XF 3 "=2"))]
13529 "TARGET_USE_FANCY_MATH_387
13530 && flag_unsafe_math_optimizations"
13532 [(set_attr "type" "fpspc")
13533 (set_attr "mode" "XF")])
13535 (define_insn "fyl2x_extend<mode>xf3_i387"
13536 [(set (match_operand:XF 0 "register_operand" "=f")
13537 (unspec:XF [(float_extend:XF
13538 (match_operand:MODEF 1 "register_operand" "0"))
13539 (match_operand:XF 2 "register_operand" "u")]
13541 (clobber (match_scratch:XF 3 "=2"))]
13542 "TARGET_USE_FANCY_MATH_387
13543 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13544 || TARGET_MIX_SSE_I387)
13545 && flag_unsafe_math_optimizations"
13547 [(set_attr "type" "fpspc")
13548 (set_attr "mode" "XF")])
13550 (define_expand "logxf2"
13551 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13552 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13553 (match_dup 2)] UNSPEC_FYL2X))
13554 (clobber (match_scratch:XF 3 ""))])]
13555 "TARGET_USE_FANCY_MATH_387
13556 && flag_unsafe_math_optimizations"
13558 operands[2] = gen_reg_rtx (XFmode);
13559 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13562 (define_expand "log<mode>2"
13563 [(use (match_operand:MODEF 0 "register_operand" ""))
13564 (use (match_operand:MODEF 1 "register_operand" ""))]
13565 "TARGET_USE_FANCY_MATH_387
13566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13567 || TARGET_MIX_SSE_I387)
13568 && flag_unsafe_math_optimizations"
13570 rtx op0 = gen_reg_rtx (XFmode);
13572 rtx op2 = gen_reg_rtx (XFmode);
13573 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13575 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13576 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13580 (define_expand "log10xf2"
13581 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13582 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13583 (match_dup 2)] UNSPEC_FYL2X))
13584 (clobber (match_scratch:XF 3 ""))])]
13585 "TARGET_USE_FANCY_MATH_387
13586 && flag_unsafe_math_optimizations"
13588 operands[2] = gen_reg_rtx (XFmode);
13589 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13592 (define_expand "log10<mode>2"
13593 [(use (match_operand:MODEF 0 "register_operand" ""))
13594 (use (match_operand:MODEF 1 "register_operand" ""))]
13595 "TARGET_USE_FANCY_MATH_387
13596 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13597 || TARGET_MIX_SSE_I387)
13598 && flag_unsafe_math_optimizations"
13600 rtx op0 = gen_reg_rtx (XFmode);
13602 rtx op2 = gen_reg_rtx (XFmode);
13603 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13605 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13606 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13610 (define_expand "log2xf2"
13611 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13612 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13613 (match_dup 2)] UNSPEC_FYL2X))
13614 (clobber (match_scratch:XF 3 ""))])]
13615 "TARGET_USE_FANCY_MATH_387
13616 && flag_unsafe_math_optimizations"
13618 operands[2] = gen_reg_rtx (XFmode);
13619 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13622 (define_expand "log2<mode>2"
13623 [(use (match_operand:MODEF 0 "register_operand" ""))
13624 (use (match_operand:MODEF 1 "register_operand" ""))]
13625 "TARGET_USE_FANCY_MATH_387
13626 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13627 || TARGET_MIX_SSE_I387)
13628 && flag_unsafe_math_optimizations"
13630 rtx op0 = gen_reg_rtx (XFmode);
13632 rtx op2 = gen_reg_rtx (XFmode);
13633 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13635 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13636 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13640 (define_insn "fyl2xp1xf3_i387"
13641 [(set (match_operand:XF 0 "register_operand" "=f")
13642 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13643 (match_operand:XF 2 "register_operand" "u")]
13645 (clobber (match_scratch:XF 3 "=2"))]
13646 "TARGET_USE_FANCY_MATH_387
13647 && flag_unsafe_math_optimizations"
13649 [(set_attr "type" "fpspc")
13650 (set_attr "mode" "XF")])
13652 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13653 [(set (match_operand:XF 0 "register_operand" "=f")
13654 (unspec:XF [(float_extend:XF
13655 (match_operand:MODEF 1 "register_operand" "0"))
13656 (match_operand:XF 2 "register_operand" "u")]
13658 (clobber (match_scratch:XF 3 "=2"))]
13659 "TARGET_USE_FANCY_MATH_387
13660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13661 || TARGET_MIX_SSE_I387)
13662 && flag_unsafe_math_optimizations"
13664 [(set_attr "type" "fpspc")
13665 (set_attr "mode" "XF")])
13667 (define_expand "log1pxf2"
13668 [(use (match_operand:XF 0 "register_operand" ""))
13669 (use (match_operand:XF 1 "register_operand" ""))]
13670 "TARGET_USE_FANCY_MATH_387
13671 && flag_unsafe_math_optimizations"
13673 if (optimize_insn_for_size_p ())
13676 ix86_emit_i387_log1p (operands[0], operands[1]);
13680 (define_expand "log1p<mode>2"
13681 [(use (match_operand:MODEF 0 "register_operand" ""))
13682 (use (match_operand:MODEF 1 "register_operand" ""))]
13683 "TARGET_USE_FANCY_MATH_387
13684 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13685 || TARGET_MIX_SSE_I387)
13686 && flag_unsafe_math_optimizations"
13690 if (optimize_insn_for_size_p ())
13693 op0 = gen_reg_rtx (XFmode);
13695 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13697 ix86_emit_i387_log1p (op0, operands[1]);
13698 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13702 (define_insn "fxtractxf3_i387"
13703 [(set (match_operand:XF 0 "register_operand" "=f")
13704 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13705 UNSPEC_XTRACT_FRACT))
13706 (set (match_operand:XF 1 "register_operand" "=u")
13707 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13708 "TARGET_USE_FANCY_MATH_387
13709 && flag_unsafe_math_optimizations"
13711 [(set_attr "type" "fpspc")
13712 (set_attr "mode" "XF")])
13714 (define_insn "fxtract_extend<mode>xf3_i387"
13715 [(set (match_operand:XF 0 "register_operand" "=f")
13716 (unspec:XF [(float_extend:XF
13717 (match_operand:MODEF 2 "register_operand" "0"))]
13718 UNSPEC_XTRACT_FRACT))
13719 (set (match_operand:XF 1 "register_operand" "=u")
13720 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13721 "TARGET_USE_FANCY_MATH_387
13722 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13723 || TARGET_MIX_SSE_I387)
13724 && flag_unsafe_math_optimizations"
13726 [(set_attr "type" "fpspc")
13727 (set_attr "mode" "XF")])
13729 (define_expand "logbxf2"
13730 [(parallel [(set (match_dup 2)
13731 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13732 UNSPEC_XTRACT_FRACT))
13733 (set (match_operand:XF 0 "register_operand" "")
13734 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13735 "TARGET_USE_FANCY_MATH_387
13736 && flag_unsafe_math_optimizations"
13738 operands[2] = gen_reg_rtx (XFmode);
13741 (define_expand "logb<mode>2"
13742 [(use (match_operand:MODEF 0 "register_operand" ""))
13743 (use (match_operand:MODEF 1 "register_operand" ""))]
13744 "TARGET_USE_FANCY_MATH_387
13745 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13746 || TARGET_MIX_SSE_I387)
13747 && flag_unsafe_math_optimizations"
13749 rtx op0 = gen_reg_rtx (XFmode);
13750 rtx op1 = gen_reg_rtx (XFmode);
13752 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13753 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13757 (define_expand "ilogbxf2"
13758 [(use (match_operand:SI 0 "register_operand" ""))
13759 (use (match_operand:XF 1 "register_operand" ""))]
13760 "TARGET_USE_FANCY_MATH_387
13761 && flag_unsafe_math_optimizations"
13765 if (optimize_insn_for_size_p ())
13768 op0 = gen_reg_rtx (XFmode);
13769 op1 = gen_reg_rtx (XFmode);
13771 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13772 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13776 (define_expand "ilogb<mode>2"
13777 [(use (match_operand:SI 0 "register_operand" ""))
13778 (use (match_operand:MODEF 1 "register_operand" ""))]
13779 "TARGET_USE_FANCY_MATH_387
13780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13781 || TARGET_MIX_SSE_I387)
13782 && flag_unsafe_math_optimizations"
13786 if (optimize_insn_for_size_p ())
13789 op0 = gen_reg_rtx (XFmode);
13790 op1 = gen_reg_rtx (XFmode);
13792 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13793 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13797 (define_insn "*f2xm1xf2_i387"
13798 [(set (match_operand:XF 0 "register_operand" "=f")
13799 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13801 "TARGET_USE_FANCY_MATH_387
13802 && flag_unsafe_math_optimizations"
13804 [(set_attr "type" "fpspc")
13805 (set_attr "mode" "XF")])
13807 (define_insn "*fscalexf4_i387"
13808 [(set (match_operand:XF 0 "register_operand" "=f")
13809 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13810 (match_operand:XF 3 "register_operand" "1")]
13811 UNSPEC_FSCALE_FRACT))
13812 (set (match_operand:XF 1 "register_operand" "=u")
13813 (unspec:XF [(match_dup 2) (match_dup 3)]
13814 UNSPEC_FSCALE_EXP))]
13815 "TARGET_USE_FANCY_MATH_387
13816 && flag_unsafe_math_optimizations"
13818 [(set_attr "type" "fpspc")
13819 (set_attr "mode" "XF")])
13821 (define_expand "expNcorexf3"
13822 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13823 (match_operand:XF 2 "register_operand" "")))
13824 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13825 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13826 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13827 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13828 (parallel [(set (match_operand:XF 0 "register_operand" "")
13829 (unspec:XF [(match_dup 8) (match_dup 4)]
13830 UNSPEC_FSCALE_FRACT))
13832 (unspec:XF [(match_dup 8) (match_dup 4)]
13833 UNSPEC_FSCALE_EXP))])]
13834 "TARGET_USE_FANCY_MATH_387
13835 && flag_unsafe_math_optimizations"
13839 if (optimize_insn_for_size_p ())
13842 for (i = 3; i < 10; i++)
13843 operands[i] = gen_reg_rtx (XFmode);
13845 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13848 (define_expand "expxf2"
13849 [(use (match_operand:XF 0 "register_operand" ""))
13850 (use (match_operand:XF 1 "register_operand" ""))]
13851 "TARGET_USE_FANCY_MATH_387
13852 && flag_unsafe_math_optimizations"
13856 if (optimize_insn_for_size_p ())
13859 op2 = gen_reg_rtx (XFmode);
13860 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13862 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13866 (define_expand "exp<mode>2"
13867 [(use (match_operand:MODEF 0 "register_operand" ""))
13868 (use (match_operand:MODEF 1 "general_operand" ""))]
13869 "TARGET_USE_FANCY_MATH_387
13870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13871 || TARGET_MIX_SSE_I387)
13872 && flag_unsafe_math_optimizations"
13876 if (optimize_insn_for_size_p ())
13879 op0 = gen_reg_rtx (XFmode);
13880 op1 = gen_reg_rtx (XFmode);
13882 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13883 emit_insn (gen_expxf2 (op0, op1));
13884 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13888 (define_expand "exp10xf2"
13889 [(use (match_operand:XF 0 "register_operand" ""))
13890 (use (match_operand:XF 1 "register_operand" ""))]
13891 "TARGET_USE_FANCY_MATH_387
13892 && flag_unsafe_math_optimizations"
13896 if (optimize_insn_for_size_p ())
13899 op2 = gen_reg_rtx (XFmode);
13900 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13902 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13906 (define_expand "exp10<mode>2"
13907 [(use (match_operand:MODEF 0 "register_operand" ""))
13908 (use (match_operand:MODEF 1 "general_operand" ""))]
13909 "TARGET_USE_FANCY_MATH_387
13910 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13911 || TARGET_MIX_SSE_I387)
13912 && flag_unsafe_math_optimizations"
13916 if (optimize_insn_for_size_p ())
13919 op0 = gen_reg_rtx (XFmode);
13920 op1 = gen_reg_rtx (XFmode);
13922 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13923 emit_insn (gen_exp10xf2 (op0, op1));
13924 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13928 (define_expand "exp2xf2"
13929 [(use (match_operand:XF 0 "register_operand" ""))
13930 (use (match_operand:XF 1 "register_operand" ""))]
13931 "TARGET_USE_FANCY_MATH_387
13932 && flag_unsafe_math_optimizations"
13936 if (optimize_insn_for_size_p ())
13939 op2 = gen_reg_rtx (XFmode);
13940 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13942 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13946 (define_expand "exp2<mode>2"
13947 [(use (match_operand:MODEF 0 "register_operand" ""))
13948 (use (match_operand:MODEF 1 "general_operand" ""))]
13949 "TARGET_USE_FANCY_MATH_387
13950 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13951 || TARGET_MIX_SSE_I387)
13952 && flag_unsafe_math_optimizations"
13956 if (optimize_insn_for_size_p ())
13959 op0 = gen_reg_rtx (XFmode);
13960 op1 = gen_reg_rtx (XFmode);
13962 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13963 emit_insn (gen_exp2xf2 (op0, op1));
13964 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13968 (define_expand "expm1xf2"
13969 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13971 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13972 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13973 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13974 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13975 (parallel [(set (match_dup 7)
13976 (unspec:XF [(match_dup 6) (match_dup 4)]
13977 UNSPEC_FSCALE_FRACT))
13979 (unspec:XF [(match_dup 6) (match_dup 4)]
13980 UNSPEC_FSCALE_EXP))])
13981 (parallel [(set (match_dup 10)
13982 (unspec:XF [(match_dup 9) (match_dup 8)]
13983 UNSPEC_FSCALE_FRACT))
13984 (set (match_dup 11)
13985 (unspec:XF [(match_dup 9) (match_dup 8)]
13986 UNSPEC_FSCALE_EXP))])
13987 (set (match_dup 12) (minus:XF (match_dup 10)
13988 (float_extend:XF (match_dup 13))))
13989 (set (match_operand:XF 0 "register_operand" "")
13990 (plus:XF (match_dup 12) (match_dup 7)))]
13991 "TARGET_USE_FANCY_MATH_387
13992 && flag_unsafe_math_optimizations"
13996 if (optimize_insn_for_size_p ())
13999 for (i = 2; i < 13; i++)
14000 operands[i] = gen_reg_rtx (XFmode);
14003 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14005 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14008 (define_expand "expm1<mode>2"
14009 [(use (match_operand:MODEF 0 "register_operand" ""))
14010 (use (match_operand:MODEF 1 "general_operand" ""))]
14011 "TARGET_USE_FANCY_MATH_387
14012 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14013 || TARGET_MIX_SSE_I387)
14014 && flag_unsafe_math_optimizations"
14018 if (optimize_insn_for_size_p ())
14021 op0 = gen_reg_rtx (XFmode);
14022 op1 = gen_reg_rtx (XFmode);
14024 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14025 emit_insn (gen_expm1xf2 (op0, op1));
14026 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14030 (define_expand "ldexpxf3"
14031 [(set (match_dup 3)
14032 (float:XF (match_operand:SI 2 "register_operand" "")))
14033 (parallel [(set (match_operand:XF 0 " register_operand" "")
14034 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14036 UNSPEC_FSCALE_FRACT))
14038 (unspec:XF [(match_dup 1) (match_dup 3)]
14039 UNSPEC_FSCALE_EXP))])]
14040 "TARGET_USE_FANCY_MATH_387
14041 && flag_unsafe_math_optimizations"
14043 if (optimize_insn_for_size_p ())
14046 operands[3] = gen_reg_rtx (XFmode);
14047 operands[4] = gen_reg_rtx (XFmode);
14050 (define_expand "ldexp<mode>3"
14051 [(use (match_operand:MODEF 0 "register_operand" ""))
14052 (use (match_operand:MODEF 1 "general_operand" ""))
14053 (use (match_operand:SI 2 "register_operand" ""))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056 || TARGET_MIX_SSE_I387)
14057 && flag_unsafe_math_optimizations"
14061 if (optimize_insn_for_size_p ())
14064 op0 = gen_reg_rtx (XFmode);
14065 op1 = gen_reg_rtx (XFmode);
14067 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14068 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14069 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14073 (define_expand "scalbxf3"
14074 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14075 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14076 (match_operand:XF 2 "register_operand" "")]
14077 UNSPEC_FSCALE_FRACT))
14079 (unspec:XF [(match_dup 1) (match_dup 2)]
14080 UNSPEC_FSCALE_EXP))])]
14081 "TARGET_USE_FANCY_MATH_387
14082 && flag_unsafe_math_optimizations"
14084 if (optimize_insn_for_size_p ())
14087 operands[3] = gen_reg_rtx (XFmode);
14090 (define_expand "scalb<mode>3"
14091 [(use (match_operand:MODEF 0 "register_operand" ""))
14092 (use (match_operand:MODEF 1 "general_operand" ""))
14093 (use (match_operand:MODEF 2 "general_operand" ""))]
14094 "TARGET_USE_FANCY_MATH_387
14095 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14096 || TARGET_MIX_SSE_I387)
14097 && flag_unsafe_math_optimizations"
14101 if (optimize_insn_for_size_p ())
14104 op0 = gen_reg_rtx (XFmode);
14105 op1 = gen_reg_rtx (XFmode);
14106 op2 = gen_reg_rtx (XFmode);
14108 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14109 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14110 emit_insn (gen_scalbxf3 (op0, op1, op2));
14111 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14115 (define_expand "significandxf2"
14116 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14117 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14118 UNSPEC_XTRACT_FRACT))
14120 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14121 "TARGET_USE_FANCY_MATH_387
14122 && flag_unsafe_math_optimizations"
14124 operands[2] = gen_reg_rtx (XFmode);
14127 (define_expand "significand<mode>2"
14128 [(use (match_operand:MODEF 0 "register_operand" ""))
14129 (use (match_operand:MODEF 1 "register_operand" ""))]
14130 "TARGET_USE_FANCY_MATH_387
14131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14132 || TARGET_MIX_SSE_I387)
14133 && flag_unsafe_math_optimizations"
14135 rtx op0 = gen_reg_rtx (XFmode);
14136 rtx op1 = gen_reg_rtx (XFmode);
14138 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14139 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14144 (define_insn "sse4_1_round<mode>2"
14145 [(set (match_operand:MODEF 0 "register_operand" "=x")
14146 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14147 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14150 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14151 [(set_attr "type" "ssecvt")
14152 (set_attr "prefix_extra" "1")
14153 (set_attr "prefix" "maybe_vex")
14154 (set_attr "mode" "<MODE>")])
14156 (define_insn "rintxf2"
14157 [(set (match_operand:XF 0 "register_operand" "=f")
14158 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14160 "TARGET_USE_FANCY_MATH_387
14161 && flag_unsafe_math_optimizations"
14163 [(set_attr "type" "fpspc")
14164 (set_attr "mode" "XF")])
14166 (define_expand "rint<mode>2"
14167 [(use (match_operand:MODEF 0 "register_operand" ""))
14168 (use (match_operand:MODEF 1 "register_operand" ""))]
14169 "(TARGET_USE_FANCY_MATH_387
14170 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14171 || TARGET_MIX_SSE_I387)
14172 && flag_unsafe_math_optimizations)
14173 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14174 && !flag_trapping_math)"
14176 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14177 && !flag_trapping_math)
14179 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14182 emit_insn (gen_sse4_1_round<mode>2
14183 (operands[0], operands[1], GEN_INT (0x04)));
14185 ix86_expand_rint (operand0, operand1);
14189 rtx op0 = gen_reg_rtx (XFmode);
14190 rtx op1 = gen_reg_rtx (XFmode);
14192 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14193 emit_insn (gen_rintxf2 (op0, op1));
14195 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14200 (define_expand "round<mode>2"
14201 [(match_operand:MODEF 0 "register_operand" "")
14202 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14203 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14204 && !flag_trapping_math && !flag_rounding_math"
14206 if (optimize_insn_for_size_p ())
14208 if (TARGET_64BIT || (<MODE>mode != DFmode))
14209 ix86_expand_round (operand0, operand1);
14211 ix86_expand_rounddf_32 (operand0, operand1);
14215 (define_insn_and_split "*fistdi2_1"
14216 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14217 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14219 "TARGET_USE_FANCY_MATH_387
14220 && can_create_pseudo_p ()"
14225 if (memory_operand (operands[0], VOIDmode))
14226 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14229 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14230 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14235 [(set_attr "type" "fpspc")
14236 (set_attr "mode" "DI")])
14238 (define_insn "fistdi2"
14239 [(set (match_operand:DI 0 "memory_operand" "=m")
14240 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14242 (clobber (match_scratch:XF 2 "=&1f"))]
14243 "TARGET_USE_FANCY_MATH_387"
14244 "* return output_fix_trunc (insn, operands, 0);"
14245 [(set_attr "type" "fpspc")
14246 (set_attr "mode" "DI")])
14248 (define_insn "fistdi2_with_temp"
14249 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14250 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14252 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14253 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14254 "TARGET_USE_FANCY_MATH_387"
14256 [(set_attr "type" "fpspc")
14257 (set_attr "mode" "DI")])
14260 [(set (match_operand:DI 0 "register_operand" "")
14261 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14263 (clobber (match_operand:DI 2 "memory_operand" ""))
14264 (clobber (match_scratch 3 ""))]
14266 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14267 (clobber (match_dup 3))])
14268 (set (match_dup 0) (match_dup 2))]
14272 [(set (match_operand:DI 0 "memory_operand" "")
14273 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14275 (clobber (match_operand:DI 2 "memory_operand" ""))
14276 (clobber (match_scratch 3 ""))]
14278 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14279 (clobber (match_dup 3))])]
14282 (define_insn_and_split "*fist<mode>2_1"
14283 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14284 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14286 "TARGET_USE_FANCY_MATH_387
14287 && can_create_pseudo_p ()"
14292 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14293 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14297 [(set_attr "type" "fpspc")
14298 (set_attr "mode" "<MODE>")])
14300 (define_insn "fist<mode>2"
14301 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14302 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14304 "TARGET_USE_FANCY_MATH_387"
14305 "* return output_fix_trunc (insn, operands, 0);"
14306 [(set_attr "type" "fpspc")
14307 (set_attr "mode" "<MODE>")])
14309 (define_insn "fist<mode>2_with_temp"
14310 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14311 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14313 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14314 "TARGET_USE_FANCY_MATH_387"
14316 [(set_attr "type" "fpspc")
14317 (set_attr "mode" "<MODE>")])
14320 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14321 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14323 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14325 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14326 (set (match_dup 0) (match_dup 2))]
14330 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14331 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14333 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14335 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14338 (define_expand "lrintxf<mode>2"
14339 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14340 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14342 "TARGET_USE_FANCY_MATH_387"
14345 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14346 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14347 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14348 UNSPEC_FIX_NOTRUNC))]
14349 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14350 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14353 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14354 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14355 (match_operand:MODEF 1 "register_operand" "")]
14356 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14357 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14358 && !flag_trapping_math && !flag_rounding_math"
14360 if (optimize_insn_for_size_p ())
14362 ix86_expand_lround (operand0, operand1);
14366 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14367 (define_insn_and_split "frndintxf2_floor"
14368 [(set (match_operand:XF 0 "register_operand" "")
14369 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14370 UNSPEC_FRNDINT_FLOOR))
14371 (clobber (reg:CC FLAGS_REG))]
14372 "TARGET_USE_FANCY_MATH_387
14373 && flag_unsafe_math_optimizations
14374 && can_create_pseudo_p ()"
14379 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14381 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14382 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14384 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14385 operands[2], operands[3]));
14388 [(set_attr "type" "frndint")
14389 (set_attr "i387_cw" "floor")
14390 (set_attr "mode" "XF")])
14392 (define_insn "frndintxf2_floor_i387"
14393 [(set (match_operand:XF 0 "register_operand" "=f")
14394 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14395 UNSPEC_FRNDINT_FLOOR))
14396 (use (match_operand:HI 2 "memory_operand" "m"))
14397 (use (match_operand:HI 3 "memory_operand" "m"))]
14398 "TARGET_USE_FANCY_MATH_387
14399 && flag_unsafe_math_optimizations"
14400 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14401 [(set_attr "type" "frndint")
14402 (set_attr "i387_cw" "floor")
14403 (set_attr "mode" "XF")])
14405 (define_expand "floorxf2"
14406 [(use (match_operand:XF 0 "register_operand" ""))
14407 (use (match_operand:XF 1 "register_operand" ""))]
14408 "TARGET_USE_FANCY_MATH_387
14409 && flag_unsafe_math_optimizations"
14411 if (optimize_insn_for_size_p ())
14413 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14417 (define_expand "floor<mode>2"
14418 [(use (match_operand:MODEF 0 "register_operand" ""))
14419 (use (match_operand:MODEF 1 "register_operand" ""))]
14420 "(TARGET_USE_FANCY_MATH_387
14421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14422 || TARGET_MIX_SSE_I387)
14423 && flag_unsafe_math_optimizations)
14424 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14425 && !flag_trapping_math)"
14427 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14428 && !flag_trapping_math
14429 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14431 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14434 emit_insn (gen_sse4_1_round<mode>2
14435 (operands[0], operands[1], GEN_INT (0x01)));
14436 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14437 ix86_expand_floorceil (operand0, operand1, true);
14439 ix86_expand_floorceildf_32 (operand0, operand1, true);
14445 if (optimize_insn_for_size_p ())
14448 op0 = gen_reg_rtx (XFmode);
14449 op1 = gen_reg_rtx (XFmode);
14450 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14451 emit_insn (gen_frndintxf2_floor (op0, op1));
14453 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14458 (define_insn_and_split "*fist<mode>2_floor_1"
14459 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14460 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14461 UNSPEC_FIST_FLOOR))
14462 (clobber (reg:CC FLAGS_REG))]
14463 "TARGET_USE_FANCY_MATH_387
14464 && flag_unsafe_math_optimizations
14465 && can_create_pseudo_p ()"
14470 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14472 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14473 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14474 if (memory_operand (operands[0], VOIDmode))
14475 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14476 operands[2], operands[3]));
14479 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14480 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14481 operands[2], operands[3],
14486 [(set_attr "type" "fistp")
14487 (set_attr "i387_cw" "floor")
14488 (set_attr "mode" "<MODE>")])
14490 (define_insn "fistdi2_floor"
14491 [(set (match_operand:DI 0 "memory_operand" "=m")
14492 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14493 UNSPEC_FIST_FLOOR))
14494 (use (match_operand:HI 2 "memory_operand" "m"))
14495 (use (match_operand:HI 3 "memory_operand" "m"))
14496 (clobber (match_scratch:XF 4 "=&1f"))]
14497 "TARGET_USE_FANCY_MATH_387
14498 && flag_unsafe_math_optimizations"
14499 "* return output_fix_trunc (insn, operands, 0);"
14500 [(set_attr "type" "fistp")
14501 (set_attr "i387_cw" "floor")
14502 (set_attr "mode" "DI")])
14504 (define_insn "fistdi2_floor_with_temp"
14505 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14506 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14507 UNSPEC_FIST_FLOOR))
14508 (use (match_operand:HI 2 "memory_operand" "m,m"))
14509 (use (match_operand:HI 3 "memory_operand" "m,m"))
14510 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14511 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14512 "TARGET_USE_FANCY_MATH_387
14513 && flag_unsafe_math_optimizations"
14515 [(set_attr "type" "fistp")
14516 (set_attr "i387_cw" "floor")
14517 (set_attr "mode" "DI")])
14520 [(set (match_operand:DI 0 "register_operand" "")
14521 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14522 UNSPEC_FIST_FLOOR))
14523 (use (match_operand:HI 2 "memory_operand" ""))
14524 (use (match_operand:HI 3 "memory_operand" ""))
14525 (clobber (match_operand:DI 4 "memory_operand" ""))
14526 (clobber (match_scratch 5 ""))]
14528 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14529 (use (match_dup 2))
14530 (use (match_dup 3))
14531 (clobber (match_dup 5))])
14532 (set (match_dup 0) (match_dup 4))]
14536 [(set (match_operand:DI 0 "memory_operand" "")
14537 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14538 UNSPEC_FIST_FLOOR))
14539 (use (match_operand:HI 2 "memory_operand" ""))
14540 (use (match_operand:HI 3 "memory_operand" ""))
14541 (clobber (match_operand:DI 4 "memory_operand" ""))
14542 (clobber (match_scratch 5 ""))]
14544 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14545 (use (match_dup 2))
14546 (use (match_dup 3))
14547 (clobber (match_dup 5))])]
14550 (define_insn "fist<mode>2_floor"
14551 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14552 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14553 UNSPEC_FIST_FLOOR))
14554 (use (match_operand:HI 2 "memory_operand" "m"))
14555 (use (match_operand:HI 3 "memory_operand" "m"))]
14556 "TARGET_USE_FANCY_MATH_387
14557 && flag_unsafe_math_optimizations"
14558 "* return output_fix_trunc (insn, operands, 0);"
14559 [(set_attr "type" "fistp")
14560 (set_attr "i387_cw" "floor")
14561 (set_attr "mode" "<MODE>")])
14563 (define_insn "fist<mode>2_floor_with_temp"
14564 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14565 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14566 UNSPEC_FIST_FLOOR))
14567 (use (match_operand:HI 2 "memory_operand" "m,m"))
14568 (use (match_operand:HI 3 "memory_operand" "m,m"))
14569 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14570 "TARGET_USE_FANCY_MATH_387
14571 && flag_unsafe_math_optimizations"
14573 [(set_attr "type" "fistp")
14574 (set_attr "i387_cw" "floor")
14575 (set_attr "mode" "<MODE>")])
14578 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14579 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14580 UNSPEC_FIST_FLOOR))
14581 (use (match_operand:HI 2 "memory_operand" ""))
14582 (use (match_operand:HI 3 "memory_operand" ""))
14583 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14585 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14586 UNSPEC_FIST_FLOOR))
14587 (use (match_dup 2))
14588 (use (match_dup 3))])
14589 (set (match_dup 0) (match_dup 4))]
14593 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14594 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14595 UNSPEC_FIST_FLOOR))
14596 (use (match_operand:HI 2 "memory_operand" ""))
14597 (use (match_operand:HI 3 "memory_operand" ""))
14598 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14600 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14601 UNSPEC_FIST_FLOOR))
14602 (use (match_dup 2))
14603 (use (match_dup 3))])]
14606 (define_expand "lfloorxf<mode>2"
14607 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14608 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14609 UNSPEC_FIST_FLOOR))
14610 (clobber (reg:CC FLAGS_REG))])]
14611 "TARGET_USE_FANCY_MATH_387
14612 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14613 && flag_unsafe_math_optimizations"
14616 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14617 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14618 (match_operand:MODEF 1 "register_operand" "")]
14619 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14620 && !flag_trapping_math"
14622 if (TARGET_64BIT && optimize_insn_for_size_p ())
14624 ix86_expand_lfloorceil (operand0, operand1, true);
14628 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14629 (define_insn_and_split "frndintxf2_ceil"
14630 [(set (match_operand:XF 0 "register_operand" "")
14631 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14632 UNSPEC_FRNDINT_CEIL))
14633 (clobber (reg:CC FLAGS_REG))]
14634 "TARGET_USE_FANCY_MATH_387
14635 && flag_unsafe_math_optimizations
14636 && can_create_pseudo_p ()"
14641 ix86_optimize_mode_switching[I387_CEIL] = 1;
14643 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14644 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14646 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14647 operands[2], operands[3]));
14650 [(set_attr "type" "frndint")
14651 (set_attr "i387_cw" "ceil")
14652 (set_attr "mode" "XF")])
14654 (define_insn "frndintxf2_ceil_i387"
14655 [(set (match_operand:XF 0 "register_operand" "=f")
14656 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14657 UNSPEC_FRNDINT_CEIL))
14658 (use (match_operand:HI 2 "memory_operand" "m"))
14659 (use (match_operand:HI 3 "memory_operand" "m"))]
14660 "TARGET_USE_FANCY_MATH_387
14661 && flag_unsafe_math_optimizations"
14662 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14663 [(set_attr "type" "frndint")
14664 (set_attr "i387_cw" "ceil")
14665 (set_attr "mode" "XF")])
14667 (define_expand "ceilxf2"
14668 [(use (match_operand:XF 0 "register_operand" ""))
14669 (use (match_operand:XF 1 "register_operand" ""))]
14670 "TARGET_USE_FANCY_MATH_387
14671 && flag_unsafe_math_optimizations"
14673 if (optimize_insn_for_size_p ())
14675 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14679 (define_expand "ceil<mode>2"
14680 [(use (match_operand:MODEF 0 "register_operand" ""))
14681 (use (match_operand:MODEF 1 "register_operand" ""))]
14682 "(TARGET_USE_FANCY_MATH_387
14683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14684 || TARGET_MIX_SSE_I387)
14685 && flag_unsafe_math_optimizations)
14686 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14687 && !flag_trapping_math)"
14689 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14690 && !flag_trapping_math
14691 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14694 emit_insn (gen_sse4_1_round<mode>2
14695 (operands[0], operands[1], GEN_INT (0x02)));
14696 else if (optimize_insn_for_size_p ())
14698 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14699 ix86_expand_floorceil (operand0, operand1, false);
14701 ix86_expand_floorceildf_32 (operand0, operand1, false);
14707 if (optimize_insn_for_size_p ())
14710 op0 = gen_reg_rtx (XFmode);
14711 op1 = gen_reg_rtx (XFmode);
14712 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14713 emit_insn (gen_frndintxf2_ceil (op0, op1));
14715 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14720 (define_insn_and_split "*fist<mode>2_ceil_1"
14721 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14722 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14724 (clobber (reg:CC FLAGS_REG))]
14725 "TARGET_USE_FANCY_MATH_387
14726 && flag_unsafe_math_optimizations
14727 && can_create_pseudo_p ()"
14732 ix86_optimize_mode_switching[I387_CEIL] = 1;
14734 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14735 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14736 if (memory_operand (operands[0], VOIDmode))
14737 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14738 operands[2], operands[3]));
14741 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14742 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14743 operands[2], operands[3],
14748 [(set_attr "type" "fistp")
14749 (set_attr "i387_cw" "ceil")
14750 (set_attr "mode" "<MODE>")])
14752 (define_insn "fistdi2_ceil"
14753 [(set (match_operand:DI 0 "memory_operand" "=m")
14754 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14756 (use (match_operand:HI 2 "memory_operand" "m"))
14757 (use (match_operand:HI 3 "memory_operand" "m"))
14758 (clobber (match_scratch:XF 4 "=&1f"))]
14759 "TARGET_USE_FANCY_MATH_387
14760 && flag_unsafe_math_optimizations"
14761 "* return output_fix_trunc (insn, operands, 0);"
14762 [(set_attr "type" "fistp")
14763 (set_attr "i387_cw" "ceil")
14764 (set_attr "mode" "DI")])
14766 (define_insn "fistdi2_ceil_with_temp"
14767 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14768 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14770 (use (match_operand:HI 2 "memory_operand" "m,m"))
14771 (use (match_operand:HI 3 "memory_operand" "m,m"))
14772 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14773 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14774 "TARGET_USE_FANCY_MATH_387
14775 && flag_unsafe_math_optimizations"
14777 [(set_attr "type" "fistp")
14778 (set_attr "i387_cw" "ceil")
14779 (set_attr "mode" "DI")])
14782 [(set (match_operand:DI 0 "register_operand" "")
14783 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14785 (use (match_operand:HI 2 "memory_operand" ""))
14786 (use (match_operand:HI 3 "memory_operand" ""))
14787 (clobber (match_operand:DI 4 "memory_operand" ""))
14788 (clobber (match_scratch 5 ""))]
14790 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14791 (use (match_dup 2))
14792 (use (match_dup 3))
14793 (clobber (match_dup 5))])
14794 (set (match_dup 0) (match_dup 4))]
14798 [(set (match_operand:DI 0 "memory_operand" "")
14799 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14801 (use (match_operand:HI 2 "memory_operand" ""))
14802 (use (match_operand:HI 3 "memory_operand" ""))
14803 (clobber (match_operand:DI 4 "memory_operand" ""))
14804 (clobber (match_scratch 5 ""))]
14806 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14807 (use (match_dup 2))
14808 (use (match_dup 3))
14809 (clobber (match_dup 5))])]
14812 (define_insn "fist<mode>2_ceil"
14813 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14814 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14816 (use (match_operand:HI 2 "memory_operand" "m"))
14817 (use (match_operand:HI 3 "memory_operand" "m"))]
14818 "TARGET_USE_FANCY_MATH_387
14819 && flag_unsafe_math_optimizations"
14820 "* return output_fix_trunc (insn, operands, 0);"
14821 [(set_attr "type" "fistp")
14822 (set_attr "i387_cw" "ceil")
14823 (set_attr "mode" "<MODE>")])
14825 (define_insn "fist<mode>2_ceil_with_temp"
14826 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14827 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14829 (use (match_operand:HI 2 "memory_operand" "m,m"))
14830 (use (match_operand:HI 3 "memory_operand" "m,m"))
14831 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14832 "TARGET_USE_FANCY_MATH_387
14833 && flag_unsafe_math_optimizations"
14835 [(set_attr "type" "fistp")
14836 (set_attr "i387_cw" "ceil")
14837 (set_attr "mode" "<MODE>")])
14840 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14841 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14843 (use (match_operand:HI 2 "memory_operand" ""))
14844 (use (match_operand:HI 3 "memory_operand" ""))
14845 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14847 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14849 (use (match_dup 2))
14850 (use (match_dup 3))])
14851 (set (match_dup 0) (match_dup 4))]
14855 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14856 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14858 (use (match_operand:HI 2 "memory_operand" ""))
14859 (use (match_operand:HI 3 "memory_operand" ""))
14860 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14862 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14864 (use (match_dup 2))
14865 (use (match_dup 3))])]
14868 (define_expand "lceilxf<mode>2"
14869 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14870 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14872 (clobber (reg:CC FLAGS_REG))])]
14873 "TARGET_USE_FANCY_MATH_387
14874 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14875 && flag_unsafe_math_optimizations"
14878 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14879 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14880 (match_operand:MODEF 1 "register_operand" "")]
14881 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14882 && !flag_trapping_math"
14884 ix86_expand_lfloorceil (operand0, operand1, false);
14888 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14889 (define_insn_and_split "frndintxf2_trunc"
14890 [(set (match_operand:XF 0 "register_operand" "")
14891 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14892 UNSPEC_FRNDINT_TRUNC))
14893 (clobber (reg:CC FLAGS_REG))]
14894 "TARGET_USE_FANCY_MATH_387
14895 && flag_unsafe_math_optimizations
14896 && can_create_pseudo_p ()"
14901 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14903 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14904 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14906 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14907 operands[2], operands[3]));
14910 [(set_attr "type" "frndint")
14911 (set_attr "i387_cw" "trunc")
14912 (set_attr "mode" "XF")])
14914 (define_insn "frndintxf2_trunc_i387"
14915 [(set (match_operand:XF 0 "register_operand" "=f")
14916 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14917 UNSPEC_FRNDINT_TRUNC))
14918 (use (match_operand:HI 2 "memory_operand" "m"))
14919 (use (match_operand:HI 3 "memory_operand" "m"))]
14920 "TARGET_USE_FANCY_MATH_387
14921 && flag_unsafe_math_optimizations"
14922 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14923 [(set_attr "type" "frndint")
14924 (set_attr "i387_cw" "trunc")
14925 (set_attr "mode" "XF")])
14927 (define_expand "btruncxf2"
14928 [(use (match_operand:XF 0 "register_operand" ""))
14929 (use (match_operand:XF 1 "register_operand" ""))]
14930 "TARGET_USE_FANCY_MATH_387
14931 && flag_unsafe_math_optimizations"
14933 if (optimize_insn_for_size_p ())
14935 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14939 (define_expand "btrunc<mode>2"
14940 [(use (match_operand:MODEF 0 "register_operand" ""))
14941 (use (match_operand:MODEF 1 "register_operand" ""))]
14942 "(TARGET_USE_FANCY_MATH_387
14943 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14944 || TARGET_MIX_SSE_I387)
14945 && flag_unsafe_math_optimizations)
14946 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14947 && !flag_trapping_math)"
14949 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14950 && !flag_trapping_math
14951 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14954 emit_insn (gen_sse4_1_round<mode>2
14955 (operands[0], operands[1], GEN_INT (0x03)));
14956 else if (optimize_insn_for_size_p ())
14958 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14959 ix86_expand_trunc (operand0, operand1);
14961 ix86_expand_truncdf_32 (operand0, operand1);
14967 if (optimize_insn_for_size_p ())
14970 op0 = gen_reg_rtx (XFmode);
14971 op1 = gen_reg_rtx (XFmode);
14972 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14973 emit_insn (gen_frndintxf2_trunc (op0, op1));
14975 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14980 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14981 (define_insn_and_split "frndintxf2_mask_pm"
14982 [(set (match_operand:XF 0 "register_operand" "")
14983 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14984 UNSPEC_FRNDINT_MASK_PM))
14985 (clobber (reg:CC FLAGS_REG))]
14986 "TARGET_USE_FANCY_MATH_387
14987 && flag_unsafe_math_optimizations
14988 && can_create_pseudo_p ()"
14993 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14995 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14996 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14998 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14999 operands[2], operands[3]));
15002 [(set_attr "type" "frndint")
15003 (set_attr "i387_cw" "mask_pm")
15004 (set_attr "mode" "XF")])
15006 (define_insn "frndintxf2_mask_pm_i387"
15007 [(set (match_operand:XF 0 "register_operand" "=f")
15008 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15009 UNSPEC_FRNDINT_MASK_PM))
15010 (use (match_operand:HI 2 "memory_operand" "m"))
15011 (use (match_operand:HI 3 "memory_operand" "m"))]
15012 "TARGET_USE_FANCY_MATH_387
15013 && flag_unsafe_math_optimizations"
15014 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15015 [(set_attr "type" "frndint")
15016 (set_attr "i387_cw" "mask_pm")
15017 (set_attr "mode" "XF")])
15019 (define_expand "nearbyintxf2"
15020 [(use (match_operand:XF 0 "register_operand" ""))
15021 (use (match_operand:XF 1 "register_operand" ""))]
15022 "TARGET_USE_FANCY_MATH_387
15023 && flag_unsafe_math_optimizations"
15025 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15030 (define_expand "nearbyint<mode>2"
15031 [(use (match_operand:MODEF 0 "register_operand" ""))
15032 (use (match_operand:MODEF 1 "register_operand" ""))]
15033 "TARGET_USE_FANCY_MATH_387
15034 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15035 || TARGET_MIX_SSE_I387)
15036 && flag_unsafe_math_optimizations"
15038 rtx op0 = gen_reg_rtx (XFmode);
15039 rtx op1 = gen_reg_rtx (XFmode);
15041 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15042 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15044 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15048 (define_insn "fxam<mode>2_i387"
15049 [(set (match_operand:HI 0 "register_operand" "=a")
15051 [(match_operand:X87MODEF 1 "register_operand" "f")]
15053 "TARGET_USE_FANCY_MATH_387"
15054 "fxam\n\tfnstsw\t%0"
15055 [(set_attr "type" "multi")
15056 (set_attr "length" "4")
15057 (set_attr "unit" "i387")
15058 (set_attr "mode" "<MODE>")])
15060 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15061 [(set (match_operand:HI 0 "register_operand" "")
15063 [(match_operand:MODEF 1 "memory_operand" "")]
15065 "TARGET_USE_FANCY_MATH_387
15066 && can_create_pseudo_p ()"
15069 [(set (match_dup 2)(match_dup 1))
15071 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15073 operands[2] = gen_reg_rtx (<MODE>mode);
15075 MEM_VOLATILE_P (operands[1]) = 1;
15077 [(set_attr "type" "multi")
15078 (set_attr "unit" "i387")
15079 (set_attr "mode" "<MODE>")])
15081 (define_expand "isinfxf2"
15082 [(use (match_operand:SI 0 "register_operand" ""))
15083 (use (match_operand:XF 1 "register_operand" ""))]
15084 "TARGET_USE_FANCY_MATH_387
15085 && TARGET_C99_FUNCTIONS"
15087 rtx mask = GEN_INT (0x45);
15088 rtx val = GEN_INT (0x05);
15092 rtx scratch = gen_reg_rtx (HImode);
15093 rtx res = gen_reg_rtx (QImode);
15095 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15097 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15098 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15099 cond = gen_rtx_fmt_ee (EQ, QImode,
15100 gen_rtx_REG (CCmode, FLAGS_REG),
15102 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15103 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15107 (define_expand "isinf<mode>2"
15108 [(use (match_operand:SI 0 "register_operand" ""))
15109 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15110 "TARGET_USE_FANCY_MATH_387
15111 && TARGET_C99_FUNCTIONS
15112 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15114 rtx mask = GEN_INT (0x45);
15115 rtx val = GEN_INT (0x05);
15119 rtx scratch = gen_reg_rtx (HImode);
15120 rtx res = gen_reg_rtx (QImode);
15122 /* Remove excess precision by forcing value through memory. */
15123 if (memory_operand (operands[1], VOIDmode))
15124 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15127 enum ix86_stack_slot slot = (virtuals_instantiated
15130 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15132 emit_move_insn (temp, operands[1]);
15133 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15136 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15137 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15138 cond = gen_rtx_fmt_ee (EQ, QImode,
15139 gen_rtx_REG (CCmode, FLAGS_REG),
15141 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15142 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15146 (define_expand "signbit<mode>2"
15147 [(use (match_operand:SI 0 "register_operand" ""))
15148 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15149 "TARGET_USE_FANCY_MATH_387
15150 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15152 rtx mask = GEN_INT (0x0200);
15154 rtx scratch = gen_reg_rtx (HImode);
15156 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15157 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15161 ;; Block operation instructions
15164 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15167 [(set_attr "length" "1")
15168 (set_attr "length_immediate" "0")
15169 (set_attr "modrm" "0")])
15171 (define_expand "movmemsi"
15172 [(use (match_operand:BLK 0 "memory_operand" ""))
15173 (use (match_operand:BLK 1 "memory_operand" ""))
15174 (use (match_operand:SI 2 "nonmemory_operand" ""))
15175 (use (match_operand:SI 3 "const_int_operand" ""))
15176 (use (match_operand:SI 4 "const_int_operand" ""))
15177 (use (match_operand:SI 5 "const_int_operand" ""))]
15180 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15181 operands[4], operands[5]))
15187 (define_expand "movmemdi"
15188 [(use (match_operand:BLK 0 "memory_operand" ""))
15189 (use (match_operand:BLK 1 "memory_operand" ""))
15190 (use (match_operand:DI 2 "nonmemory_operand" ""))
15191 (use (match_operand:DI 3 "const_int_operand" ""))
15192 (use (match_operand:SI 4 "const_int_operand" ""))
15193 (use (match_operand:SI 5 "const_int_operand" ""))]
15196 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15197 operands[4], operands[5]))
15203 ;; Most CPUs don't like single string operations
15204 ;; Handle this case here to simplify previous expander.
15206 (define_expand "strmov"
15207 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15208 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15209 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15210 (clobber (reg:CC FLAGS_REG))])
15211 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15212 (clobber (reg:CC FLAGS_REG))])]
15215 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15217 /* If .md ever supports :P for Pmode, these can be directly
15218 in the pattern above. */
15219 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15220 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15222 /* Can't use this if the user has appropriated esi or edi. */
15223 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15224 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15226 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15227 operands[2], operands[3],
15228 operands[5], operands[6]));
15232 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15235 (define_expand "strmov_singleop"
15236 [(parallel [(set (match_operand 1 "memory_operand" "")
15237 (match_operand 3 "memory_operand" ""))
15238 (set (match_operand 0 "register_operand" "")
15239 (match_operand 4 "" ""))
15240 (set (match_operand 2 "register_operand" "")
15241 (match_operand 5 "" ""))])]
15243 "ix86_current_function_needs_cld = 1;")
15245 (define_insn "*strmovdi_rex_1"
15246 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15247 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15248 (set (match_operand:DI 0 "register_operand" "=D")
15249 (plus:DI (match_dup 2)
15251 (set (match_operand:DI 1 "register_operand" "=S")
15252 (plus:DI (match_dup 3)
15256 [(set_attr "type" "str")
15257 (set_attr "mode" "DI")
15258 (set_attr "memory" "both")])
15260 (define_insn "*strmovsi_1"
15261 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15262 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15263 (set (match_operand:SI 0 "register_operand" "=D")
15264 (plus:SI (match_dup 2)
15266 (set (match_operand:SI 1 "register_operand" "=S")
15267 (plus:SI (match_dup 3)
15271 [(set_attr "type" "str")
15272 (set_attr "mode" "SI")
15273 (set_attr "memory" "both")])
15275 (define_insn "*strmovsi_rex_1"
15276 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15277 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15278 (set (match_operand:DI 0 "register_operand" "=D")
15279 (plus:DI (match_dup 2)
15281 (set (match_operand:DI 1 "register_operand" "=S")
15282 (plus:DI (match_dup 3)
15286 [(set_attr "type" "str")
15287 (set_attr "mode" "SI")
15288 (set_attr "memory" "both")])
15290 (define_insn "*strmovhi_1"
15291 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15292 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15293 (set (match_operand:SI 0 "register_operand" "=D")
15294 (plus:SI (match_dup 2)
15296 (set (match_operand:SI 1 "register_operand" "=S")
15297 (plus:SI (match_dup 3)
15301 [(set_attr "type" "str")
15302 (set_attr "memory" "both")
15303 (set_attr "mode" "HI")])
15305 (define_insn "*strmovhi_rex_1"
15306 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15307 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15308 (set (match_operand:DI 0 "register_operand" "=D")
15309 (plus:DI (match_dup 2)
15311 (set (match_operand:DI 1 "register_operand" "=S")
15312 (plus:DI (match_dup 3)
15316 [(set_attr "type" "str")
15317 (set_attr "memory" "both")
15318 (set_attr "mode" "HI")])
15320 (define_insn "*strmovqi_1"
15321 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15322 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15323 (set (match_operand:SI 0 "register_operand" "=D")
15324 (plus:SI (match_dup 2)
15326 (set (match_operand:SI 1 "register_operand" "=S")
15327 (plus:SI (match_dup 3)
15331 [(set_attr "type" "str")
15332 (set_attr "memory" "both")
15333 (set_attr "mode" "QI")])
15335 (define_insn "*strmovqi_rex_1"
15336 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15337 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15338 (set (match_operand:DI 0 "register_operand" "=D")
15339 (plus:DI (match_dup 2)
15341 (set (match_operand:DI 1 "register_operand" "=S")
15342 (plus:DI (match_dup 3)
15346 [(set_attr "type" "str")
15347 (set_attr "memory" "both")
15348 (set_attr "prefix_rex" "0")
15349 (set_attr "mode" "QI")])
15351 (define_expand "rep_mov"
15352 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15353 (set (match_operand 0 "register_operand" "")
15354 (match_operand 5 "" ""))
15355 (set (match_operand 2 "register_operand" "")
15356 (match_operand 6 "" ""))
15357 (set (match_operand 1 "memory_operand" "")
15358 (match_operand 3 "memory_operand" ""))
15359 (use (match_dup 4))])]
15361 "ix86_current_function_needs_cld = 1;")
15363 (define_insn "*rep_movdi_rex64"
15364 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15365 (set (match_operand:DI 0 "register_operand" "=D")
15366 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15368 (match_operand:DI 3 "register_operand" "0")))
15369 (set (match_operand:DI 1 "register_operand" "=S")
15370 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15371 (match_operand:DI 4 "register_operand" "1")))
15372 (set (mem:BLK (match_dup 3))
15373 (mem:BLK (match_dup 4)))
15374 (use (match_dup 5))]
15377 [(set_attr "type" "str")
15378 (set_attr "prefix_rep" "1")
15379 (set_attr "memory" "both")
15380 (set_attr "mode" "DI")])
15382 (define_insn "*rep_movsi"
15383 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15384 (set (match_operand:SI 0 "register_operand" "=D")
15385 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15387 (match_operand:SI 3 "register_operand" "0")))
15388 (set (match_operand:SI 1 "register_operand" "=S")
15389 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15390 (match_operand:SI 4 "register_operand" "1")))
15391 (set (mem:BLK (match_dup 3))
15392 (mem:BLK (match_dup 4)))
15393 (use (match_dup 5))]
15395 "rep{%;} movs{l|d}"
15396 [(set_attr "type" "str")
15397 (set_attr "prefix_rep" "1")
15398 (set_attr "memory" "both")
15399 (set_attr "mode" "SI")])
15401 (define_insn "*rep_movsi_rex64"
15402 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15403 (set (match_operand:DI 0 "register_operand" "=D")
15404 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15406 (match_operand:DI 3 "register_operand" "0")))
15407 (set (match_operand:DI 1 "register_operand" "=S")
15408 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15409 (match_operand:DI 4 "register_operand" "1")))
15410 (set (mem:BLK (match_dup 3))
15411 (mem:BLK (match_dup 4)))
15412 (use (match_dup 5))]
15414 "rep{%;} movs{l|d}"
15415 [(set_attr "type" "str")
15416 (set_attr "prefix_rep" "1")
15417 (set_attr "memory" "both")
15418 (set_attr "mode" "SI")])
15420 (define_insn "*rep_movqi"
15421 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15422 (set (match_operand:SI 0 "register_operand" "=D")
15423 (plus:SI (match_operand:SI 3 "register_operand" "0")
15424 (match_operand:SI 5 "register_operand" "2")))
15425 (set (match_operand:SI 1 "register_operand" "=S")
15426 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15427 (set (mem:BLK (match_dup 3))
15428 (mem:BLK (match_dup 4)))
15429 (use (match_dup 5))]
15432 [(set_attr "type" "str")
15433 (set_attr "prefix_rep" "1")
15434 (set_attr "memory" "both")
15435 (set_attr "mode" "SI")])
15437 (define_insn "*rep_movqi_rex64"
15438 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15439 (set (match_operand:DI 0 "register_operand" "=D")
15440 (plus:DI (match_operand:DI 3 "register_operand" "0")
15441 (match_operand:DI 5 "register_operand" "2")))
15442 (set (match_operand:DI 1 "register_operand" "=S")
15443 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15444 (set (mem:BLK (match_dup 3))
15445 (mem:BLK (match_dup 4)))
15446 (use (match_dup 5))]
15449 [(set_attr "type" "str")
15450 (set_attr "prefix_rep" "1")
15451 (set_attr "memory" "both")
15452 (set_attr "mode" "SI")])
15454 (define_expand "setmemsi"
15455 [(use (match_operand:BLK 0 "memory_operand" ""))
15456 (use (match_operand:SI 1 "nonmemory_operand" ""))
15457 (use (match_operand 2 "const_int_operand" ""))
15458 (use (match_operand 3 "const_int_operand" ""))
15459 (use (match_operand:SI 4 "const_int_operand" ""))
15460 (use (match_operand:SI 5 "const_int_operand" ""))]
15463 if (ix86_expand_setmem (operands[0], operands[1],
15464 operands[2], operands[3],
15465 operands[4], operands[5]))
15471 (define_expand "setmemdi"
15472 [(use (match_operand:BLK 0 "memory_operand" ""))
15473 (use (match_operand:DI 1 "nonmemory_operand" ""))
15474 (use (match_operand 2 "const_int_operand" ""))
15475 (use (match_operand 3 "const_int_operand" ""))
15476 (use (match_operand 4 "const_int_operand" ""))
15477 (use (match_operand 5 "const_int_operand" ""))]
15480 if (ix86_expand_setmem (operands[0], operands[1],
15481 operands[2], operands[3],
15482 operands[4], operands[5]))
15488 ;; Most CPUs don't like single string operations
15489 ;; Handle this case here to simplify previous expander.
15491 (define_expand "strset"
15492 [(set (match_operand 1 "memory_operand" "")
15493 (match_operand 2 "register_operand" ""))
15494 (parallel [(set (match_operand 0 "register_operand" "")
15496 (clobber (reg:CC FLAGS_REG))])]
15499 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15500 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15502 /* If .md ever supports :P for Pmode, this can be directly
15503 in the pattern above. */
15504 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15505 GEN_INT (GET_MODE_SIZE (GET_MODE
15507 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15509 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15515 (define_expand "strset_singleop"
15516 [(parallel [(set (match_operand 1 "memory_operand" "")
15517 (match_operand 2 "register_operand" ""))
15518 (set (match_operand 0 "register_operand" "")
15519 (match_operand 3 "" ""))])]
15521 "ix86_current_function_needs_cld = 1;")
15523 (define_insn "*strsetdi_rex_1"
15524 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15525 (match_operand:DI 2 "register_operand" "a"))
15526 (set (match_operand:DI 0 "register_operand" "=D")
15527 (plus:DI (match_dup 1)
15531 [(set_attr "type" "str")
15532 (set_attr "memory" "store")
15533 (set_attr "mode" "DI")])
15535 (define_insn "*strsetsi_1"
15536 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15537 (match_operand:SI 2 "register_operand" "a"))
15538 (set (match_operand:SI 0 "register_operand" "=D")
15539 (plus:SI (match_dup 1)
15543 [(set_attr "type" "str")
15544 (set_attr "memory" "store")
15545 (set_attr "mode" "SI")])
15547 (define_insn "*strsetsi_rex_1"
15548 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15549 (match_operand:SI 2 "register_operand" "a"))
15550 (set (match_operand:DI 0 "register_operand" "=D")
15551 (plus:DI (match_dup 1)
15555 [(set_attr "type" "str")
15556 (set_attr "memory" "store")
15557 (set_attr "mode" "SI")])
15559 (define_insn "*strsethi_1"
15560 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15561 (match_operand:HI 2 "register_operand" "a"))
15562 (set (match_operand:SI 0 "register_operand" "=D")
15563 (plus:SI (match_dup 1)
15567 [(set_attr "type" "str")
15568 (set_attr "memory" "store")
15569 (set_attr "mode" "HI")])
15571 (define_insn "*strsethi_rex_1"
15572 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15573 (match_operand:HI 2 "register_operand" "a"))
15574 (set (match_operand:DI 0 "register_operand" "=D")
15575 (plus:DI (match_dup 1)
15579 [(set_attr "type" "str")
15580 (set_attr "memory" "store")
15581 (set_attr "mode" "HI")])
15583 (define_insn "*strsetqi_1"
15584 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15585 (match_operand:QI 2 "register_operand" "a"))
15586 (set (match_operand:SI 0 "register_operand" "=D")
15587 (plus:SI (match_dup 1)
15591 [(set_attr "type" "str")
15592 (set_attr "memory" "store")
15593 (set_attr "mode" "QI")])
15595 (define_insn "*strsetqi_rex_1"
15596 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15597 (match_operand:QI 2 "register_operand" "a"))
15598 (set (match_operand:DI 0 "register_operand" "=D")
15599 (plus:DI (match_dup 1)
15603 [(set_attr "type" "str")
15604 (set_attr "memory" "store")
15605 (set_attr "prefix_rex" "0")
15606 (set_attr "mode" "QI")])
15608 (define_expand "rep_stos"
15609 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15610 (set (match_operand 0 "register_operand" "")
15611 (match_operand 4 "" ""))
15612 (set (match_operand 2 "memory_operand" "") (const_int 0))
15613 (use (match_operand 3 "register_operand" ""))
15614 (use (match_dup 1))])]
15616 "ix86_current_function_needs_cld = 1;")
15618 (define_insn "*rep_stosdi_rex64"
15619 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15620 (set (match_operand:DI 0 "register_operand" "=D")
15621 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15623 (match_operand:DI 3 "register_operand" "0")))
15624 (set (mem:BLK (match_dup 3))
15626 (use (match_operand:DI 2 "register_operand" "a"))
15627 (use (match_dup 4))]
15630 [(set_attr "type" "str")
15631 (set_attr "prefix_rep" "1")
15632 (set_attr "memory" "store")
15633 (set_attr "mode" "DI")])
15635 (define_insn "*rep_stossi"
15636 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15637 (set (match_operand:SI 0 "register_operand" "=D")
15638 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15640 (match_operand:SI 3 "register_operand" "0")))
15641 (set (mem:BLK (match_dup 3))
15643 (use (match_operand:SI 2 "register_operand" "a"))
15644 (use (match_dup 4))]
15646 "rep{%;} stos{l|d}"
15647 [(set_attr "type" "str")
15648 (set_attr "prefix_rep" "1")
15649 (set_attr "memory" "store")
15650 (set_attr "mode" "SI")])
15652 (define_insn "*rep_stossi_rex64"
15653 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15654 (set (match_operand:DI 0 "register_operand" "=D")
15655 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15657 (match_operand:DI 3 "register_operand" "0")))
15658 (set (mem:BLK (match_dup 3))
15660 (use (match_operand:SI 2 "register_operand" "a"))
15661 (use (match_dup 4))]
15663 "rep{%;} stos{l|d}"
15664 [(set_attr "type" "str")
15665 (set_attr "prefix_rep" "1")
15666 (set_attr "memory" "store")
15667 (set_attr "mode" "SI")])
15669 (define_insn "*rep_stosqi"
15670 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15671 (set (match_operand:SI 0 "register_operand" "=D")
15672 (plus:SI (match_operand:SI 3 "register_operand" "0")
15673 (match_operand:SI 4 "register_operand" "1")))
15674 (set (mem:BLK (match_dup 3))
15676 (use (match_operand:QI 2 "register_operand" "a"))
15677 (use (match_dup 4))]
15680 [(set_attr "type" "str")
15681 (set_attr "prefix_rep" "1")
15682 (set_attr "memory" "store")
15683 (set_attr "mode" "QI")])
15685 (define_insn "*rep_stosqi_rex64"
15686 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15687 (set (match_operand:DI 0 "register_operand" "=D")
15688 (plus:DI (match_operand:DI 3 "register_operand" "0")
15689 (match_operand:DI 4 "register_operand" "1")))
15690 (set (mem:BLK (match_dup 3))
15692 (use (match_operand:QI 2 "register_operand" "a"))
15693 (use (match_dup 4))]
15696 [(set_attr "type" "str")
15697 (set_attr "prefix_rep" "1")
15698 (set_attr "memory" "store")
15699 (set_attr "prefix_rex" "0")
15700 (set_attr "mode" "QI")])
15702 (define_expand "cmpstrnsi"
15703 [(set (match_operand:SI 0 "register_operand" "")
15704 (compare:SI (match_operand:BLK 1 "general_operand" "")
15705 (match_operand:BLK 2 "general_operand" "")))
15706 (use (match_operand 3 "general_operand" ""))
15707 (use (match_operand 4 "immediate_operand" ""))]
15710 rtx addr1, addr2, out, outlow, count, countreg, align;
15712 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15715 /* Can't use this if the user has appropriated esi or edi. */
15716 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15721 out = gen_reg_rtx (SImode);
15723 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15724 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15725 if (addr1 != XEXP (operands[1], 0))
15726 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15727 if (addr2 != XEXP (operands[2], 0))
15728 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15730 count = operands[3];
15731 countreg = ix86_zero_extend_to_Pmode (count);
15733 /* %%% Iff we are testing strict equality, we can use known alignment
15734 to good advantage. This may be possible with combine, particularly
15735 once cc0 is dead. */
15736 align = operands[4];
15738 if (CONST_INT_P (count))
15740 if (INTVAL (count) == 0)
15742 emit_move_insn (operands[0], const0_rtx);
15745 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15746 operands[1], operands[2]));
15750 rtx (*gen_cmp) (rtx, rtx);
15752 gen_cmp = (TARGET_64BIT
15753 ? gen_cmpdi_1 : gen_cmpsi_1);
15755 emit_insn (gen_cmp (countreg, countreg));
15756 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15757 operands[1], operands[2]));
15760 outlow = gen_lowpart (QImode, out);
15761 emit_insn (gen_cmpintqi (outlow));
15762 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15764 if (operands[0] != out)
15765 emit_move_insn (operands[0], out);
15770 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15772 (define_expand "cmpintqi"
15773 [(set (match_dup 1)
15774 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15776 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15777 (parallel [(set (match_operand:QI 0 "register_operand" "")
15778 (minus:QI (match_dup 1)
15780 (clobber (reg:CC FLAGS_REG))])]
15782 "operands[1] = gen_reg_rtx (QImode);
15783 operands[2] = gen_reg_rtx (QImode);")
15785 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15786 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15788 (define_expand "cmpstrnqi_nz_1"
15789 [(parallel [(set (reg:CC FLAGS_REG)
15790 (compare:CC (match_operand 4 "memory_operand" "")
15791 (match_operand 5 "memory_operand" "")))
15792 (use (match_operand 2 "register_operand" ""))
15793 (use (match_operand:SI 3 "immediate_operand" ""))
15794 (clobber (match_operand 0 "register_operand" ""))
15795 (clobber (match_operand 1 "register_operand" ""))
15796 (clobber (match_dup 2))])]
15798 "ix86_current_function_needs_cld = 1;")
15800 (define_insn "*cmpstrnqi_nz_1"
15801 [(set (reg:CC FLAGS_REG)
15802 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15803 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15804 (use (match_operand:SI 6 "register_operand" "2"))
15805 (use (match_operand:SI 3 "immediate_operand" "i"))
15806 (clobber (match_operand:SI 0 "register_operand" "=S"))
15807 (clobber (match_operand:SI 1 "register_operand" "=D"))
15808 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15811 [(set_attr "type" "str")
15812 (set_attr "mode" "QI")
15813 (set_attr "prefix_rep" "1")])
15815 (define_insn "*cmpstrnqi_nz_rex_1"
15816 [(set (reg:CC FLAGS_REG)
15817 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15818 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15819 (use (match_operand:DI 6 "register_operand" "2"))
15820 (use (match_operand:SI 3 "immediate_operand" "i"))
15821 (clobber (match_operand:DI 0 "register_operand" "=S"))
15822 (clobber (match_operand:DI 1 "register_operand" "=D"))
15823 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15826 [(set_attr "type" "str")
15827 (set_attr "mode" "QI")
15828 (set_attr "prefix_rex" "0")
15829 (set_attr "prefix_rep" "1")])
15831 ;; The same, but the count is not known to not be zero.
15833 (define_expand "cmpstrnqi_1"
15834 [(parallel [(set (reg:CC FLAGS_REG)
15835 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15837 (compare:CC (match_operand 4 "memory_operand" "")
15838 (match_operand 5 "memory_operand" ""))
15840 (use (match_operand:SI 3 "immediate_operand" ""))
15841 (use (reg:CC FLAGS_REG))
15842 (clobber (match_operand 0 "register_operand" ""))
15843 (clobber (match_operand 1 "register_operand" ""))
15844 (clobber (match_dup 2))])]
15846 "ix86_current_function_needs_cld = 1;")
15848 (define_insn "*cmpstrnqi_1"
15849 [(set (reg:CC FLAGS_REG)
15850 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15852 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15853 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15855 (use (match_operand:SI 3 "immediate_operand" "i"))
15856 (use (reg:CC FLAGS_REG))
15857 (clobber (match_operand:SI 0 "register_operand" "=S"))
15858 (clobber (match_operand:SI 1 "register_operand" "=D"))
15859 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15862 [(set_attr "type" "str")
15863 (set_attr "mode" "QI")
15864 (set_attr "prefix_rep" "1")])
15866 (define_insn "*cmpstrnqi_rex_1"
15867 [(set (reg:CC FLAGS_REG)
15868 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15870 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15871 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15873 (use (match_operand:SI 3 "immediate_operand" "i"))
15874 (use (reg:CC FLAGS_REG))
15875 (clobber (match_operand:DI 0 "register_operand" "=S"))
15876 (clobber (match_operand:DI 1 "register_operand" "=D"))
15877 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15880 [(set_attr "type" "str")
15881 (set_attr "mode" "QI")
15882 (set_attr "prefix_rex" "0")
15883 (set_attr "prefix_rep" "1")])
15885 (define_expand "strlensi"
15886 [(set (match_operand:SI 0 "register_operand" "")
15887 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15888 (match_operand:QI 2 "immediate_operand" "")
15889 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15892 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15898 (define_expand "strlendi"
15899 [(set (match_operand:DI 0 "register_operand" "")
15900 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15901 (match_operand:QI 2 "immediate_operand" "")
15902 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15905 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15911 (define_expand "strlenqi_1"
15912 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15913 (clobber (match_operand 1 "register_operand" ""))
15914 (clobber (reg:CC FLAGS_REG))])]
15916 "ix86_current_function_needs_cld = 1;")
15918 (define_insn "*strlenqi_1"
15919 [(set (match_operand:SI 0 "register_operand" "=&c")
15920 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15921 (match_operand:QI 2 "register_operand" "a")
15922 (match_operand:SI 3 "immediate_operand" "i")
15923 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15924 (clobber (match_operand:SI 1 "register_operand" "=D"))
15925 (clobber (reg:CC FLAGS_REG))]
15928 [(set_attr "type" "str")
15929 (set_attr "mode" "QI")
15930 (set_attr "prefix_rep" "1")])
15932 (define_insn "*strlenqi_rex_1"
15933 [(set (match_operand:DI 0 "register_operand" "=&c")
15934 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15935 (match_operand:QI 2 "register_operand" "a")
15936 (match_operand:DI 3 "immediate_operand" "i")
15937 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15938 (clobber (match_operand:DI 1 "register_operand" "=D"))
15939 (clobber (reg:CC FLAGS_REG))]
15942 [(set_attr "type" "str")
15943 (set_attr "mode" "QI")
15944 (set_attr "prefix_rex" "0")
15945 (set_attr "prefix_rep" "1")])
15947 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15948 ;; handled in combine, but it is not currently up to the task.
15949 ;; When used for their truth value, the cmpstrn* expanders generate
15958 ;; The intermediate three instructions are unnecessary.
15960 ;; This one handles cmpstrn*_nz_1...
15963 (set (reg:CC FLAGS_REG)
15964 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15965 (mem:BLK (match_operand 5 "register_operand" ""))))
15966 (use (match_operand 6 "register_operand" ""))
15967 (use (match_operand:SI 3 "immediate_operand" ""))
15968 (clobber (match_operand 0 "register_operand" ""))
15969 (clobber (match_operand 1 "register_operand" ""))
15970 (clobber (match_operand 2 "register_operand" ""))])
15971 (set (match_operand:QI 7 "register_operand" "")
15972 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15973 (set (match_operand:QI 8 "register_operand" "")
15974 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15975 (set (reg FLAGS_REG)
15976 (compare (match_dup 7) (match_dup 8)))
15978 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15980 (set (reg:CC FLAGS_REG)
15981 (compare:CC (mem:BLK (match_dup 4))
15982 (mem:BLK (match_dup 5))))
15983 (use (match_dup 6))
15984 (use (match_dup 3))
15985 (clobber (match_dup 0))
15986 (clobber (match_dup 1))
15987 (clobber (match_dup 2))])]
15990 ;; ...and this one handles cmpstrn*_1.
15993 (set (reg:CC FLAGS_REG)
15994 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15996 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15997 (mem:BLK (match_operand 5 "register_operand" "")))
15999 (use (match_operand:SI 3 "immediate_operand" ""))
16000 (use (reg:CC FLAGS_REG))
16001 (clobber (match_operand 0 "register_operand" ""))
16002 (clobber (match_operand 1 "register_operand" ""))
16003 (clobber (match_operand 2 "register_operand" ""))])
16004 (set (match_operand:QI 7 "register_operand" "")
16005 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16006 (set (match_operand:QI 8 "register_operand" "")
16007 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16008 (set (reg FLAGS_REG)
16009 (compare (match_dup 7) (match_dup 8)))
16011 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16013 (set (reg:CC FLAGS_REG)
16014 (if_then_else:CC (ne (match_dup 6)
16016 (compare:CC (mem:BLK (match_dup 4))
16017 (mem:BLK (match_dup 5)))
16019 (use (match_dup 3))
16020 (use (reg:CC FLAGS_REG))
16021 (clobber (match_dup 0))
16022 (clobber (match_dup 1))
16023 (clobber (match_dup 2))])]
16028 ;; Conditional move instructions.
16030 (define_expand "mov<mode>cc"
16031 [(set (match_operand:SWIM 0 "register_operand" "")
16032 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16033 (match_operand:SWIM 2 "general_operand" "")
16034 (match_operand:SWIM 3 "general_operand" "")))]
16036 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16038 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16039 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16040 ;; So just document what we're doing explicitly.
16042 (define_expand "x86_mov<mode>cc_0_m1"
16044 [(set (match_operand:SWI48 0 "register_operand" "")
16045 (if_then_else:SWI48
16046 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16047 [(match_operand 1 "flags_reg_operand" "")
16051 (clobber (reg:CC FLAGS_REG))])]
16055 (define_insn "*x86_mov<mode>cc_0_m1"
16056 [(set (match_operand:SWI48 0 "register_operand" "=r")
16057 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16058 [(reg FLAGS_REG) (const_int 0)])
16061 (clobber (reg:CC FLAGS_REG))]
16063 "sbb{<imodesuffix>}\t%0, %0"
16064 ; Since we don't have the proper number of operands for an alu insn,
16065 ; fill in all the blanks.
16066 [(set_attr "type" "alu")
16067 (set_attr "use_carry" "1")
16068 (set_attr "pent_pair" "pu")
16069 (set_attr "memory" "none")
16070 (set_attr "imm_disp" "false")
16071 (set_attr "mode" "<MODE>")
16072 (set_attr "length_immediate" "0")])
16074 (define_insn "*x86_mov<mode>cc_0_m1_se"
16075 [(set (match_operand:SWI48 0 "register_operand" "=r")
16076 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16077 [(reg FLAGS_REG) (const_int 0)])
16080 (clobber (reg:CC FLAGS_REG))]
16082 "sbb{<imodesuffix>}\t%0, %0"
16083 [(set_attr "type" "alu")
16084 (set_attr "use_carry" "1")
16085 (set_attr "pent_pair" "pu")
16086 (set_attr "memory" "none")
16087 (set_attr "imm_disp" "false")
16088 (set_attr "mode" "<MODE>")
16089 (set_attr "length_immediate" "0")])
16091 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16092 [(set (match_operand:SWI48 0 "register_operand" "=r")
16093 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16094 [(reg FLAGS_REG) (const_int 0)])))]
16096 "sbb{<imodesuffix>}\t%0, %0"
16097 [(set_attr "type" "alu")
16098 (set_attr "use_carry" "1")
16099 (set_attr "pent_pair" "pu")
16100 (set_attr "memory" "none")
16101 (set_attr "imm_disp" "false")
16102 (set_attr "mode" "<MODE>")
16103 (set_attr "length_immediate" "0")])
16105 (define_insn "*mov<mode>cc_noc"
16106 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16107 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16108 [(reg FLAGS_REG) (const_int 0)])
16109 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16110 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16111 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16113 cmov%O2%C1\t{%2, %0|%0, %2}
16114 cmov%O2%c1\t{%3, %0|%0, %3}"
16115 [(set_attr "type" "icmov")
16116 (set_attr "mode" "<MODE>")])
16118 (define_insn_and_split "*movqicc_noc"
16119 [(set (match_operand:QI 0 "register_operand" "=r,r")
16120 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16121 [(match_operand 4 "flags_reg_operand" "")
16123 (match_operand:QI 2 "register_operand" "r,0")
16124 (match_operand:QI 3 "register_operand" "0,r")))]
16125 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16127 "&& reload_completed"
16128 [(set (match_dup 0)
16129 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16132 "operands[0] = gen_lowpart (SImode, operands[0]);
16133 operands[2] = gen_lowpart (SImode, operands[2]);
16134 operands[3] = gen_lowpart (SImode, operands[3]);"
16135 [(set_attr "type" "icmov")
16136 (set_attr "mode" "SI")])
16138 (define_expand "mov<mode>cc"
16139 [(set (match_operand:X87MODEF 0 "register_operand" "")
16140 (if_then_else:X87MODEF
16141 (match_operand 1 "ix86_fp_comparison_operator" "")
16142 (match_operand:X87MODEF 2 "register_operand" "")
16143 (match_operand:X87MODEF 3 "register_operand" "")))]
16144 "(TARGET_80387 && TARGET_CMOVE)
16145 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16146 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16148 (define_insn "*movsfcc_1_387"
16149 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16150 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16151 [(reg FLAGS_REG) (const_int 0)])
16152 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16153 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16154 "TARGET_80387 && TARGET_CMOVE
16155 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16157 fcmov%F1\t{%2, %0|%0, %2}
16158 fcmov%f1\t{%3, %0|%0, %3}
16159 cmov%O2%C1\t{%2, %0|%0, %2}
16160 cmov%O2%c1\t{%3, %0|%0, %3}"
16161 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16162 (set_attr "mode" "SF,SF,SI,SI")])
16164 (define_insn "*movdfcc_1"
16165 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16166 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16167 [(reg FLAGS_REG) (const_int 0)])
16168 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16169 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16170 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16171 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16173 fcmov%F1\t{%2, %0|%0, %2}
16174 fcmov%f1\t{%3, %0|%0, %3}
16177 [(set_attr "type" "fcmov,fcmov,multi,multi")
16178 (set_attr "mode" "DF")])
16180 (define_insn "*movdfcc_1_rex64"
16181 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16182 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16183 [(reg FLAGS_REG) (const_int 0)])
16184 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16185 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16186 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16187 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16189 fcmov%F1\t{%2, %0|%0, %2}
16190 fcmov%f1\t{%3, %0|%0, %3}
16191 cmov%O2%C1\t{%2, %0|%0, %2}
16192 cmov%O2%c1\t{%3, %0|%0, %3}"
16193 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16194 (set_attr "mode" "DF")])
16197 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16198 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16199 [(match_operand 4 "flags_reg_operand" "")
16201 (match_operand:DF 2 "nonimmediate_operand" "")
16202 (match_operand:DF 3 "nonimmediate_operand" "")))]
16203 "!TARGET_64BIT && reload_completed"
16204 [(set (match_dup 2)
16205 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16209 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16213 split_di (&operands[2], 2, &operands[5], &operands[7]);
16214 split_di (&operands[0], 1, &operands[2], &operands[3]);
16217 (define_insn "*movxfcc_1"
16218 [(set (match_operand:XF 0 "register_operand" "=f,f")
16219 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16220 [(reg FLAGS_REG) (const_int 0)])
16221 (match_operand:XF 2 "register_operand" "f,0")
16222 (match_operand:XF 3 "register_operand" "0,f")))]
16223 "TARGET_80387 && TARGET_CMOVE"
16225 fcmov%F1\t{%2, %0|%0, %2}
16226 fcmov%f1\t{%3, %0|%0, %3}"
16227 [(set_attr "type" "fcmov")
16228 (set_attr "mode" "XF")])
16230 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16231 ;; the scalar versions to have only XMM registers as operands.
16233 ;; XOP conditional move
16234 (define_insn "*xop_pcmov_<mode>"
16235 [(set (match_operand:MODEF 0 "register_operand" "=x")
16236 (if_then_else:MODEF
16237 (match_operand:MODEF 1 "register_operand" "x")
16238 (match_operand:MODEF 2 "register_operand" "x")
16239 (match_operand:MODEF 3 "register_operand" "x")))]
16241 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16242 [(set_attr "type" "sse4arg")])
16244 ;; These versions of the min/max patterns are intentionally ignorant of
16245 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16246 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16247 ;; are undefined in this condition, we're certain this is correct.
16249 (define_insn "*avx_<code><mode>3"
16250 [(set (match_operand:MODEF 0 "register_operand" "=x")
16252 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16253 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16254 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16255 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16256 [(set_attr "type" "sseadd")
16257 (set_attr "prefix" "vex")
16258 (set_attr "mode" "<MODE>")])
16260 (define_insn "<code><mode>3"
16261 [(set (match_operand:MODEF 0 "register_operand" "=x")
16263 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16264 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16265 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16266 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16267 [(set_attr "type" "sseadd")
16268 (set_attr "mode" "<MODE>")])
16270 ;; These versions of the min/max patterns implement exactly the operations
16271 ;; min = (op1 < op2 ? op1 : op2)
16272 ;; max = (!(op1 < op2) ? op1 : op2)
16273 ;; Their operands are not commutative, and thus they may be used in the
16274 ;; presence of -0.0 and NaN.
16276 (define_insn "*avx_ieee_smin<mode>3"
16277 [(set (match_operand:MODEF 0 "register_operand" "=x")
16279 [(match_operand:MODEF 1 "register_operand" "x")
16280 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16282 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16283 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16284 [(set_attr "type" "sseadd")
16285 (set_attr "prefix" "vex")
16286 (set_attr "mode" "<MODE>")])
16288 (define_insn "*ieee_smin<mode>3"
16289 [(set (match_operand:MODEF 0 "register_operand" "=x")
16291 [(match_operand:MODEF 1 "register_operand" "0")
16292 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16294 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16295 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16296 [(set_attr "type" "sseadd")
16297 (set_attr "mode" "<MODE>")])
16299 (define_insn "*avx_ieee_smax<mode>3"
16300 [(set (match_operand:MODEF 0 "register_operand" "=x")
16302 [(match_operand:MODEF 1 "register_operand" "0")
16303 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16305 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16306 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16307 [(set_attr "type" "sseadd")
16308 (set_attr "prefix" "vex")
16309 (set_attr "mode" "<MODE>")])
16311 (define_insn "*ieee_smax<mode>3"
16312 [(set (match_operand:MODEF 0 "register_operand" "=x")
16314 [(match_operand:MODEF 1 "register_operand" "0")
16315 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16317 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16318 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16319 [(set_attr "type" "sseadd")
16320 (set_attr "mode" "<MODE>")])
16322 ;; Make two stack loads independent:
16324 ;; fld %st(0) -> fld bb
16325 ;; fmul bb fmul %st(1), %st
16327 ;; Actually we only match the last two instructions for simplicity.
16329 [(set (match_operand 0 "fp_register_operand" "")
16330 (match_operand 1 "fp_register_operand" ""))
16332 (match_operator 2 "binary_fp_operator"
16334 (match_operand 3 "memory_operand" "")]))]
16335 "REGNO (operands[0]) != REGNO (operands[1])"
16336 [(set (match_dup 0) (match_dup 3))
16337 (set (match_dup 0) (match_dup 4))]
16339 ;; The % modifier is not operational anymore in peephole2's, so we have to
16340 ;; swap the operands manually in the case of addition and multiplication.
16341 "if (COMMUTATIVE_ARITH_P (operands[2]))
16342 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16343 operands[0], operands[1]);
16345 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16346 operands[1], operands[0]);")
16348 ;; Conditional addition patterns
16349 (define_expand "add<mode>cc"
16350 [(match_operand:SWI 0 "register_operand" "")
16351 (match_operand 1 "ordered_comparison_operator" "")
16352 (match_operand:SWI 2 "register_operand" "")
16353 (match_operand:SWI 3 "const_int_operand" "")]
16355 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16358 ;; Misc patterns (?)
16360 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16361 ;; Otherwise there will be nothing to keep
16363 ;; [(set (reg ebp) (reg esp))]
16364 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16365 ;; (clobber (eflags)]
16366 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16368 ;; in proper program order.
16370 (define_insn "pro_epilogue_adjust_stack_<mode>_1"
16371 [(set (match_operand:P 0 "register_operand" "=r,r")
16372 (plus:P (match_operand:P 1 "register_operand" "0,r")
16373 (match_operand:P 2 "<immediate_operand>" "<i>,<i>")))
16374 (clobber (reg:CC FLAGS_REG))
16375 (clobber (mem:BLK (scratch)))]
16378 switch (get_attr_type (insn))
16381 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16384 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16385 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16386 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16388 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16391 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16392 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16395 [(set (attr "type")
16396 (cond [(and (eq_attr "alternative" "0")
16397 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16398 (const_string "alu")
16399 (match_operand:<MODE> 2 "const0_operand" "")
16400 (const_string "imov")
16402 (const_string "lea")))
16403 (set (attr "length_immediate")
16404 (cond [(eq_attr "type" "imov")
16406 (and (eq_attr "type" "alu")
16407 (match_operand 2 "const128_operand" ""))
16410 (const_string "*")))
16411 (set_attr "mode" "<MODE>")])
16413 (define_insn "pro_epilogue_adjust_stack_di_2"
16414 [(set (match_operand:DI 0 "register_operand" "=r,r")
16415 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16416 (match_operand:DI 3 "immediate_operand" "i,i")))
16417 (use (match_operand:DI 2 "register_operand" "r,r"))
16418 (clobber (reg:CC FLAGS_REG))
16419 (clobber (mem:BLK (scratch)))]
16422 switch (get_attr_type (insn))
16425 return "add{q}\t{%2, %0|%0, %2}";
16428 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16429 return "lea{q}\t{%a2, %0|%0, %a2}";
16432 gcc_unreachable ();
16435 [(set_attr "type" "alu,lea")
16436 (set_attr "mode" "DI")])
16438 (define_insn "allocate_stack_worker_32"
16439 [(set (match_operand:SI 0 "register_operand" "=a")
16440 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16441 UNSPECV_STACK_PROBE))
16442 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16443 (clobber (reg:CC FLAGS_REG))]
16444 "!TARGET_64BIT && ix86_target_stack_probe ()"
16446 [(set_attr "type" "multi")
16447 (set_attr "length" "5")])
16449 (define_insn "allocate_stack_worker_64"
16450 [(set (match_operand:DI 0 "register_operand" "=a")
16451 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16452 UNSPECV_STACK_PROBE))
16453 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16454 (clobber (reg:DI R10_REG))
16455 (clobber (reg:DI R11_REG))
16456 (clobber (reg:CC FLAGS_REG))]
16457 "TARGET_64BIT && ix86_target_stack_probe ()"
16459 [(set_attr "type" "multi")
16460 (set_attr "length" "5")])
16462 (define_expand "allocate_stack"
16463 [(match_operand 0 "register_operand" "")
16464 (match_operand 1 "general_operand" "")]
16465 "ix86_target_stack_probe ()"
16469 #ifndef CHECK_STACK_LIMIT
16470 #define CHECK_STACK_LIMIT 0
16473 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16474 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16476 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16477 stack_pointer_rtx, 0, OPTAB_DIRECT);
16478 if (x != stack_pointer_rtx)
16479 emit_move_insn (stack_pointer_rtx, x);
16483 rtx (*gen_allocate_stack_worker) (rtx, rtx);
16486 gen_allocate_stack_worker = gen_allocate_stack_worker_64;
16488 gen_allocate_stack_worker = gen_allocate_stack_worker_32;
16490 x = copy_to_mode_reg (Pmode, operands[1]);
16491 emit_insn (gen_allocate_stack_worker (x, x));
16494 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16498 ;; Use IOR for stack probes, this is shorter.
16499 (define_expand "probe_stack"
16500 [(match_operand 0 "memory_operand" "")]
16503 rtx (*gen_ior3) (rtx, rtx, rtx);
16505 gen_ior3 = (GET_MODE (operands[0]) == DImode
16506 ? gen_iordi3 : gen_iorsi3);
16508 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16512 (define_insn "adjust_stack_and_probe<mode>"
16513 [(set (match_operand:P 0 "register_operand" "=r")
16514 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16515 UNSPECV_PROBE_STACK_RANGE))
16516 (set (reg:P SP_REG)
16517 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16518 (clobber (reg:CC FLAGS_REG))
16519 (clobber (mem:BLK (scratch)))]
16521 "* return output_adjust_stack_and_probe (operands[0]);"
16522 [(set_attr "type" "multi")])
16524 (define_insn "probe_stack_range<mode>"
16525 [(set (match_operand:P 0 "register_operand" "=r")
16526 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16527 (match_operand:P 2 "const_int_operand" "n")]
16528 UNSPECV_PROBE_STACK_RANGE))
16529 (clobber (reg:CC FLAGS_REG))]
16531 "* return output_probe_stack_range (operands[0], operands[2]);"
16532 [(set_attr "type" "multi")])
16534 (define_expand "builtin_setjmp_receiver"
16535 [(label_ref (match_operand 0 "" ""))]
16536 "!TARGET_64BIT && flag_pic"
16542 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16543 rtx label_rtx = gen_label_rtx ();
16544 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16545 xops[0] = xops[1] = picreg;
16546 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16547 ix86_expand_binary_operator (MINUS, SImode, xops);
16551 emit_insn (gen_set_got (pic_offset_table_rtx));
16555 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16558 [(set (match_operand 0 "register_operand" "")
16559 (match_operator 3 "promotable_binary_operator"
16560 [(match_operand 1 "register_operand" "")
16561 (match_operand 2 "aligned_operand" "")]))
16562 (clobber (reg:CC FLAGS_REG))]
16563 "! TARGET_PARTIAL_REG_STALL && reload_completed
16564 && ((GET_MODE (operands[0]) == HImode
16565 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16566 /* ??? next two lines just !satisfies_constraint_K (...) */
16567 || !CONST_INT_P (operands[2])
16568 || satisfies_constraint_K (operands[2])))
16569 || (GET_MODE (operands[0]) == QImode
16570 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16571 [(parallel [(set (match_dup 0)
16572 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16573 (clobber (reg:CC FLAGS_REG))])]
16574 "operands[0] = gen_lowpart (SImode, operands[0]);
16575 operands[1] = gen_lowpart (SImode, operands[1]);
16576 if (GET_CODE (operands[3]) != ASHIFT)
16577 operands[2] = gen_lowpart (SImode, operands[2]);
16578 PUT_MODE (operands[3], SImode);")
16580 ; Promote the QImode tests, as i386 has encoding of the AND
16581 ; instruction with 32-bit sign-extended immediate and thus the
16582 ; instruction size is unchanged, except in the %eax case for
16583 ; which it is increased by one byte, hence the ! optimize_size.
16585 [(set (match_operand 0 "flags_reg_operand" "")
16586 (match_operator 2 "compare_operator"
16587 [(and (match_operand 3 "aligned_operand" "")
16588 (match_operand 4 "const_int_operand" ""))
16590 (set (match_operand 1 "register_operand" "")
16591 (and (match_dup 3) (match_dup 4)))]
16592 "! TARGET_PARTIAL_REG_STALL && reload_completed
16593 && optimize_insn_for_speed_p ()
16594 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16595 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16596 /* Ensure that the operand will remain sign-extended immediate. */
16597 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16598 [(parallel [(set (match_dup 0)
16599 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16602 (and:SI (match_dup 3) (match_dup 4)))])]
16605 = gen_int_mode (INTVAL (operands[4])
16606 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16607 operands[1] = gen_lowpart (SImode, operands[1]);
16608 operands[3] = gen_lowpart (SImode, operands[3]);
16611 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16612 ; the TEST instruction with 32-bit sign-extended immediate and thus
16613 ; the instruction size would at least double, which is not what we
16614 ; want even with ! optimize_size.
16616 [(set (match_operand 0 "flags_reg_operand" "")
16617 (match_operator 1 "compare_operator"
16618 [(and (match_operand:HI 2 "aligned_operand" "")
16619 (match_operand:HI 3 "const_int_operand" ""))
16621 "! TARGET_PARTIAL_REG_STALL && reload_completed
16622 && ! TARGET_FAST_PREFIX
16623 && optimize_insn_for_speed_p ()
16624 /* Ensure that the operand will remain sign-extended immediate. */
16625 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16626 [(set (match_dup 0)
16627 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16631 = gen_int_mode (INTVAL (operands[3])
16632 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16633 operands[2] = gen_lowpart (SImode, operands[2]);
16637 [(set (match_operand 0 "register_operand" "")
16638 (neg (match_operand 1 "register_operand" "")))
16639 (clobber (reg:CC FLAGS_REG))]
16640 "! TARGET_PARTIAL_REG_STALL && reload_completed
16641 && (GET_MODE (operands[0]) == HImode
16642 || (GET_MODE (operands[0]) == QImode
16643 && (TARGET_PROMOTE_QImode
16644 || optimize_insn_for_size_p ())))"
16645 [(parallel [(set (match_dup 0)
16646 (neg:SI (match_dup 1)))
16647 (clobber (reg:CC FLAGS_REG))])]
16648 "operands[0] = gen_lowpart (SImode, operands[0]);
16649 operands[1] = gen_lowpart (SImode, operands[1]);")
16652 [(set (match_operand 0 "register_operand" "")
16653 (not (match_operand 1 "register_operand" "")))]
16654 "! TARGET_PARTIAL_REG_STALL && reload_completed
16655 && (GET_MODE (operands[0]) == HImode
16656 || (GET_MODE (operands[0]) == QImode
16657 && (TARGET_PROMOTE_QImode
16658 || optimize_insn_for_size_p ())))"
16659 [(set (match_dup 0)
16660 (not:SI (match_dup 1)))]
16661 "operands[0] = gen_lowpart (SImode, operands[0]);
16662 operands[1] = gen_lowpart (SImode, operands[1]);")
16665 [(set (match_operand 0 "register_operand" "")
16666 (if_then_else (match_operator 1 "ordered_comparison_operator"
16667 [(reg FLAGS_REG) (const_int 0)])
16668 (match_operand 2 "register_operand" "")
16669 (match_operand 3 "register_operand" "")))]
16670 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16671 && (GET_MODE (operands[0]) == HImode
16672 || (GET_MODE (operands[0]) == QImode
16673 && (TARGET_PROMOTE_QImode
16674 || optimize_insn_for_size_p ())))"
16675 [(set (match_dup 0)
16676 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16677 "operands[0] = gen_lowpart (SImode, operands[0]);
16678 operands[2] = gen_lowpart (SImode, operands[2]);
16679 operands[3] = gen_lowpart (SImode, operands[3]);")
16682 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16683 ;; transform a complex memory operation into two memory to register operations.
16685 ;; Don't push memory operands
16687 [(set (match_operand:SI 0 "push_operand" "")
16688 (match_operand:SI 1 "memory_operand" ""))
16689 (match_scratch:SI 2 "r")]
16690 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16691 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16692 [(set (match_dup 2) (match_dup 1))
16693 (set (match_dup 0) (match_dup 2))]
16697 [(set (match_operand:DI 0 "push_operand" "")
16698 (match_operand:DI 1 "memory_operand" ""))
16699 (match_scratch:DI 2 "r")]
16700 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16701 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16702 [(set (match_dup 2) (match_dup 1))
16703 (set (match_dup 0) (match_dup 2))]
16706 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16709 [(set (match_operand:SF 0 "push_operand" "")
16710 (match_operand:SF 1 "memory_operand" ""))
16711 (match_scratch:SF 2 "r")]
16712 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16713 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16714 [(set (match_dup 2) (match_dup 1))
16715 (set (match_dup 0) (match_dup 2))]
16719 [(set (match_operand:HI 0 "push_operand" "")
16720 (match_operand:HI 1 "memory_operand" ""))
16721 (match_scratch:HI 2 "r")]
16722 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16723 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16724 [(set (match_dup 2) (match_dup 1))
16725 (set (match_dup 0) (match_dup 2))]
16729 [(set (match_operand:QI 0 "push_operand" "")
16730 (match_operand:QI 1 "memory_operand" ""))
16731 (match_scratch:QI 2 "q")]
16732 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16733 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16734 [(set (match_dup 2) (match_dup 1))
16735 (set (match_dup 0) (match_dup 2))]
16738 ;; Don't move an immediate directly to memory when the instruction
16741 [(match_scratch:SI 1 "r")
16742 (set (match_operand:SI 0 "memory_operand" "")
16744 "optimize_insn_for_speed_p ()
16745 && ! TARGET_USE_MOV0
16746 && TARGET_SPLIT_LONG_MOVES
16747 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16748 && peep2_regno_dead_p (0, FLAGS_REG)"
16749 [(parallel [(set (match_dup 1) (const_int 0))
16750 (clobber (reg:CC FLAGS_REG))])
16751 (set (match_dup 0) (match_dup 1))]
16755 [(match_scratch:HI 1 "r")
16756 (set (match_operand:HI 0 "memory_operand" "")
16758 "optimize_insn_for_speed_p ()
16759 && ! TARGET_USE_MOV0
16760 && TARGET_SPLIT_LONG_MOVES
16761 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16762 && peep2_regno_dead_p (0, FLAGS_REG)"
16763 [(parallel [(set (match_dup 2) (const_int 0))
16764 (clobber (reg:CC FLAGS_REG))])
16765 (set (match_dup 0) (match_dup 1))]
16766 "operands[2] = gen_lowpart (SImode, operands[1]);")
16769 [(match_scratch:QI 1 "q")
16770 (set (match_operand:QI 0 "memory_operand" "")
16772 "optimize_insn_for_speed_p ()
16773 && ! TARGET_USE_MOV0
16774 && TARGET_SPLIT_LONG_MOVES
16775 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16776 && peep2_regno_dead_p (0, FLAGS_REG)"
16777 [(parallel [(set (match_dup 2) (const_int 0))
16778 (clobber (reg:CC FLAGS_REG))])
16779 (set (match_dup 0) (match_dup 1))]
16780 "operands[2] = gen_lowpart (SImode, operands[1]);")
16783 [(match_scratch:SI 2 "r")
16784 (set (match_operand:SI 0 "memory_operand" "")
16785 (match_operand:SI 1 "immediate_operand" ""))]
16786 "optimize_insn_for_speed_p ()
16787 && TARGET_SPLIT_LONG_MOVES
16788 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16789 [(set (match_dup 2) (match_dup 1))
16790 (set (match_dup 0) (match_dup 2))]
16794 [(match_scratch:HI 2 "r")
16795 (set (match_operand:HI 0 "memory_operand" "")
16796 (match_operand:HI 1 "immediate_operand" ""))]
16797 "optimize_insn_for_speed_p ()
16798 && TARGET_SPLIT_LONG_MOVES
16799 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16800 [(set (match_dup 2) (match_dup 1))
16801 (set (match_dup 0) (match_dup 2))]
16805 [(match_scratch:QI 2 "q")
16806 (set (match_operand:QI 0 "memory_operand" "")
16807 (match_operand:QI 1 "immediate_operand" ""))]
16808 "optimize_insn_for_speed_p ()
16809 && TARGET_SPLIT_LONG_MOVES
16810 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16811 [(set (match_dup 2) (match_dup 1))
16812 (set (match_dup 0) (match_dup 2))]
16815 ;; Don't compare memory with zero, load and use a test instead.
16817 [(set (match_operand 0 "flags_reg_operand" "")
16818 (match_operator 1 "compare_operator"
16819 [(match_operand:SI 2 "memory_operand" "")
16821 (match_scratch:SI 3 "r")]
16822 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16823 [(set (match_dup 3) (match_dup 2))
16824 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
16827 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16828 ;; Don't split NOTs with a displacement operand, because resulting XOR
16829 ;; will not be pairable anyway.
16831 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16832 ;; represented using a modRM byte. The XOR replacement is long decoded,
16833 ;; so this split helps here as well.
16835 ;; Note: Can't do this as a regular split because we can't get proper
16836 ;; lifetime information then.
16839 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16840 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
16841 "optimize_insn_for_speed_p ()
16842 && ((TARGET_NOT_UNPAIRABLE
16843 && (!MEM_P (operands[0])
16844 || !memory_displacement_operand (operands[0], SImode)))
16845 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
16846 && peep2_regno_dead_p (0, FLAGS_REG)"
16847 [(parallel [(set (match_dup 0)
16848 (xor:SI (match_dup 1) (const_int -1)))
16849 (clobber (reg:CC FLAGS_REG))])]
16853 [(set (match_operand:HI 0 "nonimmediate_operand" "")
16854 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
16855 "optimize_insn_for_speed_p ()
16856 && ((TARGET_NOT_UNPAIRABLE
16857 && (!MEM_P (operands[0])
16858 || !memory_displacement_operand (operands[0], HImode)))
16859 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
16860 && peep2_regno_dead_p (0, FLAGS_REG)"
16861 [(parallel [(set (match_dup 0)
16862 (xor:HI (match_dup 1) (const_int -1)))
16863 (clobber (reg:CC FLAGS_REG))])]
16867 [(set (match_operand:QI 0 "nonimmediate_operand" "")
16868 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
16869 "optimize_insn_for_speed_p ()
16870 && ((TARGET_NOT_UNPAIRABLE
16871 && (!MEM_P (operands[0])
16872 || !memory_displacement_operand (operands[0], QImode)))
16873 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
16874 && peep2_regno_dead_p (0, FLAGS_REG)"
16875 [(parallel [(set (match_dup 0)
16876 (xor:QI (match_dup 1) (const_int -1)))
16877 (clobber (reg:CC FLAGS_REG))])]
16880 ;; Non pairable "test imm, reg" instructions can be translated to
16881 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16882 ;; byte opcode instead of two, have a short form for byte operands),
16883 ;; so do it for other CPUs as well. Given that the value was dead,
16884 ;; this should not create any new dependencies. Pass on the sub-word
16885 ;; versions if we're concerned about partial register stalls.
16888 [(set (match_operand 0 "flags_reg_operand" "")
16889 (match_operator 1 "compare_operator"
16890 [(and:SI (match_operand:SI 2 "register_operand" "")
16891 (match_operand:SI 3 "immediate_operand" ""))
16893 "ix86_match_ccmode (insn, CCNOmode)
16894 && (true_regnum (operands[2]) != AX_REG
16895 || satisfies_constraint_K (operands[3]))
16896 && peep2_reg_dead_p (1, operands[2])"
16898 [(set (match_dup 0)
16899 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16902 (and:SI (match_dup 2) (match_dup 3)))])]
16905 ;; We don't need to handle HImode case, because it will be promoted to SImode
16906 ;; on ! TARGET_PARTIAL_REG_STALL
16909 [(set (match_operand 0 "flags_reg_operand" "")
16910 (match_operator 1 "compare_operator"
16911 [(and:QI (match_operand:QI 2 "register_operand" "")
16912 (match_operand:QI 3 "immediate_operand" ""))
16914 "! TARGET_PARTIAL_REG_STALL
16915 && ix86_match_ccmode (insn, CCNOmode)
16916 && true_regnum (operands[2]) != AX_REG
16917 && peep2_reg_dead_p (1, operands[2])"
16919 [(set (match_dup 0)
16920 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16923 (and:QI (match_dup 2) (match_dup 3)))])]
16927 [(set (match_operand 0 "flags_reg_operand" "")
16928 (match_operator 1 "compare_operator"
16931 (match_operand 2 "ext_register_operand" "")
16934 (match_operand 3 "const_int_operand" ""))
16936 "! TARGET_PARTIAL_REG_STALL
16937 && ix86_match_ccmode (insn, CCNOmode)
16938 && true_regnum (operands[2]) != AX_REG
16939 && peep2_reg_dead_p (1, operands[2])"
16940 [(parallel [(set (match_dup 0)
16949 (set (zero_extract:SI (match_dup 2)
16960 ;; Don't do logical operations with memory inputs.
16962 [(match_scratch:SI 2 "r")
16963 (parallel [(set (match_operand:SI 0 "register_operand" "")
16964 (match_operator:SI 3 "arith_or_logical_operator"
16966 (match_operand:SI 1 "memory_operand" "")]))
16967 (clobber (reg:CC FLAGS_REG))])]
16968 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16969 [(set (match_dup 2) (match_dup 1))
16970 (parallel [(set (match_dup 0)
16971 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16972 (clobber (reg:CC FLAGS_REG))])]
16976 [(match_scratch:SI 2 "r")
16977 (parallel [(set (match_operand:SI 0 "register_operand" "")
16978 (match_operator:SI 3 "arith_or_logical_operator"
16979 [(match_operand:SI 1 "memory_operand" "")
16981 (clobber (reg:CC FLAGS_REG))])]
16982 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16983 [(set (match_dup 2) (match_dup 1))
16984 (parallel [(set (match_dup 0)
16985 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16986 (clobber (reg:CC FLAGS_REG))])]
16989 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16990 ;; refers to the destination of the load!
16993 [(set (match_operand:SI 0 "register_operand" "")
16994 (match_operand:SI 1 "register_operand" ""))
16995 (parallel [(set (match_dup 0)
16996 (match_operator:SI 3 "commutative_operator"
16998 (match_operand:SI 2 "memory_operand" "")]))
16999 (clobber (reg:CC FLAGS_REG))])]
17000 "REGNO (operands[0]) != REGNO (operands[1])
17001 && GENERAL_REGNO_P (REGNO (operands[0]))
17002 && GENERAL_REGNO_P (REGNO (operands[1]))"
17003 [(set (match_dup 0) (match_dup 4))
17004 (parallel [(set (match_dup 0)
17005 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17006 (clobber (reg:CC FLAGS_REG))])]
17007 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17010 [(set (match_operand 0 "register_operand" "")
17011 (match_operand 1 "register_operand" ""))
17013 (match_operator 3 "commutative_operator"
17015 (match_operand 2 "memory_operand" "")]))]
17016 "REGNO (operands[0]) != REGNO (operands[1])
17017 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17018 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17019 [(set (match_dup 0) (match_dup 2))
17021 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17024 ; Don't do logical operations with memory outputs
17026 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17027 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17028 ; the same decoder scheduling characteristics as the original.
17031 [(match_scratch:SI 2 "r")
17032 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17033 (match_operator:SI 3 "arith_or_logical_operator"
17035 (match_operand:SI 1 "nonmemory_operand" "")]))
17036 (clobber (reg:CC FLAGS_REG))])]
17037 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17038 /* Do not split stack checking probes. */
17039 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17040 [(set (match_dup 2) (match_dup 0))
17041 (parallel [(set (match_dup 2)
17042 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17043 (clobber (reg:CC FLAGS_REG))])
17044 (set (match_dup 0) (match_dup 2))]
17048 [(match_scratch:SI 2 "r")
17049 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17050 (match_operator:SI 3 "arith_or_logical_operator"
17051 [(match_operand:SI 1 "nonmemory_operand" "")
17053 (clobber (reg:CC FLAGS_REG))])]
17054 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17055 /* Do not split stack checking probes. */
17056 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17057 [(set (match_dup 2) (match_dup 0))
17058 (parallel [(set (match_dup 2)
17059 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17060 (clobber (reg:CC FLAGS_REG))])
17061 (set (match_dup 0) (match_dup 2))]
17064 ;; Attempt to always use XOR for zeroing registers.
17066 [(set (match_operand 0 "register_operand" "")
17067 (match_operand 1 "const0_operand" ""))]
17068 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17069 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17070 && GENERAL_REG_P (operands[0])
17071 && peep2_regno_dead_p (0, FLAGS_REG)"
17072 [(parallel [(set (match_dup 0) (const_int 0))
17073 (clobber (reg:CC FLAGS_REG))])]
17075 operands[0] = gen_lowpart (word_mode, operands[0]);
17079 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17081 "(GET_MODE (operands[0]) == QImode
17082 || GET_MODE (operands[0]) == HImode)
17083 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17084 && peep2_regno_dead_p (0, FLAGS_REG)"
17085 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17086 (clobber (reg:CC FLAGS_REG))])])
17088 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17090 [(set (match_operand 0 "register_operand" "")
17092 "(GET_MODE (operands[0]) == HImode
17093 || GET_MODE (operands[0]) == SImode
17094 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17095 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17096 && peep2_regno_dead_p (0, FLAGS_REG)"
17097 [(parallel [(set (match_dup 0) (const_int -1))
17098 (clobber (reg:CC FLAGS_REG))])]
17099 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17102 ;; Attempt to convert simple leas to adds. These can be created by
17105 [(set (match_operand:SI 0 "register_operand" "")
17106 (plus:SI (match_dup 0)
17107 (match_operand:SI 1 "nonmemory_operand" "")))]
17108 "peep2_regno_dead_p (0, FLAGS_REG)"
17109 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17110 (clobber (reg:CC FLAGS_REG))])]
17114 [(set (match_operand:SI 0 "register_operand" "")
17115 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17116 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17117 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17118 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17119 (clobber (reg:CC FLAGS_REG))])]
17120 "operands[2] = gen_lowpart (SImode, operands[2]);")
17123 [(set (match_operand:DI 0 "register_operand" "")
17124 (plus:DI (match_dup 0)
17125 (match_operand:DI 1 "x86_64_general_operand" "")))]
17126 "peep2_regno_dead_p (0, FLAGS_REG)"
17127 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17128 (clobber (reg:CC FLAGS_REG))])]
17132 [(set (match_operand:SI 0 "register_operand" "")
17133 (mult:SI (match_dup 0)
17134 (match_operand:SI 1 "const_int_operand" "")))]
17135 "exact_log2 (INTVAL (operands[1])) >= 0
17136 && peep2_regno_dead_p (0, FLAGS_REG)"
17137 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17138 (clobber (reg:CC FLAGS_REG))])]
17139 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17142 [(set (match_operand:DI 0 "register_operand" "")
17143 (mult:DI (match_dup 0)
17144 (match_operand:DI 1 "const_int_operand" "")))]
17145 "exact_log2 (INTVAL (operands[1])) >= 0
17146 && peep2_regno_dead_p (0, FLAGS_REG)"
17147 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17148 (clobber (reg:CC FLAGS_REG))])]
17149 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17152 [(set (match_operand:SI 0 "register_operand" "")
17153 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17154 (match_operand:DI 2 "const_int_operand" "")) 0))]
17155 "exact_log2 (INTVAL (operands[2])) >= 0
17156 && REGNO (operands[0]) == REGNO (operands[1])
17157 && peep2_regno_dead_p (0, FLAGS_REG)"
17158 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17159 (clobber (reg:CC FLAGS_REG))])]
17160 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17162 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17163 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17164 ;; many CPUs it is also faster, since special hardware to avoid esp
17165 ;; dependencies is present.
17167 ;; While some of these conversions may be done using splitters, we use peepholes
17168 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17170 ;; Convert prologue esp subtractions to push.
17171 ;; We need register to push. In order to keep verify_flow_info happy we have
17173 ;; - use scratch and clobber it in order to avoid dependencies
17174 ;; - use already live register
17175 ;; We can't use the second way right now, since there is no reliable way how to
17176 ;; verify that given register is live. First choice will also most likely in
17177 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17178 ;; call clobbered registers are dead. We may want to use base pointer as an
17179 ;; alternative when no register is available later.
17182 [(match_scratch:SI 0 "r")
17183 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17184 (clobber (reg:CC FLAGS_REG))
17185 (clobber (mem:BLK (scratch)))])]
17186 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17187 [(clobber (match_dup 0))
17188 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17189 (clobber (mem:BLK (scratch)))])])
17192 [(match_scratch:SI 0 "r")
17193 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17194 (clobber (reg:CC FLAGS_REG))
17195 (clobber (mem:BLK (scratch)))])]
17196 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17197 [(clobber (match_dup 0))
17198 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17199 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17200 (clobber (mem:BLK (scratch)))])])
17202 ;; Convert esp subtractions to push.
17204 [(match_scratch:SI 0 "r")
17205 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17206 (clobber (reg:CC FLAGS_REG))])]
17207 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17208 [(clobber (match_dup 0))
17209 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17212 [(match_scratch:SI 0 "r")
17213 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17214 (clobber (reg:CC FLAGS_REG))])]
17215 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17216 [(clobber (match_dup 0))
17217 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17218 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17220 ;; Convert epilogue deallocator to pop.
17222 [(match_scratch:SI 0 "r")
17223 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17224 (clobber (reg:CC FLAGS_REG))
17225 (clobber (mem:BLK (scratch)))])]
17226 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17227 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17228 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17229 (clobber (mem:BLK (scratch)))])]
17232 ;; Two pops case is tricky, since pop causes dependency on destination register.
17233 ;; We use two registers if available.
17235 [(match_scratch:SI 0 "r")
17236 (match_scratch:SI 1 "r")
17237 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17238 (clobber (reg:CC FLAGS_REG))
17239 (clobber (mem:BLK (scratch)))])]
17240 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17241 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17242 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17243 (clobber (mem:BLK (scratch)))])
17244 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17245 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17249 [(match_scratch:SI 0 "r")
17250 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17251 (clobber (reg:CC FLAGS_REG))
17252 (clobber (mem:BLK (scratch)))])]
17253 "optimize_insn_for_size_p ()"
17254 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17255 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17256 (clobber (mem:BLK (scratch)))])
17257 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17258 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17261 ;; Convert esp additions to pop.
17263 [(match_scratch:SI 0 "r")
17264 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17265 (clobber (reg:CC FLAGS_REG))])]
17267 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17268 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17271 ;; Two pops case is tricky, since pop causes dependency on destination register.
17272 ;; We use two registers if available.
17274 [(match_scratch:SI 0 "r")
17275 (match_scratch:SI 1 "r")
17276 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17277 (clobber (reg:CC FLAGS_REG))])]
17279 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17280 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17281 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17282 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17286 [(match_scratch:SI 0 "r")
17287 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17288 (clobber (reg:CC FLAGS_REG))])]
17289 "optimize_insn_for_size_p ()"
17290 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17291 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17292 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17293 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17296 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17297 ;; required and register dies. Similarly for 128 to -128.
17299 [(set (match_operand 0 "flags_reg_operand" "")
17300 (match_operator 1 "compare_operator"
17301 [(match_operand 2 "register_operand" "")
17302 (match_operand 3 "const_int_operand" "")]))]
17303 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17304 && incdec_operand (operands[3], GET_MODE (operands[3])))
17305 || (!TARGET_FUSE_CMP_AND_BRANCH
17306 && INTVAL (operands[3]) == 128))
17307 && ix86_match_ccmode (insn, CCGCmode)
17308 && peep2_reg_dead_p (1, operands[2])"
17309 [(parallel [(set (match_dup 0)
17310 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17311 (clobber (match_dup 2))])]
17315 [(match_scratch:DI 0 "r")
17316 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17317 (clobber (reg:CC FLAGS_REG))
17318 (clobber (mem:BLK (scratch)))])]
17319 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17320 [(clobber (match_dup 0))
17321 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17322 (clobber (mem:BLK (scratch)))])])
17325 [(match_scratch:DI 0 "r")
17326 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17327 (clobber (reg:CC FLAGS_REG))
17328 (clobber (mem:BLK (scratch)))])]
17329 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17330 [(clobber (match_dup 0))
17331 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17332 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17333 (clobber (mem:BLK (scratch)))])])
17335 ;; Convert esp subtractions to push.
17337 [(match_scratch:DI 0 "r")
17338 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17339 (clobber (reg:CC FLAGS_REG))])]
17340 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17341 [(clobber (match_dup 0))
17342 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17345 [(match_scratch:DI 0 "r")
17346 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17347 (clobber (reg:CC FLAGS_REG))])]
17348 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17349 [(clobber (match_dup 0))
17350 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17351 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17353 ;; Convert epilogue deallocator to pop.
17355 [(match_scratch:DI 0 "r")
17356 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17357 (clobber (reg:CC FLAGS_REG))
17358 (clobber (mem:BLK (scratch)))])]
17359 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17360 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17361 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17362 (clobber (mem:BLK (scratch)))])]
17365 ;; Two pops case is tricky, since pop causes dependency on destination register.
17366 ;; We use two registers if available.
17368 [(match_scratch:DI 0 "r")
17369 (match_scratch:DI 1 "r")
17370 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17371 (clobber (reg:CC FLAGS_REG))
17372 (clobber (mem:BLK (scratch)))])]
17373 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17374 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17375 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17376 (clobber (mem:BLK (scratch)))])
17377 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17378 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17382 [(match_scratch:DI 0 "r")
17383 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17384 (clobber (reg:CC FLAGS_REG))
17385 (clobber (mem:BLK (scratch)))])]
17386 "optimize_insn_for_size_p ()"
17387 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17388 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17389 (clobber (mem:BLK (scratch)))])
17390 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17391 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17394 ;; Convert esp additions to pop.
17396 [(match_scratch:DI 0 "r")
17397 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17398 (clobber (reg:CC FLAGS_REG))])]
17400 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17401 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17404 ;; Two pops case is tricky, since pop causes dependency on destination register.
17405 ;; We use two registers if available.
17407 [(match_scratch:DI 0 "r")
17408 (match_scratch:DI 1 "r")
17409 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17410 (clobber (reg:CC FLAGS_REG))])]
17412 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17413 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17414 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17415 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17419 [(match_scratch:DI 0 "r")
17420 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17421 (clobber (reg:CC FLAGS_REG))])]
17422 "optimize_insn_for_size_p ()"
17423 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17424 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17425 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17426 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17429 ;; Convert imul by three, five and nine into lea
17432 [(set (match_operand:SI 0 "register_operand" "")
17433 (mult:SI (match_operand:SI 1 "register_operand" "")
17434 (match_operand:SI 2 "const_int_operand" "")))
17435 (clobber (reg:CC FLAGS_REG))])]
17436 "INTVAL (operands[2]) == 3
17437 || INTVAL (operands[2]) == 5
17438 || INTVAL (operands[2]) == 9"
17439 [(set (match_dup 0)
17440 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17442 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17446 [(set (match_operand:SI 0 "register_operand" "")
17447 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17448 (match_operand:SI 2 "const_int_operand" "")))
17449 (clobber (reg:CC FLAGS_REG))])]
17450 "optimize_insn_for_speed_p ()
17451 && (INTVAL (operands[2]) == 3
17452 || INTVAL (operands[2]) == 5
17453 || INTVAL (operands[2]) == 9)"
17454 [(set (match_dup 0) (match_dup 1))
17456 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17458 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17462 [(set (match_operand:DI 0 "register_operand" "")
17463 (mult:DI (match_operand:DI 1 "register_operand" "")
17464 (match_operand:DI 2 "const_int_operand" "")))
17465 (clobber (reg:CC FLAGS_REG))])]
17467 && (INTVAL (operands[2]) == 3
17468 || INTVAL (operands[2]) == 5
17469 || INTVAL (operands[2]) == 9)"
17470 [(set (match_dup 0)
17471 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17473 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17477 [(set (match_operand:DI 0 "register_operand" "")
17478 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17479 (match_operand:DI 2 "const_int_operand" "")))
17480 (clobber (reg:CC FLAGS_REG))])]
17482 && optimize_insn_for_speed_p ()
17483 && (INTVAL (operands[2]) == 3
17484 || INTVAL (operands[2]) == 5
17485 || INTVAL (operands[2]) == 9)"
17486 [(set (match_dup 0) (match_dup 1))
17488 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17490 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17492 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17493 ;; imul $32bit_imm, reg, reg is direct decoded.
17495 [(match_scratch:DI 3 "r")
17496 (parallel [(set (match_operand:DI 0 "register_operand" "")
17497 (mult:DI (match_operand:DI 1 "memory_operand" "")
17498 (match_operand:DI 2 "immediate_operand" "")))
17499 (clobber (reg:CC FLAGS_REG))])]
17500 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17501 && !satisfies_constraint_K (operands[2])"
17502 [(set (match_dup 3) (match_dup 1))
17503 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17504 (clobber (reg:CC FLAGS_REG))])]
17508 [(match_scratch:SI 3 "r")
17509 (parallel [(set (match_operand:SI 0 "register_operand" "")
17510 (mult:SI (match_operand:SI 1 "memory_operand" "")
17511 (match_operand:SI 2 "immediate_operand" "")))
17512 (clobber (reg:CC FLAGS_REG))])]
17513 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17514 && !satisfies_constraint_K (operands[2])"
17515 [(set (match_dup 3) (match_dup 1))
17516 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
17517 (clobber (reg:CC FLAGS_REG))])]
17521 [(match_scratch:SI 3 "r")
17522 (parallel [(set (match_operand:DI 0 "register_operand" "")
17524 (mult:SI (match_operand:SI 1 "memory_operand" "")
17525 (match_operand:SI 2 "immediate_operand" ""))))
17526 (clobber (reg:CC FLAGS_REG))])]
17527 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17528 && !satisfies_constraint_K (operands[2])"
17529 [(set (match_dup 3) (match_dup 1))
17530 (parallel [(set (match_dup 0)
17531 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17532 (clobber (reg:CC FLAGS_REG))])]
17535 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17536 ;; Convert it into imul reg, reg
17537 ;; It would be better to force assembler to encode instruction using long
17538 ;; immediate, but there is apparently no way to do so.
17540 [(parallel [(set (match_operand:DI 0 "register_operand" "")
17541 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17542 (match_operand:DI 2 "const_int_operand" "")))
17543 (clobber (reg:CC FLAGS_REG))])
17544 (match_scratch:DI 3 "r")]
17545 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17546 && satisfies_constraint_K (operands[2])"
17547 [(set (match_dup 3) (match_dup 2))
17548 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
17549 (clobber (reg:CC FLAGS_REG))])]
17551 if (!rtx_equal_p (operands[0], operands[1]))
17552 emit_move_insn (operands[0], operands[1]);
17556 [(parallel [(set (match_operand:SI 0 "register_operand" "")
17557 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17558 (match_operand:SI 2 "const_int_operand" "")))
17559 (clobber (reg:CC FLAGS_REG))])
17560 (match_scratch:SI 3 "r")]
17561 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17562 && satisfies_constraint_K (operands[2])"
17563 [(set (match_dup 3) (match_dup 2))
17564 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
17565 (clobber (reg:CC FLAGS_REG))])]
17567 if (!rtx_equal_p (operands[0], operands[1]))
17568 emit_move_insn (operands[0], operands[1]);
17572 [(parallel [(set (match_operand:HI 0 "register_operand" "")
17573 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
17574 (match_operand:HI 2 "immediate_operand" "")))
17575 (clobber (reg:CC FLAGS_REG))])
17576 (match_scratch:HI 3 "r")]
17577 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
17578 [(set (match_dup 3) (match_dup 2))
17579 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
17580 (clobber (reg:CC FLAGS_REG))])]
17582 if (!rtx_equal_p (operands[0], operands[1]))
17583 emit_move_insn (operands[0], operands[1]);
17586 ;; After splitting up read-modify operations, array accesses with memory
17587 ;; operands might end up in form:
17589 ;; movl 4(%esp), %edx
17591 ;; instead of pre-splitting:
17593 ;; addl 4(%esp), %eax
17595 ;; movl 4(%esp), %edx
17596 ;; leal (%edx,%eax,4), %eax
17599 [(match_scratch:P 5 "r")
17600 (parallel [(set (match_operand 0 "register_operand" "")
17601 (ashift (match_operand 1 "register_operand" "")
17602 (match_operand 2 "const_int_operand" "")))
17603 (clobber (reg:CC FLAGS_REG))])
17604 (parallel [(set (match_operand 3 "register_operand" "")
17605 (plus (match_dup 0)
17606 (match_operand 4 "x86_64_general_operand" "")))
17607 (clobber (reg:CC FLAGS_REG))])]
17608 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17609 /* Validate MODE for lea. */
17610 && ((!TARGET_PARTIAL_REG_STALL
17611 && (GET_MODE (operands[0]) == QImode
17612 || GET_MODE (operands[0]) == HImode))
17613 || GET_MODE (operands[0]) == SImode
17614 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17615 && (rtx_equal_p (operands[0], operands[3])
17616 || peep2_reg_dead_p (2, operands[0]))
17617 /* We reorder load and the shift. */
17618 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17619 [(set (match_dup 5) (match_dup 4))
17620 (set (match_dup 0) (match_dup 1))]
17622 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17623 int scale = 1 << INTVAL (operands[2]);
17624 rtx index = gen_lowpart (Pmode, operands[1]);
17625 rtx base = gen_lowpart (Pmode, operands[5]);
17626 rtx dest = gen_lowpart (mode, operands[3]);
17628 operands[1] = gen_rtx_PLUS (Pmode, base,
17629 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17630 operands[5] = base;
17633 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17634 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17636 operands[0] = dest;
17639 ;; Call-value patterns last so that the wildcard operand does not
17640 ;; disrupt insn-recog's switch tables.
17642 (define_insn "*call_value_pop_0"
17643 [(set (match_operand 0 "" "")
17644 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17645 (match_operand:SI 2 "" "")))
17646 (set (reg:SI SP_REG)
17647 (plus:SI (reg:SI SP_REG)
17648 (match_operand:SI 3 "immediate_operand" "")))]
17651 if (SIBLING_CALL_P (insn))
17654 return "call\t%P1";
17656 [(set_attr "type" "callv")])
17658 (define_insn "*call_value_pop_1"
17659 [(set (match_operand 0 "" "")
17660 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17661 (match_operand:SI 2 "" "")))
17662 (set (reg:SI SP_REG)
17663 (plus:SI (reg:SI SP_REG)
17664 (match_operand:SI 3 "immediate_operand" "i")))]
17665 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17667 if (constant_call_address_operand (operands[1], Pmode))
17668 return "call\t%P1";
17669 return "call\t%A1";
17671 [(set_attr "type" "callv")])
17673 (define_insn "*sibcall_value_pop_1"
17674 [(set (match_operand 0 "" "")
17675 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17676 (match_operand:SI 2 "" "")))
17677 (set (reg:SI SP_REG)
17678 (plus:SI (reg:SI SP_REG)
17679 (match_operand:SI 3 "immediate_operand" "i,i")))]
17680 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17684 [(set_attr "type" "callv")])
17686 (define_insn "*call_value_0"
17687 [(set (match_operand 0 "" "")
17688 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17689 (match_operand:SI 2 "" "")))]
17692 if (SIBLING_CALL_P (insn))
17695 return "call\t%P1";
17697 [(set_attr "type" "callv")])
17699 (define_insn "*call_value_0_rex64"
17700 [(set (match_operand 0 "" "")
17701 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17702 (match_operand:DI 2 "const_int_operand" "")))]
17705 if (SIBLING_CALL_P (insn))
17708 return "call\t%P1";
17710 [(set_attr "type" "callv")])
17712 (define_insn "*call_value_0_rex64_ms_sysv"
17713 [(set (match_operand 0 "" "")
17714 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17715 (match_operand:DI 2 "const_int_operand" "")))
17716 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17717 (clobber (reg:TI XMM6_REG))
17718 (clobber (reg:TI XMM7_REG))
17719 (clobber (reg:TI XMM8_REG))
17720 (clobber (reg:TI XMM9_REG))
17721 (clobber (reg:TI XMM10_REG))
17722 (clobber (reg:TI XMM11_REG))
17723 (clobber (reg:TI XMM12_REG))
17724 (clobber (reg:TI XMM13_REG))
17725 (clobber (reg:TI XMM14_REG))
17726 (clobber (reg:TI XMM15_REG))
17727 (clobber (reg:DI SI_REG))
17728 (clobber (reg:DI DI_REG))]
17729 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17731 if (SIBLING_CALL_P (insn))
17734 return "call\t%P1";
17736 [(set_attr "type" "callv")])
17738 (define_insn "*call_value_1"
17739 [(set (match_operand 0 "" "")
17740 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17741 (match_operand:SI 2 "" "")))]
17742 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17744 if (constant_call_address_operand (operands[1], Pmode))
17745 return "call\t%P1";
17746 return "call\t%A1";
17748 [(set_attr "type" "callv")])
17750 (define_insn "*sibcall_value_1"
17751 [(set (match_operand 0 "" "")
17752 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17753 (match_operand:SI 2 "" "")))]
17754 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17758 [(set_attr "type" "callv")])
17760 (define_insn "*call_value_1_rex64"
17761 [(set (match_operand 0 "" "")
17762 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17763 (match_operand:DI 2 "" "")))]
17764 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17765 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17767 if (constant_call_address_operand (operands[1], Pmode))
17768 return "call\t%P1";
17769 return "call\t%A1";
17771 [(set_attr "type" "callv")])
17773 (define_insn "*call_value_1_rex64_ms_sysv"
17774 [(set (match_operand 0 "" "")
17775 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17776 (match_operand:DI 2 "" "")))
17777 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17778 (clobber (reg:TI XMM6_REG))
17779 (clobber (reg:TI XMM7_REG))
17780 (clobber (reg:TI XMM8_REG))
17781 (clobber (reg:TI XMM9_REG))
17782 (clobber (reg:TI XMM10_REG))
17783 (clobber (reg:TI XMM11_REG))
17784 (clobber (reg:TI XMM12_REG))
17785 (clobber (reg:TI XMM13_REG))
17786 (clobber (reg:TI XMM14_REG))
17787 (clobber (reg:TI XMM15_REG))
17788 (clobber (reg:DI SI_REG))
17789 (clobber (reg:DI DI_REG))]
17790 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17792 if (constant_call_address_operand (operands[1], Pmode))
17793 return "call\t%P1";
17794 return "call\t%A1";
17796 [(set_attr "type" "callv")])
17798 (define_insn "*call_value_1_rex64_large"
17799 [(set (match_operand 0 "" "")
17800 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17801 (match_operand:DI 2 "" "")))]
17802 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17804 [(set_attr "type" "callv")])
17806 (define_insn "*sibcall_value_1_rex64"
17807 [(set (match_operand 0 "" "")
17808 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17809 (match_operand:DI 2 "" "")))]
17810 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17814 [(set_attr "type" "callv")])
17816 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17817 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17818 ;; caught for use by garbage collectors and the like. Using an insn that
17819 ;; maps to SIGILL makes it more likely the program will rightfully die.
17820 ;; Keeping with tradition, "6" is in honor of #UD.
17821 (define_insn "trap"
17822 [(trap_if (const_int 1) (const_int 6))]
17824 { return ASM_SHORT "0x0b0f"; }
17825 [(set_attr "length" "2")])
17827 (define_expand "prefetch"
17828 [(prefetch (match_operand 0 "address_operand" "")
17829 (match_operand:SI 1 "const_int_operand" "")
17830 (match_operand:SI 2 "const_int_operand" ""))]
17831 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17833 int rw = INTVAL (operands[1]);
17834 int locality = INTVAL (operands[2]);
17836 gcc_assert (rw == 0 || rw == 1);
17837 gcc_assert (locality >= 0 && locality <= 3);
17838 gcc_assert (GET_MODE (operands[0]) == Pmode
17839 || GET_MODE (operands[0]) == VOIDmode);
17841 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17842 supported by SSE counterpart or the SSE prefetch is not available
17843 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17845 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17846 operands[2] = GEN_INT (3);
17848 operands[1] = const0_rtx;
17851 (define_insn "*prefetch_sse_<mode>"
17852 [(prefetch (match_operand:P 0 "address_operand" "p")
17854 (match_operand:SI 1 "const_int_operand" ""))]
17855 "TARGET_PREFETCH_SSE"
17857 static const char * const patterns[4] = {
17858 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17861 int locality = INTVAL (operands[1]);
17862 gcc_assert (locality >= 0 && locality <= 3);
17864 return patterns[locality];
17866 [(set_attr "type" "sse")
17867 (set_attr "atom_sse_attr" "prefetch")
17868 (set (attr "length_address")
17869 (symbol_ref "memory_address_length (operands[0])"))
17870 (set_attr "memory" "none")])
17872 (define_insn "*prefetch_3dnow_<mode>"
17873 [(prefetch (match_operand:P 0 "address_operand" "p")
17874 (match_operand:SI 1 "const_int_operand" "n")
17878 if (INTVAL (operands[1]) == 0)
17879 return "prefetch\t%a0";
17881 return "prefetchw\t%a0";
17883 [(set_attr "type" "mmx")
17884 (set (attr "length_address")
17885 (symbol_ref "memory_address_length (operands[0])"))
17886 (set_attr "memory" "none")])
17888 (define_expand "stack_protect_set"
17889 [(match_operand 0 "memory_operand" "")
17890 (match_operand 1 "memory_operand" "")]
17893 #ifdef TARGET_THREAD_SSP_OFFSET
17895 emit_insn (gen_stack_tls_protect_set_di (operands[0],
17896 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17898 emit_insn (gen_stack_tls_protect_set_si (operands[0],
17899 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17902 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
17904 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
17909 (define_insn "stack_protect_set_si"
17910 [(set (match_operand:SI 0 "memory_operand" "=m")
17911 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17912 (set (match_scratch:SI 2 "=&r") (const_int 0))
17913 (clobber (reg:CC FLAGS_REG))]
17915 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17916 [(set_attr "type" "multi")])
17918 (define_insn "stack_protect_set_di"
17919 [(set (match_operand:DI 0 "memory_operand" "=m")
17920 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17921 (set (match_scratch:DI 2 "=&r") (const_int 0))
17922 (clobber (reg:CC FLAGS_REG))]
17924 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17925 [(set_attr "type" "multi")])
17927 (define_insn "stack_tls_protect_set_si"
17928 [(set (match_operand:SI 0 "memory_operand" "=m")
17929 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
17930 UNSPEC_SP_TLS_SET))
17931 (set (match_scratch:SI 2 "=&r") (const_int 0))
17932 (clobber (reg:CC FLAGS_REG))]
17934 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17935 [(set_attr "type" "multi")])
17937 (define_insn "stack_tls_protect_set_di"
17938 [(set (match_operand:DI 0 "memory_operand" "=m")
17939 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
17940 UNSPEC_SP_TLS_SET))
17941 (set (match_scratch:DI 2 "=&r") (const_int 0))
17942 (clobber (reg:CC FLAGS_REG))]
17945 /* The kernel uses a different segment register for performance reasons; a
17946 system call would not have to trash the userspace segment register,
17947 which would be expensive */
17948 if (ix86_cmodel != CM_KERNEL)
17949 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17951 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17953 [(set_attr "type" "multi")])
17955 (define_expand "stack_protect_test"
17956 [(match_operand 0 "memory_operand" "")
17957 (match_operand 1 "memory_operand" "")
17958 (match_operand 2 "" "")]
17961 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17963 #ifdef TARGET_THREAD_SSP_OFFSET
17965 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
17966 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17968 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
17969 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17972 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
17974 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
17977 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17978 flags, const0_rtx, operands[2]));
17982 (define_insn "stack_protect_test_si"
17983 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17984 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
17985 (match_operand:SI 2 "memory_operand" "m")]
17987 (clobber (match_scratch:SI 3 "=&r"))]
17989 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
17990 [(set_attr "type" "multi")])
17992 (define_insn "stack_protect_test_di"
17993 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17994 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
17995 (match_operand:DI 2 "memory_operand" "m")]
17997 (clobber (match_scratch:DI 3 "=&r"))]
17999 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18000 [(set_attr "type" "multi")])
18002 (define_insn "stack_tls_protect_test_si"
18003 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18004 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18005 (match_operand:SI 2 "const_int_operand" "i")]
18006 UNSPEC_SP_TLS_TEST))
18007 (clobber (match_scratch:SI 3 "=r"))]
18009 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18010 [(set_attr "type" "multi")])
18012 (define_insn "stack_tls_protect_test_di"
18013 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18014 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18015 (match_operand:DI 2 "const_int_operand" "i")]
18016 UNSPEC_SP_TLS_TEST))
18017 (clobber (match_scratch:DI 3 "=r"))]
18020 /* The kernel uses a different segment register for performance reasons; a
18021 system call would not have to trash the userspace segment register,
18022 which would be expensive */
18023 if (ix86_cmodel != CM_KERNEL)
18024 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18026 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18028 [(set_attr "type" "multi")])
18030 (define_insn "sse4_2_crc32<mode>"
18031 [(set (match_operand:SI 0 "register_operand" "=r")
18033 [(match_operand:SI 1 "register_operand" "0")
18034 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18036 "TARGET_SSE4_2 || TARGET_CRC32"
18037 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18038 [(set_attr "type" "sselog1")
18039 (set_attr "prefix_rep" "1")
18040 (set_attr "prefix_extra" "1")
18041 (set (attr "prefix_data16")
18042 (if_then_else (match_operand:HI 2 "" "")
18044 (const_string "*")))
18045 (set (attr "prefix_rex")
18046 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18048 (const_string "*")))
18049 (set_attr "mode" "SI")])
18051 (define_insn "sse4_2_crc32di"
18052 [(set (match_operand:DI 0 "register_operand" "=r")
18054 [(match_operand:DI 1 "register_operand" "0")
18055 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18057 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18058 "crc32{q}\t{%2, %0|%0, %2}"
18059 [(set_attr "type" "sselog1")
18060 (set_attr "prefix_rep" "1")
18061 (set_attr "prefix_extra" "1")
18062 (set_attr "mode" "DI")])
18064 (define_expand "rdpmc"
18065 [(match_operand:DI 0 "register_operand" "")
18066 (match_operand:SI 1 "register_operand" "")]
18069 rtx reg = gen_reg_rtx (DImode);
18072 /* Force operand 1 into ECX. */
18073 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18074 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18075 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18080 rtvec vec = rtvec_alloc (2);
18081 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18082 rtx upper = gen_reg_rtx (DImode);
18083 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18084 gen_rtvec (1, const0_rtx),
18086 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18087 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18089 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18090 NULL, 1, OPTAB_DIRECT);
18091 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18095 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18096 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18100 (define_insn "*rdpmc"
18101 [(set (match_operand:DI 0 "register_operand" "=A")
18102 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18106 [(set_attr "type" "other")
18107 (set_attr "length" "2")])
18109 (define_insn "*rdpmc_rex64"
18110 [(set (match_operand:DI 0 "register_operand" "=a")
18111 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18113 (set (match_operand:DI 1 "register_operand" "=d")
18114 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18117 [(set_attr "type" "other")
18118 (set_attr "length" "2")])
18120 (define_expand "rdtsc"
18121 [(set (match_operand:DI 0 "register_operand" "")
18122 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18127 rtvec vec = rtvec_alloc (2);
18128 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18129 rtx upper = gen_reg_rtx (DImode);
18130 rtx lower = gen_reg_rtx (DImode);
18131 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18132 gen_rtvec (1, const0_rtx),
18134 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18135 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18137 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18138 NULL, 1, OPTAB_DIRECT);
18139 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18141 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18146 (define_insn "*rdtsc"
18147 [(set (match_operand:DI 0 "register_operand" "=A")
18148 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18151 [(set_attr "type" "other")
18152 (set_attr "length" "2")])
18154 (define_insn "*rdtsc_rex64"
18155 [(set (match_operand:DI 0 "register_operand" "=a")
18156 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18157 (set (match_operand:DI 1 "register_operand" "=d")
18158 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18161 [(set_attr "type" "other")
18162 (set_attr "length" "2")])
18164 (define_expand "rdtscp"
18165 [(match_operand:DI 0 "register_operand" "")
18166 (match_operand:SI 1 "memory_operand" "")]
18169 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18170 gen_rtvec (1, const0_rtx),
18172 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18173 gen_rtvec (1, const0_rtx),
18175 rtx reg = gen_reg_rtx (DImode);
18176 rtx tmp = gen_reg_rtx (SImode);
18180 rtvec vec = rtvec_alloc (3);
18181 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18182 rtx upper = gen_reg_rtx (DImode);
18183 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18184 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18185 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18187 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18188 NULL, 1, OPTAB_DIRECT);
18189 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18194 rtvec vec = rtvec_alloc (2);
18195 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18196 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18197 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18200 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18201 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18205 (define_insn "*rdtscp"
18206 [(set (match_operand:DI 0 "register_operand" "=A")
18207 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18208 (set (match_operand:SI 1 "register_operand" "=c")
18209 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18212 [(set_attr "type" "other")
18213 (set_attr "length" "3")])
18215 (define_insn "*rdtscp_rex64"
18216 [(set (match_operand:DI 0 "register_operand" "=a")
18217 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18218 (set (match_operand:DI 1 "register_operand" "=d")
18219 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18220 (set (match_operand:SI 2 "register_operand" "=c")
18221 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18224 [(set_attr "type" "other")
18225 (set_attr "length" "3")])
18227 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18229 ;; LWP instructions
18231 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18233 (define_expand "lwp_llwpcb"
18234 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18235 UNSPECV_LLWP_INTRINSIC)]
18239 (define_insn "*lwp_llwpcb<mode>1"
18240 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18241 UNSPECV_LLWP_INTRINSIC)]
18244 [(set_attr "type" "lwp")
18245 (set_attr "mode" "<MODE>")
18246 (set_attr "length" "5")])
18248 (define_expand "lwp_slwpcb"
18249 [(set (match_operand 0 "register_operand" "=r")
18250 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18254 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18256 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18260 (define_insn "lwp_slwpcb<mode>"
18261 [(set (match_operand:P 0 "register_operand" "=r")
18262 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18265 [(set_attr "type" "lwp")
18266 (set_attr "mode" "<MODE>")
18267 (set_attr "length" "5")])
18269 (define_expand "lwp_lwpval<mode>3"
18270 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18271 (match_operand:SI 2 "nonimmediate_operand" "rm")
18272 (match_operand:SI 3 "const_int_operand" "i")]
18273 UNSPECV_LWPVAL_INTRINSIC)]
18275 "/* Avoid unused variable warning. */
18278 (define_insn "*lwp_lwpval<mode>3_1"
18279 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18280 (match_operand:SI 1 "nonimmediate_operand" "rm")
18281 (match_operand:SI 2 "const_int_operand" "i")]
18282 UNSPECV_LWPVAL_INTRINSIC)]
18284 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18285 [(set_attr "type" "lwp")
18286 (set_attr "mode" "<MODE>")
18287 (set (attr "length")
18288 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18290 (define_expand "lwp_lwpins<mode>3"
18291 [(set (reg:CCC FLAGS_REG)
18292 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18293 (match_operand:SI 2 "nonimmediate_operand" "rm")
18294 (match_operand:SI 3 "const_int_operand" "i")]
18295 UNSPECV_LWPINS_INTRINSIC))
18296 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18297 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18301 (define_insn "*lwp_lwpins<mode>3_1"
18302 [(set (reg:CCC FLAGS_REG)
18303 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18304 (match_operand:SI 1 "nonimmediate_operand" "rm")
18305 (match_operand:SI 2 "const_int_operand" "i")]
18306 UNSPECV_LWPINS_INTRINSIC))]
18308 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18309 [(set_attr "type" "lwp")
18310 (set_attr "mode" "<MODE>")
18311 (set (attr "length")
18312 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18314 (define_insn "rdfsbase<mode>"
18315 [(set (match_operand:SWI48 0 "register_operand" "=r")
18316 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18317 "TARGET_64BIT && TARGET_FSGSBASE"
18319 [(set_attr "type" "other")
18320 (set_attr "prefix_extra" "2")])
18322 (define_insn "rdgsbase<mode>"
18323 [(set (match_operand:SWI48 0 "register_operand" "=r")
18324 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18325 "TARGET_64BIT && TARGET_FSGSBASE"
18327 [(set_attr "type" "other")
18328 (set_attr "prefix_extra" "2")])
18330 (define_insn "wrfsbase<mode>"
18331 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18333 "TARGET_64BIT && TARGET_FSGSBASE"
18335 [(set_attr "type" "other")
18336 (set_attr "prefix_extra" "2")])
18338 (define_insn "wrgsbase<mode>"
18339 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18341 "TARGET_64BIT && TARGET_FSGSBASE"
18343 [(set_attr "type" "other")
18344 (set_attr "prefix_extra" "2")])
18346 (define_expand "rdrand<mode>"
18347 [(set (match_operand:SWI248 0 "register_operand" "=r")
18348 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18351 rtx retry_label, insn, ccc;
18353 retry_label = gen_label_rtx ();
18355 emit_label (retry_label);
18357 /* Generate rdrand. */
18358 emit_insn (gen_rdrand<mode>_1 (operands[0]));
18360 /* Retry if the carry flag isn't valid. */
18361 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
18362 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
18363 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
18364 gen_rtx_LABEL_REF (VOIDmode, retry_label));
18365 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
18366 JUMP_LABEL (insn) = retry_label;
18371 (define_insn "rdrand<mode>_1"
18372 [(set (match_operand:SWI248 0 "register_operand" "=r")
18373 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18376 [(set_attr "type" "other")
18377 (set_attr "prefix_extra" "1")])
18381 (include "sync.md")