1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2014 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
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 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
97 ;; Other random patterns
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_MS_TO_SYSV_CALL
115 ;; For SSE/MMX support:
123 ;; Generic math support
125 UNSPEC_IEEE_MIN ; not commutative
126 UNSPEC_IEEE_MAX ; not commutative
128 ;; x87 Floating point
144 UNSPEC_FRNDINT_MASK_PM
148 ;; x87 Double output FP
182 ;; For AVX512F support
186 (define_c_enum "unspecv" [
189 UNSPECV_PROBE_STACK_RANGE
192 UNSPECV_SPLIT_STACK_RETURN
198 UNSPECV_LLWP_INTRINSIC
199 UNSPECV_SLWP_INTRINSIC
200 UNSPECV_LWPVAL_INTRINSIC
201 UNSPECV_LWPINS_INTRINSIC
217 ;; For atomic compound assignments.
223 ;; For RDRAND support
226 ;; For RDSEED support
238 ;; Constants to represent rounding modes in the ROUND instruction
247 ;; Constants to represent AVX512F embeded rounding
249 [(ROUND_NEAREST_INT 0)
257 ;; Constants to represent pcomtrue/pcomfalse variants
267 ;; Constants used in the XOP pperm instruction
269 [(PPERM_SRC 0x00) /* copy source */
270 (PPERM_INVERT 0x20) /* invert source */
271 (PPERM_REVERSE 0x40) /* bit reverse source */
272 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
273 (PPERM_ZERO 0x80) /* all 0's */
274 (PPERM_ONES 0xa0) /* all 1's */
275 (PPERM_SIGN 0xc0) /* propagate sign bit */
276 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
277 (PPERM_SRC1 0x00) /* use first source byte */
278 (PPERM_SRC2 0x10) /* use second source byte */
281 ;; Registers by name.
360 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
363 ;; In C guard expressions, put expressions which may be compile-time
364 ;; constants first. This allows for better optimization. For
365 ;; example, write "TARGET_64BIT && reload_completed", not
366 ;; "reload_completed && TARGET_64BIT".
370 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
371 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
373 (const (symbol_ref "ix86_schedule")))
375 ;; A basic instruction type. Refinements due to arguments to be
376 ;; provided in other attributes.
379 alu,alu1,negnot,imov,imovx,lea,
380 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
381 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
382 push,pop,call,callv,leave,
384 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
385 fxch,fistp,fisttp,frndint,
386 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
387 ssemul,sseimul,ssediv,sselog,sselog1,
388 sseishft,sseishft1,ssecmp,ssecomi,
389 ssecvt,ssecvt1,sseicvt,sseins,
390 sseshuf,sseshuf1,ssemuladd,sse4arg,
392 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
393 (const_string "other"))
395 ;; Main data type used by the insn
397 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
399 (const_string "unknown"))
401 ;; The CPU unit operations uses.
402 (define_attr "unit" "integer,i387,sse,mmx,unknown"
403 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
404 fxch,fistp,fisttp,frndint")
405 (const_string "i387")
406 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
407 ssemul,sseimul,ssediv,sselog,sselog1,
408 sseishft,sseishft1,ssecmp,ssecomi,
409 ssecvt,ssecvt1,sseicvt,sseins,
410 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
412 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
414 (eq_attr "type" "other")
415 (const_string "unknown")]
416 (const_string "integer")))
418 ;; The minimum required alignment of vector mode memory operands of the SSE
419 ;; (non-VEX/EVEX) instruction in bits, if it is different from
420 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
421 ;; multiple alternatives, this should be conservative maximum of those minimum
422 ;; required alignments.
423 (define_attr "ssememalign" "" (const_int 0))
425 ;; The (bounding maximum) length of an instruction immediate.
426 (define_attr "length_immediate" ""
427 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
428 bitmanip,imulx,msklog,mskmov")
430 (eq_attr "unit" "i387,sse,mmx")
432 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
433 rotate,rotatex,rotate1,imul,icmp,push,pop")
434 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
435 (eq_attr "type" "imov,test")
436 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
437 (eq_attr "type" "call")
438 (if_then_else (match_operand 0 "constant_call_address_operand")
441 (eq_attr "type" "callv")
442 (if_then_else (match_operand 1 "constant_call_address_operand")
445 ;; We don't know the size before shorten_branches. Expect
446 ;; the instruction to fit for better scheduling.
447 (eq_attr "type" "ibr")
450 (symbol_ref "/* Update immediate_length and other attributes! */
451 gcc_unreachable (),1")))
453 ;; The (bounding maximum) length of an instruction address.
454 (define_attr "length_address" ""
455 (cond [(eq_attr "type" "str,other,multi,fxch")
457 (and (eq_attr "type" "call")
458 (match_operand 0 "constant_call_address_operand"))
460 (and (eq_attr "type" "callv")
461 (match_operand 1 "constant_call_address_operand"))
464 (symbol_ref "ix86_attr_length_address_default (insn)")))
466 ;; Set when length prefix is used.
467 (define_attr "prefix_data16" ""
468 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
470 (eq_attr "mode" "HI")
472 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
477 ;; Set when string REP prefix is used.
478 (define_attr "prefix_rep" ""
479 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
481 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
486 ;; Set when 0f opcode prefix is used.
487 (define_attr "prefix_0f" ""
489 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
490 (eq_attr "unit" "sse,mmx"))
494 ;; Set when REX opcode prefix is used.
495 (define_attr "prefix_rex" ""
496 (cond [(not (match_test "TARGET_64BIT"))
498 (and (eq_attr "mode" "DI")
499 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
500 (eq_attr "unit" "!mmx")))
502 (and (eq_attr "mode" "QI")
503 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
505 (match_test "x86_extended_reg_mentioned_p (insn)")
507 (and (eq_attr "type" "imovx")
508 (match_operand:QI 1 "ext_QIreg_operand"))
513 ;; There are also additional prefixes in 3DNOW, SSSE3.
514 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
515 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
516 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
517 (define_attr "prefix_extra" ""
518 (cond [(eq_attr "type" "ssemuladd,sse4arg")
520 (eq_attr "type" "sseiadd1,ssecvt1")
525 ;; Prefix used: original, VEX or maybe VEX.
526 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
527 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
529 (eq_attr "mode" "XI,V16SF,V8DF")
530 (const_string "evex")
532 (const_string "orig")))
534 ;; VEX W bit is used.
535 (define_attr "prefix_vex_w" "" (const_int 0))
537 ;; The length of VEX prefix
538 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
539 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
540 ;; still prefix_0f 1, with prefix_extra 1.
541 (define_attr "length_vex" ""
542 (if_then_else (and (eq_attr "prefix_0f" "1")
543 (eq_attr "prefix_extra" "0"))
544 (if_then_else (eq_attr "prefix_vex_w" "1")
545 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
546 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
547 (if_then_else (eq_attr "prefix_vex_w" "1")
548 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
549 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
551 ;; 4-bytes evex prefix and 1 byte opcode.
552 (define_attr "length_evex" "" (const_int 5))
554 ;; Set when modrm byte is used.
555 (define_attr "modrm" ""
556 (cond [(eq_attr "type" "str,leave")
558 (eq_attr "unit" "i387")
560 (and (eq_attr "type" "incdec")
561 (and (not (match_test "TARGET_64BIT"))
562 (ior (match_operand:SI 1 "register_operand")
563 (match_operand:HI 1 "register_operand"))))
565 (and (eq_attr "type" "push")
566 (not (match_operand 1 "memory_operand")))
568 (and (eq_attr "type" "pop")
569 (not (match_operand 0 "memory_operand")))
571 (and (eq_attr "type" "imov")
572 (and (not (eq_attr "mode" "DI"))
573 (ior (and (match_operand 0 "register_operand")
574 (match_operand 1 "immediate_operand"))
575 (ior (and (match_operand 0 "ax_reg_operand")
576 (match_operand 1 "memory_displacement_only_operand"))
577 (and (match_operand 0 "memory_displacement_only_operand")
578 (match_operand 1 "ax_reg_operand"))))))
580 (and (eq_attr "type" "call")
581 (match_operand 0 "constant_call_address_operand"))
583 (and (eq_attr "type" "callv")
584 (match_operand 1 "constant_call_address_operand"))
586 (and (eq_attr "type" "alu,alu1,icmp,test")
587 (match_operand 0 "ax_reg_operand"))
588 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
592 ;; The (bounding maximum) length of an instruction in bytes.
593 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
594 ;; Later we may want to split them and compute proper length as for
596 (define_attr "length" ""
597 (cond [(eq_attr "type" "other,multi,fistp,frndint")
599 (eq_attr "type" "fcmp")
601 (eq_attr "unit" "i387")
603 (plus (attr "prefix_data16")
604 (attr "length_address")))
605 (ior (eq_attr "prefix" "evex")
606 (and (ior (eq_attr "prefix" "maybe_evex")
607 (eq_attr "prefix" "maybe_vex"))
608 (match_test "TARGET_AVX512F")))
609 (plus (attr "length_evex")
610 (plus (attr "length_immediate")
612 (attr "length_address"))))
613 (ior (eq_attr "prefix" "vex")
614 (and (ior (eq_attr "prefix" "maybe_vex")
615 (eq_attr "prefix" "maybe_evex"))
616 (match_test "TARGET_AVX")))
617 (plus (attr "length_vex")
618 (plus (attr "length_immediate")
620 (attr "length_address"))))]
621 (plus (plus (attr "modrm")
622 (plus (attr "prefix_0f")
623 (plus (attr "prefix_rex")
624 (plus (attr "prefix_extra")
626 (plus (attr "prefix_rep")
627 (plus (attr "prefix_data16")
628 (plus (attr "length_immediate")
629 (attr "length_address")))))))
631 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
632 ;; `store' if there is a simple memory reference therein, or `unknown'
633 ;; if the instruction is complex.
635 (define_attr "memory" "none,load,store,both,unknown"
636 (cond [(eq_attr "type" "other,multi,str,lwp")
637 (const_string "unknown")
638 (eq_attr "type" "lea,fcmov,fpspc")
639 (const_string "none")
640 (eq_attr "type" "fistp,leave")
641 (const_string "both")
642 (eq_attr "type" "frndint")
643 (const_string "load")
644 (eq_attr "type" "push")
645 (if_then_else (match_operand 1 "memory_operand")
646 (const_string "both")
647 (const_string "store"))
648 (eq_attr "type" "pop")
649 (if_then_else (match_operand 0 "memory_operand")
650 (const_string "both")
651 (const_string "load"))
652 (eq_attr "type" "setcc")
653 (if_then_else (match_operand 0 "memory_operand")
654 (const_string "store")
655 (const_string "none"))
656 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
657 (if_then_else (ior (match_operand 0 "memory_operand")
658 (match_operand 1 "memory_operand"))
659 (const_string "load")
660 (const_string "none"))
661 (eq_attr "type" "ibr")
662 (if_then_else (match_operand 0 "memory_operand")
663 (const_string "load")
664 (const_string "none"))
665 (eq_attr "type" "call")
666 (if_then_else (match_operand 0 "constant_call_address_operand")
667 (const_string "none")
668 (const_string "load"))
669 (eq_attr "type" "callv")
670 (if_then_else (match_operand 1 "constant_call_address_operand")
671 (const_string "none")
672 (const_string "load"))
673 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
674 (match_operand 1 "memory_operand"))
675 (const_string "both")
676 (and (match_operand 0 "memory_operand")
677 (match_operand 1 "memory_operand"))
678 (const_string "both")
679 (match_operand 0 "memory_operand")
680 (const_string "store")
681 (match_operand 1 "memory_operand")
682 (const_string "load")
684 "!alu1,negnot,ishift1,
685 imov,imovx,icmp,test,bitmanip,
687 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
688 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
689 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
690 (match_operand 2 "memory_operand"))
691 (const_string "load")
692 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
693 (match_operand 3 "memory_operand"))
694 (const_string "load")
696 (const_string "none")))
698 ;; Indicates if an instruction has both an immediate and a displacement.
700 (define_attr "imm_disp" "false,true,unknown"
701 (cond [(eq_attr "type" "other,multi")
702 (const_string "unknown")
703 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
704 (and (match_operand 0 "memory_displacement_operand")
705 (match_operand 1 "immediate_operand")))
706 (const_string "true")
707 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
708 (and (match_operand 0 "memory_displacement_operand")
709 (match_operand 2 "immediate_operand")))
710 (const_string "true")
712 (const_string "false")))
714 ;; Indicates if an FP operation has an integer source.
716 (define_attr "fp_int_src" "false,true"
717 (const_string "false"))
719 ;; Defines rounding mode of an FP operation.
721 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
722 (const_string "any"))
724 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
725 (define_attr "use_carry" "0,1" (const_string "0"))
727 ;; Define attribute to indicate unaligned ssemov insns
728 (define_attr "movu" "0,1" (const_string "0"))
730 ;; Used to control the "enabled" attribute on a per-instruction basis.
731 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
732 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
733 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f"
734 (const_string "base"))
736 (define_attr "enabled" ""
737 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
738 (eq_attr "isa" "x64_sse4")
739 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
740 (eq_attr "isa" "x64_sse4_noavx")
741 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
742 (eq_attr "isa" "x64_avx")
743 (symbol_ref "TARGET_64BIT && TARGET_AVX")
744 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
745 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
746 (eq_attr "isa" "sse2_noavx")
747 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
748 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
749 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
750 (eq_attr "isa" "sse4_noavx")
751 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
752 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
753 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
754 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
755 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
756 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
757 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
758 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
759 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
760 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
761 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
762 (eq_attr "isa" "fma_avx512f")
763 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
767 ;; Describe a user's asm statement.
768 (define_asm_attributes
769 [(set_attr "length" "128")
770 (set_attr "type" "multi")])
772 (define_code_iterator plusminus [plus minus])
774 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
776 (define_code_iterator multdiv [mult div])
778 ;; Base name for define_insn
779 (define_code_attr plusminus_insn
780 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
781 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
783 ;; Base name for insn mnemonic.
784 (define_code_attr plusminus_mnemonic
785 [(plus "add") (ss_plus "adds") (us_plus "addus")
786 (minus "sub") (ss_minus "subs") (us_minus "subus")])
787 (define_code_attr plusminus_carry_mnemonic
788 [(plus "adc") (minus "sbb")])
789 (define_code_attr multdiv_mnemonic
790 [(mult "mul") (div "div")])
792 ;; Mark commutative operators as such in constraints.
793 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
794 (minus "") (ss_minus "") (us_minus "")])
796 ;; Mapping of max and min
797 (define_code_iterator maxmin [smax smin umax umin])
799 ;; Mapping of signed max and min
800 (define_code_iterator smaxmin [smax smin])
802 ;; Mapping of unsigned max and min
803 (define_code_iterator umaxmin [umax umin])
805 ;; Base name for integer and FP insn mnemonic
806 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
807 (umax "maxu") (umin "minu")])
808 (define_code_attr maxmin_float [(smax "max") (smin "min")])
810 ;; Mapping of logic operators
811 (define_code_iterator any_logic [and ior xor])
812 (define_code_iterator any_or [ior xor])
813 (define_code_iterator fpint_logic [and xor])
815 ;; Base name for insn mnemonic.
816 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
818 ;; Mapping of logic-shift operators
819 (define_code_iterator any_lshift [ashift lshiftrt])
821 ;; Mapping of shift-right operators
822 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
824 ;; Mapping of all shift operators
825 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
827 ;; Base name for define_insn
828 (define_code_attr shift_insn
829 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
831 ;; Base name for insn mnemonic.
832 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
833 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
835 ;; Mapping of rotate operators
836 (define_code_iterator any_rotate [rotate rotatert])
838 ;; Base name for define_insn
839 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
841 ;; Base name for insn mnemonic.
842 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
844 ;; Mapping of abs neg operators
845 (define_code_iterator absneg [abs neg])
847 ;; Base name for x87 insn mnemonic.
848 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
850 ;; Used in signed and unsigned widening multiplications.
851 (define_code_iterator any_extend [sign_extend zero_extend])
853 ;; Prefix for insn menmonic.
854 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
856 ;; Prefix for define_insn
857 (define_code_attr u [(sign_extend "") (zero_extend "u")])
858 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
859 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
861 ;; Used in signed and unsigned truncations.
862 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
863 ;; Instruction suffix for truncations.
864 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
866 ;; Used in signed and unsigned fix.
867 (define_code_iterator any_fix [fix unsigned_fix])
868 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
870 ;; All integer modes.
871 (define_mode_iterator SWI1248x [QI HI SI DI])
873 ;; All integer modes without QImode.
874 (define_mode_iterator SWI248x [HI SI DI])
876 ;; All integer modes without QImode and HImode.
877 (define_mode_iterator SWI48x [SI DI])
879 ;; All integer modes without SImode and DImode.
880 (define_mode_iterator SWI12 [QI HI])
882 ;; All integer modes without DImode.
883 (define_mode_iterator SWI124 [QI HI SI])
885 ;; All integer modes without QImode and DImode.
886 (define_mode_iterator SWI24 [HI SI])
888 ;; Single word integer modes.
889 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
891 ;; Single word integer modes without QImode.
892 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
894 ;; Single word integer modes without QImode and HImode.
895 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
897 ;; All math-dependant single and double word integer modes.
898 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
899 (HI "TARGET_HIMODE_MATH")
900 SI DI (TI "TARGET_64BIT")])
902 ;; Math-dependant single word integer modes.
903 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
904 (HI "TARGET_HIMODE_MATH")
905 SI (DI "TARGET_64BIT")])
907 ;; Math-dependant integer modes without DImode.
908 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
909 (HI "TARGET_HIMODE_MATH")
912 ;; Math-dependant single word integer modes without QImode.
913 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
914 SI (DI "TARGET_64BIT")])
916 ;; Double word integer modes.
917 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
918 (TI "TARGET_64BIT")])
920 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
921 ;; compile time constant, it is faster to use <MODE_SIZE> than
922 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
923 ;; command line options just use GET_MODE_SIZE macro.
924 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
925 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
926 (V16QI "16") (V32QI "32") (V64QI "64")
927 (V8HI "16") (V16HI "32") (V32HI "64")
928 (V4SI "16") (V8SI "32") (V16SI "64")
929 (V2DI "16") (V4DI "32") (V8DI "64")
930 (V1TI "16") (V2TI "32") (V4TI "64")
931 (V2DF "16") (V4DF "32") (V8DF "64")
932 (V4SF "16") (V8SF "32") (V16SF "64")])
934 ;; Double word integer modes as mode attribute.
935 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
936 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
938 ;; Half mode for double word integer modes.
939 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
940 (DI "TARGET_64BIT")])
942 ;; Instruction suffix for integer modes.
943 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
945 ;; Pointer size prefix for integer modes (Intel asm dialect)
946 (define_mode_attr iptrsize [(QI "BYTE")
951 ;; Register class for integer modes.
952 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
954 ;; Immediate operand constraint for integer modes.
955 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
957 ;; General operand constraint for word modes.
958 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
960 ;; Immediate operand constraint for double integer modes.
961 (define_mode_attr di [(SI "nF") (DI "e")])
963 ;; Immediate operand constraint for shifts.
964 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
966 ;; General operand predicate for integer modes.
967 (define_mode_attr general_operand
968 [(QI "general_operand")
969 (HI "general_operand")
970 (SI "x86_64_general_operand")
971 (DI "x86_64_general_operand")
972 (TI "x86_64_general_operand")])
974 ;; General sign/zero extend operand predicate for integer modes.
975 (define_mode_attr general_szext_operand
976 [(QI "general_operand")
977 (HI "general_operand")
978 (SI "x86_64_szext_general_operand")
979 (DI "x86_64_szext_general_operand")])
981 ;; Immediate operand predicate for integer modes.
982 (define_mode_attr immediate_operand
983 [(QI "immediate_operand")
984 (HI "immediate_operand")
985 (SI "x86_64_immediate_operand")
986 (DI "x86_64_immediate_operand")])
988 ;; Nonmemory operand predicate for integer modes.
989 (define_mode_attr nonmemory_operand
990 [(QI "nonmemory_operand")
991 (HI "nonmemory_operand")
992 (SI "x86_64_nonmemory_operand")
993 (DI "x86_64_nonmemory_operand")])
995 ;; Operand predicate for shifts.
996 (define_mode_attr shift_operand
997 [(QI "nonimmediate_operand")
998 (HI "nonimmediate_operand")
999 (SI "nonimmediate_operand")
1000 (DI "shiftdi_operand")
1001 (TI "register_operand")])
1003 ;; Operand predicate for shift argument.
1004 (define_mode_attr shift_immediate_operand
1005 [(QI "const_1_to_31_operand")
1006 (HI "const_1_to_31_operand")
1007 (SI "const_1_to_31_operand")
1008 (DI "const_1_to_63_operand")])
1010 ;; Input operand predicate for arithmetic left shifts.
1011 (define_mode_attr ashl_input_operand
1012 [(QI "nonimmediate_operand")
1013 (HI "nonimmediate_operand")
1014 (SI "nonimmediate_operand")
1015 (DI "ashldi_input_operand")
1016 (TI "reg_or_pm1_operand")])
1018 ;; SSE and x87 SFmode and DFmode floating point modes
1019 (define_mode_iterator MODEF [SF DF])
1021 ;; All x87 floating point modes
1022 (define_mode_iterator X87MODEF [SF DF XF])
1024 ;; SSE instruction suffix for various modes
1025 (define_mode_attr ssemodesuffix
1026 [(SF "ss") (DF "sd")
1027 (V16SF "ps") (V8DF "pd")
1028 (V8SF "ps") (V4DF "pd")
1029 (V4SF "ps") (V2DF "pd")
1030 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1031 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1032 (V64QI "b") (V16SI "d") (V8DI "q")])
1034 ;; SSE vector suffix for floating point modes
1035 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1037 ;; SSE vector mode corresponding to a scalar mode
1038 (define_mode_attr ssevecmode
1039 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1040 (define_mode_attr ssevecmodelower
1041 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1043 ;; Instruction suffix for REX 64bit operators.
1044 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1046 ;; This mode iterator allows :P to be used for patterns that operate on
1047 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1048 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1050 ;; This mode iterator allows :W to be used for patterns that operate on
1051 ;; word_mode sized quantities.
1052 (define_mode_iterator W
1053 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1055 ;; This mode iterator allows :PTR to be used for patterns that operate on
1056 ;; ptr_mode sized quantities.
1057 (define_mode_iterator PTR
1058 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1060 ;; Scheduling descriptions
1062 (include "pentium.md")
1065 (include "athlon.md")
1066 (include "bdver1.md")
1067 (include "bdver3.md")
1068 (include "btver2.md")
1069 (include "geode.md")
1072 (include "core2.md")
1075 ;; Operand and operator predicates and constraints
1077 (include "predicates.md")
1078 (include "constraints.md")
1081 ;; Compare and branch/compare and store instructions.
1083 (define_expand "cbranch<mode>4"
1084 [(set (reg:CC FLAGS_REG)
1085 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1086 (match_operand:SDWIM 2 "<general_operand>")))
1087 (set (pc) (if_then_else
1088 (match_operator 0 "ordered_comparison_operator"
1089 [(reg:CC FLAGS_REG) (const_int 0)])
1090 (label_ref (match_operand 3))
1094 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1095 operands[1] = force_reg (<MODE>mode, operands[1]);
1096 ix86_expand_branch (GET_CODE (operands[0]),
1097 operands[1], operands[2], operands[3]);
1101 (define_expand "cstore<mode>4"
1102 [(set (reg:CC FLAGS_REG)
1103 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1104 (match_operand:SWIM 3 "<general_operand>")))
1105 (set (match_operand:QI 0 "register_operand")
1106 (match_operator 1 "ordered_comparison_operator"
1107 [(reg:CC FLAGS_REG) (const_int 0)]))]
1110 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1111 operands[2] = force_reg (<MODE>mode, operands[2]);
1112 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1113 operands[2], operands[3]);
1117 (define_expand "cmp<mode>_1"
1118 [(set (reg:CC FLAGS_REG)
1119 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1120 (match_operand:SWI48 1 "<general_operand>")))])
1122 (define_insn "*cmp<mode>_ccno_1"
1123 [(set (reg FLAGS_REG)
1124 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1125 (match_operand:SWI 1 "const0_operand")))]
1126 "ix86_match_ccmode (insn, CCNOmode)"
1128 test{<imodesuffix>}\t%0, %0
1129 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1130 [(set_attr "type" "test,icmp")
1131 (set_attr "length_immediate" "0,1")
1132 (set_attr "mode" "<MODE>")])
1134 (define_insn "*cmp<mode>_1"
1135 [(set (reg FLAGS_REG)
1136 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1137 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1138 "ix86_match_ccmode (insn, CCmode)"
1139 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1140 [(set_attr "type" "icmp")
1141 (set_attr "mode" "<MODE>")])
1143 (define_insn "*cmp<mode>_minus_1"
1144 [(set (reg FLAGS_REG)
1146 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1147 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1149 "ix86_match_ccmode (insn, CCGOCmode)"
1150 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1151 [(set_attr "type" "icmp")
1152 (set_attr "mode" "<MODE>")])
1154 (define_insn "*cmpqi_ext_1"
1155 [(set (reg FLAGS_REG)
1157 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1160 (match_operand 1 "ext_register_operand" "Q,Q")
1162 (const_int 8)) 0)))]
1163 "ix86_match_ccmode (insn, CCmode)"
1164 "cmp{b}\t{%h1, %0|%0, %h1}"
1165 [(set_attr "isa" "*,nox64")
1166 (set_attr "type" "icmp")
1167 (set_attr "mode" "QI")])
1169 (define_insn "*cmpqi_ext_2"
1170 [(set (reg FLAGS_REG)
1174 (match_operand 0 "ext_register_operand" "Q")
1177 (match_operand:QI 1 "const0_operand")))]
1178 "ix86_match_ccmode (insn, CCNOmode)"
1180 [(set_attr "type" "test")
1181 (set_attr "length_immediate" "0")
1182 (set_attr "mode" "QI")])
1184 (define_expand "cmpqi_ext_3"
1185 [(set (reg:CC FLAGS_REG)
1189 (match_operand 0 "ext_register_operand")
1192 (match_operand:QI 1 "const_int_operand")))])
1194 (define_insn "*cmpqi_ext_3"
1195 [(set (reg FLAGS_REG)
1199 (match_operand 0 "ext_register_operand" "Q,Q")
1202 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1203 "ix86_match_ccmode (insn, CCmode)"
1204 "cmp{b}\t{%1, %h0|%h0, %1}"
1205 [(set_attr "isa" "*,nox64")
1206 (set_attr "type" "icmp")
1207 (set_attr "modrm" "1")
1208 (set_attr "mode" "QI")])
1210 (define_insn "*cmpqi_ext_4"
1211 [(set (reg FLAGS_REG)
1215 (match_operand 0 "ext_register_operand" "Q")
1220 (match_operand 1 "ext_register_operand" "Q")
1222 (const_int 8)) 0)))]
1223 "ix86_match_ccmode (insn, CCmode)"
1224 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1225 [(set_attr "type" "icmp")
1226 (set_attr "mode" "QI")])
1228 ;; These implement float point compares.
1229 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1230 ;; which would allow mix and match FP modes on the compares. Which is what
1231 ;; the old patterns did, but with many more of them.
1233 (define_expand "cbranchxf4"
1234 [(set (reg:CC FLAGS_REG)
1235 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1236 (match_operand:XF 2 "nonmemory_operand")))
1237 (set (pc) (if_then_else
1238 (match_operator 0 "ix86_fp_comparison_operator"
1241 (label_ref (match_operand 3))
1245 ix86_expand_branch (GET_CODE (operands[0]),
1246 operands[1], operands[2], operands[3]);
1250 (define_expand "cstorexf4"
1251 [(set (reg:CC FLAGS_REG)
1252 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1253 (match_operand:XF 3 "nonmemory_operand")))
1254 (set (match_operand:QI 0 "register_operand")
1255 (match_operator 1 "ix86_fp_comparison_operator"
1260 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1261 operands[2], operands[3]);
1265 (define_expand "cbranch<mode>4"
1266 [(set (reg:CC FLAGS_REG)
1267 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1268 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1269 (set (pc) (if_then_else
1270 (match_operator 0 "ix86_fp_comparison_operator"
1273 (label_ref (match_operand 3))
1275 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1277 ix86_expand_branch (GET_CODE (operands[0]),
1278 operands[1], operands[2], operands[3]);
1282 (define_expand "cstore<mode>4"
1283 [(set (reg:CC FLAGS_REG)
1284 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1285 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1286 (set (match_operand:QI 0 "register_operand")
1287 (match_operator 1 "ix86_fp_comparison_operator"
1290 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1292 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1293 operands[2], operands[3]);
1297 (define_expand "cbranchcc4"
1298 [(set (pc) (if_then_else
1299 (match_operator 0 "comparison_operator"
1300 [(match_operand 1 "flags_reg_operand")
1301 (match_operand 2 "const0_operand")])
1302 (label_ref (match_operand 3))
1306 ix86_expand_branch (GET_CODE (operands[0]),
1307 operands[1], operands[2], operands[3]);
1311 (define_expand "cstorecc4"
1312 [(set (match_operand:QI 0 "register_operand")
1313 (match_operator 1 "comparison_operator"
1314 [(match_operand 2 "flags_reg_operand")
1315 (match_operand 3 "const0_operand")]))]
1318 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1319 operands[2], operands[3]);
1324 ;; FP compares, step 1:
1325 ;; Set the FP condition codes.
1327 ;; CCFPmode compare with exceptions
1328 ;; CCFPUmode compare with no exceptions
1330 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1331 ;; used to manage the reg stack popping would not be preserved.
1333 (define_insn "*cmp<mode>_0_i387"
1334 [(set (match_operand:HI 0 "register_operand" "=a")
1337 (match_operand:X87MODEF 1 "register_operand" "f")
1338 (match_operand:X87MODEF 2 "const0_operand"))]
1341 "* return output_fp_compare (insn, operands, false, false);"
1342 [(set_attr "type" "multi")
1343 (set_attr "unit" "i387")
1344 (set_attr "mode" "<MODE>")])
1346 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1347 [(set (reg:CCFP FLAGS_REG)
1349 (match_operand:X87MODEF 1 "register_operand" "f")
1350 (match_operand:X87MODEF 2 "const0_operand")))
1351 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1352 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1354 "&& reload_completed"
1357 [(compare:CCFP (match_dup 1)(match_dup 2))]
1359 (set (reg:CC FLAGS_REG)
1360 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1362 [(set_attr "type" "multi")
1363 (set_attr "unit" "i387")
1364 (set_attr "mode" "<MODE>")])
1366 (define_insn "*cmpxf_i387"
1367 [(set (match_operand:HI 0 "register_operand" "=a")
1370 (match_operand:XF 1 "register_operand" "f")
1371 (match_operand:XF 2 "register_operand" "f"))]
1374 "* return output_fp_compare (insn, operands, false, false);"
1375 [(set_attr "type" "multi")
1376 (set_attr "unit" "i387")
1377 (set_attr "mode" "XF")])
1379 (define_insn_and_split "*cmpxf_cc_i387"
1380 [(set (reg:CCFP FLAGS_REG)
1382 (match_operand:XF 1 "register_operand" "f")
1383 (match_operand:XF 2 "register_operand" "f")))
1384 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1385 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1387 "&& reload_completed"
1390 [(compare:CCFP (match_dup 1)(match_dup 2))]
1392 (set (reg:CC FLAGS_REG)
1393 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1395 [(set_attr "type" "multi")
1396 (set_attr "unit" "i387")
1397 (set_attr "mode" "XF")])
1399 (define_insn "*cmp<mode>_i387"
1400 [(set (match_operand:HI 0 "register_operand" "=a")
1403 (match_operand:MODEF 1 "register_operand" "f")
1404 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1407 "* return output_fp_compare (insn, operands, false, false);"
1408 [(set_attr "type" "multi")
1409 (set_attr "unit" "i387")
1410 (set_attr "mode" "<MODE>")])
1412 (define_insn_and_split "*cmp<mode>_cc_i387"
1413 [(set (reg:CCFP FLAGS_REG)
1415 (match_operand:MODEF 1 "register_operand" "f")
1416 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1417 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1418 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1420 "&& reload_completed"
1423 [(compare:CCFP (match_dup 1)(match_dup 2))]
1425 (set (reg:CC FLAGS_REG)
1426 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1430 (set_attr "mode" "<MODE>")])
1432 (define_insn "*cmpu<mode>_i387"
1433 [(set (match_operand:HI 0 "register_operand" "=a")
1436 (match_operand:X87MODEF 1 "register_operand" "f")
1437 (match_operand:X87MODEF 2 "register_operand" "f"))]
1440 "* return output_fp_compare (insn, operands, false, true);"
1441 [(set_attr "type" "multi")
1442 (set_attr "unit" "i387")
1443 (set_attr "mode" "<MODE>")])
1445 (define_insn_and_split "*cmpu<mode>_cc_i387"
1446 [(set (reg:CCFPU FLAGS_REG)
1448 (match_operand:X87MODEF 1 "register_operand" "f")
1449 (match_operand:X87MODEF 2 "register_operand" "f")))
1450 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1451 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1453 "&& reload_completed"
1456 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1458 (set (reg:CC FLAGS_REG)
1459 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1461 [(set_attr "type" "multi")
1462 (set_attr "unit" "i387")
1463 (set_attr "mode" "<MODE>")])
1465 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1466 [(set (match_operand:HI 0 "register_operand" "=a")
1469 (match_operand:X87MODEF 1 "register_operand" "f")
1470 (match_operator:X87MODEF 3 "float_operator"
1471 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1474 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1475 || optimize_function_for_size_p (cfun))"
1476 "* return output_fp_compare (insn, operands, false, false);"
1477 [(set_attr "type" "multi")
1478 (set_attr "unit" "i387")
1479 (set_attr "fp_int_src" "true")
1480 (set_attr "mode" "<SWI24:MODE>")])
1482 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1483 [(set (reg:CCFP FLAGS_REG)
1485 (match_operand:X87MODEF 1 "register_operand" "f")
1486 (match_operator:X87MODEF 3 "float_operator"
1487 [(match_operand:SWI24 2 "memory_operand" "m")])))
1488 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1489 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1490 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1491 || optimize_function_for_size_p (cfun))"
1493 "&& reload_completed"
1498 (match_op_dup 3 [(match_dup 2)]))]
1500 (set (reg:CC FLAGS_REG)
1501 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1503 [(set_attr "type" "multi")
1504 (set_attr "unit" "i387")
1505 (set_attr "fp_int_src" "true")
1506 (set_attr "mode" "<SWI24:MODE>")])
1508 ;; FP compares, step 2
1509 ;; Move the fpsw to ax.
1511 (define_insn "x86_fnstsw_1"
1512 [(set (match_operand:HI 0 "register_operand" "=a")
1513 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1516 [(set (attr "length")
1517 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1518 (set_attr "mode" "SI")
1519 (set_attr "unit" "i387")])
1521 ;; FP compares, step 3
1522 ;; Get ax into flags, general case.
1524 (define_insn "x86_sahf_1"
1525 [(set (reg:CC FLAGS_REG)
1526 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1530 #ifndef HAVE_AS_IX86_SAHF
1532 return ASM_BYTE "0x9e";
1537 [(set_attr "length" "1")
1538 (set_attr "athlon_decode" "vector")
1539 (set_attr "amdfam10_decode" "direct")
1540 (set_attr "bdver1_decode" "direct")
1541 (set_attr "mode" "SI")])
1543 ;; Pentium Pro can do steps 1 through 3 in one go.
1544 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1545 ;; (these i387 instructions set flags directly)
1547 (define_mode_iterator FPCMP [CCFP CCFPU])
1548 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1550 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1551 [(set (reg:FPCMP FLAGS_REG)
1553 (match_operand:MODEF 0 "register_operand" "f,x")
1554 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1555 "TARGET_MIX_SSE_I387
1556 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1557 "* return output_fp_compare (insn, operands, true,
1558 <FPCMP:MODE>mode == CCFPUmode);"
1559 [(set_attr "type" "fcmp,ssecomi")
1560 (set_attr "prefix" "orig,maybe_vex")
1561 (set_attr "mode" "<MODEF:MODE>")
1562 (set (attr "prefix_rep")
1563 (if_then_else (eq_attr "type" "ssecomi")
1565 (const_string "*")))
1566 (set (attr "prefix_data16")
1567 (cond [(eq_attr "type" "fcmp")
1569 (eq_attr "mode" "DF")
1572 (const_string "0")))
1573 (set_attr "athlon_decode" "vector")
1574 (set_attr "amdfam10_decode" "direct")
1575 (set_attr "bdver1_decode" "double")])
1577 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1578 [(set (reg:FPCMP FLAGS_REG)
1580 (match_operand:MODEF 0 "register_operand" "x")
1581 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1583 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1584 "* return output_fp_compare (insn, operands, true,
1585 <FPCMP:MODE>mode == CCFPUmode);"
1586 [(set_attr "type" "ssecomi")
1587 (set_attr "prefix" "maybe_vex")
1588 (set_attr "mode" "<MODEF:MODE>")
1589 (set_attr "prefix_rep" "0")
1590 (set (attr "prefix_data16")
1591 (if_then_else (eq_attr "mode" "DF")
1593 (const_string "0")))
1594 (set_attr "athlon_decode" "vector")
1595 (set_attr "amdfam10_decode" "direct")
1596 (set_attr "bdver1_decode" "double")])
1598 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1599 [(set (reg:FPCMP FLAGS_REG)
1601 (match_operand:X87MODEF 0 "register_operand" "f")
1602 (match_operand:X87MODEF 1 "register_operand" "f")))]
1603 "TARGET_80387 && TARGET_CMOVE
1604 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1605 "* return output_fp_compare (insn, operands, true,
1606 <FPCMP:MODE>mode == CCFPUmode);"
1607 [(set_attr "type" "fcmp")
1608 (set_attr "mode" "<X87MODEF:MODE>")
1609 (set_attr "athlon_decode" "vector")
1610 (set_attr "amdfam10_decode" "direct")
1611 (set_attr "bdver1_decode" "double")])
1613 ;; Push/pop instructions.
1615 (define_insn "*push<mode>2"
1616 [(set (match_operand:DWI 0 "push_operand" "=<")
1617 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1620 [(set_attr "type" "multi")
1621 (set_attr "mode" "<MODE>")])
1624 [(set (match_operand:TI 0 "push_operand")
1625 (match_operand:TI 1 "general_operand"))]
1626 "TARGET_64BIT && reload_completed
1627 && !SSE_REG_P (operands[1])"
1629 "ix86_split_long_move (operands); DONE;")
1631 (define_insn "*pushdi2_rex64"
1632 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1633 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1638 [(set_attr "type" "push,multi")
1639 (set_attr "mode" "DI")])
1641 ;; Convert impossible pushes of immediate to existing instructions.
1642 ;; First try to get scratch register and go through it. In case this
1643 ;; fails, push sign extended lower part first and then overwrite
1644 ;; upper part by 32bit move.
1646 [(match_scratch:DI 2 "r")
1647 (set (match_operand:DI 0 "push_operand")
1648 (match_operand:DI 1 "immediate_operand"))]
1649 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1650 && !x86_64_immediate_operand (operands[1], DImode)"
1651 [(set (match_dup 2) (match_dup 1))
1652 (set (match_dup 0) (match_dup 2))])
1654 ;; We need to define this as both peepholer and splitter for case
1655 ;; peephole2 pass is not run.
1656 ;; "&& 1" is needed to keep it from matching the previous pattern.
1658 [(set (match_operand:DI 0 "push_operand")
1659 (match_operand:DI 1 "immediate_operand"))]
1660 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1661 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1662 [(set (match_dup 0) (match_dup 1))
1663 (set (match_dup 2) (match_dup 3))]
1665 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1667 operands[1] = gen_lowpart (DImode, operands[2]);
1668 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1673 [(set (match_operand:DI 0 "push_operand")
1674 (match_operand:DI 1 "immediate_operand"))]
1675 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1676 ? epilogue_completed : reload_completed)
1677 && !symbolic_operand (operands[1], DImode)
1678 && !x86_64_immediate_operand (operands[1], DImode)"
1679 [(set (match_dup 0) (match_dup 1))
1680 (set (match_dup 2) (match_dup 3))]
1682 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1684 operands[1] = gen_lowpart (DImode, operands[2]);
1685 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1690 [(set (match_operand:DI 0 "push_operand")
1691 (match_operand:DI 1 "general_operand"))]
1692 "!TARGET_64BIT && reload_completed
1693 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1695 "ix86_split_long_move (operands); DONE;")
1697 (define_insn "*pushsi2"
1698 [(set (match_operand:SI 0 "push_operand" "=<")
1699 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1702 [(set_attr "type" "push")
1703 (set_attr "mode" "SI")])
1705 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1706 ;; "push a byte/word". But actually we use pushl, which has the effect
1707 ;; of rounding the amount pushed up to a word.
1709 ;; For TARGET_64BIT we always round up to 8 bytes.
1710 (define_insn "*push<mode>2_rex64"
1711 [(set (match_operand:SWI124 0 "push_operand" "=X")
1712 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1715 [(set_attr "type" "push")
1716 (set_attr "mode" "DI")])
1718 (define_insn "*push<mode>2"
1719 [(set (match_operand:SWI12 0 "push_operand" "=X")
1720 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1723 [(set_attr "type" "push")
1724 (set_attr "mode" "SI")])
1726 (define_insn "*push<mode>2_prologue"
1727 [(set (match_operand:W 0 "push_operand" "=<")
1728 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1729 (clobber (mem:BLK (scratch)))]
1731 "push{<imodesuffix>}\t%1"
1732 [(set_attr "type" "push")
1733 (set_attr "mode" "<MODE>")])
1735 (define_insn "*pop<mode>1"
1736 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1737 (match_operand:W 1 "pop_operand" ">"))]
1739 "pop{<imodesuffix>}\t%0"
1740 [(set_attr "type" "pop")
1741 (set_attr "mode" "<MODE>")])
1743 (define_insn "*pop<mode>1_epilogue"
1744 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1745 (match_operand:W 1 "pop_operand" ">"))
1746 (clobber (mem:BLK (scratch)))]
1748 "pop{<imodesuffix>}\t%0"
1749 [(set_attr "type" "pop")
1750 (set_attr "mode" "<MODE>")])
1752 (define_insn "*pushfl<mode>2"
1753 [(set (match_operand:W 0 "push_operand" "=<")
1754 (match_operand:W 1 "flags_reg_operand"))]
1756 "pushf{<imodesuffix>}"
1757 [(set_attr "type" "push")
1758 (set_attr "mode" "<MODE>")])
1760 (define_insn "*popfl<mode>1"
1761 [(set (match_operand:W 0 "flags_reg_operand")
1762 (match_operand:W 1 "pop_operand" ">"))]
1764 "popf{<imodesuffix>}"
1765 [(set_attr "type" "pop")
1766 (set_attr "mode" "<MODE>")])
1769 ;; Move instructions.
1771 (define_expand "movxi"
1772 [(set (match_operand:XI 0 "nonimmediate_operand")
1773 (match_operand:XI 1 "general_operand"))]
1775 "ix86_expand_move (XImode, operands); DONE;")
1777 ;; Reload patterns to support multi-word load/store
1778 ;; with non-offsetable address.
1779 (define_expand "reload_noff_store"
1780 [(parallel [(match_operand 0 "memory_operand" "=m")
1781 (match_operand 1 "register_operand" "r")
1782 (match_operand:DI 2 "register_operand" "=&r")])]
1785 rtx mem = operands[0];
1786 rtx addr = XEXP (mem, 0);
1788 emit_move_insn (operands[2], addr);
1789 mem = replace_equiv_address_nv (mem, operands[2]);
1791 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1795 (define_expand "reload_noff_load"
1796 [(parallel [(match_operand 0 "register_operand" "=r")
1797 (match_operand 1 "memory_operand" "m")
1798 (match_operand:DI 2 "register_operand" "=r")])]
1801 rtx mem = operands[1];
1802 rtx addr = XEXP (mem, 0);
1804 emit_move_insn (operands[2], addr);
1805 mem = replace_equiv_address_nv (mem, operands[2]);
1807 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1811 (define_expand "movoi"
1812 [(set (match_operand:OI 0 "nonimmediate_operand")
1813 (match_operand:OI 1 "general_operand"))]
1815 "ix86_expand_move (OImode, operands); DONE;")
1817 (define_expand "movti"
1818 [(set (match_operand:TI 0 "nonimmediate_operand")
1819 (match_operand:TI 1 "nonimmediate_operand"))]
1820 "TARGET_64BIT || TARGET_SSE"
1823 ix86_expand_move (TImode, operands);
1825 ix86_expand_vector_move (TImode, operands);
1829 ;; This expands to what emit_move_complex would generate if we didn't
1830 ;; have a movti pattern. Having this avoids problems with reload on
1831 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1832 ;; to have around all the time.
1833 (define_expand "movcdi"
1834 [(set (match_operand:CDI 0 "nonimmediate_operand")
1835 (match_operand:CDI 1 "general_operand"))]
1838 if (push_operand (operands[0], CDImode))
1839 emit_move_complex_push (CDImode, operands[0], operands[1]);
1841 emit_move_complex_parts (operands[0], operands[1]);
1845 (define_expand "mov<mode>"
1846 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1847 (match_operand:SWI1248x 1 "general_operand"))]
1849 "ix86_expand_move (<MODE>mode, operands); DONE;")
1851 (define_insn "*mov<mode>_xor"
1852 [(set (match_operand:SWI48 0 "register_operand" "=r")
1853 (match_operand:SWI48 1 "const0_operand"))
1854 (clobber (reg:CC FLAGS_REG))]
1857 [(set_attr "type" "alu1")
1858 (set_attr "mode" "SI")
1859 (set_attr "length_immediate" "0")])
1861 (define_insn "*mov<mode>_or"
1862 [(set (match_operand:SWI48 0 "register_operand" "=r")
1863 (match_operand:SWI48 1 "const_int_operand"))
1864 (clobber (reg:CC FLAGS_REG))]
1866 && operands[1] == constm1_rtx"
1867 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1868 [(set_attr "type" "alu1")
1869 (set_attr "mode" "<MODE>")
1870 (set_attr "length_immediate" "1")])
1872 (define_insn "*movxi_internal_avx512f"
1873 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1874 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1875 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1877 switch (which_alternative)
1880 return standard_sse_constant_opcode (insn, operands[1]);
1883 if (misaligned_operand (operands[0], XImode)
1884 || misaligned_operand (operands[1], XImode))
1885 return "vmovdqu32\t{%1, %0|%0, %1}";
1887 return "vmovdqa32\t{%1, %0|%0, %1}";
1892 [(set_attr "type" "sselog1,ssemov,ssemov")
1893 (set_attr "prefix" "evex")
1894 (set_attr "mode" "XI")])
1896 (define_insn "*movoi_internal_avx"
1897 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1898 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1899 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1901 switch (get_attr_type (insn))
1904 return standard_sse_constant_opcode (insn, operands[1]);
1907 if (misaligned_operand (operands[0], OImode)
1908 || misaligned_operand (operands[1], OImode))
1910 if (get_attr_mode (insn) == MODE_V8SF)
1911 return "vmovups\t{%1, %0|%0, %1}";
1913 return "vmovdqu\t{%1, %0|%0, %1}";
1917 if (get_attr_mode (insn) == MODE_V8SF)
1918 return "vmovaps\t{%1, %0|%0, %1}";
1920 return "vmovdqa\t{%1, %0|%0, %1}";
1927 [(set_attr "type" "sselog1,ssemov,ssemov")
1928 (set_attr "prefix" "vex")
1930 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1931 (const_string "V8SF")
1932 (and (eq_attr "alternative" "2")
1933 (match_test "TARGET_SSE_TYPELESS_STORES"))
1934 (const_string "V8SF")
1936 (const_string "OI")))])
1938 (define_insn "*movti_internal"
1939 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1940 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1941 "(TARGET_64BIT || TARGET_SSE)
1942 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1944 switch (get_attr_type (insn))
1950 return standard_sse_constant_opcode (insn, operands[1]);
1953 /* TDmode values are passed as TImode on the stack. Moving them
1954 to stack may result in unaligned memory access. */
1955 if (misaligned_operand (operands[0], TImode)
1956 || misaligned_operand (operands[1], TImode))
1958 if (get_attr_mode (insn) == MODE_V4SF)
1959 return "%vmovups\t{%1, %0|%0, %1}";
1961 return "%vmovdqu\t{%1, %0|%0, %1}";
1965 if (get_attr_mode (insn) == MODE_V4SF)
1966 return "%vmovaps\t{%1, %0|%0, %1}";
1968 return "%vmovdqa\t{%1, %0|%0, %1}";
1975 [(set_attr "isa" "x64,x64,*,*,*")
1976 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1977 (set (attr "prefix")
1978 (if_then_else (eq_attr "type" "sselog1,ssemov")
1979 (const_string "maybe_vex")
1980 (const_string "orig")))
1982 (cond [(eq_attr "alternative" "0,1")
1984 (ior (not (match_test "TARGET_SSE2"))
1985 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1986 (const_string "V4SF")
1987 (and (eq_attr "alternative" "4")
1988 (match_test "TARGET_SSE_TYPELESS_STORES"))
1989 (const_string "V4SF")
1990 (match_test "TARGET_AVX")
1992 (match_test "optimize_function_for_size_p (cfun)")
1993 (const_string "V4SF")
1995 (const_string "TI")))])
1998 [(set (match_operand:TI 0 "nonimmediate_operand")
1999 (match_operand:TI 1 "general_operand"))]
2001 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2003 "ix86_split_long_move (operands); DONE;")
2005 (define_insn "*movdi_internal"
2006 [(set (match_operand:DI 0 "nonimmediate_operand"
2007 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
2008 (match_operand:DI 1 "general_operand"
2009 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn"))]
2010 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2012 switch (get_attr_type (insn))
2018 return "pxor\t%0, %0";
2021 /* Handle broken assemblers that require movd instead of movq. */
2022 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2023 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2024 return "movd\t{%1, %0|%0, %1}";
2025 return "movq\t{%1, %0|%0, %1}";
2028 if (GENERAL_REG_P (operands[0]))
2029 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2031 return standard_sse_constant_opcode (insn, operands[1]);
2034 switch (get_attr_mode (insn))
2037 /* Handle broken assemblers that require movd instead of movq. */
2038 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2039 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2040 return "%vmovd\t{%1, %0|%0, %1}";
2041 return "%vmovq\t{%1, %0|%0, %1}";
2043 return "%vmovdqa\t{%1, %0|%0, %1}";
2045 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2048 gcc_assert (!TARGET_AVX);
2049 return "movlps\t{%1, %0|%0, %1}";
2051 return "%vmovaps\t{%1, %0|%0, %1}";
2058 if (SSE_REG_P (operands[0]))
2059 return "movq2dq\t{%1, %0|%0, %1}";
2061 return "movdq2q\t{%1, %0|%0, %1}";
2064 return "lea{q}\t{%E1, %0|%0, %E1}";
2067 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2068 if (get_attr_mode (insn) == MODE_SI)
2069 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2070 else if (which_alternative == 4)
2071 return "movabs{q}\t{%1, %0|%0, %1}";
2072 else if (ix86_use_lea_for_mov (insn, operands))
2073 return "lea{q}\t{%E1, %0|%0, %E1}";
2075 return "mov{q}\t{%1, %0|%0, %1}";
2082 (cond [(eq_attr "alternative" "0,1")
2083 (const_string "nox64")
2084 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
2085 (const_string "x64")
2086 (eq_attr "alternative" "17")
2087 (const_string "x64_sse4")
2089 (const_string "*")))
2091 (cond [(eq_attr "alternative" "0,1")
2092 (const_string "multi")
2093 (eq_attr "alternative" "6")
2094 (const_string "mmx")
2095 (eq_attr "alternative" "7,8,9,10,11")
2096 (const_string "mmxmov")
2097 (eq_attr "alternative" "12,17")
2098 (const_string "sselog1")
2099 (eq_attr "alternative" "13,14,15,16,18")
2100 (const_string "ssemov")
2101 (eq_attr "alternative" "19,20")
2102 (const_string "ssecvt")
2103 (match_operand 1 "pic_32bit_operand")
2104 (const_string "lea")
2106 (const_string "imov")))
2109 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2111 (const_string "*")))
2112 (set (attr "length_immediate")
2113 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2115 (eq_attr "alternative" "17")
2118 (const_string "*")))
2119 (set (attr "prefix_rex")
2120 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2122 (const_string "*")))
2123 (set (attr "prefix_extra")
2124 (if_then_else (eq_attr "alternative" "17")
2126 (const_string "*")))
2127 (set (attr "prefix")
2128 (if_then_else (eq_attr "type" "sselog1,ssemov")
2129 (const_string "maybe_vex")
2130 (const_string "orig")))
2131 (set (attr "prefix_data16")
2132 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2134 (const_string "*")))
2136 (cond [(eq_attr "alternative" "2")
2138 (eq_attr "alternative" "12,13")
2139 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2140 (match_operand 1 "ext_sse_reg_operand"))
2142 (ior (not (match_test "TARGET_SSE2"))
2143 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2144 (const_string "V4SF")
2145 (match_test "TARGET_AVX")
2147 (match_test "optimize_function_for_size_p (cfun)")
2148 (const_string "V4SF")
2150 (const_string "TI"))
2152 (and (eq_attr "alternative" "14,15")
2153 (not (match_test "TARGET_SSE2")))
2154 (const_string "V2SF")
2155 (eq_attr "alternative" "17")
2158 (const_string "DI")))])
2161 [(set (match_operand:DI 0 "nonimmediate_operand")
2162 (match_operand:DI 1 "general_operand"))]
2163 "!TARGET_64BIT && reload_completed
2164 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2165 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2167 "ix86_split_long_move (operands); DONE;")
2169 (define_insn "*movsi_internal"
2170 [(set (match_operand:SI 0 "nonimmediate_operand"
2171 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi")
2172 (match_operand:SI 1 "general_operand"
2173 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r"))]
2174 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2176 switch (get_attr_type (insn))
2179 if (GENERAL_REG_P (operands[0]))
2180 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2182 return standard_sse_constant_opcode (insn, operands[1]);
2185 switch (get_attr_mode (insn))
2188 return "%vmovd\t{%1, %0|%0, %1}";
2190 return "%vmovdqa\t{%1, %0|%0, %1}";
2192 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2195 return "%vmovaps\t{%1, %0|%0, %1}";
2198 gcc_assert (!TARGET_AVX);
2199 return "movss\t{%1, %0|%0, %1}";
2206 return "pxor\t%0, %0";
2209 switch (get_attr_mode (insn))
2212 return "movq\t{%1, %0|%0, %1}";
2214 return "movd\t{%1, %0|%0, %1}";
2221 return "lea{l}\t{%E1, %0|%0, %E1}";
2224 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2225 if (ix86_use_lea_for_mov (insn, operands))
2226 return "lea{l}\t{%E1, %0|%0, %E1}";
2228 return "mov{l}\t{%1, %0|%0, %1}";
2235 (if_then_else (eq_attr "alternative" "11")
2236 (const_string "sse4")
2237 (const_string "*")))
2239 (cond [(eq_attr "alternative" "2")
2240 (const_string "mmx")
2241 (eq_attr "alternative" "3,4,5")
2242 (const_string "mmxmov")
2243 (eq_attr "alternative" "6,11")
2244 (const_string "sselog1")
2245 (eq_attr "alternative" "7,8,9,10,12")
2246 (const_string "ssemov")
2247 (match_operand 1 "pic_32bit_operand")
2248 (const_string "lea")
2250 (const_string "imov")))
2251 (set (attr "length_immediate")
2252 (if_then_else (eq_attr "alternative" "11")
2254 (const_string "*")))
2255 (set (attr "prefix_extra")
2256 (if_then_else (eq_attr "alternative" "11")
2258 (const_string "*")))
2259 (set (attr "prefix")
2260 (if_then_else (eq_attr "type" "sselog1,ssemov")
2261 (const_string "maybe_vex")
2262 (const_string "orig")))
2263 (set (attr "prefix_data16")
2264 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2266 (const_string "*")))
2268 (cond [(eq_attr "alternative" "2,3")
2270 (eq_attr "alternative" "6,7")
2271 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2272 (match_operand 1 "ext_sse_reg_operand"))
2274 (ior (not (match_test "TARGET_SSE2"))
2275 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2276 (const_string "V4SF")
2277 (match_test "TARGET_AVX")
2279 (match_test "optimize_function_for_size_p (cfun)")
2280 (const_string "V4SF")
2282 (const_string "TI"))
2284 (and (eq_attr "alternative" "8,9")
2285 (not (match_test "TARGET_SSE2")))
2287 (eq_attr "alternative" "11")
2290 (const_string "SI")))])
2292 (define_insn "kmovw"
2293 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2295 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2297 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2299 kmovw\t{%k1, %0|%0, %k1}
2300 kmovw\t{%1, %0|%0, %1}";
2301 [(set_attr "mode" "HI")
2302 (set_attr "type" "mskmov")
2303 (set_attr "prefix" "vex")])
2306 (define_insn "*movhi_internal"
2307 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2308 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2309 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2311 switch (get_attr_type (insn))
2314 /* movzwl is faster than movw on p2 due to partial word stalls,
2315 though not as fast as an aligned movl. */
2316 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2319 switch (which_alternative)
2321 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2322 case 5: return "kmovw\t{%1, %0|%0, %1}";
2323 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2324 default: gcc_unreachable ();
2328 if (get_attr_mode (insn) == MODE_SI)
2329 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2331 return "mov{w}\t{%1, %0|%0, %1}";
2335 (cond [(match_test "optimize_function_for_size_p (cfun)")
2336 (const_string "imov")
2337 (and (eq_attr "alternative" "0")
2338 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2339 (not (match_test "TARGET_HIMODE_MATH"))))
2340 (const_string "imov")
2341 (and (eq_attr "alternative" "1,2")
2342 (match_operand:HI 1 "aligned_operand"))
2343 (const_string "imov")
2344 (eq_attr "alternative" "4,5,6")
2345 (const_string "mskmov")
2346 (and (match_test "TARGET_MOVX")
2347 (eq_attr "alternative" "0,2"))
2348 (const_string "imovx")
2350 (const_string "imov")))
2351 (set (attr "prefix")
2352 (if_then_else (eq_attr "alternative" "4,5,6")
2353 (const_string "vex")
2354 (const_string "orig")))
2356 (cond [(eq_attr "type" "imovx")
2358 (and (eq_attr "alternative" "1,2")
2359 (match_operand:HI 1 "aligned_operand"))
2361 (and (eq_attr "alternative" "0")
2362 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2363 (not (match_test "TARGET_HIMODE_MATH"))))
2366 (const_string "HI")))])
2368 ;; Situation is quite tricky about when to choose full sized (SImode) move
2369 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2370 ;; partial register dependency machines (such as AMD Athlon), where QImode
2371 ;; moves issue extra dependency and for partial register stalls machines
2372 ;; that don't use QImode patterns (and QImode move cause stall on the next
2375 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2376 ;; register stall machines with, where we use QImode instructions, since
2377 ;; partial register stall can be caused there. Then we use movzx.
2379 (define_insn "*movqi_internal"
2380 [(set (match_operand:QI 0 "nonimmediate_operand"
2381 "=q,q ,q ,r,r ,?r,m ,k,k,r")
2382 (match_operand:QI 1 "general_operand"
2383 "q ,qn,qm,q,rn,qm,qn,r ,k,k"))]
2384 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2386 switch (get_attr_type (insn))
2389 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2390 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2393 switch (which_alternative)
2395 case 7: return "kmovw\t{%k1, %0|%0, %k1}";
2396 case 8: return "kmovw\t{%1, %0|%0, %1}";
2397 case 9: return "kmovw\t{%1, %k0|%k0, %1}";
2398 default: gcc_unreachable ();
2402 if (get_attr_mode (insn) == MODE_SI)
2403 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2405 return "mov{b}\t{%1, %0|%0, %1}";
2409 (cond [(and (eq_attr "alternative" "5")
2410 (not (match_operand:QI 1 "aligned_operand")))
2411 (const_string "imovx")
2412 (match_test "optimize_function_for_size_p (cfun)")
2413 (const_string "imov")
2414 (and (eq_attr "alternative" "3")
2415 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2416 (not (match_test "TARGET_QIMODE_MATH"))))
2417 (const_string "imov")
2418 (eq_attr "alternative" "3,5")
2419 (const_string "imovx")
2420 (eq_attr "alternative" "7,8,9")
2421 (const_string "mskmov")
2422 (and (match_test "TARGET_MOVX")
2423 (eq_attr "alternative" "2"))
2424 (const_string "imovx")
2426 (const_string "imov")))
2427 (set (attr "prefix")
2428 (if_then_else (eq_attr "alternative" "7,8,9")
2429 (const_string "vex")
2430 (const_string "orig")))
2432 (cond [(eq_attr "alternative" "3,4,5")
2434 (eq_attr "alternative" "6")
2436 (eq_attr "type" "imovx")
2438 (and (eq_attr "type" "imov")
2439 (and (eq_attr "alternative" "0,1")
2440 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2441 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2442 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2444 ;; Avoid partial register stalls when not using QImode arithmetic
2445 (and (eq_attr "type" "imov")
2446 (and (eq_attr "alternative" "0,1")
2447 (and (match_test "TARGET_PARTIAL_REG_STALL")
2448 (not (match_test "TARGET_QIMODE_MATH")))))
2451 (const_string "QI")))])
2453 ;; Stores and loads of ax to arbitrary constant address.
2454 ;; We fake an second form of instruction to force reload to load address
2455 ;; into register when rax is not available
2456 (define_insn "*movabs<mode>_1"
2457 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2458 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2459 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2461 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2462 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2463 [(set_attr "type" "imov")
2464 (set_attr "modrm" "0,*")
2465 (set_attr "length_address" "8,0")
2466 (set_attr "length_immediate" "0,*")
2467 (set_attr "memory" "store")
2468 (set_attr "mode" "<MODE>")])
2470 (define_insn "*movabs<mode>_2"
2471 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2472 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2473 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2475 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2476 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2477 [(set_attr "type" "imov")
2478 (set_attr "modrm" "0,*")
2479 (set_attr "length_address" "8,0")
2480 (set_attr "length_immediate" "0")
2481 (set_attr "memory" "load")
2482 (set_attr "mode" "<MODE>")])
2484 (define_insn "*swap<mode>"
2485 [(set (match_operand:SWI48 0 "register_operand" "+r")
2486 (match_operand:SWI48 1 "register_operand" "+r"))
2490 "xchg{<imodesuffix>}\t%1, %0"
2491 [(set_attr "type" "imov")
2492 (set_attr "mode" "<MODE>")
2493 (set_attr "pent_pair" "np")
2494 (set_attr "athlon_decode" "vector")
2495 (set_attr "amdfam10_decode" "double")
2496 (set_attr "bdver1_decode" "double")])
2498 (define_insn "*swap<mode>_1"
2499 [(set (match_operand:SWI12 0 "register_operand" "+r")
2500 (match_operand:SWI12 1 "register_operand" "+r"))
2503 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2505 [(set_attr "type" "imov")
2506 (set_attr "mode" "SI")
2507 (set_attr "pent_pair" "np")
2508 (set_attr "athlon_decode" "vector")
2509 (set_attr "amdfam10_decode" "double")
2510 (set_attr "bdver1_decode" "double")])
2512 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2513 ;; is disabled for AMDFAM10
2514 (define_insn "*swap<mode>_2"
2515 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2516 (match_operand:SWI12 1 "register_operand" "+<r>"))
2519 "TARGET_PARTIAL_REG_STALL"
2520 "xchg{<imodesuffix>}\t%1, %0"
2521 [(set_attr "type" "imov")
2522 (set_attr "mode" "<MODE>")
2523 (set_attr "pent_pair" "np")
2524 (set_attr "athlon_decode" "vector")])
2526 (define_expand "movstrict<mode>"
2527 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2528 (match_operand:SWI12 1 "general_operand"))]
2531 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2533 if (GET_CODE (operands[0]) == SUBREG
2534 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2536 /* Don't generate memory->memory moves, go through a register */
2537 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2538 operands[1] = force_reg (<MODE>mode, operands[1]);
2541 (define_insn "*movstrict<mode>_1"
2542 [(set (strict_low_part
2543 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2544 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2545 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2546 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2547 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2548 [(set_attr "type" "imov")
2549 (set_attr "mode" "<MODE>")])
2551 (define_insn "*movstrict<mode>_xor"
2552 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2553 (match_operand:SWI12 1 "const0_operand"))
2554 (clobber (reg:CC FLAGS_REG))]
2556 "xor{<imodesuffix>}\t%0, %0"
2557 [(set_attr "type" "alu1")
2558 (set_attr "mode" "<MODE>")
2559 (set_attr "length_immediate" "0")])
2561 (define_insn "*mov<mode>_extv_1"
2562 [(set (match_operand:SWI24 0 "register_operand" "=R")
2563 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2567 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2568 [(set_attr "type" "imovx")
2569 (set_attr "mode" "SI")])
2571 (define_insn "*movqi_extv_1"
2572 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2573 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2578 switch (get_attr_type (insn))
2581 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2583 return "mov{b}\t{%h1, %0|%0, %h1}";
2586 [(set_attr "isa" "*,*,nox64")
2588 (if_then_else (and (match_operand:QI 0 "register_operand")
2589 (ior (not (match_operand:QI 0 "QIreg_operand"))
2590 (match_test "TARGET_MOVX")))
2591 (const_string "imovx")
2592 (const_string "imov")))
2594 (if_then_else (eq_attr "type" "imovx")
2596 (const_string "QI")))])
2598 (define_insn "*mov<mode>_extzv_1"
2599 [(set (match_operand:SWI48 0 "register_operand" "=R")
2600 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2604 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2605 [(set_attr "type" "imovx")
2606 (set_attr "mode" "SI")])
2608 (define_insn "*movqi_extzv_2"
2609 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2611 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2616 switch (get_attr_type (insn))
2619 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2621 return "mov{b}\t{%h1, %0|%0, %h1}";
2624 [(set_attr "isa" "*,*,nox64")
2626 (if_then_else (and (match_operand:QI 0 "register_operand")
2627 (ior (not (match_operand:QI 0 "QIreg_operand"))
2628 (match_test "TARGET_MOVX")))
2629 (const_string "imovx")
2630 (const_string "imov")))
2632 (if_then_else (eq_attr "type" "imovx")
2634 (const_string "QI")))])
2636 (define_insn "mov<mode>_insv_1"
2637 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2640 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2643 if (CONST_INT_P (operands[1]))
2644 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2645 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2647 [(set_attr "isa" "*,nox64")
2648 (set_attr "type" "imov")
2649 (set_attr "mode" "QI")])
2651 (define_insn "*movqi_insv_2"
2652 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2655 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2658 "mov{b}\t{%h1, %h0|%h0, %h1}"
2659 [(set_attr "type" "imov")
2660 (set_attr "mode" "QI")])
2662 ;; Floating point push instructions.
2664 (define_insn "*pushtf"
2665 [(set (match_operand:TF 0 "push_operand" "=<,<")
2666 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2667 "TARGET_64BIT || TARGET_SSE"
2669 /* This insn should be already split before reg-stack. */
2672 [(set_attr "isa" "*,x64")
2673 (set_attr "type" "multi")
2674 (set_attr "unit" "sse,*")
2675 (set_attr "mode" "TF,DI")])
2677 ;; %%% Kill this when call knows how to work this out.
2679 [(set (match_operand:TF 0 "push_operand")
2680 (match_operand:TF 1 "sse_reg_operand"))]
2681 "TARGET_SSE && reload_completed"
2682 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2683 (set (match_dup 0) (match_dup 1))]
2685 /* Preserve memory attributes. */
2686 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2689 (define_insn "*pushxf"
2690 [(set (match_operand:XF 0 "push_operand" "=<,<")
2691 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2694 /* This insn should be already split before reg-stack. */
2697 [(set_attr "type" "multi")
2698 (set_attr "unit" "i387,*")
2700 (cond [(eq_attr "alternative" "1")
2701 (if_then_else (match_test "TARGET_64BIT")
2703 (const_string "SI"))
2705 (const_string "XF")))])
2707 ;; %%% Kill this when call knows how to work this out.
2709 [(set (match_operand:XF 0 "push_operand")
2710 (match_operand:XF 1 "fp_register_operand"))]
2712 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2713 (set (match_dup 0) (match_dup 1))]
2715 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2716 /* Preserve memory attributes. */
2717 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2720 (define_insn "*pushdf"
2721 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2722 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2725 /* This insn should be already split before reg-stack. */
2728 [(set_attr "isa" "*,nox64,x64,sse2")
2729 (set_attr "type" "multi")
2730 (set_attr "unit" "i387,*,*,sse")
2731 (set_attr "mode" "DF,SI,DI,DF")])
2733 ;; %%% Kill this when call knows how to work this out.
2735 [(set (match_operand:DF 0 "push_operand")
2736 (match_operand:DF 1 "any_fp_register_operand"))]
2738 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2739 (set (match_dup 0) (match_dup 1))]
2741 /* Preserve memory attributes. */
2742 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2745 (define_insn "*pushsf_rex64"
2746 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2747 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2750 /* Anything else should be already split before reg-stack. */
2751 gcc_assert (which_alternative == 1);
2752 return "push{q}\t%q1";
2754 [(set_attr "type" "multi,push,multi")
2755 (set_attr "unit" "i387,*,*")
2756 (set_attr "mode" "SF,DI,SF")])
2758 (define_insn "*pushsf"
2759 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2760 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2763 /* Anything else should be already split before reg-stack. */
2764 gcc_assert (which_alternative == 1);
2765 return "push{l}\t%1";
2767 [(set_attr "type" "multi,push,multi")
2768 (set_attr "unit" "i387,*,*")
2769 (set_attr "mode" "SF,SI,SF")])
2771 ;; %%% Kill this when call knows how to work this out.
2773 [(set (match_operand:SF 0 "push_operand")
2774 (match_operand:SF 1 "any_fp_register_operand"))]
2776 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2777 (set (match_dup 0) (match_dup 1))]
2779 rtx op = XEXP (operands[0], 0);
2780 if (GET_CODE (op) == PRE_DEC)
2782 gcc_assert (!TARGET_64BIT);
2787 op = XEXP (XEXP (op, 1), 1);
2788 gcc_assert (CONST_INT_P (op));
2791 /* Preserve memory attributes. */
2792 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2796 [(set (match_operand:SF 0 "push_operand")
2797 (match_operand:SF 1 "memory_operand"))]
2799 && (operands[2] = find_constant_src (insn))"
2800 [(set (match_dup 0) (match_dup 2))])
2803 [(set (match_operand 0 "push_operand")
2804 (match_operand 1 "general_operand"))]
2806 && (GET_MODE (operands[0]) == TFmode
2807 || GET_MODE (operands[0]) == XFmode
2808 || GET_MODE (operands[0]) == DFmode)
2809 && !ANY_FP_REG_P (operands[1])"
2811 "ix86_split_long_move (operands); DONE;")
2813 ;; Floating point move instructions.
2815 (define_expand "movtf"
2816 [(set (match_operand:TF 0 "nonimmediate_operand")
2817 (match_operand:TF 1 "nonimmediate_operand"))]
2818 "TARGET_64BIT || TARGET_SSE"
2819 "ix86_expand_move (TFmode, operands); DONE;")
2821 (define_expand "mov<mode>"
2822 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2823 (match_operand:X87MODEF 1 "general_operand"))]
2825 "ix86_expand_move (<MODE>mode, operands); DONE;")
2827 (define_insn "*movtf_internal"
2828 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2829 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2830 "(TARGET_64BIT || TARGET_SSE)
2831 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2832 && (!can_create_pseudo_p ()
2833 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2834 || GET_CODE (operands[1]) != CONST_DOUBLE
2835 || (optimize_function_for_size_p (cfun)
2836 && standard_sse_constant_p (operands[1])
2837 && !memory_operand (operands[0], TFmode))
2838 || (!TARGET_MEMORY_MISMATCH_STALL
2839 && memory_operand (operands[0], TFmode)))"
2841 switch (get_attr_type (insn))
2844 return standard_sse_constant_opcode (insn, operands[1]);
2847 /* Handle misaligned load/store since we
2848 don't have movmisaligntf pattern. */
2849 if (misaligned_operand (operands[0], TFmode)
2850 || misaligned_operand (operands[1], TFmode))
2852 if (get_attr_mode (insn) == MODE_V4SF)
2853 return "%vmovups\t{%1, %0|%0, %1}";
2855 return "%vmovdqu\t{%1, %0|%0, %1}";
2859 if (get_attr_mode (insn) == MODE_V4SF)
2860 return "%vmovaps\t{%1, %0|%0, %1}";
2862 return "%vmovdqa\t{%1, %0|%0, %1}";
2872 [(set_attr "isa" "*,*,*,x64,x64")
2873 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2874 (set (attr "prefix")
2875 (if_then_else (eq_attr "type" "sselog1,ssemov")
2876 (const_string "maybe_vex")
2877 (const_string "orig")))
2879 (cond [(eq_attr "alternative" "3,4")
2881 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2882 (const_string "V4SF")
2883 (and (eq_attr "alternative" "2")
2884 (match_test "TARGET_SSE_TYPELESS_STORES"))
2885 (const_string "V4SF")
2886 (match_test "TARGET_AVX")
2888 (ior (not (match_test "TARGET_SSE2"))
2889 (match_test "optimize_function_for_size_p (cfun)"))
2890 (const_string "V4SF")
2892 (const_string "TI")))])
2894 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2895 (define_insn "*movxf_internal"
2896 [(set (match_operand:XF 0 "nonimmediate_operand"
2897 "=f,m,f,?Yx*r ,!o ,!o")
2898 (match_operand:XF 1 "general_operand"
2899 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2900 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2901 && (!can_create_pseudo_p ()
2902 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2903 || GET_CODE (operands[1]) != CONST_DOUBLE
2904 || (optimize_function_for_size_p (cfun)
2905 && standard_80387_constant_p (operands[1]) > 0
2906 && !memory_operand (operands[0], XFmode))
2907 || (!TARGET_MEMORY_MISMATCH_STALL
2908 && memory_operand (operands[0], XFmode)))"
2910 switch (get_attr_type (insn))
2913 if (which_alternative == 2)
2914 return standard_80387_constant_opcode (operands[1]);
2915 return output_387_reg_move (insn, operands);
2924 [(set_attr "isa" "*,*,*,*,nox64,x64")
2925 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2927 (cond [(eq_attr "alternative" "3,4,5")
2928 (if_then_else (match_test "TARGET_64BIT")
2930 (const_string "SI"))
2932 (const_string "XF")))])
2934 ;; Possible store forwarding (partial memory) stall in alternative 4.
2935 (define_insn "*movdf_internal"
2936 [(set (match_operand:DF 0 "nonimmediate_operand"
2937 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2938 (match_operand:DF 1 "general_operand"
2939 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2940 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2941 && (!can_create_pseudo_p ()
2942 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2943 || GET_CODE (operands[1]) != CONST_DOUBLE
2944 || (optimize_function_for_size_p (cfun)
2945 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2946 && standard_80387_constant_p (operands[1]) > 0)
2947 || (TARGET_SSE2 && TARGET_SSE_MATH
2948 && standard_sse_constant_p (operands[1])))
2949 && !memory_operand (operands[0], DFmode))
2950 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2951 && memory_operand (operands[0], DFmode)))"
2953 switch (get_attr_type (insn))
2956 if (which_alternative == 2)
2957 return standard_80387_constant_opcode (operands[1]);
2958 return output_387_reg_move (insn, operands);
2964 if (get_attr_mode (insn) == MODE_SI)
2965 return "mov{l}\t{%1, %k0|%k0, %1}";
2966 else if (which_alternative == 8)
2967 return "movabs{q}\t{%1, %0|%0, %1}";
2969 return "mov{q}\t{%1, %0|%0, %1}";
2972 return standard_sse_constant_opcode (insn, operands[1]);
2975 switch (get_attr_mode (insn))
2978 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2979 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2980 return "%vmovsd\t{%1, %0|%0, %1}";
2983 return "%vmovaps\t{%1, %0|%0, %1}";
2985 return "vmovapd\t{%g1, %g0|%g0, %g1}";
2987 return "%vmovapd\t{%1, %0|%0, %1}";
2990 gcc_assert (!TARGET_AVX);
2991 return "movlps\t{%1, %0|%0, %1}";
2993 gcc_assert (!TARGET_AVX);
2994 return "movlpd\t{%1, %0|%0, %1}";
2997 /* Handle broken assemblers that require movd instead of movq. */
2998 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2999 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3000 return "%vmovd\t{%1, %0|%0, %1}";
3001 return "%vmovq\t{%1, %0|%0, %1}";
3012 (cond [(eq_attr "alternative" "3,4")
3013 (const_string "nox64")
3014 (eq_attr "alternative" "5,6,7,8,17,18")
3015 (const_string "x64")
3016 (eq_attr "alternative" "9,10,11,12")
3017 (const_string "sse2")
3019 (const_string "*")))
3021 (cond [(eq_attr "alternative" "0,1,2")
3022 (const_string "fmov")
3023 (eq_attr "alternative" "3,4")
3024 (const_string "multi")
3025 (eq_attr "alternative" "5,6,7,8")
3026 (const_string "imov")
3027 (eq_attr "alternative" "9,13")
3028 (const_string "sselog1")
3030 (const_string "ssemov")))
3032 (if_then_else (eq_attr "alternative" "8")
3034 (const_string "*")))
3035 (set (attr "length_immediate")
3036 (if_then_else (eq_attr "alternative" "8")
3038 (const_string "*")))
3039 (set (attr "prefix")
3040 (if_then_else (eq_attr "type" "sselog1,ssemov")
3041 (const_string "maybe_vex")
3042 (const_string "orig")))
3043 (set (attr "prefix_data16")
3045 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3046 (eq_attr "mode" "V1DF"))
3048 (const_string "*")))
3050 (cond [(eq_attr "alternative" "3,4,7")
3052 (eq_attr "alternative" "5,6,8,17,18")
3055 /* xorps is one byte shorter for non-AVX targets. */
3056 (eq_attr "alternative" "9,13")
3057 (cond [(not (match_test "TARGET_SSE2"))
3058 (const_string "V4SF")
3059 (match_test "TARGET_AVX512F")
3061 (match_test "TARGET_AVX")
3062 (const_string "V2DF")
3063 (match_test "optimize_function_for_size_p (cfun)")
3064 (const_string "V4SF")
3065 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3068 (const_string "V2DF"))
3070 /* For architectures resolving dependencies on
3071 whole SSE registers use movapd to break dependency
3072 chains, otherwise use short move to avoid extra work. */
3074 /* movaps is one byte shorter for non-AVX targets. */
3075 (eq_attr "alternative" "10,14")
3076 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3077 (match_operand 1 "ext_sse_reg_operand"))
3078 (const_string "V8DF")
3079 (ior (not (match_test "TARGET_SSE2"))
3080 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3081 (const_string "V4SF")
3082 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3083 (const_string "V2DF")
3084 (match_test "TARGET_AVX")
3086 (match_test "optimize_function_for_size_p (cfun)")
3087 (const_string "V4SF")
3089 (const_string "DF"))
3091 /* For architectures resolving dependencies on register
3092 parts we may avoid extra work to zero out upper part
3094 (eq_attr "alternative" "11,15")
3095 (cond [(not (match_test "TARGET_SSE2"))
3096 (const_string "V2SF")
3097 (match_test "TARGET_AVX")
3099 (match_test "TARGET_SSE_SPLIT_REGS")
3100 (const_string "V1DF")
3102 (const_string "DF"))
3104 (and (eq_attr "alternative" "12,16")
3105 (not (match_test "TARGET_SSE2")))
3106 (const_string "V2SF")
3108 (const_string "DF")))])
3110 (define_insn "*movsf_internal"
3111 [(set (match_operand:SF 0 "nonimmediate_operand"
3112 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3113 (match_operand:SF 1 "general_operand"
3114 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3115 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3116 && (!can_create_pseudo_p ()
3117 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3118 || GET_CODE (operands[1]) != CONST_DOUBLE
3119 || (optimize_function_for_size_p (cfun)
3120 && ((!TARGET_SSE_MATH
3121 && standard_80387_constant_p (operands[1]) > 0)
3123 && standard_sse_constant_p (operands[1]))))
3124 || memory_operand (operands[0], SFmode))"
3126 switch (get_attr_type (insn))
3129 if (which_alternative == 2)
3130 return standard_80387_constant_opcode (operands[1]);
3131 return output_387_reg_move (insn, operands);
3134 return "mov{l}\t{%1, %0|%0, %1}";
3137 return standard_sse_constant_opcode (insn, operands[1]);
3140 switch (get_attr_mode (insn))
3143 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3144 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3145 return "%vmovss\t{%1, %0|%0, %1}";
3148 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3150 return "%vmovaps\t{%1, %0|%0, %1}";
3153 return "%vmovd\t{%1, %0|%0, %1}";
3160 switch (get_attr_mode (insn))
3163 return "movq\t{%1, %0|%0, %1}";
3165 return "movd\t{%1, %0|%0, %1}";
3176 (cond [(eq_attr "alternative" "0,1,2")
3177 (const_string "fmov")
3178 (eq_attr "alternative" "3,4")
3179 (const_string "imov")
3180 (eq_attr "alternative" "5")
3181 (const_string "sselog1")
3182 (eq_attr "alternative" "11,12,13,14,15")
3183 (const_string "mmxmov")
3185 (const_string "ssemov")))
3186 (set (attr "prefix")
3187 (if_then_else (eq_attr "type" "sselog1,ssemov")
3188 (const_string "maybe_vex")
3189 (const_string "orig")))
3190 (set (attr "prefix_data16")
3191 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3193 (const_string "*")))
3195 (cond [(eq_attr "alternative" "3,4,9,10,13,14,15")
3197 (eq_attr "alternative" "11")
3199 (eq_attr "alternative" "5")
3200 (cond [(not (match_test "TARGET_SSE2"))
3201 (const_string "V4SF")
3202 (match_test "TARGET_AVX512F")
3203 (const_string "V16SF")
3204 (match_test "TARGET_AVX")
3205 (const_string "V4SF")
3206 (match_test "optimize_function_for_size_p (cfun)")
3207 (const_string "V4SF")
3208 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3211 (const_string "V4SF"))
3213 /* For architectures resolving dependencies on
3214 whole SSE registers use APS move to break dependency
3215 chains, otherwise use short move to avoid extra work.
3217 Do the same for architectures resolving dependencies on
3218 the parts. While in DF mode it is better to always handle
3219 just register parts, the SF mode is different due to lack
3220 of instructions to load just part of the register. It is
3221 better to maintain the whole registers in single format
3222 to avoid problems on using packed logical operations. */
3223 (eq_attr "alternative" "6")
3224 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3225 (match_operand 1 "ext_sse_reg_operand"))
3226 (const_string "V16SF")
3227 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3228 (match_test "TARGET_SSE_SPLIT_REGS"))
3229 (const_string "V4SF")
3231 (const_string "SF"))
3233 (const_string "SF")))])
3236 [(set (match_operand 0 "any_fp_register_operand")
3237 (match_operand 1 "memory_operand"))]
3239 && (GET_MODE (operands[0]) == TFmode
3240 || GET_MODE (operands[0]) == XFmode
3241 || GET_MODE (operands[0]) == DFmode
3242 || GET_MODE (operands[0]) == SFmode)
3243 && (operands[2] = find_constant_src (insn))"
3244 [(set (match_dup 0) (match_dup 2))]
3246 rtx c = operands[2];
3247 int r = REGNO (operands[0]);
3249 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3250 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3255 [(set (match_operand 0 "any_fp_register_operand")
3256 (float_extend (match_operand 1 "memory_operand")))]
3258 && (GET_MODE (operands[0]) == TFmode
3259 || GET_MODE (operands[0]) == XFmode
3260 || GET_MODE (operands[0]) == DFmode)
3261 && (operands[2] = find_constant_src (insn))"
3262 [(set (match_dup 0) (match_dup 2))]
3264 rtx c = operands[2];
3265 int r = REGNO (operands[0]);
3267 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3268 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3272 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3274 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3275 (match_operand:X87MODEF 1 "immediate_operand"))]
3277 && (standard_80387_constant_p (operands[1]) == 8
3278 || standard_80387_constant_p (operands[1]) == 9)"
3279 [(set (match_dup 0)(match_dup 1))
3281 (neg:X87MODEF (match_dup 0)))]
3285 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3286 if (real_isnegzero (&r))
3287 operands[1] = CONST0_RTX (<MODE>mode);
3289 operands[1] = CONST1_RTX (<MODE>mode);
3293 [(set (match_operand 0 "nonimmediate_operand")
3294 (match_operand 1 "general_operand"))]
3296 && (GET_MODE (operands[0]) == TFmode
3297 || GET_MODE (operands[0]) == XFmode
3298 || GET_MODE (operands[0]) == DFmode)
3299 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3301 "ix86_split_long_move (operands); DONE;")
3303 (define_insn "swapxf"
3304 [(set (match_operand:XF 0 "register_operand" "+f")
3305 (match_operand:XF 1 "register_operand" "+f"))
3310 if (STACK_TOP_P (operands[0]))
3315 [(set_attr "type" "fxch")
3316 (set_attr "mode" "XF")])
3318 (define_insn "*swap<mode>"
3319 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3320 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3323 "TARGET_80387 || reload_completed"
3325 if (STACK_TOP_P (operands[0]))
3330 [(set_attr "type" "fxch")
3331 (set_attr "mode" "<MODE>")])
3333 ;; Zero extension instructions
3335 (define_expand "zero_extendsidi2"
3336 [(set (match_operand:DI 0 "nonimmediate_operand")
3337 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3339 (define_insn "*zero_extendsidi2"
3340 [(set (match_operand:DI 0 "nonimmediate_operand"
3341 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3343 (match_operand:SI 1 "x86_64_zext_operand"
3344 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3347 switch (get_attr_type (insn))
3350 if (ix86_use_lea_for_mov (insn, operands))
3351 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3353 return "mov{l}\t{%1, %k0|%k0, %1}";
3359 return "movd\t{%1, %0|%0, %1}";
3362 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3365 if (GENERAL_REG_P (operands[0]))
3366 return "%vmovd\t{%1, %k0|%k0, %1}";
3368 return "%vmovd\t{%1, %0|%0, %1}";
3375 (cond [(eq_attr "alternative" "0,1,2")
3376 (const_string "nox64")
3377 (eq_attr "alternative" "3,7")
3378 (const_string "x64")
3379 (eq_attr "alternative" "8")
3380 (const_string "x64_sse4")
3381 (eq_attr "alternative" "10")
3382 (const_string "sse2")
3384 (const_string "*")))
3386 (cond [(eq_attr "alternative" "0,1,2,4")
3387 (const_string "multi")
3388 (eq_attr "alternative" "5,6")
3389 (const_string "mmxmov")
3390 (eq_attr "alternative" "7,9,10")
3391 (const_string "ssemov")
3392 (eq_attr "alternative" "8")
3393 (const_string "sselog1")
3395 (const_string "imovx")))
3396 (set (attr "prefix_extra")
3397 (if_then_else (eq_attr "alternative" "8")
3399 (const_string "*")))
3400 (set (attr "length_immediate")
3401 (if_then_else (eq_attr "alternative" "8")
3403 (const_string "*")))
3404 (set (attr "prefix")
3405 (if_then_else (eq_attr "type" "ssemov,sselog1")
3406 (const_string "maybe_vex")
3407 (const_string "orig")))
3408 (set (attr "prefix_0f")
3409 (if_then_else (eq_attr "type" "imovx")
3411 (const_string "*")))
3413 (cond [(eq_attr "alternative" "5,6")
3415 (eq_attr "alternative" "7,8,9")
3418 (const_string "SI")))])
3421 [(set (match_operand:DI 0 "memory_operand")
3422 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3424 [(set (match_dup 4) (const_int 0))]
3425 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3428 [(set (match_operand:DI 0 "register_operand")
3429 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3430 "!TARGET_64BIT && reload_completed
3431 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3432 && true_regnum (operands[0]) == true_regnum (operands[1])"
3433 [(set (match_dup 4) (const_int 0))]
3434 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3437 [(set (match_operand:DI 0 "nonimmediate_operand")
3438 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3439 "!TARGET_64BIT && reload_completed
3440 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3441 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3442 [(set (match_dup 3) (match_dup 1))
3443 (set (match_dup 4) (const_int 0))]
3444 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3446 (define_insn "zero_extend<mode>di2"
3447 [(set (match_operand:DI 0 "register_operand" "=r")
3449 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3451 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3452 [(set_attr "type" "imovx")
3453 (set_attr "mode" "SI")])
3455 (define_expand "zero_extend<mode>si2"
3456 [(set (match_operand:SI 0 "register_operand")
3457 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3460 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3462 operands[1] = force_reg (<MODE>mode, operands[1]);
3463 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3468 (define_insn_and_split "zero_extend<mode>si2_and"
3469 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3471 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3472 (clobber (reg:CC FLAGS_REG))]
3473 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3475 "&& reload_completed"
3476 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3477 (clobber (reg:CC FLAGS_REG))])]
3479 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3481 ix86_expand_clear (operands[0]);
3483 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3484 emit_insn (gen_movstrict<mode>
3485 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3489 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3491 [(set_attr "type" "alu1")
3492 (set_attr "mode" "SI")])
3494 (define_insn "*zero_extend<mode>si2"
3495 [(set (match_operand:SI 0 "register_operand" "=r")
3497 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3498 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3499 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3500 [(set_attr "type" "imovx")
3501 (set_attr "mode" "SI")])
3503 (define_expand "zero_extendqihi2"
3504 [(set (match_operand:HI 0 "register_operand")
3505 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3508 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3510 operands[1] = force_reg (QImode, operands[1]);
3511 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3516 (define_insn_and_split "zero_extendqihi2_and"
3517 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3518 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3519 (clobber (reg:CC FLAGS_REG))]
3520 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3522 "&& reload_completed"
3523 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3524 (clobber (reg:CC FLAGS_REG))])]
3526 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3528 ix86_expand_clear (operands[0]);
3530 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3531 emit_insn (gen_movstrictqi
3532 (gen_lowpart (QImode, operands[0]), operands[1]));
3536 operands[0] = gen_lowpart (SImode, operands[0]);
3538 [(set_attr "type" "alu1")
3539 (set_attr "mode" "SI")])
3541 ; zero extend to SImode to avoid partial register stalls
3542 (define_insn "*zero_extendqihi2"
3543 [(set (match_operand:HI 0 "register_operand" "=r")
3544 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3545 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3546 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3547 [(set_attr "type" "imovx")
3548 (set_attr "mode" "SI")])
3550 ;; Sign extension instructions
3552 (define_expand "extendsidi2"
3553 [(set (match_operand:DI 0 "register_operand")
3554 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3559 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3564 (define_insn "*extendsidi2_rex64"
3565 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3566 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3570 movs{lq|x}\t{%1, %0|%0, %1}"
3571 [(set_attr "type" "imovx")
3572 (set_attr "mode" "DI")
3573 (set_attr "prefix_0f" "0")
3574 (set_attr "modrm" "0,1")])
3576 (define_insn "extendsidi2_1"
3577 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3578 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3579 (clobber (reg:CC FLAGS_REG))
3580 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3584 ;; Split the memory case. If the source register doesn't die, it will stay
3585 ;; this way, if it does die, following peephole2s take care of it.
3587 [(set (match_operand:DI 0 "memory_operand")
3588 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3589 (clobber (reg:CC FLAGS_REG))
3590 (clobber (match_operand:SI 2 "register_operand"))]
3594 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3596 emit_move_insn (operands[3], operands[1]);
3598 /* Generate a cltd if possible and doing so it profitable. */
3599 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3600 && true_regnum (operands[1]) == AX_REG
3601 && true_regnum (operands[2]) == DX_REG)
3603 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3607 emit_move_insn (operands[2], operands[1]);
3608 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3610 emit_move_insn (operands[4], operands[2]);
3614 ;; Peepholes for the case where the source register does die, after
3615 ;; being split with the above splitter.
3617 [(set (match_operand:SI 0 "memory_operand")
3618 (match_operand:SI 1 "register_operand"))
3619 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3620 (parallel [(set (match_dup 2)
3621 (ashiftrt:SI (match_dup 2) (const_int 31)))
3622 (clobber (reg:CC FLAGS_REG))])
3623 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3624 "REGNO (operands[1]) != REGNO (operands[2])
3625 && peep2_reg_dead_p (2, operands[1])
3626 && peep2_reg_dead_p (4, operands[2])
3627 && !reg_mentioned_p (operands[2], operands[3])"
3628 [(set (match_dup 0) (match_dup 1))
3629 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3630 (clobber (reg:CC FLAGS_REG))])
3631 (set (match_dup 3) (match_dup 1))])
3634 [(set (match_operand:SI 0 "memory_operand")
3635 (match_operand:SI 1 "register_operand"))
3636 (parallel [(set (match_operand:SI 2 "register_operand")
3637 (ashiftrt:SI (match_dup 1) (const_int 31)))
3638 (clobber (reg:CC FLAGS_REG))])
3639 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3640 "/* cltd is shorter than sarl $31, %eax */
3641 !optimize_function_for_size_p (cfun)
3642 && true_regnum (operands[1]) == AX_REG
3643 && true_regnum (operands[2]) == DX_REG
3644 && peep2_reg_dead_p (2, operands[1])
3645 && peep2_reg_dead_p (3, operands[2])
3646 && !reg_mentioned_p (operands[2], operands[3])"
3647 [(set (match_dup 0) (match_dup 1))
3648 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3649 (clobber (reg:CC FLAGS_REG))])
3650 (set (match_dup 3) (match_dup 1))])
3652 ;; Extend to register case. Optimize case where source and destination
3653 ;; registers match and cases where we can use cltd.
3655 [(set (match_operand:DI 0 "register_operand")
3656 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3657 (clobber (reg:CC FLAGS_REG))
3658 (clobber (match_scratch:SI 2))]
3662 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3664 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3665 emit_move_insn (operands[3], operands[1]);
3667 /* Generate a cltd if possible and doing so it profitable. */
3668 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3669 && true_regnum (operands[3]) == AX_REG
3670 && true_regnum (operands[4]) == DX_REG)
3672 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3676 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3677 emit_move_insn (operands[4], operands[1]);
3679 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3683 (define_insn "extend<mode>di2"
3684 [(set (match_operand:DI 0 "register_operand" "=r")
3686 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3688 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3689 [(set_attr "type" "imovx")
3690 (set_attr "mode" "DI")])
3692 (define_insn "extendhisi2"
3693 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3694 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3697 switch (get_attr_prefix_0f (insn))
3700 return "{cwtl|cwde}";
3702 return "movs{wl|x}\t{%1, %0|%0, %1}";
3705 [(set_attr "type" "imovx")
3706 (set_attr "mode" "SI")
3707 (set (attr "prefix_0f")
3708 ;; movsx is short decodable while cwtl is vector decoded.
3709 (if_then_else (and (eq_attr "cpu" "!k6")
3710 (eq_attr "alternative" "0"))
3712 (const_string "1")))
3714 (if_then_else (eq_attr "prefix_0f" "0")
3716 (const_string "1")))])
3718 (define_insn "*extendhisi2_zext"
3719 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3722 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3725 switch (get_attr_prefix_0f (insn))
3728 return "{cwtl|cwde}";
3730 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3733 [(set_attr "type" "imovx")
3734 (set_attr "mode" "SI")
3735 (set (attr "prefix_0f")
3736 ;; movsx is short decodable while cwtl is vector decoded.
3737 (if_then_else (and (eq_attr "cpu" "!k6")
3738 (eq_attr "alternative" "0"))
3740 (const_string "1")))
3742 (if_then_else (eq_attr "prefix_0f" "0")
3744 (const_string "1")))])
3746 (define_insn "extendqisi2"
3747 [(set (match_operand:SI 0 "register_operand" "=r")
3748 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3750 "movs{bl|x}\t{%1, %0|%0, %1}"
3751 [(set_attr "type" "imovx")
3752 (set_attr "mode" "SI")])
3754 (define_insn "*extendqisi2_zext"
3755 [(set (match_operand:DI 0 "register_operand" "=r")
3757 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3759 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3760 [(set_attr "type" "imovx")
3761 (set_attr "mode" "SI")])
3763 (define_insn "extendqihi2"
3764 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3765 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3768 switch (get_attr_prefix_0f (insn))
3771 return "{cbtw|cbw}";
3773 return "movs{bw|x}\t{%1, %0|%0, %1}";
3776 [(set_attr "type" "imovx")
3777 (set_attr "mode" "HI")
3778 (set (attr "prefix_0f")
3779 ;; movsx is short decodable while cwtl is vector decoded.
3780 (if_then_else (and (eq_attr "cpu" "!k6")
3781 (eq_attr "alternative" "0"))
3783 (const_string "1")))
3785 (if_then_else (eq_attr "prefix_0f" "0")
3787 (const_string "1")))])
3789 ;; Conversions between float and double.
3791 ;; These are all no-ops in the model used for the 80387.
3792 ;; So just emit moves.
3794 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3796 [(set (match_operand:DF 0 "push_operand")
3797 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3799 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3800 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3803 [(set (match_operand:XF 0 "push_operand")
3804 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3806 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3807 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3808 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3810 (define_expand "extendsfdf2"
3811 [(set (match_operand:DF 0 "nonimmediate_operand")
3812 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3813 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3815 /* ??? Needed for compress_float_constant since all fp constants
3816 are TARGET_LEGITIMATE_CONSTANT_P. */
3817 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3819 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3820 && standard_80387_constant_p (operands[1]) > 0)
3822 operands[1] = simplify_const_unary_operation
3823 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3824 emit_move_insn_1 (operands[0], operands[1]);
3827 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3831 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3833 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3835 We do the conversion post reload to avoid producing of 128bit spills
3836 that might lead to ICE on 32bit target. The sequence unlikely combine
3839 [(set (match_operand:DF 0 "register_operand")
3841 (match_operand:SF 1 "nonimmediate_operand")))]
3842 "TARGET_USE_VECTOR_FP_CONVERTS
3843 && optimize_insn_for_speed_p ()
3844 && reload_completed && SSE_REG_P (operands[0])"
3849 (parallel [(const_int 0) (const_int 1)]))))]
3851 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3852 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3853 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3854 Try to avoid move when unpacking can be done in source. */
3855 if (REG_P (operands[1]))
3857 /* If it is unsafe to overwrite upper half of source, we need
3858 to move to destination and unpack there. */
3859 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3860 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3861 && true_regnum (operands[0]) != true_regnum (operands[1]))
3863 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3864 emit_move_insn (tmp, operands[1]);
3867 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3868 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3872 emit_insn (gen_vec_setv4sf_0 (operands[3],
3873 CONST0_RTX (V4SFmode), operands[1]));
3876 ;; It's more profitable to split and then extend in the same register.
3878 [(set (match_operand:DF 0 "register_operand")
3880 (match_operand:SF 1 "memory_operand")))]
3881 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3882 && optimize_insn_for_speed_p ()
3883 && SSE_REG_P (operands[0])"
3884 [(set (match_dup 2) (match_dup 1))
3885 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3886 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3888 (define_insn "*extendsfdf2_mixed"
3889 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3891 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3892 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3894 switch (which_alternative)
3898 return output_387_reg_move (insn, operands);
3901 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3907 [(set_attr "type" "fmov,fmov,ssecvt")
3908 (set_attr "prefix" "orig,orig,maybe_vex")
3909 (set_attr "mode" "SF,XF,DF")])
3911 (define_insn "*extendsfdf2_sse"
3912 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3913 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3914 "TARGET_SSE2 && TARGET_SSE_MATH"
3915 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3916 [(set_attr "type" "ssecvt")
3917 (set_attr "prefix" "maybe_vex")
3918 (set_attr "mode" "DF")])
3920 (define_insn "*extendsfdf2_i387"
3921 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3922 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3924 "* return output_387_reg_move (insn, operands);"
3925 [(set_attr "type" "fmov")
3926 (set_attr "mode" "SF,XF")])
3928 (define_expand "extend<mode>xf2"
3929 [(set (match_operand:XF 0 "nonimmediate_operand")
3930 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3933 /* ??? Needed for compress_float_constant since all fp constants
3934 are TARGET_LEGITIMATE_CONSTANT_P. */
3935 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3937 if (standard_80387_constant_p (operands[1]) > 0)
3939 operands[1] = simplify_const_unary_operation
3940 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3941 emit_move_insn_1 (operands[0], operands[1]);
3944 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3948 (define_insn "*extend<mode>xf2_i387"
3949 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3951 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3953 "* return output_387_reg_move (insn, operands);"
3954 [(set_attr "type" "fmov")
3955 (set_attr "mode" "<MODE>,XF")])
3957 ;; %%% This seems bad bad news.
3958 ;; This cannot output into an f-reg because there is no way to be sure
3959 ;; of truncating in that case. Otherwise this is just like a simple move
3960 ;; insn. So we pretend we can output to a reg in order to get better
3961 ;; register preferencing, but we really use a stack slot.
3963 ;; Conversion from DFmode to SFmode.
3965 (define_expand "truncdfsf2"
3966 [(set (match_operand:SF 0 "nonimmediate_operand")
3968 (match_operand:DF 1 "nonimmediate_operand")))]
3969 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3971 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3973 else if (flag_unsafe_math_optimizations)
3977 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3978 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3983 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3985 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3987 We do the conversion post reload to avoid producing of 128bit spills
3988 that might lead to ICE on 32bit target. The sequence unlikely combine
3991 [(set (match_operand:SF 0 "register_operand")
3993 (match_operand:DF 1 "nonimmediate_operand")))]
3994 "TARGET_USE_VECTOR_FP_CONVERTS
3995 && optimize_insn_for_speed_p ()
3996 && reload_completed && SSE_REG_P (operands[0])"
3999 (float_truncate:V2SF
4003 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4004 operands[3] = CONST0_RTX (V2SFmode);
4005 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4006 /* Use movsd for loading from memory, unpcklpd for registers.
4007 Try to avoid move when unpacking can be done in source, or SSE3
4008 movddup is available. */
4009 if (REG_P (operands[1]))
4012 && true_regnum (operands[0]) != true_regnum (operands[1])
4013 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4014 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4016 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4017 emit_move_insn (tmp, operands[1]);
4020 else if (!TARGET_SSE3)
4021 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4022 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4025 emit_insn (gen_sse2_loadlpd (operands[4],
4026 CONST0_RTX (V2DFmode), operands[1]));
4029 ;; It's more profitable to split and then extend in the same register.
4031 [(set (match_operand:SF 0 "register_operand")
4033 (match_operand:DF 1 "memory_operand")))]
4034 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4035 && optimize_insn_for_speed_p ()
4036 && SSE_REG_P (operands[0])"
4037 [(set (match_dup 2) (match_dup 1))
4038 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4039 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4041 (define_expand "truncdfsf2_with_temp"
4042 [(parallel [(set (match_operand:SF 0)
4043 (float_truncate:SF (match_operand:DF 1)))
4044 (clobber (match_operand:SF 2))])])
4046 (define_insn "*truncdfsf_fast_mixed"
4047 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4049 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4050 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4052 switch (which_alternative)
4055 return output_387_reg_move (insn, operands);
4057 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4062 [(set_attr "type" "fmov,ssecvt")
4063 (set_attr "prefix" "orig,maybe_vex")
4064 (set_attr "mode" "SF")])
4066 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4067 ;; because nothing we do here is unsafe.
4068 (define_insn "*truncdfsf_fast_sse"
4069 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4071 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4072 "TARGET_SSE2 && TARGET_SSE_MATH"
4073 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4074 [(set_attr "type" "ssecvt")
4075 (set_attr "prefix" "maybe_vex")
4076 (set_attr "mode" "SF")])
4078 (define_insn "*truncdfsf_fast_i387"
4079 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4081 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4082 "TARGET_80387 && flag_unsafe_math_optimizations"
4083 "* return output_387_reg_move (insn, operands);"
4084 [(set_attr "type" "fmov")
4085 (set_attr "mode" "SF")])
4087 (define_insn "*truncdfsf_mixed"
4088 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4090 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4091 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4092 "TARGET_MIX_SSE_I387"
4094 switch (which_alternative)
4097 return output_387_reg_move (insn, operands);
4099 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4105 [(set_attr "isa" "*,sse2,*,*,*")
4106 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4107 (set_attr "unit" "*,*,i387,i387,i387")
4108 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4109 (set_attr "mode" "SF")])
4111 (define_insn "*truncdfsf_i387"
4112 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4114 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4115 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4118 switch (which_alternative)
4121 return output_387_reg_move (insn, operands);
4127 [(set_attr "type" "fmov,multi,multi,multi")
4128 (set_attr "unit" "*,i387,i387,i387")
4129 (set_attr "mode" "SF")])
4131 (define_insn "*truncdfsf2_i387_1"
4132 [(set (match_operand:SF 0 "memory_operand" "=m")
4134 (match_operand:DF 1 "register_operand" "f")))]
4136 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4137 && !TARGET_MIX_SSE_I387"
4138 "* return output_387_reg_move (insn, operands);"
4139 [(set_attr "type" "fmov")
4140 (set_attr "mode" "SF")])
4143 [(set (match_operand:SF 0 "register_operand")
4145 (match_operand:DF 1 "fp_register_operand")))
4146 (clobber (match_operand 2))]
4148 [(set (match_dup 2) (match_dup 1))
4149 (set (match_dup 0) (match_dup 2))]
4150 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4152 ;; Conversion from XFmode to {SF,DF}mode
4154 (define_expand "truncxf<mode>2"
4155 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4156 (float_truncate:MODEF
4157 (match_operand:XF 1 "register_operand")))
4158 (clobber (match_dup 2))])]
4161 if (flag_unsafe_math_optimizations)
4163 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4164 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4165 if (reg != operands[0])
4166 emit_move_insn (operands[0], reg);
4170 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4173 (define_insn "*truncxfsf2_mixed"
4174 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4176 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4177 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4180 gcc_assert (!which_alternative);
4181 return output_387_reg_move (insn, operands);
4183 [(set_attr "type" "fmov,multi,multi,multi")
4184 (set_attr "unit" "*,i387,i387,i387")
4185 (set_attr "mode" "SF")])
4187 (define_insn "*truncxfdf2_mixed"
4188 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4190 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4191 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4194 gcc_assert (!which_alternative);
4195 return output_387_reg_move (insn, operands);
4197 [(set_attr "isa" "*,*,sse2,*")
4198 (set_attr "type" "fmov,multi,multi,multi")
4199 (set_attr "unit" "*,i387,i387,i387")
4200 (set_attr "mode" "DF")])
4202 (define_insn "truncxf<mode>2_i387_noop"
4203 [(set (match_operand:MODEF 0 "register_operand" "=f")
4204 (float_truncate:MODEF
4205 (match_operand:XF 1 "register_operand" "f")))]
4206 "TARGET_80387 && flag_unsafe_math_optimizations"
4207 "* return output_387_reg_move (insn, operands);"
4208 [(set_attr "type" "fmov")
4209 (set_attr "mode" "<MODE>")])
4211 (define_insn "*truncxf<mode>2_i387"
4212 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4213 (float_truncate:MODEF
4214 (match_operand:XF 1 "register_operand" "f")))]
4216 "* return output_387_reg_move (insn, operands);"
4217 [(set_attr "type" "fmov")
4218 (set_attr "mode" "<MODE>")])
4221 [(set (match_operand:MODEF 0 "register_operand")
4222 (float_truncate:MODEF
4223 (match_operand:XF 1 "register_operand")))
4224 (clobber (match_operand:MODEF 2 "memory_operand"))]
4225 "TARGET_80387 && reload_completed"
4226 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4227 (set (match_dup 0) (match_dup 2))])
4230 [(set (match_operand:MODEF 0 "memory_operand")
4231 (float_truncate:MODEF
4232 (match_operand:XF 1 "register_operand")))
4233 (clobber (match_operand:MODEF 2 "memory_operand"))]
4235 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4237 ;; Signed conversion to DImode.
4239 (define_expand "fix_truncxfdi2"
4240 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4241 (fix:DI (match_operand:XF 1 "register_operand")))
4242 (clobber (reg:CC FLAGS_REG))])]
4247 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4252 (define_expand "fix_trunc<mode>di2"
4253 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4254 (fix:DI (match_operand:MODEF 1 "register_operand")))
4255 (clobber (reg:CC FLAGS_REG))])]
4256 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4259 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4261 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4264 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4266 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4267 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4268 if (out != operands[0])
4269 emit_move_insn (operands[0], out);
4274 ;; Signed conversion to SImode.
4276 (define_expand "fix_truncxfsi2"
4277 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4278 (fix:SI (match_operand:XF 1 "register_operand")))
4279 (clobber (reg:CC FLAGS_REG))])]
4284 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4289 (define_expand "fix_trunc<mode>si2"
4290 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4291 (fix:SI (match_operand:MODEF 1 "register_operand")))
4292 (clobber (reg:CC FLAGS_REG))])]
4293 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4296 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4298 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4301 if (SSE_FLOAT_MODE_P (<MODE>mode))
4303 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4304 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4305 if (out != operands[0])
4306 emit_move_insn (operands[0], out);
4311 ;; Signed conversion to HImode.
4313 (define_expand "fix_trunc<mode>hi2"
4314 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4315 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4316 (clobber (reg:CC FLAGS_REG))])]
4318 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4322 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4327 ;; Unsigned conversion to SImode.
4329 (define_expand "fixuns_trunc<mode>si2"
4331 [(set (match_operand:SI 0 "register_operand")
4333 (match_operand:MODEF 1 "nonimmediate_operand")))
4335 (clobber (match_scratch:<ssevecmode> 3))
4336 (clobber (match_scratch:<ssevecmode> 4))])]
4337 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4339 enum machine_mode mode = <MODE>mode;
4340 enum machine_mode vecmode = <ssevecmode>mode;
4341 REAL_VALUE_TYPE TWO31r;
4344 if (optimize_insn_for_size_p ())
4347 real_ldexp (&TWO31r, &dconst1, 31);
4348 two31 = const_double_from_real_value (TWO31r, mode);
4349 two31 = ix86_build_const_vector (vecmode, true, two31);
4350 operands[2] = force_reg (vecmode, two31);
4353 (define_insn_and_split "*fixuns_trunc<mode>_1"
4354 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4356 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4357 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4358 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4359 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4360 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4361 && optimize_function_for_speed_p (cfun)"
4363 "&& reload_completed"
4366 ix86_split_convert_uns_si_sse (operands);
4370 ;; Unsigned conversion to HImode.
4371 ;; Without these patterns, we'll try the unsigned SI conversion which
4372 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4374 (define_expand "fixuns_trunc<mode>hi2"
4376 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4377 (set (match_operand:HI 0 "nonimmediate_operand")
4378 (subreg:HI (match_dup 2) 0))]
4379 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4380 "operands[2] = gen_reg_rtx (SImode);")
4382 ;; When SSE is available, it is always faster to use it!
4383 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4384 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4385 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4386 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4387 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4388 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4389 [(set_attr "type" "sseicvt")
4390 (set_attr "prefix" "maybe_vex")
4391 (set (attr "prefix_rex")
4393 (match_test "<SWI48:MODE>mode == DImode")
4395 (const_string "*")))
4396 (set_attr "mode" "<MODEF:MODE>")
4397 (set_attr "athlon_decode" "double,vector")
4398 (set_attr "amdfam10_decode" "double,double")
4399 (set_attr "bdver1_decode" "double,double")])
4401 ;; Avoid vector decoded forms of the instruction.
4403 [(match_scratch:MODEF 2 "x")
4404 (set (match_operand:SWI48 0 "register_operand")
4405 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4406 "TARGET_AVOID_VECTOR_DECODE
4407 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4408 && optimize_insn_for_speed_p ()"
4409 [(set (match_dup 2) (match_dup 1))
4410 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4412 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4413 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4414 (fix:SWI248x (match_operand 1 "register_operand")))]
4415 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4417 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4418 && (TARGET_64BIT || <MODE>mode != DImode))
4420 && can_create_pseudo_p ()"
4425 if (memory_operand (operands[0], VOIDmode))
4426 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4429 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4430 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4436 [(set_attr "type" "fisttp")
4437 (set_attr "mode" "<MODE>")])
4439 (define_insn "fix_trunc<mode>_i387_fisttp"
4440 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4441 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4442 (clobber (match_scratch:XF 2 "=&1f"))]
4443 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4445 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4446 && (TARGET_64BIT || <MODE>mode != DImode))
4447 && TARGET_SSE_MATH)"
4448 "* return output_fix_trunc (insn, operands, true);"
4449 [(set_attr "type" "fisttp")
4450 (set_attr "mode" "<MODE>")])
4452 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4453 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4454 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4455 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4456 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4457 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4459 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4460 && (TARGET_64BIT || <MODE>mode != DImode))
4461 && TARGET_SSE_MATH)"
4463 [(set_attr "type" "fisttp")
4464 (set_attr "mode" "<MODE>")])
4467 [(set (match_operand:SWI248x 0 "register_operand")
4468 (fix:SWI248x (match_operand 1 "register_operand")))
4469 (clobber (match_operand:SWI248x 2 "memory_operand"))
4470 (clobber (match_scratch 3))]
4472 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4473 (clobber (match_dup 3))])
4474 (set (match_dup 0) (match_dup 2))])
4477 [(set (match_operand:SWI248x 0 "memory_operand")
4478 (fix:SWI248x (match_operand 1 "register_operand")))
4479 (clobber (match_operand:SWI248x 2 "memory_operand"))
4480 (clobber (match_scratch 3))]
4482 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4483 (clobber (match_dup 3))])])
4485 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4486 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4487 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4488 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4489 ;; function in i386.c.
4490 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4491 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4492 (fix:SWI248x (match_operand 1 "register_operand")))
4493 (clobber (reg:CC FLAGS_REG))]
4494 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4496 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4497 && (TARGET_64BIT || <MODE>mode != DImode))
4498 && can_create_pseudo_p ()"
4503 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4505 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4506 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4507 if (memory_operand (operands[0], VOIDmode))
4508 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4509 operands[2], operands[3]));
4512 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4513 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4514 operands[2], operands[3],
4519 [(set_attr "type" "fistp")
4520 (set_attr "i387_cw" "trunc")
4521 (set_attr "mode" "<MODE>")])
4523 (define_insn "fix_truncdi_i387"
4524 [(set (match_operand:DI 0 "memory_operand" "=m")
4525 (fix:DI (match_operand 1 "register_operand" "f")))
4526 (use (match_operand:HI 2 "memory_operand" "m"))
4527 (use (match_operand:HI 3 "memory_operand" "m"))
4528 (clobber (match_scratch:XF 4 "=&1f"))]
4529 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4531 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4532 "* return output_fix_trunc (insn, operands, false);"
4533 [(set_attr "type" "fistp")
4534 (set_attr "i387_cw" "trunc")
4535 (set_attr "mode" "DI")])
4537 (define_insn "fix_truncdi_i387_with_temp"
4538 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4539 (fix:DI (match_operand 1 "register_operand" "f,f")))
4540 (use (match_operand:HI 2 "memory_operand" "m,m"))
4541 (use (match_operand:HI 3 "memory_operand" "m,m"))
4542 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4543 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4544 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4546 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4548 [(set_attr "type" "fistp")
4549 (set_attr "i387_cw" "trunc")
4550 (set_attr "mode" "DI")])
4553 [(set (match_operand:DI 0 "register_operand")
4554 (fix:DI (match_operand 1 "register_operand")))
4555 (use (match_operand:HI 2 "memory_operand"))
4556 (use (match_operand:HI 3 "memory_operand"))
4557 (clobber (match_operand:DI 4 "memory_operand"))
4558 (clobber (match_scratch 5))]
4560 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4563 (clobber (match_dup 5))])
4564 (set (match_dup 0) (match_dup 4))])
4567 [(set (match_operand:DI 0 "memory_operand")
4568 (fix:DI (match_operand 1 "register_operand")))
4569 (use (match_operand:HI 2 "memory_operand"))
4570 (use (match_operand:HI 3 "memory_operand"))
4571 (clobber (match_operand:DI 4 "memory_operand"))
4572 (clobber (match_scratch 5))]
4574 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4577 (clobber (match_dup 5))])])
4579 (define_insn "fix_trunc<mode>_i387"
4580 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4581 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4582 (use (match_operand:HI 2 "memory_operand" "m"))
4583 (use (match_operand:HI 3 "memory_operand" "m"))]
4584 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4586 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4587 "* return output_fix_trunc (insn, operands, false);"
4588 [(set_attr "type" "fistp")
4589 (set_attr "i387_cw" "trunc")
4590 (set_attr "mode" "<MODE>")])
4592 (define_insn "fix_trunc<mode>_i387_with_temp"
4593 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4594 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4595 (use (match_operand:HI 2 "memory_operand" "m,m"))
4596 (use (match_operand:HI 3 "memory_operand" "m,m"))
4597 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4598 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4600 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4602 [(set_attr "type" "fistp")
4603 (set_attr "i387_cw" "trunc")
4604 (set_attr "mode" "<MODE>")])
4607 [(set (match_operand:SWI24 0 "register_operand")
4608 (fix:SWI24 (match_operand 1 "register_operand")))
4609 (use (match_operand:HI 2 "memory_operand"))
4610 (use (match_operand:HI 3 "memory_operand"))
4611 (clobber (match_operand:SWI24 4 "memory_operand"))]
4613 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4615 (use (match_dup 3))])
4616 (set (match_dup 0) (match_dup 4))])
4619 [(set (match_operand:SWI24 0 "memory_operand")
4620 (fix:SWI24 (match_operand 1 "register_operand")))
4621 (use (match_operand:HI 2 "memory_operand"))
4622 (use (match_operand:HI 3 "memory_operand"))
4623 (clobber (match_operand:SWI24 4 "memory_operand"))]
4625 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4627 (use (match_dup 3))])])
4629 (define_insn "x86_fnstcw_1"
4630 [(set (match_operand:HI 0 "memory_operand" "=m")
4631 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4634 [(set (attr "length")
4635 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4636 (set_attr "mode" "HI")
4637 (set_attr "unit" "i387")
4638 (set_attr "bdver1_decode" "vector")])
4640 (define_insn "x86_fldcw_1"
4641 [(set (reg:HI FPCR_REG)
4642 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4645 [(set (attr "length")
4646 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4647 (set_attr "mode" "HI")
4648 (set_attr "unit" "i387")
4649 (set_attr "athlon_decode" "vector")
4650 (set_attr "amdfam10_decode" "vector")
4651 (set_attr "bdver1_decode" "vector")])
4653 ;; Conversion between fixed point and floating point.
4655 ;; Even though we only accept memory inputs, the backend _really_
4656 ;; wants to be able to do this between registers.
4658 (define_expand "floathi<mode>2"
4659 [(set (match_operand:X87MODEF 0 "register_operand")
4660 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4662 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4663 || TARGET_MIX_SSE_I387)")
4665 ;; Pre-reload splitter to add memory clobber to the pattern.
4666 (define_insn_and_split "*floathi<mode>2_1"
4667 [(set (match_operand:X87MODEF 0 "register_operand")
4668 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4670 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4671 || TARGET_MIX_SSE_I387)
4672 && can_create_pseudo_p ()"
4675 [(parallel [(set (match_dup 0)
4676 (float:X87MODEF (match_dup 1)))
4677 (clobber (match_dup 2))])]
4678 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4680 (define_insn "*floathi<mode>2_i387_with_temp"
4681 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4682 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4683 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4685 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4686 || TARGET_MIX_SSE_I387)"
4688 [(set_attr "type" "fmov,multi")
4689 (set_attr "mode" "<MODE>")
4690 (set_attr "unit" "*,i387")
4691 (set_attr "fp_int_src" "true")])
4693 (define_insn "*floathi<mode>2_i387"
4694 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4695 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4697 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4698 || TARGET_MIX_SSE_I387)"
4700 [(set_attr "type" "fmov")
4701 (set_attr "mode" "<MODE>")
4702 (set_attr "fp_int_src" "true")])
4705 [(set (match_operand:X87MODEF 0 "register_operand")
4706 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4707 (clobber (match_operand:HI 2 "memory_operand"))]
4709 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4710 || TARGET_MIX_SSE_I387)
4711 && reload_completed"
4712 [(set (match_dup 2) (match_dup 1))
4713 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4716 [(set (match_operand:X87MODEF 0 "register_operand")
4717 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4718 (clobber (match_operand:HI 2 "memory_operand"))]
4720 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4721 || TARGET_MIX_SSE_I387)
4722 && reload_completed"
4723 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4725 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4726 [(set (match_operand:X87MODEF 0 "register_operand")
4728 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4730 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4731 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4733 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4734 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4735 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4737 rtx reg = gen_reg_rtx (XFmode);
4738 rtx (*insn)(rtx, rtx);
4740 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4742 if (<X87MODEF:MODE>mode == SFmode)
4743 insn = gen_truncxfsf2;
4744 else if (<X87MODEF:MODE>mode == DFmode)
4745 insn = gen_truncxfdf2;
4749 emit_insn (insn (operands[0], reg));
4754 ;; Pre-reload splitter to add memory clobber to the pattern.
4755 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4756 [(set (match_operand:X87MODEF 0 "register_operand")
4757 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4759 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4760 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4761 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4762 || TARGET_MIX_SSE_I387))
4763 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4764 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4765 && ((<SWI48x:MODE>mode == SImode
4766 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4767 && optimize_function_for_speed_p (cfun)
4768 && flag_trapping_math)
4769 || !(TARGET_INTER_UNIT_CONVERSIONS
4770 || optimize_function_for_size_p (cfun)))))
4771 && can_create_pseudo_p ()"
4774 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4775 (clobber (match_dup 2))])]
4777 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4779 /* Avoid store forwarding (partial memory) stall penalty
4780 by passing DImode value through XMM registers. */
4781 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4782 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4783 && optimize_function_for_speed_p (cfun))
4785 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4792 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4793 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4795 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4796 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4797 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4798 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4800 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4801 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4802 (set_attr "unit" "*,i387,*,*,*")
4803 (set_attr "athlon_decode" "*,*,double,direct,double")
4804 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4805 (set_attr "bdver1_decode" "*,*,double,direct,double")
4806 (set_attr "fp_int_src" "true")])
4808 (define_insn "*floatsi<mode>2_vector_mixed"
4809 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4810 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4811 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4812 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4816 [(set_attr "type" "fmov,sseicvt")
4817 (set_attr "mode" "<MODE>,<ssevecmode>")
4818 (set_attr "unit" "i387,*")
4819 (set_attr "athlon_decode" "*,direct")
4820 (set_attr "amdfam10_decode" "*,double")
4821 (set_attr "bdver1_decode" "*,direct")
4822 (set_attr "fp_int_src" "true")])
4824 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4825 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4827 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4828 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4829 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4831 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4832 (set_attr "mode" "<MODEF:MODE>")
4833 (set_attr "unit" "*,i387,*,*")
4834 (set_attr "athlon_decode" "*,*,double,direct")
4835 (set_attr "amdfam10_decode" "*,*,vector,double")
4836 (set_attr "bdver1_decode" "*,*,double,direct")
4837 (set_attr "fp_int_src" "true")])
4840 [(set (match_operand:MODEF 0 "register_operand")
4841 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4842 (clobber (match_operand:SWI48 2 "memory_operand"))]
4843 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4844 && TARGET_INTER_UNIT_CONVERSIONS
4845 && reload_completed && SSE_REG_P (operands[0])"
4846 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4849 [(set (match_operand:MODEF 0 "register_operand")
4850 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4851 (clobber (match_operand:SWI48 2 "memory_operand"))]
4852 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4853 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4854 && reload_completed && SSE_REG_P (operands[0])"
4855 [(set (match_dup 2) (match_dup 1))
4856 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4858 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4859 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4861 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4862 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4863 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4866 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4867 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4868 [(set_attr "type" "fmov,sseicvt,sseicvt")
4869 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4870 (set_attr "mode" "<MODEF:MODE>")
4871 (set (attr "prefix_rex")
4873 (and (eq_attr "prefix" "maybe_vex")
4874 (match_test "<SWI48:MODE>mode == DImode"))
4876 (const_string "*")))
4877 (set_attr "unit" "i387,*,*")
4878 (set_attr "athlon_decode" "*,double,direct")
4879 (set_attr "amdfam10_decode" "*,vector,double")
4880 (set_attr "bdver1_decode" "*,double,direct")
4881 (set_attr "fp_int_src" "true")])
4883 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4884 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4886 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4887 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4888 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4891 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4892 [(set_attr "type" "fmov,sseicvt")
4893 (set_attr "prefix" "orig,maybe_vex")
4894 (set_attr "mode" "<MODEF:MODE>")
4895 (set (attr "prefix_rex")
4897 (and (eq_attr "prefix" "maybe_vex")
4898 (match_test "<SWI48:MODE>mode == DImode"))
4900 (const_string "*")))
4901 (set_attr "athlon_decode" "*,direct")
4902 (set_attr "amdfam10_decode" "*,double")
4903 (set_attr "bdver1_decode" "*,direct")
4904 (set_attr "fp_int_src" "true")])
4906 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4907 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4909 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4910 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4911 "TARGET_SSE2 && TARGET_SSE_MATH
4912 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4914 [(set_attr "type" "sseicvt")
4915 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4916 (set_attr "athlon_decode" "double,direct,double")
4917 (set_attr "amdfam10_decode" "vector,double,double")
4918 (set_attr "bdver1_decode" "double,direct,double")
4919 (set_attr "fp_int_src" "true")])
4921 (define_insn "*floatsi<mode>2_vector_sse"
4922 [(set (match_operand:MODEF 0 "register_operand" "=x")
4923 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4924 "TARGET_SSE2 && TARGET_SSE_MATH
4925 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4927 [(set_attr "type" "sseicvt")
4928 (set_attr "mode" "<MODE>")
4929 (set_attr "athlon_decode" "direct")
4930 (set_attr "amdfam10_decode" "double")
4931 (set_attr "bdver1_decode" "direct")
4932 (set_attr "fp_int_src" "true")])
4935 [(set (match_operand:MODEF 0 "register_operand")
4936 (float:MODEF (match_operand:SI 1 "register_operand")))
4937 (clobber (match_operand:SI 2 "memory_operand"))]
4938 "TARGET_SSE2 && TARGET_SSE_MATH
4939 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4940 && reload_completed && SSE_REG_P (operands[0])"
4943 rtx op1 = operands[1];
4945 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4947 if (GET_CODE (op1) == SUBREG)
4948 op1 = SUBREG_REG (op1);
4950 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4952 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4953 emit_insn (gen_sse2_loadld (operands[4],
4954 CONST0_RTX (V4SImode), operands[1]));
4956 /* We can ignore possible trapping value in the
4957 high part of SSE register for non-trapping math. */
4958 else if (SSE_REG_P (op1) && !flag_trapping_math)
4959 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4962 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4963 emit_move_insn (operands[2], operands[1]);
4964 emit_insn (gen_sse2_loadld (operands[4],
4965 CONST0_RTX (V4SImode), operands[2]));
4967 if (<ssevecmode>mode == V4SFmode)
4968 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4970 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4975 [(set (match_operand:MODEF 0 "register_operand")
4976 (float:MODEF (match_operand:SI 1 "memory_operand")))
4977 (clobber (match_operand:SI 2 "memory_operand"))]
4978 "TARGET_SSE2 && TARGET_SSE_MATH
4979 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4980 && reload_completed && SSE_REG_P (operands[0])"
4983 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4985 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4987 emit_insn (gen_sse2_loadld (operands[4],
4988 CONST0_RTX (V4SImode), operands[1]));
4989 if (<ssevecmode>mode == V4SFmode)
4990 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4992 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4997 [(set (match_operand:MODEF 0 "register_operand")
4998 (float:MODEF (match_operand:SI 1 "register_operand")))]
4999 "TARGET_SSE2 && TARGET_SSE_MATH
5000 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5001 && reload_completed && SSE_REG_P (operands[0])"
5004 rtx op1 = operands[1];
5006 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5008 if (GET_CODE (op1) == SUBREG)
5009 op1 = SUBREG_REG (op1);
5011 if (GENERAL_REG_P (op1))
5013 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5014 if (TARGET_INTER_UNIT_MOVES_TO_VEC)
5015 emit_insn (gen_sse2_loadld (operands[4],
5016 CONST0_RTX (V4SImode), operands[1]));
5019 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5021 emit_insn (gen_sse2_loadld (operands[4],
5022 CONST0_RTX (V4SImode), operands[5]));
5023 ix86_free_from_memory (GET_MODE (operands[1]));
5026 /* We can ignore possible trapping value in the
5027 high part of SSE register for non-trapping math. */
5028 else if (SSE_REG_P (op1) && !flag_trapping_math)
5029 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5032 if (<ssevecmode>mode == V4SFmode)
5033 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5035 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5040 [(set (match_operand:MODEF 0 "register_operand")
5041 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5042 "TARGET_SSE2 && TARGET_SSE_MATH
5043 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5044 && reload_completed && SSE_REG_P (operands[0])"
5047 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5049 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5051 emit_insn (gen_sse2_loadld (operands[4],
5052 CONST0_RTX (V4SImode), operands[1]));
5053 if (<ssevecmode>mode == V4SFmode)
5054 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5056 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5060 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
5061 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5063 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
5064 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
5065 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5067 [(set_attr "type" "sseicvt")
5068 (set_attr "mode" "<MODEF:MODE>")
5069 (set_attr "athlon_decode" "double,direct")
5070 (set_attr "amdfam10_decode" "vector,double")
5071 (set_attr "bdver1_decode" "double,direct")
5072 (set_attr "btver2_decode" "double,double")
5073 (set_attr "fp_int_src" "true")])
5075 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
5076 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5078 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
5079 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5080 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5081 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5082 [(set_attr "type" "sseicvt")
5083 (set_attr "prefix" "maybe_vex")
5084 (set_attr "mode" "<MODEF:MODE>")
5085 (set (attr "prefix_rex")
5087 (and (eq_attr "prefix" "maybe_vex")
5088 (match_test "<SWI48:MODE>mode == DImode"))
5090 (const_string "*")))
5091 (set_attr "athlon_decode" "double,direct")
5092 (set_attr "amdfam10_decode" "vector,double")
5093 (set_attr "bdver1_decode" "double,direct")
5094 (set_attr "btver2_decode" "double,double")
5095 (set_attr "fp_int_src" "true")])
5098 [(set (match_operand:MODEF 0 "register_operand")
5099 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
5100 (clobber (match_operand:SWI48 2 "memory_operand"))]
5101 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5102 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5103 && reload_completed && SSE_REG_P (operands[0])"
5104 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5106 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
5107 [(set (match_operand:MODEF 0 "register_operand" "=x")
5109 (match_operand:SWI48 1 "memory_operand" "m")))]
5110 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5111 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5112 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5113 [(set_attr "type" "sseicvt")
5114 (set_attr "prefix" "maybe_vex")
5115 (set_attr "mode" "<MODEF:MODE>")
5116 (set (attr "prefix_rex")
5118 (and (eq_attr "prefix" "maybe_vex")
5119 (match_test "<SWI48:MODE>mode == DImode"))
5121 (const_string "*")))
5122 (set_attr "athlon_decode" "direct")
5123 (set_attr "amdfam10_decode" "double")
5124 (set_attr "bdver1_decode" "direct")
5125 (set_attr "fp_int_src" "true")])
5128 [(set (match_operand:MODEF 0 "register_operand")
5129 (float:MODEF (match_operand:SWI48 1 "register_operand")))
5130 (clobber (match_operand:SWI48 2 "memory_operand"))]
5131 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5132 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5133 && reload_completed && SSE_REG_P (operands[0])"
5134 [(set (match_dup 2) (match_dup 1))
5135 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5138 [(set (match_operand:MODEF 0 "register_operand")
5139 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
5140 (clobber (match_operand:SWI48 2 "memory_operand"))]
5141 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5142 && reload_completed && SSE_REG_P (operands[0])"
5143 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5145 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5146 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5148 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5149 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5151 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5155 [(set_attr "type" "fmov,multi")
5156 (set_attr "mode" "<X87MODEF:MODE>")
5157 (set_attr "unit" "*,i387")
5158 (set_attr "fp_int_src" "true")])
5160 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5161 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5163 (match_operand:SWI48x 1 "memory_operand" "m")))]
5165 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5167 [(set_attr "type" "fmov")
5168 (set_attr "mode" "<X87MODEF:MODE>")
5169 (set_attr "fp_int_src" "true")])
5172 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5173 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5174 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5176 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5177 && reload_completed"
5178 [(set (match_dup 2) (match_dup 1))
5179 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5182 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5183 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5184 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5186 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5187 && reload_completed"
5188 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5190 ;; Avoid partial SSE register dependency stalls
5193 [(set (match_operand:MODEF 0 "register_operand")
5194 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5195 "TARGET_SSE2 && TARGET_SSE_MATH
5196 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5197 && optimize_function_for_speed_p (cfun)
5198 && reload_completed && SSE_REG_P (operands[0])"
5200 (vec_merge:<ssevecmode>
5201 (vec_duplicate:<ssevecmode>
5202 (float:MODEF (match_dup 1)))
5206 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5208 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5212 [(set (match_operand:MODEF 0 "register_operand")
5213 (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
5214 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5215 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5216 && optimize_function_for_speed_p (cfun)
5217 && reload_completed && SSE_REG_P (operands[0])"
5219 (vec_merge:<ssevecmode>
5220 (vec_duplicate:<ssevecmode>
5221 (float:MODEF (match_dup 1)))
5225 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5227 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5230 ;; Break partial reg stall for cvtsd2ss.
5233 [(set (match_operand:SF 0 "register_operand")
5235 (match_operand:DF 1 "nonimmediate_operand")))]
5236 "TARGET_SSE2 && TARGET_SSE_MATH
5237 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5238 && optimize_function_for_speed_p (cfun)
5239 && SSE_REG_P (operands[0])
5240 && (!SSE_REG_P (operands[1])
5241 || REGNO (operands[0]) != REGNO (operands[1]))"
5245 (float_truncate:V2SF
5250 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5252 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5254 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5257 ;; Break partial reg stall for cvtss2sd.
5260 [(set (match_operand:DF 0 "register_operand")
5262 (match_operand:SF 1 "nonimmediate_operand")))]
5263 "TARGET_SSE2 && TARGET_SSE_MATH
5264 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5265 && optimize_function_for_speed_p (cfun)
5266 && SSE_REG_P (operands[0])
5267 && (!SSE_REG_P (operands[1])
5268 || REGNO (operands[0]) != REGNO (operands[1]))"
5274 (parallel [(const_int 0) (const_int 1)])))
5278 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5280 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5282 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5285 ;; Avoid store forwarding (partial memory) stall penalty
5286 ;; by passing DImode value through XMM registers. */
5288 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5289 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5291 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5292 (clobber (match_scratch:V4SI 3 "=X,x"))
5293 (clobber (match_scratch:V4SI 4 "=X,x"))
5294 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5295 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5296 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5297 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5299 [(set_attr "type" "multi")
5300 (set_attr "mode" "<X87MODEF:MODE>")
5301 (set_attr "unit" "i387")
5302 (set_attr "fp_int_src" "true")])
5305 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5306 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5307 (clobber (match_scratch:V4SI 3))
5308 (clobber (match_scratch:V4SI 4))
5309 (clobber (match_operand:DI 2 "memory_operand"))]
5310 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5311 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5312 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5313 && reload_completed"
5314 [(set (match_dup 2) (match_dup 3))
5315 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5317 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5318 Assemble the 64-bit DImode value in an xmm register. */
5319 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5320 gen_rtx_SUBREG (SImode, operands[1], 0)));
5321 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5322 gen_rtx_SUBREG (SImode, operands[1], 4)));
5323 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5326 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5330 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5331 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5332 (clobber (match_scratch:V4SI 3))
5333 (clobber (match_scratch:V4SI 4))
5334 (clobber (match_operand:DI 2 "memory_operand"))]
5335 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5336 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5337 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5338 && reload_completed"
5339 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5341 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5342 [(set (match_operand:MODEF 0 "register_operand")
5343 (unsigned_float:MODEF
5344 (match_operand:SWI12 1 "nonimmediate_operand")))]
5346 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5348 operands[1] = convert_to_mode (SImode, operands[1], 1);
5349 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5353 ;; Avoid store forwarding (partial memory) stall penalty by extending
5354 ;; SImode value to DImode through XMM register instead of pushing two
5355 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5356 ;; targets benefit from this optimization. Also note that fild
5357 ;; loads from memory only.
5359 (define_insn "*floatunssi<mode>2_1"
5360 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5361 (unsigned_float:X87MODEF
5362 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5363 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5364 (clobber (match_scratch:SI 3 "=X,x"))]
5366 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5369 [(set_attr "type" "multi")
5370 (set_attr "mode" "<MODE>")])
5373 [(set (match_operand:X87MODEF 0 "register_operand")
5374 (unsigned_float:X87MODEF
5375 (match_operand:SI 1 "register_operand")))
5376 (clobber (match_operand:DI 2 "memory_operand"))
5377 (clobber (match_scratch:SI 3))]
5379 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5381 && reload_completed"
5382 [(set (match_dup 2) (match_dup 1))
5384 (float:X87MODEF (match_dup 2)))]
5385 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5388 [(set (match_operand:X87MODEF 0 "register_operand")
5389 (unsigned_float:X87MODEF
5390 (match_operand:SI 1 "memory_operand")))
5391 (clobber (match_operand:DI 2 "memory_operand"))
5392 (clobber (match_scratch:SI 3))]
5394 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5396 && reload_completed"
5397 [(set (match_dup 2) (match_dup 3))
5399 (float:X87MODEF (match_dup 2)))]
5401 emit_move_insn (operands[3], operands[1]);
5402 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5405 (define_expand "floatunssi<mode>2"
5407 [(set (match_operand:X87MODEF 0 "register_operand")
5408 (unsigned_float:X87MODEF
5409 (match_operand:SI 1 "nonimmediate_operand")))
5410 (clobber (match_dup 2))
5411 (clobber (match_scratch:SI 3))])]
5413 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5415 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5417 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5419 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5423 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5426 (define_expand "floatunsdisf2"
5427 [(use (match_operand:SF 0 "register_operand"))
5428 (use (match_operand:DI 1 "nonimmediate_operand"))]
5429 "TARGET_64BIT && TARGET_SSE_MATH"
5430 "x86_emit_floatuns (operands); DONE;")
5432 (define_expand "floatunsdidf2"
5433 [(use (match_operand:DF 0 "register_operand"))
5434 (use (match_operand:DI 1 "nonimmediate_operand"))]
5435 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5436 && TARGET_SSE2 && TARGET_SSE_MATH"
5439 x86_emit_floatuns (operands);
5441 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5445 ;; Load effective address instructions
5447 (define_insn_and_split "*lea<mode>"
5448 [(set (match_operand:SWI48 0 "register_operand" "=r")
5449 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5452 if (SImode_address_operand (operands[1], VOIDmode))
5454 gcc_assert (TARGET_64BIT);
5455 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5458 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5460 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5463 enum machine_mode mode = <MODE>mode;
5466 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5467 change operands[] array behind our back. */
5468 pat = PATTERN (curr_insn);
5470 operands[0] = SET_DEST (pat);
5471 operands[1] = SET_SRC (pat);
5473 /* Emit all operations in SImode for zero-extended addresses. */
5474 if (SImode_address_operand (operands[1], VOIDmode))
5477 ix86_split_lea_for_addr (curr_insn, operands, mode);
5479 /* Zero-extend return register to DImode for zero-extended addresses. */
5480 if (mode != <MODE>mode)
5481 emit_insn (gen_zero_extendsidi2
5482 (operands[0], gen_lowpart (mode, operands[0])));
5486 [(set_attr "type" "lea")
5489 (match_operand 1 "SImode_address_operand")
5491 (const_string "<MODE>")))])
5495 (define_expand "add<mode>3"
5496 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5497 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5498 (match_operand:SDWIM 2 "<general_operand>")))]
5500 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5502 (define_insn_and_split "*add<dwi>3_doubleword"
5503 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5505 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5506 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5507 (clobber (reg:CC FLAGS_REG))]
5508 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5511 [(parallel [(set (reg:CC FLAGS_REG)
5512 (unspec:CC [(match_dup 1) (match_dup 2)]
5515 (plus:DWIH (match_dup 1) (match_dup 2)))])
5516 (parallel [(set (match_dup 3)
5520 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5522 (clobber (reg:CC FLAGS_REG))])]
5523 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5525 (define_insn "*add<mode>3_cc"
5526 [(set (reg:CC FLAGS_REG)
5528 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5529 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5531 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5532 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5533 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5534 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5535 [(set_attr "type" "alu")
5536 (set_attr "mode" "<MODE>")])
5538 (define_insn "addqi3_cc"
5539 [(set (reg:CC FLAGS_REG)
5541 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5542 (match_operand:QI 2 "general_operand" "qn,qm")]
5544 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5545 (plus:QI (match_dup 1) (match_dup 2)))]
5546 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5547 "add{b}\t{%2, %0|%0, %2}"
5548 [(set_attr "type" "alu")
5549 (set_attr "mode" "QI")])
5551 (define_insn "*add<mode>_1"
5552 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5554 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5555 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5556 (clobber (reg:CC FLAGS_REG))]
5557 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5559 switch (get_attr_type (insn))
5565 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5566 if (operands[2] == const1_rtx)
5567 return "inc{<imodesuffix>}\t%0";
5570 gcc_assert (operands[2] == constm1_rtx);
5571 return "dec{<imodesuffix>}\t%0";
5575 /* For most processors, ADD is faster than LEA. This alternative
5576 was added to use ADD as much as possible. */
5577 if (which_alternative == 2)
5580 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5583 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5584 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5585 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5587 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5591 (cond [(eq_attr "alternative" "3")
5592 (const_string "lea")
5593 (match_operand:SWI48 2 "incdec_operand")
5594 (const_string "incdec")
5596 (const_string "alu")))
5597 (set (attr "length_immediate")
5599 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5601 (const_string "*")))
5602 (set_attr "mode" "<MODE>")])
5604 ;; It may seem that nonimmediate operand is proper one for operand 1.
5605 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5606 ;; we take care in ix86_binary_operator_ok to not allow two memory
5607 ;; operands so proper swapping will be done in reload. This allow
5608 ;; patterns constructed from addsi_1 to match.
5610 (define_insn "addsi_1_zext"
5611 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5613 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5614 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5615 (clobber (reg:CC FLAGS_REG))]
5616 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5618 switch (get_attr_type (insn))
5624 if (operands[2] == const1_rtx)
5625 return "inc{l}\t%k0";
5628 gcc_assert (operands[2] == constm1_rtx);
5629 return "dec{l}\t%k0";
5633 /* For most processors, ADD is faster than LEA. This alternative
5634 was added to use ADD as much as possible. */
5635 if (which_alternative == 1)
5638 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5641 if (x86_maybe_negate_const_int (&operands[2], SImode))
5642 return "sub{l}\t{%2, %k0|%k0, %2}";
5644 return "add{l}\t{%2, %k0|%k0, %2}";
5648 (cond [(eq_attr "alternative" "2")
5649 (const_string "lea")
5650 (match_operand:SI 2 "incdec_operand")
5651 (const_string "incdec")
5653 (const_string "alu")))
5654 (set (attr "length_immediate")
5656 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5658 (const_string "*")))
5659 (set_attr "mode" "SI")])
5661 (define_insn "*addhi_1"
5662 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5663 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5664 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5665 (clobber (reg:CC FLAGS_REG))]
5666 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5668 switch (get_attr_type (insn))
5674 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5675 if (operands[2] == const1_rtx)
5676 return "inc{w}\t%0";
5679 gcc_assert (operands[2] == constm1_rtx);
5680 return "dec{w}\t%0";
5684 /* For most processors, ADD is faster than LEA. This alternative
5685 was added to use ADD as much as possible. */
5686 if (which_alternative == 2)
5689 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5692 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5693 if (x86_maybe_negate_const_int (&operands[2], HImode))
5694 return "sub{w}\t{%2, %0|%0, %2}";
5696 return "add{w}\t{%2, %0|%0, %2}";
5700 (cond [(eq_attr "alternative" "3")
5701 (const_string "lea")
5702 (match_operand:HI 2 "incdec_operand")
5703 (const_string "incdec")
5705 (const_string "alu")))
5706 (set (attr "length_immediate")
5708 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5710 (const_string "*")))
5711 (set_attr "mode" "HI,HI,HI,SI")])
5713 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5714 (define_insn "*addqi_1"
5715 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5716 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5717 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5718 (clobber (reg:CC FLAGS_REG))]
5719 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5721 bool widen = (which_alternative == 3 || which_alternative == 4);
5723 switch (get_attr_type (insn))
5729 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5730 if (operands[2] == const1_rtx)
5731 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5734 gcc_assert (operands[2] == constm1_rtx);
5735 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5739 /* For most processors, ADD is faster than LEA. These alternatives
5740 were added to use ADD as much as possible. */
5741 if (which_alternative == 2 || which_alternative == 4)
5744 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5747 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5748 if (x86_maybe_negate_const_int (&operands[2], QImode))
5751 return "sub{l}\t{%2, %k0|%k0, %2}";
5753 return "sub{b}\t{%2, %0|%0, %2}";
5756 return "add{l}\t{%k2, %k0|%k0, %k2}";
5758 return "add{b}\t{%2, %0|%0, %2}";
5762 (cond [(eq_attr "alternative" "5")
5763 (const_string "lea")
5764 (match_operand:QI 2 "incdec_operand")
5765 (const_string "incdec")
5767 (const_string "alu")))
5768 (set (attr "length_immediate")
5770 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5772 (const_string "*")))
5773 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5775 (define_insn "*addqi_1_slp"
5776 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5777 (plus:QI (match_dup 0)
5778 (match_operand:QI 1 "general_operand" "qn,qm")))
5779 (clobber (reg:CC FLAGS_REG))]
5780 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5781 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5783 switch (get_attr_type (insn))
5786 if (operands[1] == const1_rtx)
5787 return "inc{b}\t%0";
5790 gcc_assert (operands[1] == constm1_rtx);
5791 return "dec{b}\t%0";
5795 if (x86_maybe_negate_const_int (&operands[1], QImode))
5796 return "sub{b}\t{%1, %0|%0, %1}";
5798 return "add{b}\t{%1, %0|%0, %1}";
5802 (if_then_else (match_operand:QI 1 "incdec_operand")
5803 (const_string "incdec")
5804 (const_string "alu1")))
5805 (set (attr "memory")
5806 (if_then_else (match_operand 1 "memory_operand")
5807 (const_string "load")
5808 (const_string "none")))
5809 (set_attr "mode" "QI")])
5811 ;; Split non destructive adds if we cannot use lea.
5813 [(set (match_operand:SWI48 0 "register_operand")
5814 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5815 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5816 (clobber (reg:CC FLAGS_REG))]
5817 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5818 [(set (match_dup 0) (match_dup 1))
5819 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5820 (clobber (reg:CC FLAGS_REG))])])
5822 ;; Convert add to the lea pattern to avoid flags dependency.
5824 [(set (match_operand:SWI 0 "register_operand")
5825 (plus:SWI (match_operand:SWI 1 "register_operand")
5826 (match_operand:SWI 2 "<nonmemory_operand>")))
5827 (clobber (reg:CC FLAGS_REG))]
5828 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5831 enum machine_mode mode = <MODE>mode;
5834 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5837 operands[0] = gen_lowpart (mode, operands[0]);
5838 operands[1] = gen_lowpart (mode, operands[1]);
5839 operands[2] = gen_lowpart (mode, operands[2]);
5842 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5844 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5848 ;; Split non destructive adds if we cannot use lea.
5850 [(set (match_operand:DI 0 "register_operand")
5852 (plus:SI (match_operand:SI 1 "register_operand")
5853 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5854 (clobber (reg:CC FLAGS_REG))]
5856 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5857 [(set (match_dup 3) (match_dup 1))
5858 (parallel [(set (match_dup 0)
5859 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5860 (clobber (reg:CC FLAGS_REG))])]
5861 "operands[3] = gen_lowpart (SImode, operands[0]);")
5863 ;; Convert add to the lea pattern to avoid flags dependency.
5865 [(set (match_operand:DI 0 "register_operand")
5867 (plus:SI (match_operand:SI 1 "register_operand")
5868 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5869 (clobber (reg:CC FLAGS_REG))]
5870 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5872 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5874 (define_insn "*add<mode>_2"
5875 [(set (reg FLAGS_REG)
5878 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5879 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5881 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5882 (plus:SWI (match_dup 1) (match_dup 2)))]
5883 "ix86_match_ccmode (insn, CCGOCmode)
5884 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5886 switch (get_attr_type (insn))
5889 if (operands[2] == const1_rtx)
5890 return "inc{<imodesuffix>}\t%0";
5893 gcc_assert (operands[2] == constm1_rtx);
5894 return "dec{<imodesuffix>}\t%0";
5898 if (which_alternative == 2)
5901 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5904 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5905 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5906 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5908 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5912 (if_then_else (match_operand:SWI 2 "incdec_operand")
5913 (const_string "incdec")
5914 (const_string "alu")))
5915 (set (attr "length_immediate")
5917 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5919 (const_string "*")))
5920 (set_attr "mode" "<MODE>")])
5922 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5923 (define_insn "*addsi_2_zext"
5924 [(set (reg FLAGS_REG)
5926 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5927 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5929 (set (match_operand:DI 0 "register_operand" "=r,r")
5930 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5931 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5932 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5934 switch (get_attr_type (insn))
5937 if (operands[2] == const1_rtx)
5938 return "inc{l}\t%k0";
5941 gcc_assert (operands[2] == constm1_rtx);
5942 return "dec{l}\t%k0";
5946 if (which_alternative == 1)
5949 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5952 if (x86_maybe_negate_const_int (&operands[2], SImode))
5953 return "sub{l}\t{%2, %k0|%k0, %2}";
5955 return "add{l}\t{%2, %k0|%k0, %2}";
5959 (if_then_else (match_operand:SI 2 "incdec_operand")
5960 (const_string "incdec")
5961 (const_string "alu")))
5962 (set (attr "length_immediate")
5964 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5966 (const_string "*")))
5967 (set_attr "mode" "SI")])
5969 (define_insn "*add<mode>_3"
5970 [(set (reg FLAGS_REG)
5972 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5973 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5974 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5975 "ix86_match_ccmode (insn, CCZmode)
5976 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5978 switch (get_attr_type (insn))
5981 if (operands[2] == const1_rtx)
5982 return "inc{<imodesuffix>}\t%0";
5985 gcc_assert (operands[2] == constm1_rtx);
5986 return "dec{<imodesuffix>}\t%0";
5990 if (which_alternative == 1)
5993 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5996 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5997 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5998 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6000 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6004 (if_then_else (match_operand:SWI 2 "incdec_operand")
6005 (const_string "incdec")
6006 (const_string "alu")))
6007 (set (attr "length_immediate")
6009 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6011 (const_string "*")))
6012 (set_attr "mode" "<MODE>")])
6014 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6015 (define_insn "*addsi_3_zext"
6016 [(set (reg FLAGS_REG)
6018 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6019 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6020 (set (match_operand:DI 0 "register_operand" "=r,r")
6021 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6022 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6023 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6025 switch (get_attr_type (insn))
6028 if (operands[2] == const1_rtx)
6029 return "inc{l}\t%k0";
6032 gcc_assert (operands[2] == constm1_rtx);
6033 return "dec{l}\t%k0";
6037 if (which_alternative == 1)
6040 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6043 if (x86_maybe_negate_const_int (&operands[2], SImode))
6044 return "sub{l}\t{%2, %k0|%k0, %2}";
6046 return "add{l}\t{%2, %k0|%k0, %2}";
6050 (if_then_else (match_operand:SI 2 "incdec_operand")
6051 (const_string "incdec")
6052 (const_string "alu")))
6053 (set (attr "length_immediate")
6055 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6057 (const_string "*")))
6058 (set_attr "mode" "SI")])
6060 ; For comparisons against 1, -1 and 128, we may generate better code
6061 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6062 ; is matched then. We can't accept general immediate, because for
6063 ; case of overflows, the result is messed up.
6064 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6065 ; only for comparisons not depending on it.
6067 (define_insn "*adddi_4"
6068 [(set (reg FLAGS_REG)
6070 (match_operand:DI 1 "nonimmediate_operand" "0")
6071 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6072 (clobber (match_scratch:DI 0 "=rm"))]
6074 && ix86_match_ccmode (insn, CCGCmode)"
6076 switch (get_attr_type (insn))
6079 if (operands[2] == constm1_rtx)
6080 return "inc{q}\t%0";
6083 gcc_assert (operands[2] == const1_rtx);
6084 return "dec{q}\t%0";
6088 if (x86_maybe_negate_const_int (&operands[2], DImode))
6089 return "add{q}\t{%2, %0|%0, %2}";
6091 return "sub{q}\t{%2, %0|%0, %2}";
6095 (if_then_else (match_operand:DI 2 "incdec_operand")
6096 (const_string "incdec")
6097 (const_string "alu")))
6098 (set (attr "length_immediate")
6100 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6102 (const_string "*")))
6103 (set_attr "mode" "DI")])
6105 ; For comparisons against 1, -1 and 128, we may generate better code
6106 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6107 ; is matched then. We can't accept general immediate, because for
6108 ; case of overflows, the result is messed up.
6109 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6110 ; only for comparisons not depending on it.
6112 (define_insn "*add<mode>_4"
6113 [(set (reg FLAGS_REG)
6115 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6116 (match_operand:SWI124 2 "const_int_operand" "n")))
6117 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6118 "ix86_match_ccmode (insn, CCGCmode)"
6120 switch (get_attr_type (insn))
6123 if (operands[2] == constm1_rtx)
6124 return "inc{<imodesuffix>}\t%0";
6127 gcc_assert (operands[2] == const1_rtx);
6128 return "dec{<imodesuffix>}\t%0";
6132 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6133 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6135 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6139 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6140 (const_string "incdec")
6141 (const_string "alu")))
6142 (set (attr "length_immediate")
6144 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6146 (const_string "*")))
6147 (set_attr "mode" "<MODE>")])
6149 (define_insn "*add<mode>_5"
6150 [(set (reg FLAGS_REG)
6153 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6154 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6156 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6157 "ix86_match_ccmode (insn, CCGOCmode)
6158 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6160 switch (get_attr_type (insn))
6163 if (operands[2] == const1_rtx)
6164 return "inc{<imodesuffix>}\t%0";
6167 gcc_assert (operands[2] == constm1_rtx);
6168 return "dec{<imodesuffix>}\t%0";
6172 if (which_alternative == 1)
6175 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6178 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6179 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6180 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6182 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6186 (if_then_else (match_operand:SWI 2 "incdec_operand")
6187 (const_string "incdec")
6188 (const_string "alu")))
6189 (set (attr "length_immediate")
6191 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6193 (const_string "*")))
6194 (set_attr "mode" "<MODE>")])
6196 (define_insn "addqi_ext_1"
6197 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6202 (match_operand 1 "ext_register_operand" "0,0")
6205 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6206 (clobber (reg:CC FLAGS_REG))]
6209 switch (get_attr_type (insn))
6212 if (operands[2] == const1_rtx)
6213 return "inc{b}\t%h0";
6216 gcc_assert (operands[2] == constm1_rtx);
6217 return "dec{b}\t%h0";
6221 return "add{b}\t{%2, %h0|%h0, %2}";
6224 [(set_attr "isa" "*,nox64")
6226 (if_then_else (match_operand:QI 2 "incdec_operand")
6227 (const_string "incdec")
6228 (const_string "alu")))
6229 (set_attr "modrm" "1")
6230 (set_attr "mode" "QI")])
6232 (define_insn "*addqi_ext_2"
6233 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6238 (match_operand 1 "ext_register_operand" "%0")
6242 (match_operand 2 "ext_register_operand" "Q")
6245 (clobber (reg:CC FLAGS_REG))]
6247 "add{b}\t{%h2, %h0|%h0, %h2}"
6248 [(set_attr "type" "alu")
6249 (set_attr "mode" "QI")])
6251 ;; Add with jump on overflow.
6252 (define_expand "addv<mode>4"
6253 [(parallel [(set (reg:CCO FLAGS_REG)
6256 (match_operand:SWI 1 "nonimmediate_operand"))
6258 (match_operand:SWI 2 "<general_operand>")))
6260 (plus:SWI (match_dup 1) (match_dup 2)))))
6261 (set (match_operand:SWI 0 "register_operand")
6262 (plus:SWI (match_dup 1) (match_dup 2)))])
6263 (set (pc) (if_then_else
6264 (eq (reg:CCO FLAGS_REG) (const_int 0))
6265 (label_ref (match_operand 3))
6268 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6270 (define_insn "*addv<mode>4"
6271 [(set (reg:CCO FLAGS_REG)
6274 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6276 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")))
6278 (plus:SWI (match_dup 1) (match_dup 2)))))
6279 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6280 (plus:SWI (match_dup 1) (match_dup 2)))]
6281 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6282 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6283 [(set_attr "type" "alu")
6284 (set_attr "mode" "<MODE>")])
6286 ;; The lea patterns for modes less than 32 bits need to be matched by
6287 ;; several insns converted to real lea by splitters.
6289 (define_insn_and_split "*lea_general_1"
6290 [(set (match_operand 0 "register_operand" "=r")
6291 (plus (plus (match_operand 1 "index_register_operand" "l")
6292 (match_operand 2 "register_operand" "r"))
6293 (match_operand 3 "immediate_operand" "i")))]
6294 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6295 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6296 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6297 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6298 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6299 || GET_MODE (operands[3]) == VOIDmode)"
6301 "&& reload_completed"
6304 enum machine_mode mode = SImode;
6307 operands[0] = gen_lowpart (mode, operands[0]);
6308 operands[1] = gen_lowpart (mode, operands[1]);
6309 operands[2] = gen_lowpart (mode, operands[2]);
6310 operands[3] = gen_lowpart (mode, operands[3]);
6312 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6315 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6318 [(set_attr "type" "lea")
6319 (set_attr "mode" "SI")])
6321 (define_insn_and_split "*lea_general_2"
6322 [(set (match_operand 0 "register_operand" "=r")
6323 (plus (mult (match_operand 1 "index_register_operand" "l")
6324 (match_operand 2 "const248_operand" "n"))
6325 (match_operand 3 "nonmemory_operand" "ri")))]
6326 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6327 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6328 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6329 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6330 || GET_MODE (operands[3]) == VOIDmode)"
6332 "&& reload_completed"
6335 enum machine_mode mode = SImode;
6338 operands[0] = gen_lowpart (mode, operands[0]);
6339 operands[1] = gen_lowpart (mode, operands[1]);
6340 operands[3] = gen_lowpart (mode, operands[3]);
6342 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6345 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6348 [(set_attr "type" "lea")
6349 (set_attr "mode" "SI")])
6351 (define_insn_and_split "*lea_general_3"
6352 [(set (match_operand 0 "register_operand" "=r")
6353 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6354 (match_operand 2 "const248_operand" "n"))
6355 (match_operand 3 "register_operand" "r"))
6356 (match_operand 4 "immediate_operand" "i")))]
6357 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6358 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6359 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6360 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6362 "&& reload_completed"
6365 enum machine_mode mode = SImode;
6368 operands[0] = gen_lowpart (mode, operands[0]);
6369 operands[1] = gen_lowpart (mode, operands[1]);
6370 operands[3] = gen_lowpart (mode, operands[3]);
6371 operands[4] = gen_lowpart (mode, operands[4]);
6373 pat = gen_rtx_PLUS (mode,
6375 gen_rtx_MULT (mode, operands[1],
6380 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6383 [(set_attr "type" "lea")
6384 (set_attr "mode" "SI")])
6386 (define_insn_and_split "*lea_general_4"
6387 [(set (match_operand 0 "register_operand" "=r")
6389 (match_operand 1 "index_register_operand" "l")
6390 (match_operand 2 "const_int_operand" "n"))
6391 (match_operand 3 "const_int_operand" "n")))]
6392 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6393 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6394 || GET_MODE (operands[0]) == SImode
6395 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6396 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6397 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6398 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6399 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6401 "&& reload_completed"
6404 enum machine_mode mode = GET_MODE (operands[0]);
6407 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6410 operands[0] = gen_lowpart (mode, operands[0]);
6411 operands[1] = gen_lowpart (mode, operands[1]);
6414 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6416 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6417 INTVAL (operands[3]));
6419 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6422 [(set_attr "type" "lea")
6424 (if_then_else (match_operand:DI 0)
6426 (const_string "SI")))])
6428 ;; Subtract instructions
6430 (define_expand "sub<mode>3"
6431 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6432 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6433 (match_operand:SDWIM 2 "<general_operand>")))]
6435 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6437 (define_insn_and_split "*sub<dwi>3_doubleword"
6438 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6440 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6441 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6442 (clobber (reg:CC FLAGS_REG))]
6443 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6446 [(parallel [(set (reg:CC FLAGS_REG)
6447 (compare:CC (match_dup 1) (match_dup 2)))
6449 (minus:DWIH (match_dup 1) (match_dup 2)))])
6450 (parallel [(set (match_dup 3)
6454 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6456 (clobber (reg:CC FLAGS_REG))])]
6457 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6459 (define_insn "*sub<mode>_1"
6460 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6462 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6463 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6464 (clobber (reg:CC FLAGS_REG))]
6465 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6466 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "<MODE>")])
6470 (define_insn "*subsi_1_zext"
6471 [(set (match_operand:DI 0 "register_operand" "=r")
6473 (minus:SI (match_operand:SI 1 "register_operand" "0")
6474 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6475 (clobber (reg:CC FLAGS_REG))]
6476 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6477 "sub{l}\t{%2, %k0|%k0, %2}"
6478 [(set_attr "type" "alu")
6479 (set_attr "mode" "SI")])
6481 (define_insn "*subqi_1_slp"
6482 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6483 (minus:QI (match_dup 0)
6484 (match_operand:QI 1 "general_operand" "qn,qm")))
6485 (clobber (reg:CC FLAGS_REG))]
6486 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6487 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6488 "sub{b}\t{%1, %0|%0, %1}"
6489 [(set_attr "type" "alu1")
6490 (set_attr "mode" "QI")])
6492 (define_insn "*sub<mode>_2"
6493 [(set (reg FLAGS_REG)
6496 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6497 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6499 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6500 (minus:SWI (match_dup 1) (match_dup 2)))]
6501 "ix86_match_ccmode (insn, CCGOCmode)
6502 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6503 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6504 [(set_attr "type" "alu")
6505 (set_attr "mode" "<MODE>")])
6507 (define_insn "*subsi_2_zext"
6508 [(set (reg FLAGS_REG)
6510 (minus:SI (match_operand:SI 1 "register_operand" "0")
6511 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6513 (set (match_operand:DI 0 "register_operand" "=r")
6515 (minus:SI (match_dup 1)
6517 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6518 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6519 "sub{l}\t{%2, %k0|%k0, %2}"
6520 [(set_attr "type" "alu")
6521 (set_attr "mode" "SI")])
6523 ;; Subtract with jump on overflow.
6524 (define_expand "subv<mode>4"
6525 [(parallel [(set (reg:CCO FLAGS_REG)
6526 (eq:CCO (minus:<DWI>
6528 (match_operand:SWI 1 "nonimmediate_operand"))
6530 (match_operand:SWI 2 "<general_operand>")))
6532 (minus:SWI (match_dup 1) (match_dup 2)))))
6533 (set (match_operand:SWI 0 "register_operand")
6534 (minus:SWI (match_dup 1) (match_dup 2)))])
6535 (set (pc) (if_then_else
6536 (eq (reg:CCO FLAGS_REG) (const_int 0))
6537 (label_ref (match_operand 3))
6540 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6542 (define_insn "*subv<mode>4"
6543 [(set (reg:CCO FLAGS_REG)
6544 (eq:CCO (minus:<DWI>
6546 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6548 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6550 (minus:SWI (match_dup 1) (match_dup 2)))))
6551 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6552 (minus:SWI (match_dup 1) (match_dup 2)))]
6553 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6554 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "mode" "<MODE>")])
6558 (define_insn "*sub<mode>_3"
6559 [(set (reg FLAGS_REG)
6560 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6561 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6562 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6563 (minus:SWI (match_dup 1) (match_dup 2)))]
6564 "ix86_match_ccmode (insn, CCmode)
6565 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6566 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6567 [(set_attr "type" "alu")
6568 (set_attr "mode" "<MODE>")])
6570 (define_insn "*subsi_3_zext"
6571 [(set (reg FLAGS_REG)
6572 (compare (match_operand:SI 1 "register_operand" "0")
6573 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6574 (set (match_operand:DI 0 "register_operand" "=r")
6576 (minus:SI (match_dup 1)
6578 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6579 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6580 "sub{l}\t{%2, %1|%1, %2}"
6581 [(set_attr "type" "alu")
6582 (set_attr "mode" "SI")])
6584 ;; Add with carry and subtract with borrow
6586 (define_expand "<plusminus_insn><mode>3_carry"
6588 [(set (match_operand:SWI 0 "nonimmediate_operand")
6590 (match_operand:SWI 1 "nonimmediate_operand")
6591 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6592 [(match_operand 3 "flags_reg_operand")
6594 (match_operand:SWI 2 "<general_operand>"))))
6595 (clobber (reg:CC FLAGS_REG))])]
6596 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6598 (define_insn "*<plusminus_insn><mode>3_carry"
6599 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6601 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6603 (match_operator 3 "ix86_carry_flag_operator"
6604 [(reg FLAGS_REG) (const_int 0)])
6605 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6606 (clobber (reg:CC FLAGS_REG))]
6607 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6608 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6609 [(set_attr "type" "alu")
6610 (set_attr "use_carry" "1")
6611 (set_attr "pent_pair" "pu")
6612 (set_attr "mode" "<MODE>")])
6614 (define_insn "*addsi3_carry_zext"
6615 [(set (match_operand:DI 0 "register_operand" "=r")
6617 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6618 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6619 [(reg FLAGS_REG) (const_int 0)])
6620 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6621 (clobber (reg:CC FLAGS_REG))]
6622 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6623 "adc{l}\t{%2, %k0|%k0, %2}"
6624 [(set_attr "type" "alu")
6625 (set_attr "use_carry" "1")
6626 (set_attr "pent_pair" "pu")
6627 (set_attr "mode" "SI")])
6629 (define_insn "*subsi3_carry_zext"
6630 [(set (match_operand:DI 0 "register_operand" "=r")
6632 (minus:SI (match_operand:SI 1 "register_operand" "0")
6633 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6634 [(reg FLAGS_REG) (const_int 0)])
6635 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6636 (clobber (reg:CC FLAGS_REG))]
6637 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6638 "sbb{l}\t{%2, %k0|%k0, %2}"
6639 [(set_attr "type" "alu")
6640 (set_attr "pent_pair" "pu")
6641 (set_attr "mode" "SI")])
6645 (define_insn "adcx<mode>3"
6646 [(set (reg:CCC FLAGS_REG)
6649 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6651 (match_operator 4 "ix86_carry_flag_operator"
6652 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6653 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6655 (set (match_operand:SWI48 0 "register_operand" "=r")
6656 (plus:SWI48 (match_dup 1)
6657 (plus:SWI48 (match_op_dup 4
6658 [(match_dup 3) (const_int 0)])
6660 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6661 "adcx\t{%2, %0|%0, %2}"
6662 [(set_attr "type" "alu")
6663 (set_attr "use_carry" "1")
6664 (set_attr "mode" "<MODE>")])
6666 ;; Overflow setting add instructions
6668 (define_insn "*add<mode>3_cconly_overflow"
6669 [(set (reg:CCC FLAGS_REG)
6672 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6673 (match_operand:SWI 2 "<general_operand>" "<g>"))
6675 (clobber (match_scratch:SWI 0 "=<r>"))]
6676 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6677 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6678 [(set_attr "type" "alu")
6679 (set_attr "mode" "<MODE>")])
6681 (define_insn "*add<mode>3_cc_overflow"
6682 [(set (reg:CCC FLAGS_REG)
6685 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6686 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6688 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6689 (plus:SWI (match_dup 1) (match_dup 2)))]
6690 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6691 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6692 [(set_attr "type" "alu")
6693 (set_attr "mode" "<MODE>")])
6695 (define_insn "*addsi3_zext_cc_overflow"
6696 [(set (reg:CCC FLAGS_REG)
6699 (match_operand:SI 1 "nonimmediate_operand" "%0")
6700 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6702 (set (match_operand:DI 0 "register_operand" "=r")
6703 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6704 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6705 "add{l}\t{%2, %k0|%k0, %2}"
6706 [(set_attr "type" "alu")
6707 (set_attr "mode" "SI")])
6709 ;; The patterns that match these are at the end of this file.
6711 (define_expand "<plusminus_insn>xf3"
6712 [(set (match_operand:XF 0 "register_operand")
6714 (match_operand:XF 1 "register_operand")
6715 (match_operand:XF 2 "register_operand")))]
6718 (define_expand "<plusminus_insn><mode>3"
6719 [(set (match_operand:MODEF 0 "register_operand")
6721 (match_operand:MODEF 1 "register_operand")
6722 (match_operand:MODEF 2 "nonimmediate_operand")))]
6723 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6724 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6726 ;; Multiply instructions
6728 (define_expand "mul<mode>3"
6729 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6731 (match_operand:SWIM248 1 "register_operand")
6732 (match_operand:SWIM248 2 "<general_operand>")))
6733 (clobber (reg:CC FLAGS_REG))])])
6735 (define_expand "mulqi3"
6736 [(parallel [(set (match_operand:QI 0 "register_operand")
6738 (match_operand:QI 1 "register_operand")
6739 (match_operand:QI 2 "nonimmediate_operand")))
6740 (clobber (reg:CC FLAGS_REG))])]
6741 "TARGET_QIMODE_MATH")
6744 ;; IMUL reg32/64, reg32/64, imm8 Direct
6745 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6746 ;; IMUL reg32/64, reg32/64, imm32 Direct
6747 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6748 ;; IMUL reg32/64, reg32/64 Direct
6749 ;; IMUL reg32/64, mem32/64 Direct
6751 ;; On BDVER1, all above IMULs use DirectPath
6753 (define_insn "*mul<mode>3_1"
6754 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6756 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6757 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6758 (clobber (reg:CC FLAGS_REG))]
6759 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6761 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6762 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6763 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6764 [(set_attr "type" "imul")
6765 (set_attr "prefix_0f" "0,0,1")
6766 (set (attr "athlon_decode")
6767 (cond [(eq_attr "cpu" "athlon")
6768 (const_string "vector")
6769 (eq_attr "alternative" "1")
6770 (const_string "vector")
6771 (and (eq_attr "alternative" "2")
6772 (match_operand 1 "memory_operand"))
6773 (const_string "vector")]
6774 (const_string "direct")))
6775 (set (attr "amdfam10_decode")
6776 (cond [(and (eq_attr "alternative" "0,1")
6777 (match_operand 1 "memory_operand"))
6778 (const_string "vector")]
6779 (const_string "direct")))
6780 (set_attr "bdver1_decode" "direct")
6781 (set_attr "mode" "<MODE>")])
6783 (define_insn "*mulsi3_1_zext"
6784 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6786 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6787 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6788 (clobber (reg:CC FLAGS_REG))]
6790 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6792 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6793 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6794 imul{l}\t{%2, %k0|%k0, %2}"
6795 [(set_attr "type" "imul")
6796 (set_attr "prefix_0f" "0,0,1")
6797 (set (attr "athlon_decode")
6798 (cond [(eq_attr "cpu" "athlon")
6799 (const_string "vector")
6800 (eq_attr "alternative" "1")
6801 (const_string "vector")
6802 (and (eq_attr "alternative" "2")
6803 (match_operand 1 "memory_operand"))
6804 (const_string "vector")]
6805 (const_string "direct")))
6806 (set (attr "amdfam10_decode")
6807 (cond [(and (eq_attr "alternative" "0,1")
6808 (match_operand 1 "memory_operand"))
6809 (const_string "vector")]
6810 (const_string "direct")))
6811 (set_attr "bdver1_decode" "direct")
6812 (set_attr "mode" "SI")])
6815 ;; IMUL reg16, reg16, imm8 VectorPath
6816 ;; IMUL reg16, mem16, imm8 VectorPath
6817 ;; IMUL reg16, reg16, imm16 VectorPath
6818 ;; IMUL reg16, mem16, imm16 VectorPath
6819 ;; IMUL reg16, reg16 Direct
6820 ;; IMUL reg16, mem16 Direct
6822 ;; On BDVER1, all HI MULs use DoublePath
6824 (define_insn "*mulhi3_1"
6825 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6826 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6827 (match_operand:HI 2 "general_operand" "K,n,mr")))
6828 (clobber (reg:CC FLAGS_REG))]
6830 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6832 imul{w}\t{%2, %1, %0|%0, %1, %2}
6833 imul{w}\t{%2, %1, %0|%0, %1, %2}
6834 imul{w}\t{%2, %0|%0, %2}"
6835 [(set_attr "type" "imul")
6836 (set_attr "prefix_0f" "0,0,1")
6837 (set (attr "athlon_decode")
6838 (cond [(eq_attr "cpu" "athlon")
6839 (const_string "vector")
6840 (eq_attr "alternative" "1,2")
6841 (const_string "vector")]
6842 (const_string "direct")))
6843 (set (attr "amdfam10_decode")
6844 (cond [(eq_attr "alternative" "0,1")
6845 (const_string "vector")]
6846 (const_string "direct")))
6847 (set_attr "bdver1_decode" "double")
6848 (set_attr "mode" "HI")])
6850 ;;On AMDFAM10 and BDVER1
6854 (define_insn "*mulqi3_1"
6855 [(set (match_operand:QI 0 "register_operand" "=a")
6856 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6857 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6858 (clobber (reg:CC FLAGS_REG))]
6860 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6862 [(set_attr "type" "imul")
6863 (set_attr "length_immediate" "0")
6864 (set (attr "athlon_decode")
6865 (if_then_else (eq_attr "cpu" "athlon")
6866 (const_string "vector")
6867 (const_string "direct")))
6868 (set_attr "amdfam10_decode" "direct")
6869 (set_attr "bdver1_decode" "direct")
6870 (set_attr "mode" "QI")])
6872 ;; Multiply with jump on overflow.
6873 (define_expand "mulv<mode>4"
6874 [(parallel [(set (reg:CCO FLAGS_REG)
6877 (match_operand:SWI48 1 "register_operand"))
6879 (match_operand:SWI48 2 "<general_operand>")))
6881 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6882 (set (match_operand:SWI48 0 "register_operand")
6883 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6884 (set (pc) (if_then_else
6885 (eq (reg:CCO FLAGS_REG) (const_int 0))
6886 (label_ref (match_operand 3))
6889 (define_insn "*mulv<mode>4"
6890 [(set (reg:CCO FLAGS_REG)
6893 (match_operand:SWI 1 "nonimmediate_operand" "%rm,rm,0"))
6895 (match_operand:SWI 2 "<general_operand>" "K,<i>,mr")))
6897 (mult:SWI (match_dup 1) (match_dup 2)))))
6898 (set (match_operand:SWI 0 "register_operand" "=r,r,r")
6899 (mult:SWI (match_dup 1) (match_dup 2)))]
6900 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6902 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6903 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6904 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6905 [(set_attr "type" "imul")
6906 (set_attr "prefix_0f" "0,0,1")
6907 (set (attr "athlon_decode")
6908 (cond [(eq_attr "cpu" "athlon")
6909 (const_string "vector")
6910 (eq_attr "alternative" "1")
6911 (const_string "vector")
6912 (and (eq_attr "alternative" "2")
6913 (match_operand 1 "memory_operand"))
6914 (const_string "vector")]
6915 (const_string "direct")))
6916 (set (attr "amdfam10_decode")
6917 (cond [(and (eq_attr "alternative" "0,1")
6918 (match_operand 1 "memory_operand"))
6919 (const_string "vector")]
6920 (const_string "direct")))
6921 (set_attr "bdver1_decode" "direct")
6922 (set_attr "mode" "<MODE>")])
6924 (define_expand "<u>mul<mode><dwi>3"
6925 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6928 (match_operand:DWIH 1 "nonimmediate_operand"))
6930 (match_operand:DWIH 2 "register_operand"))))
6931 (clobber (reg:CC FLAGS_REG))])])
6933 (define_expand "<u>mulqihi3"
6934 [(parallel [(set (match_operand:HI 0 "register_operand")
6937 (match_operand:QI 1 "nonimmediate_operand"))
6939 (match_operand:QI 2 "register_operand"))))
6940 (clobber (reg:CC FLAGS_REG))])]
6941 "TARGET_QIMODE_MATH")
6943 (define_insn "*bmi2_umulditi3_1"
6944 [(set (match_operand:DI 0 "register_operand" "=r")
6946 (match_operand:DI 2 "nonimmediate_operand" "%d")
6947 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6948 (set (match_operand:DI 1 "register_operand" "=r")
6951 (mult:TI (zero_extend:TI (match_dup 2))
6952 (zero_extend:TI (match_dup 3)))
6954 "TARGET_64BIT && TARGET_BMI2
6955 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6956 "mulx\t{%3, %0, %1|%1, %0, %3}"
6957 [(set_attr "type" "imulx")
6958 (set_attr "prefix" "vex")
6959 (set_attr "mode" "DI")])
6961 (define_insn "*bmi2_umulsidi3_1"
6962 [(set (match_operand:SI 0 "register_operand" "=r")
6964 (match_operand:SI 2 "nonimmediate_operand" "%d")
6965 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6966 (set (match_operand:SI 1 "register_operand" "=r")
6969 (mult:DI (zero_extend:DI (match_dup 2))
6970 (zero_extend:DI (match_dup 3)))
6972 "!TARGET_64BIT && TARGET_BMI2
6973 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6974 "mulx\t{%3, %0, %1|%1, %0, %3}"
6975 [(set_attr "type" "imulx")
6976 (set_attr "prefix" "vex")
6977 (set_attr "mode" "SI")])
6979 (define_insn "*umul<mode><dwi>3_1"
6980 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6983 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6985 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6986 (clobber (reg:CC FLAGS_REG))]
6987 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6990 mul{<imodesuffix>}\t%2"
6991 [(set_attr "isa" "bmi2,*")
6992 (set_attr "type" "imulx,imul")
6993 (set_attr "length_immediate" "*,0")
6994 (set (attr "athlon_decode")
6995 (cond [(eq_attr "alternative" "1")
6996 (if_then_else (eq_attr "cpu" "athlon")
6997 (const_string "vector")
6998 (const_string "double"))]
6999 (const_string "*")))
7000 (set_attr "amdfam10_decode" "*,double")
7001 (set_attr "bdver1_decode" "*,direct")
7002 (set_attr "prefix" "vex,orig")
7003 (set_attr "mode" "<MODE>")])
7005 ;; Convert mul to the mulx pattern to avoid flags dependency.
7007 [(set (match_operand:<DWI> 0 "register_operand")
7010 (match_operand:DWIH 1 "register_operand"))
7012 (match_operand:DWIH 2 "nonimmediate_operand"))))
7013 (clobber (reg:CC FLAGS_REG))]
7014 "TARGET_BMI2 && reload_completed
7015 && true_regnum (operands[1]) == DX_REG"
7016 [(parallel [(set (match_dup 3)
7017 (mult:DWIH (match_dup 1) (match_dup 2)))
7021 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7022 (zero_extend:<DWI> (match_dup 2)))
7025 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7027 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
7030 (define_insn "*mul<mode><dwi>3_1"
7031 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7034 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7036 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7037 (clobber (reg:CC FLAGS_REG))]
7038 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7039 "imul{<imodesuffix>}\t%2"
7040 [(set_attr "type" "imul")
7041 (set_attr "length_immediate" "0")
7042 (set (attr "athlon_decode")
7043 (if_then_else (eq_attr "cpu" "athlon")
7044 (const_string "vector")
7045 (const_string "double")))
7046 (set_attr "amdfam10_decode" "double")
7047 (set_attr "bdver1_decode" "direct")
7048 (set_attr "mode" "<MODE>")])
7050 (define_insn "*<u>mulqihi3_1"
7051 [(set (match_operand:HI 0 "register_operand" "=a")
7054 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7056 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7057 (clobber (reg:CC FLAGS_REG))]
7059 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7060 "<sgnprefix>mul{b}\t%2"
7061 [(set_attr "type" "imul")
7062 (set_attr "length_immediate" "0")
7063 (set (attr "athlon_decode")
7064 (if_then_else (eq_attr "cpu" "athlon")
7065 (const_string "vector")
7066 (const_string "direct")))
7067 (set_attr "amdfam10_decode" "direct")
7068 (set_attr "bdver1_decode" "direct")
7069 (set_attr "mode" "QI")])
7071 (define_expand "<s>mul<mode>3_highpart"
7072 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7077 (match_operand:SWI48 1 "nonimmediate_operand"))
7079 (match_operand:SWI48 2 "register_operand")))
7081 (clobber (match_scratch:SWI48 3))
7082 (clobber (reg:CC FLAGS_REG))])]
7084 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7086 (define_insn "*<s>muldi3_highpart_1"
7087 [(set (match_operand:DI 0 "register_operand" "=d")
7092 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7094 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7096 (clobber (match_scratch:DI 3 "=1"))
7097 (clobber (reg:CC FLAGS_REG))]
7099 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7100 "<sgnprefix>mul{q}\t%2"
7101 [(set_attr "type" "imul")
7102 (set_attr "length_immediate" "0")
7103 (set (attr "athlon_decode")
7104 (if_then_else (eq_attr "cpu" "athlon")
7105 (const_string "vector")
7106 (const_string "double")))
7107 (set_attr "amdfam10_decode" "double")
7108 (set_attr "bdver1_decode" "direct")
7109 (set_attr "mode" "DI")])
7111 (define_insn "*<s>mulsi3_highpart_1"
7112 [(set (match_operand:SI 0 "register_operand" "=d")
7117 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7119 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7121 (clobber (match_scratch:SI 3 "=1"))
7122 (clobber (reg:CC FLAGS_REG))]
7123 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7124 "<sgnprefix>mul{l}\t%2"
7125 [(set_attr "type" "imul")
7126 (set_attr "length_immediate" "0")
7127 (set (attr "athlon_decode")
7128 (if_then_else (eq_attr "cpu" "athlon")
7129 (const_string "vector")
7130 (const_string "double")))
7131 (set_attr "amdfam10_decode" "double")
7132 (set_attr "bdver1_decode" "direct")
7133 (set_attr "mode" "SI")])
7135 (define_insn "*<s>mulsi3_highpart_zext"
7136 [(set (match_operand:DI 0 "register_operand" "=d")
7137 (zero_extend:DI (truncate:SI
7139 (mult:DI (any_extend:DI
7140 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7142 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7144 (clobber (match_scratch:SI 3 "=1"))
7145 (clobber (reg:CC FLAGS_REG))]
7147 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7148 "<sgnprefix>mul{l}\t%2"
7149 [(set_attr "type" "imul")
7150 (set_attr "length_immediate" "0")
7151 (set (attr "athlon_decode")
7152 (if_then_else (eq_attr "cpu" "athlon")
7153 (const_string "vector")
7154 (const_string "double")))
7155 (set_attr "amdfam10_decode" "double")
7156 (set_attr "bdver1_decode" "direct")
7157 (set_attr "mode" "SI")])
7159 ;; The patterns that match these are at the end of this file.
7161 (define_expand "mulxf3"
7162 [(set (match_operand:XF 0 "register_operand")
7163 (mult:XF (match_operand:XF 1 "register_operand")
7164 (match_operand:XF 2 "register_operand")))]
7167 (define_expand "mul<mode>3"
7168 [(set (match_operand:MODEF 0 "register_operand")
7169 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7170 (match_operand:MODEF 2 "nonimmediate_operand")))]
7171 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7172 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7174 ;; Divide instructions
7176 ;; The patterns that match these are at the end of this file.
7178 (define_expand "divxf3"
7179 [(set (match_operand:XF 0 "register_operand")
7180 (div:XF (match_operand:XF 1 "register_operand")
7181 (match_operand:XF 2 "register_operand")))]
7184 (define_expand "divdf3"
7185 [(set (match_operand:DF 0 "register_operand")
7186 (div:DF (match_operand:DF 1 "register_operand")
7187 (match_operand:DF 2 "nonimmediate_operand")))]
7188 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7189 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7191 (define_expand "divsf3"
7192 [(set (match_operand:SF 0 "register_operand")
7193 (div:SF (match_operand:SF 1 "register_operand")
7194 (match_operand:SF 2 "nonimmediate_operand")))]
7195 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7200 && optimize_insn_for_speed_p ()
7201 && flag_finite_math_only && !flag_trapping_math
7202 && flag_unsafe_math_optimizations)
7204 ix86_emit_swdivsf (operands[0], operands[1],
7205 operands[2], SFmode);
7210 ;; Divmod instructions.
7212 (define_expand "divmod<mode>4"
7213 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7215 (match_operand:SWIM248 1 "register_operand")
7216 (match_operand:SWIM248 2 "nonimmediate_operand")))
7217 (set (match_operand:SWIM248 3 "register_operand")
7218 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7219 (clobber (reg:CC FLAGS_REG))])])
7221 ;; Split with 8bit unsigned divide:
7222 ;; if (dividend an divisor are in [0-255])
7223 ;; use 8bit unsigned integer divide
7225 ;; use original integer divide
7227 [(set (match_operand:SWI48 0 "register_operand")
7228 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7229 (match_operand:SWI48 3 "nonimmediate_operand")))
7230 (set (match_operand:SWI48 1 "register_operand")
7231 (mod:SWI48 (match_dup 2) (match_dup 3)))
7232 (clobber (reg:CC FLAGS_REG))]
7233 "TARGET_USE_8BIT_IDIV
7234 && TARGET_QIMODE_MATH
7235 && can_create_pseudo_p ()
7236 && !optimize_insn_for_size_p ()"
7238 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7240 (define_insn_and_split "divmod<mode>4_1"
7241 [(set (match_operand:SWI48 0 "register_operand" "=a")
7242 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7243 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7244 (set (match_operand:SWI48 1 "register_operand" "=&d")
7245 (mod:SWI48 (match_dup 2) (match_dup 3)))
7246 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7247 (clobber (reg:CC FLAGS_REG))]
7251 [(parallel [(set (match_dup 1)
7252 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7253 (clobber (reg:CC FLAGS_REG))])
7254 (parallel [(set (match_dup 0)
7255 (div:SWI48 (match_dup 2) (match_dup 3)))
7257 (mod:SWI48 (match_dup 2) (match_dup 3)))
7259 (clobber (reg:CC FLAGS_REG))])]
7261 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7263 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7264 operands[4] = operands[2];
7267 /* Avoid use of cltd in favor of a mov+shift. */
7268 emit_move_insn (operands[1], operands[2]);
7269 operands[4] = operands[1];
7272 [(set_attr "type" "multi")
7273 (set_attr "mode" "<MODE>")])
7275 (define_insn_and_split "*divmod<mode>4"
7276 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7277 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7278 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7279 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7280 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7281 (clobber (reg:CC FLAGS_REG))]
7285 [(parallel [(set (match_dup 1)
7286 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7287 (clobber (reg:CC FLAGS_REG))])
7288 (parallel [(set (match_dup 0)
7289 (div:SWIM248 (match_dup 2) (match_dup 3)))
7291 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7293 (clobber (reg:CC FLAGS_REG))])]
7295 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7297 if (<MODE>mode != HImode
7298 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7299 operands[4] = operands[2];
7302 /* Avoid use of cltd in favor of a mov+shift. */
7303 emit_move_insn (operands[1], operands[2]);
7304 operands[4] = operands[1];
7307 [(set_attr "type" "multi")
7308 (set_attr "mode" "<MODE>")])
7310 (define_insn "*divmod<mode>4_noext"
7311 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7312 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7313 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7314 (set (match_operand:SWIM248 1 "register_operand" "=d")
7315 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7316 (use (match_operand:SWIM248 4 "register_operand" "1"))
7317 (clobber (reg:CC FLAGS_REG))]
7319 "idiv{<imodesuffix>}\t%3"
7320 [(set_attr "type" "idiv")
7321 (set_attr "mode" "<MODE>")])
7323 (define_expand "divmodqi4"
7324 [(parallel [(set (match_operand:QI 0 "register_operand")
7326 (match_operand:QI 1 "register_operand")
7327 (match_operand:QI 2 "nonimmediate_operand")))
7328 (set (match_operand:QI 3 "register_operand")
7329 (mod:QI (match_dup 1) (match_dup 2)))
7330 (clobber (reg:CC FLAGS_REG))])]
7331 "TARGET_QIMODE_MATH"
7336 tmp0 = gen_reg_rtx (HImode);
7337 tmp1 = gen_reg_rtx (HImode);
7339 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7341 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7342 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7344 /* Extract remainder from AH. */
7345 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7346 insn = emit_move_insn (operands[3], tmp1);
7348 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7349 set_unique_reg_note (insn, REG_EQUAL, mod);
7351 /* Extract quotient from AL. */
7352 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7354 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7355 set_unique_reg_note (insn, REG_EQUAL, div);
7360 ;; Divide AX by r/m8, with result stored in
7363 ;; Change div/mod to HImode and extend the second argument to HImode
7364 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7365 ;; combine may fail.
7366 (define_insn "divmodhiqi3"
7367 [(set (match_operand:HI 0 "register_operand" "=a")
7372 (mod:HI (match_operand:HI 1 "register_operand" "0")
7374 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7378 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7379 (clobber (reg:CC FLAGS_REG))]
7380 "TARGET_QIMODE_MATH"
7382 [(set_attr "type" "idiv")
7383 (set_attr "mode" "QI")])
7385 (define_expand "udivmod<mode>4"
7386 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7388 (match_operand:SWIM248 1 "register_operand")
7389 (match_operand:SWIM248 2 "nonimmediate_operand")))
7390 (set (match_operand:SWIM248 3 "register_operand")
7391 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7392 (clobber (reg:CC FLAGS_REG))])])
7394 ;; Split with 8bit unsigned divide:
7395 ;; if (dividend an divisor are in [0-255])
7396 ;; use 8bit unsigned integer divide
7398 ;; use original integer divide
7400 [(set (match_operand:SWI48 0 "register_operand")
7401 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7402 (match_operand:SWI48 3 "nonimmediate_operand")))
7403 (set (match_operand:SWI48 1 "register_operand")
7404 (umod:SWI48 (match_dup 2) (match_dup 3)))
7405 (clobber (reg:CC FLAGS_REG))]
7406 "TARGET_USE_8BIT_IDIV
7407 && TARGET_QIMODE_MATH
7408 && can_create_pseudo_p ()
7409 && !optimize_insn_for_size_p ()"
7411 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7413 (define_insn_and_split "udivmod<mode>4_1"
7414 [(set (match_operand:SWI48 0 "register_operand" "=a")
7415 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7416 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7417 (set (match_operand:SWI48 1 "register_operand" "=&d")
7418 (umod:SWI48 (match_dup 2) (match_dup 3)))
7419 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7420 (clobber (reg:CC FLAGS_REG))]
7424 [(set (match_dup 1) (const_int 0))
7425 (parallel [(set (match_dup 0)
7426 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7428 (umod:SWI48 (match_dup 2) (match_dup 3)))
7430 (clobber (reg:CC FLAGS_REG))])]
7432 [(set_attr "type" "multi")
7433 (set_attr "mode" "<MODE>")])
7435 (define_insn_and_split "*udivmod<mode>4"
7436 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7437 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7438 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7439 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7440 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7441 (clobber (reg:CC FLAGS_REG))]
7445 [(set (match_dup 1) (const_int 0))
7446 (parallel [(set (match_dup 0)
7447 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7449 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7451 (clobber (reg:CC FLAGS_REG))])]
7453 [(set_attr "type" "multi")
7454 (set_attr "mode" "<MODE>")])
7456 (define_insn "*udivmod<mode>4_noext"
7457 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7458 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7459 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7460 (set (match_operand:SWIM248 1 "register_operand" "=d")
7461 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7462 (use (match_operand:SWIM248 4 "register_operand" "1"))
7463 (clobber (reg:CC FLAGS_REG))]
7465 "div{<imodesuffix>}\t%3"
7466 [(set_attr "type" "idiv")
7467 (set_attr "mode" "<MODE>")])
7469 (define_expand "udivmodqi4"
7470 [(parallel [(set (match_operand:QI 0 "register_operand")
7472 (match_operand:QI 1 "register_operand")
7473 (match_operand:QI 2 "nonimmediate_operand")))
7474 (set (match_operand:QI 3 "register_operand")
7475 (umod:QI (match_dup 1) (match_dup 2)))
7476 (clobber (reg:CC FLAGS_REG))])]
7477 "TARGET_QIMODE_MATH"
7482 tmp0 = gen_reg_rtx (HImode);
7483 tmp1 = gen_reg_rtx (HImode);
7485 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7487 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7488 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7490 /* Extract remainder from AH. */
7491 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7492 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7493 insn = emit_move_insn (operands[3], tmp1);
7495 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7496 set_unique_reg_note (insn, REG_EQUAL, mod);
7498 /* Extract quotient from AL. */
7499 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7501 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7502 set_unique_reg_note (insn, REG_EQUAL, div);
7507 (define_insn "udivmodhiqi3"
7508 [(set (match_operand:HI 0 "register_operand" "=a")
7513 (mod:HI (match_operand:HI 1 "register_operand" "0")
7515 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7519 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7520 (clobber (reg:CC FLAGS_REG))]
7521 "TARGET_QIMODE_MATH"
7523 [(set_attr "type" "idiv")
7524 (set_attr "mode" "QI")])
7526 ;; We cannot use div/idiv for double division, because it causes
7527 ;; "division by zero" on the overflow and that's not what we expect
7528 ;; from truncate. Because true (non truncating) double division is
7529 ;; never generated, we can't create this insn anyway.
7532 ; [(set (match_operand:SI 0 "register_operand" "=a")
7534 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7536 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7537 ; (set (match_operand:SI 3 "register_operand" "=d")
7539 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7540 ; (clobber (reg:CC FLAGS_REG))]
7542 ; "div{l}\t{%2, %0|%0, %2}"
7543 ; [(set_attr "type" "idiv")])
7545 ;;- Logical AND instructions
7547 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7548 ;; Note that this excludes ah.
7550 (define_expand "testsi_ccno_1"
7551 [(set (reg:CCNO FLAGS_REG)
7553 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7554 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7557 (define_expand "testqi_ccz_1"
7558 [(set (reg:CCZ FLAGS_REG)
7559 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7560 (match_operand:QI 1 "nonmemory_operand"))
7563 (define_expand "testdi_ccno_1"
7564 [(set (reg:CCNO FLAGS_REG)
7566 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7567 (match_operand:DI 1 "x86_64_szext_general_operand"))
7569 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7571 (define_insn "*testdi_1"
7572 [(set (reg FLAGS_REG)
7575 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7576 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7578 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7579 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7581 test{l}\t{%k1, %k0|%k0, %k1}
7582 test{l}\t{%k1, %k0|%k0, %k1}
7583 test{q}\t{%1, %0|%0, %1}
7584 test{q}\t{%1, %0|%0, %1}
7585 test{q}\t{%1, %0|%0, %1}"
7586 [(set_attr "type" "test")
7587 (set_attr "modrm" "0,1,0,1,1")
7588 (set_attr "mode" "SI,SI,DI,DI,DI")])
7590 (define_insn "*testqi_1_maybe_si"
7591 [(set (reg FLAGS_REG)
7594 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7595 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7597 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7598 && ix86_match_ccmode (insn,
7599 CONST_INT_P (operands[1])
7600 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7602 if (which_alternative == 3)
7604 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7605 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7606 return "test{l}\t{%1, %k0|%k0, %1}";
7608 return "test{b}\t{%1, %0|%0, %1}";
7610 [(set_attr "type" "test")
7611 (set_attr "modrm" "0,1,1,1")
7612 (set_attr "mode" "QI,QI,QI,SI")
7613 (set_attr "pent_pair" "uv,np,uv,np")])
7615 (define_insn "*test<mode>_1"
7616 [(set (reg FLAGS_REG)
7619 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7620 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7622 "ix86_match_ccmode (insn, CCNOmode)
7623 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7624 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7625 [(set_attr "type" "test")
7626 (set_attr "modrm" "0,1,1")
7627 (set_attr "mode" "<MODE>")
7628 (set_attr "pent_pair" "uv,np,uv")])
7630 (define_expand "testqi_ext_ccno_0"
7631 [(set (reg:CCNO FLAGS_REG)
7635 (match_operand 0 "ext_register_operand")
7638 (match_operand 1 "const_int_operand"))
7641 (define_insn "*testqi_ext_0"
7642 [(set (reg FLAGS_REG)
7646 (match_operand 0 "ext_register_operand" "Q")
7649 (match_operand 1 "const_int_operand" "n"))
7651 "ix86_match_ccmode (insn, CCNOmode)"
7652 "test{b}\t{%1, %h0|%h0, %1}"
7653 [(set_attr "type" "test")
7654 (set_attr "mode" "QI")
7655 (set_attr "length_immediate" "1")
7656 (set_attr "modrm" "1")
7657 (set_attr "pent_pair" "np")])
7659 (define_insn "*testqi_ext_1"
7660 [(set (reg FLAGS_REG)
7664 (match_operand 0 "ext_register_operand" "Q,Q")
7668 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7670 "ix86_match_ccmode (insn, CCNOmode)"
7671 "test{b}\t{%1, %h0|%h0, %1}"
7672 [(set_attr "isa" "*,nox64")
7673 (set_attr "type" "test")
7674 (set_attr "mode" "QI")])
7676 (define_insn "*testqi_ext_2"
7677 [(set (reg FLAGS_REG)
7681 (match_operand 0 "ext_register_operand" "Q")
7685 (match_operand 1 "ext_register_operand" "Q")
7689 "ix86_match_ccmode (insn, CCNOmode)"
7690 "test{b}\t{%h1, %h0|%h0, %h1}"
7691 [(set_attr "type" "test")
7692 (set_attr "mode" "QI")])
7694 ;; Combine likes to form bit extractions for some tests. Humor it.
7695 (define_insn "*testqi_ext_3"
7696 [(set (reg FLAGS_REG)
7697 (compare (zero_extract:SWI48
7698 (match_operand 0 "nonimmediate_operand" "rm")
7699 (match_operand:SWI48 1 "const_int_operand")
7700 (match_operand:SWI48 2 "const_int_operand"))
7702 "ix86_match_ccmode (insn, CCNOmode)
7703 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7704 || GET_MODE (operands[0]) == SImode
7705 || GET_MODE (operands[0]) == HImode
7706 || GET_MODE (operands[0]) == QImode)
7707 /* Ensure that resulting mask is zero or sign extended operand. */
7708 && INTVAL (operands[2]) >= 0
7709 && ((INTVAL (operands[1]) > 0
7710 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7711 || (<MODE>mode == DImode
7712 && INTVAL (operands[1]) > 32
7713 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7717 [(set (match_operand 0 "flags_reg_operand")
7718 (match_operator 1 "compare_operator"
7720 (match_operand 2 "nonimmediate_operand")
7721 (match_operand 3 "const_int_operand")
7722 (match_operand 4 "const_int_operand"))
7724 "ix86_match_ccmode (insn, CCNOmode)"
7725 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7727 rtx val = operands[2];
7728 HOST_WIDE_INT len = INTVAL (operands[3]);
7729 HOST_WIDE_INT pos = INTVAL (operands[4]);
7731 enum machine_mode mode, submode;
7733 mode = GET_MODE (val);
7736 /* ??? Combine likes to put non-volatile mem extractions in QImode
7737 no matter the size of the test. So find a mode that works. */
7738 if (! MEM_VOLATILE_P (val))
7740 mode = smallest_mode_for_size (pos + len, MODE_INT);
7741 val = adjust_address (val, mode, 0);
7744 else if (GET_CODE (val) == SUBREG
7745 && (submode = GET_MODE (SUBREG_REG (val)),
7746 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7747 && pos + len <= GET_MODE_BITSIZE (submode)
7748 && GET_MODE_CLASS (submode) == MODE_INT)
7750 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7752 val = SUBREG_REG (val);
7754 else if (mode == HImode && pos + len <= 8)
7756 /* Small HImode tests can be converted to QImode. */
7758 val = gen_lowpart (QImode, val);
7761 if (len == HOST_BITS_PER_WIDE_INT)
7764 mask = ((HOST_WIDE_INT)1 << len) - 1;
7767 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7770 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7771 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7772 ;; this is relatively important trick.
7773 ;; Do the conversion only post-reload to avoid limiting of the register class
7776 [(set (match_operand 0 "flags_reg_operand")
7777 (match_operator 1 "compare_operator"
7778 [(and (match_operand 2 "register_operand")
7779 (match_operand 3 "const_int_operand"))
7782 && QI_REG_P (operands[2])
7783 && GET_MODE (operands[2]) != QImode
7784 && ((ix86_match_ccmode (insn, CCZmode)
7785 && !(INTVAL (operands[3]) & ~(255 << 8)))
7786 || (ix86_match_ccmode (insn, CCNOmode)
7787 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7790 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7794 operands[2] = gen_lowpart (SImode, operands[2]);
7795 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7799 [(set (match_operand 0 "flags_reg_operand")
7800 (match_operator 1 "compare_operator"
7801 [(and (match_operand 2 "nonimmediate_operand")
7802 (match_operand 3 "const_int_operand"))
7805 && GET_MODE (operands[2]) != QImode
7806 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7807 && ((ix86_match_ccmode (insn, CCZmode)
7808 && !(INTVAL (operands[3]) & ~255))
7809 || (ix86_match_ccmode (insn, CCNOmode)
7810 && !(INTVAL (operands[3]) & ~127)))"
7812 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7815 operands[2] = gen_lowpart (QImode, operands[2]);
7816 operands[3] = gen_lowpart (QImode, operands[3]);
7820 [(set (match_operand:SWI12 0 "mask_reg_operand")
7821 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand")
7822 (match_operand:SWI12 2 "mask_reg_operand")))
7823 (clobber (reg:CC FLAGS_REG))]
7824 "TARGET_AVX512F && reload_completed"
7826 (any_logic:SWI12 (match_dup 1)
7829 (define_insn "*k<logic><mode>"
7830 [(set (match_operand:SWI12 0 "mask_reg_operand" "=k")
7831 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "k")
7832 (match_operand:SWI12 2 "mask_reg_operand" "k")))]
7834 "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7835 [(set_attr "mode" "<MODE>")
7836 (set_attr "type" "msklog")
7837 (set_attr "prefix" "vex")])
7839 ;; %%% This used to optimize known byte-wide and operations to memory,
7840 ;; and sometimes to QImode registers. If this is considered useful,
7841 ;; it should be done with splitters.
7843 (define_expand "and<mode>3"
7844 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7845 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7846 (match_operand:SWIM 2 "<general_szext_operand>")))]
7849 enum machine_mode mode = <MODE>mode;
7850 rtx (*insn) (rtx, rtx);
7852 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7854 HOST_WIDE_INT ival = INTVAL (operands[2]);
7856 if (ival == (HOST_WIDE_INT) 0xffffffff)
7858 else if (ival == 0xffff)
7860 else if (ival == 0xff)
7864 if (mode == <MODE>mode)
7866 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7870 if (<MODE>mode == DImode)
7871 insn = (mode == SImode)
7872 ? gen_zero_extendsidi2
7874 ? gen_zero_extendhidi2
7875 : gen_zero_extendqidi2;
7876 else if (<MODE>mode == SImode)
7877 insn = (mode == HImode)
7878 ? gen_zero_extendhisi2
7879 : gen_zero_extendqisi2;
7880 else if (<MODE>mode == HImode)
7881 insn = gen_zero_extendqihi2;
7885 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7889 (define_insn "*anddi_1"
7890 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7892 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7893 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7894 (clobber (reg:CC FLAGS_REG))]
7895 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7897 switch (get_attr_type (insn))
7903 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7904 if (get_attr_mode (insn) == MODE_SI)
7905 return "and{l}\t{%k2, %k0|%k0, %k2}";
7907 return "and{q}\t{%2, %0|%0, %2}";
7910 [(set_attr "type" "alu,alu,alu,imovx")
7911 (set_attr "length_immediate" "*,*,*,0")
7912 (set (attr "prefix_rex")
7914 (and (eq_attr "type" "imovx")
7915 (and (match_test "INTVAL (operands[2]) == 0xff")
7916 (match_operand 1 "ext_QIreg_operand")))
7918 (const_string "*")))
7919 (set_attr "mode" "SI,DI,DI,SI")])
7921 (define_insn "*andsi_1"
7922 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7923 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7924 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7925 (clobber (reg:CC FLAGS_REG))]
7926 "ix86_binary_operator_ok (AND, SImode, operands)"
7928 switch (get_attr_type (insn))
7934 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7935 return "and{l}\t{%2, %0|%0, %2}";
7938 [(set_attr "type" "alu,alu,imovx")
7939 (set (attr "prefix_rex")
7941 (and (eq_attr "type" "imovx")
7942 (and (match_test "INTVAL (operands[2]) == 0xff")
7943 (match_operand 1 "ext_QIreg_operand")))
7945 (const_string "*")))
7946 (set_attr "length_immediate" "*,*,0")
7947 (set_attr "mode" "SI")])
7949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7950 (define_insn "*andsi_1_zext"
7951 [(set (match_operand:DI 0 "register_operand" "=r")
7953 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7954 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7955 (clobber (reg:CC FLAGS_REG))]
7956 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7957 "and{l}\t{%2, %k0|%k0, %2}"
7958 [(set_attr "type" "alu")
7959 (set_attr "mode" "SI")])
7961 (define_insn "*andhi_1"
7962 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7963 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7964 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7965 (clobber (reg:CC FLAGS_REG))]
7966 "ix86_binary_operator_ok (AND, HImode, operands)"
7968 switch (get_attr_type (insn))
7974 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7977 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7978 return "and{w}\t{%2, %0|%0, %2}";
7981 [(set_attr "type" "alu,alu,imovx,msklog")
7982 (set_attr "length_immediate" "*,*,0,*")
7983 (set (attr "prefix_rex")
7985 (and (eq_attr "type" "imovx")
7986 (match_operand 1 "ext_QIreg_operand"))
7988 (const_string "*")))
7989 (set_attr "mode" "HI,HI,SI,HI")])
7991 ;; %%% Potential partial reg stall on alternative 2. What to do?
7992 (define_insn "*andqi_1"
7993 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7994 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7995 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7996 (clobber (reg:CC FLAGS_REG))]
7997 "ix86_binary_operator_ok (AND, QImode, operands)"
7999 and{b}\t{%2, %0|%0, %2}
8000 and{b}\t{%2, %0|%0, %2}
8001 and{l}\t{%k2, %k0|%k0, %k2}
8002 kandw\t{%2, %1, %0|%0, %1, %2}"
8003 [(set_attr "type" "alu,alu,alu,msklog")
8004 (set_attr "mode" "QI,QI,SI,HI")])
8006 (define_insn "*andqi_1_slp"
8007 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8008 (and:QI (match_dup 0)
8009 (match_operand:QI 1 "general_operand" "qn,qmn")))
8010 (clobber (reg:CC FLAGS_REG))]
8011 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8012 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8013 "and{b}\t{%1, %0|%0, %1}"
8014 [(set_attr "type" "alu1")
8015 (set_attr "mode" "QI")])
8017 (define_insn "kandn<mode>"
8018 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
8021 (match_operand:SWI12 1 "register_operand" "r,0,k"))
8022 (match_operand:SWI12 2 "register_operand" "r,r,k")))
8023 (clobber (reg:CC FLAGS_REG))]
8026 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
8028 kandnw\t{%2, %1, %0|%0, %1, %2}"
8029 [(set_attr "isa" "bmi,*,avx512f")
8030 (set_attr "type" "bitmanip,*,msklog")
8031 (set_attr "prefix" "*,*,vex")
8032 (set_attr "btver2_decode" "direct,*,*")
8033 (set_attr "mode" "<MODE>")])
8036 [(set (match_operand:SWI12 0 "general_reg_operand")
8040 (match_operand:SWI12 1 "general_reg_operand")))
8041 (clobber (reg:CC FLAGS_REG))]
8042 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8044 (not:HI (match_dup 0)))
8045 (parallel [(set (match_dup 0)
8046 (and:HI (match_dup 0)
8048 (clobber (reg:CC FLAGS_REG))])])
8050 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8052 [(set (match_operand:DI 0 "register_operand")
8053 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8054 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8055 (clobber (reg:CC FLAGS_REG))]
8057 [(parallel [(set (match_dup 0)
8058 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8059 (clobber (reg:CC FLAGS_REG))])]
8060 "operands[2] = gen_lowpart (SImode, operands[2]);")
8063 [(set (match_operand:SWI248 0 "register_operand")
8064 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8065 (match_operand:SWI248 2 "const_int_operand")))
8066 (clobber (reg:CC FLAGS_REG))]
8068 && true_regnum (operands[0]) != true_regnum (operands[1])"
8071 HOST_WIDE_INT ival = INTVAL (operands[2]);
8072 enum machine_mode mode;
8073 rtx (*insn) (rtx, rtx);
8075 if (ival == (HOST_WIDE_INT) 0xffffffff)
8077 else if (ival == 0xffff)
8081 gcc_assert (ival == 0xff);
8085 if (<MODE>mode == DImode)
8086 insn = (mode == SImode)
8087 ? gen_zero_extendsidi2
8089 ? gen_zero_extendhidi2
8090 : gen_zero_extendqidi2;
8093 if (<MODE>mode != SImode)
8094 /* Zero extend to SImode to avoid partial register stalls. */
8095 operands[0] = gen_lowpart (SImode, operands[0]);
8097 insn = (mode == HImode)
8098 ? gen_zero_extendhisi2
8099 : gen_zero_extendqisi2;
8101 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8106 [(set (match_operand 0 "register_operand")
8108 (const_int -65536)))
8109 (clobber (reg:CC FLAGS_REG))]
8110 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8111 || optimize_function_for_size_p (cfun)"
8112 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8113 "operands[1] = gen_lowpart (HImode, operands[0]);")
8116 [(set (match_operand 0 "ext_register_operand")
8119 (clobber (reg:CC FLAGS_REG))]
8120 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8121 && reload_completed"
8122 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8123 "operands[1] = gen_lowpart (QImode, operands[0]);")
8126 [(set (match_operand 0 "ext_register_operand")
8128 (const_int -65281)))
8129 (clobber (reg:CC FLAGS_REG))]
8130 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8131 && reload_completed"
8132 [(parallel [(set (zero_extract:SI (match_dup 0)
8136 (zero_extract:SI (match_dup 0)
8139 (zero_extract:SI (match_dup 0)
8142 (clobber (reg:CC FLAGS_REG))])]
8143 "operands[0] = gen_lowpart (SImode, operands[0]);")
8145 (define_insn "*anddi_2"
8146 [(set (reg FLAGS_REG)
8149 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8150 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8152 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8153 (and:DI (match_dup 1) (match_dup 2)))]
8155 && ix86_match_ccmode
8157 /* If we are going to emit andl instead of andq, and the operands[2]
8158 constant might have the SImode sign bit set, make sure the sign
8159 flag isn't tested, because the instruction will set the sign flag
8160 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8161 conservatively assume it might have bit 31 set. */
8162 (satisfies_constraint_Z (operands[2])
8163 && (!CONST_INT_P (operands[2])
8164 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8165 ? CCZmode : CCNOmode)
8166 && ix86_binary_operator_ok (AND, DImode, operands)"
8168 and{l}\t{%k2, %k0|%k0, %k2}
8169 and{q}\t{%2, %0|%0, %2}
8170 and{q}\t{%2, %0|%0, %2}"
8171 [(set_attr "type" "alu")
8172 (set_attr "mode" "SI,DI,DI")])
8174 (define_insn "*andqi_2_maybe_si"
8175 [(set (reg FLAGS_REG)
8177 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8178 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8180 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8181 (and:QI (match_dup 1) (match_dup 2)))]
8182 "ix86_binary_operator_ok (AND, QImode, operands)
8183 && ix86_match_ccmode (insn,
8184 CONST_INT_P (operands[2])
8185 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8187 if (which_alternative == 2)
8189 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8190 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8191 return "and{l}\t{%2, %k0|%k0, %2}";
8193 return "and{b}\t{%2, %0|%0, %2}";
8195 [(set_attr "type" "alu")
8196 (set_attr "mode" "QI,QI,SI")])
8198 (define_insn "*and<mode>_2"
8199 [(set (reg FLAGS_REG)
8200 (compare (and:SWI124
8201 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8202 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8204 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8205 (and:SWI124 (match_dup 1) (match_dup 2)))]
8206 "ix86_match_ccmode (insn, CCNOmode)
8207 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8208 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8209 [(set_attr "type" "alu")
8210 (set_attr "mode" "<MODE>")])
8212 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8213 (define_insn "*andsi_2_zext"
8214 [(set (reg FLAGS_REG)
8216 (match_operand:SI 1 "nonimmediate_operand" "%0")
8217 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8219 (set (match_operand:DI 0 "register_operand" "=r")
8220 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8221 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8222 && ix86_binary_operator_ok (AND, SImode, operands)"
8223 "and{l}\t{%2, %k0|%k0, %2}"
8224 [(set_attr "type" "alu")
8225 (set_attr "mode" "SI")])
8227 (define_insn "*andqi_2_slp"
8228 [(set (reg FLAGS_REG)
8230 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8231 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8233 (set (strict_low_part (match_dup 0))
8234 (and:QI (match_dup 0) (match_dup 1)))]
8235 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8236 && ix86_match_ccmode (insn, CCNOmode)
8237 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8238 "and{b}\t{%1, %0|%0, %1}"
8239 [(set_attr "type" "alu1")
8240 (set_attr "mode" "QI")])
8242 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8243 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8244 ;; for a QImode operand, which of course failed.
8245 (define_insn "andqi_ext_0"
8246 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8251 (match_operand 1 "ext_register_operand" "0")
8254 (match_operand 2 "const_int_operand" "n")))
8255 (clobber (reg:CC FLAGS_REG))]
8257 "and{b}\t{%2, %h0|%h0, %2}"
8258 [(set_attr "type" "alu")
8259 (set_attr "length_immediate" "1")
8260 (set_attr "modrm" "1")
8261 (set_attr "mode" "QI")])
8263 ;; Generated by peephole translating test to and. This shows up
8264 ;; often in fp comparisons.
8265 (define_insn "*andqi_ext_0_cc"
8266 [(set (reg FLAGS_REG)
8270 (match_operand 1 "ext_register_operand" "0")
8273 (match_operand 2 "const_int_operand" "n"))
8275 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8284 "ix86_match_ccmode (insn, CCNOmode)"
8285 "and{b}\t{%2, %h0|%h0, %2}"
8286 [(set_attr "type" "alu")
8287 (set_attr "length_immediate" "1")
8288 (set_attr "modrm" "1")
8289 (set_attr "mode" "QI")])
8291 (define_insn "*andqi_ext_1"
8292 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8297 (match_operand 1 "ext_register_operand" "0,0")
8301 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8302 (clobber (reg:CC FLAGS_REG))]
8304 "and{b}\t{%2, %h0|%h0, %2}"
8305 [(set_attr "isa" "*,nox64")
8306 (set_attr "type" "alu")
8307 (set_attr "length_immediate" "0")
8308 (set_attr "mode" "QI")])
8310 (define_insn "*andqi_ext_2"
8311 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8316 (match_operand 1 "ext_register_operand" "%0")
8320 (match_operand 2 "ext_register_operand" "Q")
8323 (clobber (reg:CC FLAGS_REG))]
8325 "and{b}\t{%h2, %h0|%h0, %h2}"
8326 [(set_attr "type" "alu")
8327 (set_attr "length_immediate" "0")
8328 (set_attr "mode" "QI")])
8330 ;; Convert wide AND instructions with immediate operand to shorter QImode
8331 ;; equivalents when possible.
8332 ;; Don't do the splitting with memory operands, since it introduces risk
8333 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8334 ;; for size, but that can (should?) be handled by generic code instead.
8336 [(set (match_operand 0 "register_operand")
8337 (and (match_operand 1 "register_operand")
8338 (match_operand 2 "const_int_operand")))
8339 (clobber (reg:CC FLAGS_REG))]
8341 && QI_REG_P (operands[0])
8342 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8343 && !(~INTVAL (operands[2]) & ~(255 << 8))
8344 && GET_MODE (operands[0]) != QImode"
8345 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8346 (and:SI (zero_extract:SI (match_dup 1)
8347 (const_int 8) (const_int 8))
8349 (clobber (reg:CC FLAGS_REG))])]
8351 operands[0] = gen_lowpart (SImode, operands[0]);
8352 operands[1] = gen_lowpart (SImode, operands[1]);
8353 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8356 ;; Since AND can be encoded with sign extended immediate, this is only
8357 ;; profitable when 7th bit is not set.
8359 [(set (match_operand 0 "register_operand")
8360 (and (match_operand 1 "general_operand")
8361 (match_operand 2 "const_int_operand")))
8362 (clobber (reg:CC FLAGS_REG))]
8364 && ANY_QI_REG_P (operands[0])
8365 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8366 && !(~INTVAL (operands[2]) & ~255)
8367 && !(INTVAL (operands[2]) & 128)
8368 && GET_MODE (operands[0]) != QImode"
8369 [(parallel [(set (strict_low_part (match_dup 0))
8370 (and:QI (match_dup 1)
8372 (clobber (reg:CC FLAGS_REG))])]
8374 operands[0] = gen_lowpart (QImode, operands[0]);
8375 operands[1] = gen_lowpart (QImode, operands[1]);
8376 operands[2] = gen_lowpart (QImode, operands[2]);
8379 ;; Logical inclusive and exclusive OR instructions
8381 ;; %%% This used to optimize known byte-wide and operations to memory.
8382 ;; If this is considered useful, it should be done with splitters.
8384 (define_expand "<code><mode>3"
8385 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8386 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8387 (match_operand:SWIM 2 "<general_operand>")))]
8389 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8391 (define_insn "*<code><mode>_1"
8392 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
8394 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
8395 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>")))
8396 (clobber (reg:CC FLAGS_REG))]
8397 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8398 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8399 [(set_attr "type" "alu")
8400 (set_attr "mode" "<MODE>")])
8402 (define_insn "*<code>hi_1"
8403 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8405 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8406 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8407 (clobber (reg:CC FLAGS_REG))]
8408 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8410 <logic>{w}\t{%2, %0|%0, %2}
8411 <logic>{w}\t{%2, %0|%0, %2}
8412 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8413 [(set_attr "type" "alu,alu,msklog")
8414 (set_attr "mode" "HI")])
8416 ;; %%% Potential partial reg stall on alternative 2. What to do?
8417 (define_insn "*<code>qi_1"
8418 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8419 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8420 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8421 (clobber (reg:CC FLAGS_REG))]
8422 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8424 <logic>{b}\t{%2, %0|%0, %2}
8425 <logic>{b}\t{%2, %0|%0, %2}
8426 <logic>{l}\t{%k2, %k0|%k0, %k2}
8427 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8428 [(set_attr "type" "alu,alu,alu,msklog")
8429 (set_attr "mode" "QI,QI,SI,HI")])
8431 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8432 (define_insn "*<code>si_1_zext"
8433 [(set (match_operand:DI 0 "register_operand" "=r")
8435 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8436 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8437 (clobber (reg:CC FLAGS_REG))]
8438 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8439 "<logic>{l}\t{%2, %k0|%k0, %2}"
8440 [(set_attr "type" "alu")
8441 (set_attr "mode" "SI")])
8443 (define_insn "*<code>si_1_zext_imm"
8444 [(set (match_operand:DI 0 "register_operand" "=r")
8446 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8447 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8448 (clobber (reg:CC FLAGS_REG))]
8449 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8450 "<logic>{l}\t{%2, %k0|%k0, %2}"
8451 [(set_attr "type" "alu")
8452 (set_attr "mode" "SI")])
8454 (define_insn "*<code>qi_1_slp"
8455 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8456 (any_or:QI (match_dup 0)
8457 (match_operand:QI 1 "general_operand" "qmn,qn")))
8458 (clobber (reg:CC FLAGS_REG))]
8459 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8460 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8461 "<logic>{b}\t{%1, %0|%0, %1}"
8462 [(set_attr "type" "alu1")
8463 (set_attr "mode" "QI")])
8465 (define_insn "*<code><mode>_2"
8466 [(set (reg FLAGS_REG)
8467 (compare (any_or:SWI
8468 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8469 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8471 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8472 (any_or:SWI (match_dup 1) (match_dup 2)))]
8473 "ix86_match_ccmode (insn, CCNOmode)
8474 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8475 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8476 [(set_attr "type" "alu")
8477 (set_attr "mode" "<MODE>")])
8479 (define_insn "kxnor<mode>"
8480 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8483 (match_operand:SWI12 1 "register_operand" "0,k")
8484 (match_operand:SWI12 2 "register_operand" "r,k"))))
8485 (clobber (reg:CC FLAGS_REG))]
8489 kxnorw\t{%2, %1, %0|%0, %1, %2}"
8490 [(set_attr "type" "*,msklog")
8491 (set_attr "prefix" "*,vex")
8492 (set_attr "mode" "<MODE>")])
8495 [(set (match_operand:SWI12 0 "general_reg_operand")
8499 (match_operand:SWI12 1 "general_reg_operand"))))
8500 (clobber (reg:CC FLAGS_REG))]
8501 "TARGET_AVX512F && reload_completed"
8502 [(parallel [(set (match_dup 0)
8503 (xor:HI (match_dup 0)
8505 (clobber (reg:CC FLAGS_REG))])
8507 (not:HI (match_dup 0)))])
8509 (define_insn "kortestzhi"
8510 [(set (reg:CCZ FLAGS_REG)
8513 (match_operand:HI 0 "register_operand" "k")
8514 (match_operand:HI 1 "register_operand" "k"))
8516 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8517 "kortestw\t{%1, %0|%0, %1}"
8518 [(set_attr "mode" "HI")
8519 (set_attr "type" "msklog")
8520 (set_attr "prefix" "vex")])
8522 (define_insn "kortestchi"
8523 [(set (reg:CCC FLAGS_REG)
8526 (match_operand:HI 0 "register_operand" "k")
8527 (match_operand:HI 1 "register_operand" "k"))
8529 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8530 "kortestw\t{%1, %0|%0, %1}"
8531 [(set_attr "mode" "HI")
8532 (set_attr "type" "msklog")
8533 (set_attr "prefix" "vex")])
8535 (define_insn "kunpckhi"
8536 [(set (match_operand:HI 0 "register_operand" "=k")
8539 (match_operand:HI 1 "register_operand" "k")
8541 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8543 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8544 [(set_attr "mode" "HI")
8545 (set_attr "type" "msklog")
8546 (set_attr "prefix" "vex")])
8548 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8549 ;; ??? Special case for immediate operand is missing - it is tricky.
8550 (define_insn "*<code>si_2_zext"
8551 [(set (reg FLAGS_REG)
8552 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8553 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8555 (set (match_operand:DI 0 "register_operand" "=r")
8556 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8557 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8558 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8559 "<logic>{l}\t{%2, %k0|%k0, %2}"
8560 [(set_attr "type" "alu")
8561 (set_attr "mode" "SI")])
8563 (define_insn "*<code>si_2_zext_imm"
8564 [(set (reg FLAGS_REG)
8566 (match_operand:SI 1 "nonimmediate_operand" "%0")
8567 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8569 (set (match_operand:DI 0 "register_operand" "=r")
8570 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8571 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8572 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8573 "<logic>{l}\t{%2, %k0|%k0, %2}"
8574 [(set_attr "type" "alu")
8575 (set_attr "mode" "SI")])
8577 (define_insn "*<code>qi_2_slp"
8578 [(set (reg FLAGS_REG)
8579 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8580 (match_operand:QI 1 "general_operand" "qmn,qn"))
8582 (set (strict_low_part (match_dup 0))
8583 (any_or:QI (match_dup 0) (match_dup 1)))]
8584 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8585 && ix86_match_ccmode (insn, CCNOmode)
8586 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8587 "<logic>{b}\t{%1, %0|%0, %1}"
8588 [(set_attr "type" "alu1")
8589 (set_attr "mode" "QI")])
8591 (define_insn "*<code><mode>_3"
8592 [(set (reg FLAGS_REG)
8593 (compare (any_or:SWI
8594 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8595 (match_operand:SWI 2 "<general_operand>" "<g>"))
8597 (clobber (match_scratch:SWI 0 "=<r>"))]
8598 "ix86_match_ccmode (insn, CCNOmode)
8599 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8600 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8601 [(set_attr "type" "alu")
8602 (set_attr "mode" "<MODE>")])
8604 (define_insn "*<code>qi_ext_0"
8605 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8610 (match_operand 1 "ext_register_operand" "0")
8613 (match_operand 2 "const_int_operand" "n")))
8614 (clobber (reg:CC FLAGS_REG))]
8615 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8616 "<logic>{b}\t{%2, %h0|%h0, %2}"
8617 [(set_attr "type" "alu")
8618 (set_attr "length_immediate" "1")
8619 (set_attr "modrm" "1")
8620 (set_attr "mode" "QI")])
8622 (define_insn "*<code>qi_ext_1"
8623 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8628 (match_operand 1 "ext_register_operand" "0,0")
8632 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8633 (clobber (reg:CC FLAGS_REG))]
8634 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8635 "<logic>{b}\t{%2, %h0|%h0, %2}"
8636 [(set_attr "isa" "*,nox64")
8637 (set_attr "type" "alu")
8638 (set_attr "length_immediate" "0")
8639 (set_attr "mode" "QI")])
8641 (define_insn "*<code>qi_ext_2"
8642 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8646 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8649 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8652 (clobber (reg:CC FLAGS_REG))]
8653 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8654 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8655 [(set_attr "type" "alu")
8656 (set_attr "length_immediate" "0")
8657 (set_attr "mode" "QI")])
8660 [(set (match_operand 0 "register_operand")
8661 (any_or (match_operand 1 "register_operand")
8662 (match_operand 2 "const_int_operand")))
8663 (clobber (reg:CC FLAGS_REG))]
8665 && QI_REG_P (operands[0])
8666 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8667 && !(INTVAL (operands[2]) & ~(255 << 8))
8668 && GET_MODE (operands[0]) != QImode"
8669 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8670 (any_or:SI (zero_extract:SI (match_dup 1)
8671 (const_int 8) (const_int 8))
8673 (clobber (reg:CC FLAGS_REG))])]
8675 operands[0] = gen_lowpart (SImode, operands[0]);
8676 operands[1] = gen_lowpart (SImode, operands[1]);
8677 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8680 ;; Since OR can be encoded with sign extended immediate, this is only
8681 ;; profitable when 7th bit is set.
8683 [(set (match_operand 0 "register_operand")
8684 (any_or (match_operand 1 "general_operand")
8685 (match_operand 2 "const_int_operand")))
8686 (clobber (reg:CC FLAGS_REG))]
8688 && ANY_QI_REG_P (operands[0])
8689 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8690 && !(INTVAL (operands[2]) & ~255)
8691 && (INTVAL (operands[2]) & 128)
8692 && GET_MODE (operands[0]) != QImode"
8693 [(parallel [(set (strict_low_part (match_dup 0))
8694 (any_or:QI (match_dup 1)
8696 (clobber (reg:CC FLAGS_REG))])]
8698 operands[0] = gen_lowpart (QImode, operands[0]);
8699 operands[1] = gen_lowpart (QImode, operands[1]);
8700 operands[2] = gen_lowpart (QImode, operands[2]);
8703 (define_expand "xorqi_cc_ext_1"
8705 (set (reg:CCNO FLAGS_REG)
8709 (match_operand 1 "ext_register_operand")
8712 (match_operand:QI 2 "const_int_operand"))
8714 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8724 (define_insn "*xorqi_cc_ext_1"
8725 [(set (reg FLAGS_REG)
8729 (match_operand 1 "ext_register_operand" "0,0")
8732 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8734 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8743 "ix86_match_ccmode (insn, CCNOmode)"
8744 "xor{b}\t{%2, %h0|%h0, %2}"
8745 [(set_attr "isa" "*,nox64")
8746 (set_attr "type" "alu")
8747 (set_attr "modrm" "1")
8748 (set_attr "mode" "QI")])
8750 ;; Negation instructions
8752 (define_expand "neg<mode>2"
8753 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8754 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8756 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8758 (define_insn_and_split "*neg<dwi>2_doubleword"
8759 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8760 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8761 (clobber (reg:CC FLAGS_REG))]
8762 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8766 [(set (reg:CCZ FLAGS_REG)
8767 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8768 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8771 (plus:DWIH (match_dup 3)
8772 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8774 (clobber (reg:CC FLAGS_REG))])
8777 (neg:DWIH (match_dup 2)))
8778 (clobber (reg:CC FLAGS_REG))])]
8779 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8781 (define_insn "*neg<mode>2_1"
8782 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8783 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8784 (clobber (reg:CC FLAGS_REG))]
8785 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8786 "neg{<imodesuffix>}\t%0"
8787 [(set_attr "type" "negnot")
8788 (set_attr "mode" "<MODE>")])
8790 ;; Combine is quite creative about this pattern.
8791 (define_insn "*negsi2_1_zext"
8792 [(set (match_operand:DI 0 "register_operand" "=r")
8794 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8797 (clobber (reg:CC FLAGS_REG))]
8798 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8800 [(set_attr "type" "negnot")
8801 (set_attr "mode" "SI")])
8803 ;; The problem with neg is that it does not perform (compare x 0),
8804 ;; it really performs (compare 0 x), which leaves us with the zero
8805 ;; flag being the only useful item.
8807 (define_insn "*neg<mode>2_cmpz"
8808 [(set (reg:CCZ FLAGS_REG)
8810 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8812 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8813 (neg:SWI (match_dup 1)))]
8814 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8815 "neg{<imodesuffix>}\t%0"
8816 [(set_attr "type" "negnot")
8817 (set_attr "mode" "<MODE>")])
8819 (define_insn "*negsi2_cmpz_zext"
8820 [(set (reg:CCZ FLAGS_REG)
8824 (match_operand:DI 1 "register_operand" "0")
8828 (set (match_operand:DI 0 "register_operand" "=r")
8829 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8832 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8834 [(set_attr "type" "negnot")
8835 (set_attr "mode" "SI")])
8837 ;; Negate with jump on overflow.
8838 (define_expand "negv<mode>3"
8839 [(parallel [(set (reg:CCO FLAGS_REG)
8840 (ne:CCO (match_operand:SWI 1 "register_operand")
8842 (set (match_operand:SWI 0 "register_operand")
8843 (neg:SWI (match_dup 1)))])
8844 (set (pc) (if_then_else
8845 (eq (reg:CCO FLAGS_REG) (const_int 0))
8846 (label_ref (match_operand 2))
8851 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8855 (define_insn "*negv<mode>3"
8856 [(set (reg:CCO FLAGS_REG)
8857 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8858 (match_operand:SWI 2 "const_int_operand")))
8859 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8860 (neg:SWI (match_dup 1)))]
8861 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8862 && mode_signbit_p (<MODE>mode, operands[2])"
8863 "neg{<imodesuffix>}\t%0"
8864 [(set_attr "type" "negnot")
8865 (set_attr "mode" "<MODE>")])
8867 ;; Changing of sign for FP values is doable using integer unit too.
8869 (define_expand "<code><mode>2"
8870 [(set (match_operand:X87MODEF 0 "register_operand")
8871 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8872 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8873 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8875 (define_insn "*absneg<mode>2_mixed"
8876 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8877 (match_operator:MODEF 3 "absneg_operator"
8878 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8879 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8880 (clobber (reg:CC FLAGS_REG))]
8881 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8884 (define_insn "*absneg<mode>2_sse"
8885 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8886 (match_operator:MODEF 3 "absneg_operator"
8887 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8888 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8889 (clobber (reg:CC FLAGS_REG))]
8890 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8893 (define_insn "*absneg<mode>2_i387"
8894 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8895 (match_operator:X87MODEF 3 "absneg_operator"
8896 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8897 (use (match_operand 2))
8898 (clobber (reg:CC FLAGS_REG))]
8899 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8902 (define_expand "<code>tf2"
8903 [(set (match_operand:TF 0 "register_operand")
8904 (absneg:TF (match_operand:TF 1 "register_operand")))]
8906 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8908 (define_insn "*absnegtf2_sse"
8909 [(set (match_operand:TF 0 "register_operand" "=x,x")
8910 (match_operator:TF 3 "absneg_operator"
8911 [(match_operand:TF 1 "register_operand" "0,x")]))
8912 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8913 (clobber (reg:CC FLAGS_REG))]
8917 ;; Splitters for fp abs and neg.
8920 [(set (match_operand 0 "fp_register_operand")
8921 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8922 (use (match_operand 2))
8923 (clobber (reg:CC FLAGS_REG))]
8925 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8928 [(set (match_operand 0 "register_operand")
8929 (match_operator 3 "absneg_operator"
8930 [(match_operand 1 "register_operand")]))
8931 (use (match_operand 2 "nonimmediate_operand"))
8932 (clobber (reg:CC FLAGS_REG))]
8933 "reload_completed && SSE_REG_P (operands[0])"
8934 [(set (match_dup 0) (match_dup 3))]
8936 enum machine_mode mode = GET_MODE (operands[0]);
8937 enum machine_mode vmode = GET_MODE (operands[2]);
8940 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8941 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8942 if (operands_match_p (operands[0], operands[2]))
8945 operands[1] = operands[2];
8948 if (GET_CODE (operands[3]) == ABS)
8949 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8951 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8956 [(set (match_operand:SF 0 "register_operand")
8957 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8958 (use (match_operand:V4SF 2))
8959 (clobber (reg:CC FLAGS_REG))]
8961 [(parallel [(set (match_dup 0) (match_dup 1))
8962 (clobber (reg:CC FLAGS_REG))])]
8965 operands[0] = gen_lowpart (SImode, operands[0]);
8966 if (GET_CODE (operands[1]) == ABS)
8968 tmp = gen_int_mode (0x7fffffff, SImode);
8969 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8973 tmp = gen_int_mode (0x80000000, SImode);
8974 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8980 [(set (match_operand:DF 0 "register_operand")
8981 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8982 (use (match_operand 2))
8983 (clobber (reg:CC FLAGS_REG))]
8985 [(parallel [(set (match_dup 0) (match_dup 1))
8986 (clobber (reg:CC FLAGS_REG))])]
8991 tmp = gen_lowpart (DImode, operands[0]);
8992 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8995 if (GET_CODE (operands[1]) == ABS)
8998 tmp = gen_rtx_NOT (DImode, tmp);
9002 operands[0] = gen_highpart (SImode, operands[0]);
9003 if (GET_CODE (operands[1]) == ABS)
9005 tmp = gen_int_mode (0x7fffffff, SImode);
9006 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9010 tmp = gen_int_mode (0x80000000, SImode);
9011 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9018 [(set (match_operand:XF 0 "register_operand")
9019 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9020 (use (match_operand 2))
9021 (clobber (reg:CC FLAGS_REG))]
9023 [(parallel [(set (match_dup 0) (match_dup 1))
9024 (clobber (reg:CC FLAGS_REG))])]
9027 operands[0] = gen_rtx_REG (SImode,
9028 true_regnum (operands[0])
9029 + (TARGET_64BIT ? 1 : 2));
9030 if (GET_CODE (operands[1]) == ABS)
9032 tmp = GEN_INT (0x7fff);
9033 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9037 tmp = GEN_INT (0x8000);
9038 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9043 ;; Conditionalize these after reload. If they match before reload, we
9044 ;; lose the clobber and ability to use integer instructions.
9046 (define_insn "*<code><mode>2_1"
9047 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9048 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9050 && (reload_completed
9051 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9052 "f<absneg_mnemonic>"
9053 [(set_attr "type" "fsgn")
9054 (set_attr "mode" "<MODE>")])
9056 (define_insn "*<code>extendsfdf2"
9057 [(set (match_operand:DF 0 "register_operand" "=f")
9058 (absneg:DF (float_extend:DF
9059 (match_operand:SF 1 "register_operand" "0"))))]
9060 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9061 "f<absneg_mnemonic>"
9062 [(set_attr "type" "fsgn")
9063 (set_attr "mode" "DF")])
9065 (define_insn "*<code>extendsfxf2"
9066 [(set (match_operand:XF 0 "register_operand" "=f")
9067 (absneg:XF (float_extend:XF
9068 (match_operand:SF 1 "register_operand" "0"))))]
9070 "f<absneg_mnemonic>"
9071 [(set_attr "type" "fsgn")
9072 (set_attr "mode" "XF")])
9074 (define_insn "*<code>extenddfxf2"
9075 [(set (match_operand:XF 0 "register_operand" "=f")
9076 (absneg:XF (float_extend:XF
9077 (match_operand:DF 1 "register_operand" "0"))))]
9079 "f<absneg_mnemonic>"
9080 [(set_attr "type" "fsgn")
9081 (set_attr "mode" "XF")])
9083 ;; Copysign instructions
9085 (define_mode_iterator CSGNMODE [SF DF TF])
9086 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9088 (define_expand "copysign<mode>3"
9089 [(match_operand:CSGNMODE 0 "register_operand")
9090 (match_operand:CSGNMODE 1 "nonmemory_operand")
9091 (match_operand:CSGNMODE 2 "register_operand")]
9092 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9093 || (TARGET_SSE && (<MODE>mode == TFmode))"
9094 "ix86_expand_copysign (operands); DONE;")
9096 (define_insn_and_split "copysign<mode>3_const"
9097 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9099 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9100 (match_operand:CSGNMODE 2 "register_operand" "0")
9101 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9103 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9104 || (TARGET_SSE && (<MODE>mode == TFmode))"
9106 "&& reload_completed"
9108 "ix86_split_copysign_const (operands); DONE;")
9110 (define_insn "copysign<mode>3_var"
9111 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9113 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9114 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9115 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9116 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9118 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9119 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9120 || (TARGET_SSE && (<MODE>mode == TFmode))"
9124 [(set (match_operand:CSGNMODE 0 "register_operand")
9126 [(match_operand:CSGNMODE 2 "register_operand")
9127 (match_operand:CSGNMODE 3 "register_operand")
9128 (match_operand:<CSGNVMODE> 4)
9129 (match_operand:<CSGNVMODE> 5)]
9131 (clobber (match_scratch:<CSGNVMODE> 1))]
9132 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9133 || (TARGET_SSE && (<MODE>mode == TFmode)))
9134 && reload_completed"
9136 "ix86_split_copysign_var (operands); DONE;")
9138 ;; One complement instructions
9140 (define_expand "one_cmpl<mode>2"
9141 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9142 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9144 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9146 (define_insn "*one_cmpl<mode>2_1"
9147 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9148 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))]
9149 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9150 "not{<imodesuffix>}\t%0"
9151 [(set_attr "type" "negnot")
9152 (set_attr "mode" "<MODE>")])
9154 (define_insn "*one_cmplhi2_1"
9155 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9156 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9157 "ix86_unary_operator_ok (NOT, HImode, operands)"
9160 knotw\t{%1, %0|%0, %1}"
9161 [(set_attr "isa" "*,avx512f")
9162 (set_attr "type" "negnot,msklog")
9163 (set_attr "prefix" "*,vex")
9164 (set_attr "mode" "HI")])
9166 ;; %%% Potential partial reg stall on alternative 1. What to do?
9167 (define_insn "*one_cmplqi2_1"
9168 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9169 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9170 "ix86_unary_operator_ok (NOT, QImode, operands)"
9174 knotw\t{%1, %0|%0, %1}"
9175 [(set_attr "isa" "*,*,avx512f")
9176 (set_attr "type" "negnot,negnot,msklog")
9177 (set_attr "prefix" "*,*,vex")
9178 (set_attr "mode" "QI,SI,QI")])
9180 ;; ??? Currently never generated - xor is used instead.
9181 (define_insn "*one_cmplsi2_1_zext"
9182 [(set (match_operand:DI 0 "register_operand" "=r")
9184 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9185 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9187 [(set_attr "type" "negnot")
9188 (set_attr "mode" "SI")])
9190 (define_insn "*one_cmpl<mode>2_2"
9191 [(set (reg FLAGS_REG)
9192 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9194 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9195 (not:SWI (match_dup 1)))]
9196 "ix86_match_ccmode (insn, CCNOmode)
9197 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9199 [(set_attr "type" "alu1")
9200 (set_attr "mode" "<MODE>")])
9203 [(set (match_operand 0 "flags_reg_operand")
9204 (match_operator 2 "compare_operator"
9205 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9207 (set (match_operand:SWI 1 "nonimmediate_operand")
9208 (not:SWI (match_dup 3)))]
9209 "ix86_match_ccmode (insn, CCNOmode)"
9210 [(parallel [(set (match_dup 0)
9211 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9214 (xor:SWI (match_dup 3) (const_int -1)))])])
9216 ;; ??? Currently never generated - xor is used instead.
9217 (define_insn "*one_cmplsi2_2_zext"
9218 [(set (reg FLAGS_REG)
9219 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9221 (set (match_operand:DI 0 "register_operand" "=r")
9222 (zero_extend:DI (not:SI (match_dup 1))))]
9223 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9224 && ix86_unary_operator_ok (NOT, SImode, operands)"
9226 [(set_attr "type" "alu1")
9227 (set_attr "mode" "SI")])
9230 [(set (match_operand 0 "flags_reg_operand")
9231 (match_operator 2 "compare_operator"
9232 [(not:SI (match_operand:SI 3 "register_operand"))
9234 (set (match_operand:DI 1 "register_operand")
9235 (zero_extend:DI (not:SI (match_dup 3))))]
9236 "ix86_match_ccmode (insn, CCNOmode)"
9237 [(parallel [(set (match_dup 0)
9238 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9241 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9243 ;; Shift instructions
9245 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9246 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9247 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9248 ;; from the assembler input.
9250 ;; This instruction shifts the target reg/mem as usual, but instead of
9251 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9252 ;; is a left shift double, bits are taken from the high order bits of
9253 ;; reg, else if the insn is a shift right double, bits are taken from the
9254 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9255 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9257 ;; Since sh[lr]d does not change the `reg' operand, that is done
9258 ;; separately, making all shifts emit pairs of shift double and normal
9259 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9260 ;; support a 63 bit shift, each shift where the count is in a reg expands
9261 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9263 ;; If the shift count is a constant, we need never emit more than one
9264 ;; shift pair, instead using moves and sign extension for counts greater
9267 (define_expand "ashl<mode>3"
9268 [(set (match_operand:SDWIM 0 "<shift_operand>")
9269 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9270 (match_operand:QI 2 "nonmemory_operand")))]
9272 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9274 (define_insn "*ashl<mode>3_doubleword"
9275 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9276 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9277 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9278 (clobber (reg:CC FLAGS_REG))]
9281 [(set_attr "type" "multi")])
9284 [(set (match_operand:DWI 0 "register_operand")
9285 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9286 (match_operand:QI 2 "nonmemory_operand")))
9287 (clobber (reg:CC FLAGS_REG))]
9288 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9290 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9292 ;; By default we don't ask for a scratch register, because when DWImode
9293 ;; values are manipulated, registers are already at a premium. But if
9294 ;; we have one handy, we won't turn it away.
9297 [(match_scratch:DWIH 3 "r")
9298 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9300 (match_operand:<DWI> 1 "nonmemory_operand")
9301 (match_operand:QI 2 "nonmemory_operand")))
9302 (clobber (reg:CC FLAGS_REG))])
9306 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9308 (define_insn "x86_64_shld"
9309 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9310 (ior:DI (ashift:DI (match_dup 0)
9311 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9312 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9313 (minus:QI (const_int 64) (match_dup 2)))))
9314 (clobber (reg:CC FLAGS_REG))]
9316 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9317 [(set_attr "type" "ishift")
9318 (set_attr "prefix_0f" "1")
9319 (set_attr "mode" "DI")
9320 (set_attr "athlon_decode" "vector")
9321 (set_attr "amdfam10_decode" "vector")
9322 (set_attr "bdver1_decode" "vector")])
9324 (define_insn "x86_shld"
9325 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9326 (ior:SI (ashift:SI (match_dup 0)
9327 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9328 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9329 (minus:QI (const_int 32) (match_dup 2)))))
9330 (clobber (reg:CC FLAGS_REG))]
9332 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9333 [(set_attr "type" "ishift")
9334 (set_attr "prefix_0f" "1")
9335 (set_attr "mode" "SI")
9336 (set_attr "pent_pair" "np")
9337 (set_attr "athlon_decode" "vector")
9338 (set_attr "amdfam10_decode" "vector")
9339 (set_attr "bdver1_decode" "vector")])
9341 (define_expand "x86_shift<mode>_adj_1"
9342 [(set (reg:CCZ FLAGS_REG)
9343 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9346 (set (match_operand:SWI48 0 "register_operand")
9347 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9348 (match_operand:SWI48 1 "register_operand")
9351 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9352 (match_operand:SWI48 3 "register_operand")
9355 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9357 (define_expand "x86_shift<mode>_adj_2"
9358 [(use (match_operand:SWI48 0 "register_operand"))
9359 (use (match_operand:SWI48 1 "register_operand"))
9360 (use (match_operand:QI 2 "register_operand"))]
9363 rtx label = gen_label_rtx ();
9366 emit_insn (gen_testqi_ccz_1 (operands[2],
9367 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9369 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9370 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9371 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9372 gen_rtx_LABEL_REF (VOIDmode, label),
9374 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9375 JUMP_LABEL (tmp) = label;
9377 emit_move_insn (operands[0], operands[1]);
9378 ix86_expand_clear (operands[1]);
9381 LABEL_NUSES (label) = 1;
9386 ;; Avoid useless masking of count operand.
9387 (define_insn "*ashl<mode>3_mask"
9388 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9390 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9393 (match_operand:SI 2 "register_operand" "c")
9394 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9395 (clobber (reg:CC FLAGS_REG))]
9396 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9397 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9398 == GET_MODE_BITSIZE (<MODE>mode)-1"
9400 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9402 [(set_attr "type" "ishift")
9403 (set_attr "mode" "<MODE>")])
9405 (define_insn "*bmi2_ashl<mode>3_1"
9406 [(set (match_operand:SWI48 0 "register_operand" "=r")
9407 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9408 (match_operand:SWI48 2 "register_operand" "r")))]
9410 "shlx\t{%2, %1, %0|%0, %1, %2}"
9411 [(set_attr "type" "ishiftx")
9412 (set_attr "mode" "<MODE>")])
9414 (define_insn "*ashl<mode>3_1"
9415 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9416 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9417 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9418 (clobber (reg:CC FLAGS_REG))]
9419 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9421 switch (get_attr_type (insn))
9428 gcc_assert (operands[2] == const1_rtx);
9429 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9430 return "add{<imodesuffix>}\t%0, %0";
9433 if (operands[2] == const1_rtx
9434 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9435 return "sal{<imodesuffix>}\t%0";
9437 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9440 [(set_attr "isa" "*,*,bmi2")
9442 (cond [(eq_attr "alternative" "1")
9443 (const_string "lea")
9444 (eq_attr "alternative" "2")
9445 (const_string "ishiftx")
9446 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9447 (match_operand 0 "register_operand"))
9448 (match_operand 2 "const1_operand"))
9449 (const_string "alu")
9451 (const_string "ishift")))
9452 (set (attr "length_immediate")
9454 (ior (eq_attr "type" "alu")
9455 (and (eq_attr "type" "ishift")
9456 (and (match_operand 2 "const1_operand")
9457 (ior (match_test "TARGET_SHIFT1")
9458 (match_test "optimize_function_for_size_p (cfun)")))))
9460 (const_string "*")))
9461 (set_attr "mode" "<MODE>")])
9463 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9465 [(set (match_operand:SWI48 0 "register_operand")
9466 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9467 (match_operand:QI 2 "register_operand")))
9468 (clobber (reg:CC FLAGS_REG))]
9469 "TARGET_BMI2 && reload_completed"
9471 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9472 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9474 (define_insn "*bmi2_ashlsi3_1_zext"
9475 [(set (match_operand:DI 0 "register_operand" "=r")
9477 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9478 (match_operand:SI 2 "register_operand" "r"))))]
9479 "TARGET_64BIT && TARGET_BMI2"
9480 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9481 [(set_attr "type" "ishiftx")
9482 (set_attr "mode" "SI")])
9484 (define_insn "*ashlsi3_1_zext"
9485 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9487 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9488 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9489 (clobber (reg:CC FLAGS_REG))]
9490 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9492 switch (get_attr_type (insn))
9499 gcc_assert (operands[2] == const1_rtx);
9500 return "add{l}\t%k0, %k0";
9503 if (operands[2] == const1_rtx
9504 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9505 return "sal{l}\t%k0";
9507 return "sal{l}\t{%2, %k0|%k0, %2}";
9510 [(set_attr "isa" "*,*,bmi2")
9512 (cond [(eq_attr "alternative" "1")
9513 (const_string "lea")
9514 (eq_attr "alternative" "2")
9515 (const_string "ishiftx")
9516 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9517 (match_operand 2 "const1_operand"))
9518 (const_string "alu")
9520 (const_string "ishift")))
9521 (set (attr "length_immediate")
9523 (ior (eq_attr "type" "alu")
9524 (and (eq_attr "type" "ishift")
9525 (and (match_operand 2 "const1_operand")
9526 (ior (match_test "TARGET_SHIFT1")
9527 (match_test "optimize_function_for_size_p (cfun)")))))
9529 (const_string "*")))
9530 (set_attr "mode" "SI")])
9532 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9534 [(set (match_operand:DI 0 "register_operand")
9536 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9537 (match_operand:QI 2 "register_operand"))))
9538 (clobber (reg:CC FLAGS_REG))]
9539 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9541 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9542 "operands[2] = gen_lowpart (SImode, operands[2]);")
9544 (define_insn "*ashlhi3_1"
9545 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9546 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9547 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9548 (clobber (reg:CC FLAGS_REG))]
9549 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9551 switch (get_attr_type (insn))
9557 gcc_assert (operands[2] == const1_rtx);
9558 return "add{w}\t%0, %0";
9561 if (operands[2] == const1_rtx
9562 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9563 return "sal{w}\t%0";
9565 return "sal{w}\t{%2, %0|%0, %2}";
9569 (cond [(eq_attr "alternative" "1")
9570 (const_string "lea")
9571 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9572 (match_operand 0 "register_operand"))
9573 (match_operand 2 "const1_operand"))
9574 (const_string "alu")
9576 (const_string "ishift")))
9577 (set (attr "length_immediate")
9579 (ior (eq_attr "type" "alu")
9580 (and (eq_attr "type" "ishift")
9581 (and (match_operand 2 "const1_operand")
9582 (ior (match_test "TARGET_SHIFT1")
9583 (match_test "optimize_function_for_size_p (cfun)")))))
9585 (const_string "*")))
9586 (set_attr "mode" "HI,SI")])
9588 ;; %%% Potential partial reg stall on alternative 1. What to do?
9589 (define_insn "*ashlqi3_1"
9590 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9591 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9592 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9593 (clobber (reg:CC FLAGS_REG))]
9594 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9596 switch (get_attr_type (insn))
9602 gcc_assert (operands[2] == const1_rtx);
9603 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9604 return "add{l}\t%k0, %k0";
9606 return "add{b}\t%0, %0";
9609 if (operands[2] == const1_rtx
9610 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9612 if (get_attr_mode (insn) == MODE_SI)
9613 return "sal{l}\t%k0";
9615 return "sal{b}\t%0";
9619 if (get_attr_mode (insn) == MODE_SI)
9620 return "sal{l}\t{%2, %k0|%k0, %2}";
9622 return "sal{b}\t{%2, %0|%0, %2}";
9627 (cond [(eq_attr "alternative" "2")
9628 (const_string "lea")
9629 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9630 (match_operand 0 "register_operand"))
9631 (match_operand 2 "const1_operand"))
9632 (const_string "alu")
9634 (const_string "ishift")))
9635 (set (attr "length_immediate")
9637 (ior (eq_attr "type" "alu")
9638 (and (eq_attr "type" "ishift")
9639 (and (match_operand 2 "const1_operand")
9640 (ior (match_test "TARGET_SHIFT1")
9641 (match_test "optimize_function_for_size_p (cfun)")))))
9643 (const_string "*")))
9644 (set_attr "mode" "QI,SI,SI")])
9646 (define_insn "*ashlqi3_1_slp"
9647 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9648 (ashift:QI (match_dup 0)
9649 (match_operand:QI 1 "nonmemory_operand" "cI")))
9650 (clobber (reg:CC FLAGS_REG))]
9651 "(optimize_function_for_size_p (cfun)
9652 || !TARGET_PARTIAL_FLAG_REG_STALL
9653 || (operands[1] == const1_rtx
9655 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9657 switch (get_attr_type (insn))
9660 gcc_assert (operands[1] == const1_rtx);
9661 return "add{b}\t%0, %0";
9664 if (operands[1] == const1_rtx
9665 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9666 return "sal{b}\t%0";
9668 return "sal{b}\t{%1, %0|%0, %1}";
9672 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9673 (match_operand 0 "register_operand"))
9674 (match_operand 1 "const1_operand"))
9675 (const_string "alu")
9677 (const_string "ishift1")))
9678 (set (attr "length_immediate")
9680 (ior (eq_attr "type" "alu")
9681 (and (eq_attr "type" "ishift1")
9682 (and (match_operand 1 "const1_operand")
9683 (ior (match_test "TARGET_SHIFT1")
9684 (match_test "optimize_function_for_size_p (cfun)")))))
9686 (const_string "*")))
9687 (set_attr "mode" "QI")])
9689 ;; Convert ashift to the lea pattern to avoid flags dependency.
9691 [(set (match_operand 0 "register_operand")
9692 (ashift (match_operand 1 "index_register_operand")
9693 (match_operand:QI 2 "const_int_operand")))
9694 (clobber (reg:CC FLAGS_REG))]
9695 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9697 && true_regnum (operands[0]) != true_regnum (operands[1])"
9700 enum machine_mode mode = GET_MODE (operands[0]);
9703 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9706 operands[0] = gen_lowpart (mode, operands[0]);
9707 operands[1] = gen_lowpart (mode, operands[1]);
9710 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9712 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9714 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9718 ;; Convert ashift to the lea pattern to avoid flags dependency.
9720 [(set (match_operand:DI 0 "register_operand")
9722 (ashift:SI (match_operand:SI 1 "index_register_operand")
9723 (match_operand:QI 2 "const_int_operand"))))
9724 (clobber (reg:CC FLAGS_REG))]
9725 "TARGET_64BIT && reload_completed
9726 && true_regnum (operands[0]) != true_regnum (operands[1])"
9728 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9730 operands[1] = gen_lowpart (SImode, operands[1]);
9731 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9734 ;; This pattern can't accept a variable shift count, since shifts by
9735 ;; zero don't affect the flags. We assume that shifts by constant
9736 ;; zero are optimized away.
9737 (define_insn "*ashl<mode>3_cmp"
9738 [(set (reg FLAGS_REG)
9740 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9741 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9743 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9744 (ashift:SWI (match_dup 1) (match_dup 2)))]
9745 "(optimize_function_for_size_p (cfun)
9746 || !TARGET_PARTIAL_FLAG_REG_STALL
9747 || (operands[2] == const1_rtx
9749 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9750 && ix86_match_ccmode (insn, CCGOCmode)
9751 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9753 switch (get_attr_type (insn))
9756 gcc_assert (operands[2] == const1_rtx);
9757 return "add{<imodesuffix>}\t%0, %0";
9760 if (operands[2] == const1_rtx
9761 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9762 return "sal{<imodesuffix>}\t%0";
9764 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9768 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9769 (match_operand 0 "register_operand"))
9770 (match_operand 2 "const1_operand"))
9771 (const_string "alu")
9773 (const_string "ishift")))
9774 (set (attr "length_immediate")
9776 (ior (eq_attr "type" "alu")
9777 (and (eq_attr "type" "ishift")
9778 (and (match_operand 2 "const1_operand")
9779 (ior (match_test "TARGET_SHIFT1")
9780 (match_test "optimize_function_for_size_p (cfun)")))))
9782 (const_string "*")))
9783 (set_attr "mode" "<MODE>")])
9785 (define_insn "*ashlsi3_cmp_zext"
9786 [(set (reg FLAGS_REG)
9788 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9789 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9791 (set (match_operand:DI 0 "register_operand" "=r")
9792 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9794 && (optimize_function_for_size_p (cfun)
9795 || !TARGET_PARTIAL_FLAG_REG_STALL
9796 || (operands[2] == const1_rtx
9798 || TARGET_DOUBLE_WITH_ADD)))
9799 && ix86_match_ccmode (insn, CCGOCmode)
9800 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9802 switch (get_attr_type (insn))
9805 gcc_assert (operands[2] == const1_rtx);
9806 return "add{l}\t%k0, %k0";
9809 if (operands[2] == const1_rtx
9810 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9811 return "sal{l}\t%k0";
9813 return "sal{l}\t{%2, %k0|%k0, %2}";
9817 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9818 (match_operand 2 "const1_operand"))
9819 (const_string "alu")
9821 (const_string "ishift")))
9822 (set (attr "length_immediate")
9824 (ior (eq_attr "type" "alu")
9825 (and (eq_attr "type" "ishift")
9826 (and (match_operand 2 "const1_operand")
9827 (ior (match_test "TARGET_SHIFT1")
9828 (match_test "optimize_function_for_size_p (cfun)")))))
9830 (const_string "*")))
9831 (set_attr "mode" "SI")])
9833 (define_insn "*ashl<mode>3_cconly"
9834 [(set (reg FLAGS_REG)
9836 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9837 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9839 (clobber (match_scratch:SWI 0 "=<r>"))]
9840 "(optimize_function_for_size_p (cfun)
9841 || !TARGET_PARTIAL_FLAG_REG_STALL
9842 || (operands[2] == const1_rtx
9844 || TARGET_DOUBLE_WITH_ADD)))
9845 && ix86_match_ccmode (insn, CCGOCmode)"
9847 switch (get_attr_type (insn))
9850 gcc_assert (operands[2] == const1_rtx);
9851 return "add{<imodesuffix>}\t%0, %0";
9854 if (operands[2] == const1_rtx
9855 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9856 return "sal{<imodesuffix>}\t%0";
9858 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9862 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9863 (match_operand 0 "register_operand"))
9864 (match_operand 2 "const1_operand"))
9865 (const_string "alu")
9867 (const_string "ishift")))
9868 (set (attr "length_immediate")
9870 (ior (eq_attr "type" "alu")
9871 (and (eq_attr "type" "ishift")
9872 (and (match_operand 2 "const1_operand")
9873 (ior (match_test "TARGET_SHIFT1")
9874 (match_test "optimize_function_for_size_p (cfun)")))))
9876 (const_string "*")))
9877 (set_attr "mode" "<MODE>")])
9879 ;; See comment above `ashl<mode>3' about how this works.
9881 (define_expand "<shift_insn><mode>3"
9882 [(set (match_operand:SDWIM 0 "<shift_operand>")
9883 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9884 (match_operand:QI 2 "nonmemory_operand")))]
9886 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9888 ;; Avoid useless masking of count operand.
9889 (define_insn "*<shift_insn><mode>3_mask"
9890 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9892 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9895 (match_operand:SI 2 "register_operand" "c")
9896 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9897 (clobber (reg:CC FLAGS_REG))]
9898 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9899 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9900 == GET_MODE_BITSIZE (<MODE>mode)-1"
9902 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9904 [(set_attr "type" "ishift")
9905 (set_attr "mode" "<MODE>")])
9907 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9908 [(set (match_operand:DWI 0 "register_operand" "=r")
9909 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9910 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9911 (clobber (reg:CC FLAGS_REG))]
9914 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9916 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9917 [(set_attr "type" "multi")])
9919 ;; By default we don't ask for a scratch register, because when DWImode
9920 ;; values are manipulated, registers are already at a premium. But if
9921 ;; we have one handy, we won't turn it away.
9924 [(match_scratch:DWIH 3 "r")
9925 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9927 (match_operand:<DWI> 1 "register_operand")
9928 (match_operand:QI 2 "nonmemory_operand")))
9929 (clobber (reg:CC FLAGS_REG))])
9933 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9935 (define_insn "x86_64_shrd"
9936 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9937 (ior:DI (ashiftrt:DI (match_dup 0)
9938 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9939 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9940 (minus:QI (const_int 64) (match_dup 2)))))
9941 (clobber (reg:CC FLAGS_REG))]
9943 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9944 [(set_attr "type" "ishift")
9945 (set_attr "prefix_0f" "1")
9946 (set_attr "mode" "DI")
9947 (set_attr "athlon_decode" "vector")
9948 (set_attr "amdfam10_decode" "vector")
9949 (set_attr "bdver1_decode" "vector")])
9951 (define_insn "x86_shrd"
9952 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9953 (ior:SI (ashiftrt:SI (match_dup 0)
9954 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9955 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9956 (minus:QI (const_int 32) (match_dup 2)))))
9957 (clobber (reg:CC FLAGS_REG))]
9959 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9960 [(set_attr "type" "ishift")
9961 (set_attr "prefix_0f" "1")
9962 (set_attr "mode" "SI")
9963 (set_attr "pent_pair" "np")
9964 (set_attr "athlon_decode" "vector")
9965 (set_attr "amdfam10_decode" "vector")
9966 (set_attr "bdver1_decode" "vector")])
9968 (define_insn "ashrdi3_cvt"
9969 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9970 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9971 (match_operand:QI 2 "const_int_operand")))
9972 (clobber (reg:CC FLAGS_REG))]
9973 "TARGET_64BIT && INTVAL (operands[2]) == 63
9974 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9975 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9978 sar{q}\t{%2, %0|%0, %2}"
9979 [(set_attr "type" "imovx,ishift")
9980 (set_attr "prefix_0f" "0,*")
9981 (set_attr "length_immediate" "0,*")
9982 (set_attr "modrm" "0,1")
9983 (set_attr "mode" "DI")])
9985 (define_insn "ashrsi3_cvt"
9986 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9987 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9988 (match_operand:QI 2 "const_int_operand")))
9989 (clobber (reg:CC FLAGS_REG))]
9990 "INTVAL (operands[2]) == 31
9991 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9992 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9995 sar{l}\t{%2, %0|%0, %2}"
9996 [(set_attr "type" "imovx,ishift")
9997 (set_attr "prefix_0f" "0,*")
9998 (set_attr "length_immediate" "0,*")
9999 (set_attr "modrm" "0,1")
10000 (set_attr "mode" "SI")])
10002 (define_insn "*ashrsi3_cvt_zext"
10003 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10005 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10006 (match_operand:QI 2 "const_int_operand"))))
10007 (clobber (reg:CC FLAGS_REG))]
10008 "TARGET_64BIT && INTVAL (operands[2]) == 31
10009 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10010 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10013 sar{l}\t{%2, %k0|%k0, %2}"
10014 [(set_attr "type" "imovx,ishift")
10015 (set_attr "prefix_0f" "0,*")
10016 (set_attr "length_immediate" "0,*")
10017 (set_attr "modrm" "0,1")
10018 (set_attr "mode" "SI")])
10020 (define_expand "x86_shift<mode>_adj_3"
10021 [(use (match_operand:SWI48 0 "register_operand"))
10022 (use (match_operand:SWI48 1 "register_operand"))
10023 (use (match_operand:QI 2 "register_operand"))]
10026 rtx label = gen_label_rtx ();
10029 emit_insn (gen_testqi_ccz_1 (operands[2],
10030 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10032 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10033 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10034 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10035 gen_rtx_LABEL_REF (VOIDmode, label),
10037 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10038 JUMP_LABEL (tmp) = label;
10040 emit_move_insn (operands[0], operands[1]);
10041 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10042 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10043 emit_label (label);
10044 LABEL_NUSES (label) = 1;
10049 (define_insn "*bmi2_<shift_insn><mode>3_1"
10050 [(set (match_operand:SWI48 0 "register_operand" "=r")
10051 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10052 (match_operand:SWI48 2 "register_operand" "r")))]
10054 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10055 [(set_attr "type" "ishiftx")
10056 (set_attr "mode" "<MODE>")])
10058 (define_insn "*<shift_insn><mode>3_1"
10059 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10061 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10062 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10063 (clobber (reg:CC FLAGS_REG))]
10064 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10066 switch (get_attr_type (insn))
10072 if (operands[2] == const1_rtx
10073 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10074 return "<shift>{<imodesuffix>}\t%0";
10076 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10079 [(set_attr "isa" "*,bmi2")
10080 (set_attr "type" "ishift,ishiftx")
10081 (set (attr "length_immediate")
10083 (and (match_operand 2 "const1_operand")
10084 (ior (match_test "TARGET_SHIFT1")
10085 (match_test "optimize_function_for_size_p (cfun)")))
10087 (const_string "*")))
10088 (set_attr "mode" "<MODE>")])
10090 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10092 [(set (match_operand:SWI48 0 "register_operand")
10093 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10094 (match_operand:QI 2 "register_operand")))
10095 (clobber (reg:CC FLAGS_REG))]
10096 "TARGET_BMI2 && reload_completed"
10097 [(set (match_dup 0)
10098 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10099 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10101 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10102 [(set (match_operand:DI 0 "register_operand" "=r")
10104 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10105 (match_operand:SI 2 "register_operand" "r"))))]
10106 "TARGET_64BIT && TARGET_BMI2"
10107 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10108 [(set_attr "type" "ishiftx")
10109 (set_attr "mode" "SI")])
10111 (define_insn "*<shift_insn>si3_1_zext"
10112 [(set (match_operand:DI 0 "register_operand" "=r,r")
10114 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10115 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10116 (clobber (reg:CC FLAGS_REG))]
10117 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10119 switch (get_attr_type (insn))
10125 if (operands[2] == const1_rtx
10126 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10127 return "<shift>{l}\t%k0";
10129 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10132 [(set_attr "isa" "*,bmi2")
10133 (set_attr "type" "ishift,ishiftx")
10134 (set (attr "length_immediate")
10136 (and (match_operand 2 "const1_operand")
10137 (ior (match_test "TARGET_SHIFT1")
10138 (match_test "optimize_function_for_size_p (cfun)")))
10140 (const_string "*")))
10141 (set_attr "mode" "SI")])
10143 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10145 [(set (match_operand:DI 0 "register_operand")
10147 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10148 (match_operand:QI 2 "register_operand"))))
10149 (clobber (reg:CC FLAGS_REG))]
10150 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10151 [(set (match_dup 0)
10152 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10153 "operands[2] = gen_lowpart (SImode, operands[2]);")
10155 (define_insn "*<shift_insn><mode>3_1"
10156 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10158 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10159 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10160 (clobber (reg:CC FLAGS_REG))]
10161 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10163 if (operands[2] == const1_rtx
10164 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10165 return "<shift>{<imodesuffix>}\t%0";
10167 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10169 [(set_attr "type" "ishift")
10170 (set (attr "length_immediate")
10172 (and (match_operand 2 "const1_operand")
10173 (ior (match_test "TARGET_SHIFT1")
10174 (match_test "optimize_function_for_size_p (cfun)")))
10176 (const_string "*")))
10177 (set_attr "mode" "<MODE>")])
10179 (define_insn "*<shift_insn>qi3_1_slp"
10180 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10181 (any_shiftrt:QI (match_dup 0)
10182 (match_operand:QI 1 "nonmemory_operand" "cI")))
10183 (clobber (reg:CC FLAGS_REG))]
10184 "(optimize_function_for_size_p (cfun)
10185 || !TARGET_PARTIAL_REG_STALL
10186 || (operands[1] == const1_rtx
10187 && TARGET_SHIFT1))"
10189 if (operands[1] == const1_rtx
10190 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10191 return "<shift>{b}\t%0";
10193 return "<shift>{b}\t{%1, %0|%0, %1}";
10195 [(set_attr "type" "ishift1")
10196 (set (attr "length_immediate")
10198 (and (match_operand 1 "const1_operand")
10199 (ior (match_test "TARGET_SHIFT1")
10200 (match_test "optimize_function_for_size_p (cfun)")))
10202 (const_string "*")))
10203 (set_attr "mode" "QI")])
10205 ;; This pattern can't accept a variable shift count, since shifts by
10206 ;; zero don't affect the flags. We assume that shifts by constant
10207 ;; zero are optimized away.
10208 (define_insn "*<shift_insn><mode>3_cmp"
10209 [(set (reg FLAGS_REG)
10212 (match_operand:SWI 1 "nonimmediate_operand" "0")
10213 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10215 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10216 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10217 "(optimize_function_for_size_p (cfun)
10218 || !TARGET_PARTIAL_FLAG_REG_STALL
10219 || (operands[2] == const1_rtx
10221 && ix86_match_ccmode (insn, CCGOCmode)
10222 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10224 if (operands[2] == const1_rtx
10225 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10226 return "<shift>{<imodesuffix>}\t%0";
10228 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10230 [(set_attr "type" "ishift")
10231 (set (attr "length_immediate")
10233 (and (match_operand 2 "const1_operand")
10234 (ior (match_test "TARGET_SHIFT1")
10235 (match_test "optimize_function_for_size_p (cfun)")))
10237 (const_string "*")))
10238 (set_attr "mode" "<MODE>")])
10240 (define_insn "*<shift_insn>si3_cmp_zext"
10241 [(set (reg FLAGS_REG)
10243 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10244 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10246 (set (match_operand:DI 0 "register_operand" "=r")
10247 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10249 && (optimize_function_for_size_p (cfun)
10250 || !TARGET_PARTIAL_FLAG_REG_STALL
10251 || (operands[2] == const1_rtx
10253 && ix86_match_ccmode (insn, CCGOCmode)
10254 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10256 if (operands[2] == const1_rtx
10257 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10258 return "<shift>{l}\t%k0";
10260 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10262 [(set_attr "type" "ishift")
10263 (set (attr "length_immediate")
10265 (and (match_operand 2 "const1_operand")
10266 (ior (match_test "TARGET_SHIFT1")
10267 (match_test "optimize_function_for_size_p (cfun)")))
10269 (const_string "*")))
10270 (set_attr "mode" "SI")])
10272 (define_insn "*<shift_insn><mode>3_cconly"
10273 [(set (reg FLAGS_REG)
10276 (match_operand:SWI 1 "register_operand" "0")
10277 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10279 (clobber (match_scratch:SWI 0 "=<r>"))]
10280 "(optimize_function_for_size_p (cfun)
10281 || !TARGET_PARTIAL_FLAG_REG_STALL
10282 || (operands[2] == const1_rtx
10284 && ix86_match_ccmode (insn, CCGOCmode)"
10286 if (operands[2] == const1_rtx
10287 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10288 return "<shift>{<imodesuffix>}\t%0";
10290 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10292 [(set_attr "type" "ishift")
10293 (set (attr "length_immediate")
10295 (and (match_operand 2 "const1_operand")
10296 (ior (match_test "TARGET_SHIFT1")
10297 (match_test "optimize_function_for_size_p (cfun)")))
10299 (const_string "*")))
10300 (set_attr "mode" "<MODE>")])
10302 ;; Rotate instructions
10304 (define_expand "<rotate_insn>ti3"
10305 [(set (match_operand:TI 0 "register_operand")
10306 (any_rotate:TI (match_operand:TI 1 "register_operand")
10307 (match_operand:QI 2 "nonmemory_operand")))]
10310 if (const_1_to_63_operand (operands[2], VOIDmode))
10311 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10312 (operands[0], operands[1], operands[2]));
10319 (define_expand "<rotate_insn>di3"
10320 [(set (match_operand:DI 0 "shiftdi_operand")
10321 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10322 (match_operand:QI 2 "nonmemory_operand")))]
10326 ix86_expand_binary_operator (<CODE>, DImode, operands);
10327 else if (const_1_to_31_operand (operands[2], VOIDmode))
10328 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10329 (operands[0], operands[1], operands[2]));
10336 (define_expand "<rotate_insn><mode>3"
10337 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10338 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10339 (match_operand:QI 2 "nonmemory_operand")))]
10341 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10343 ;; Avoid useless masking of count operand.
10344 (define_insn "*<rotate_insn><mode>3_mask"
10345 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10347 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10350 (match_operand:SI 2 "register_operand" "c")
10351 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10352 (clobber (reg:CC FLAGS_REG))]
10353 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10354 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10355 == GET_MODE_BITSIZE (<MODE>mode)-1"
10357 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10359 [(set_attr "type" "rotate")
10360 (set_attr "mode" "<MODE>")])
10362 ;; Implement rotation using two double-precision
10363 ;; shift instructions and a scratch register.
10365 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10366 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10367 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10368 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10369 (clobber (reg:CC FLAGS_REG))
10370 (clobber (match_scratch:DWIH 3 "=&r"))]
10374 [(set (match_dup 3) (match_dup 4))
10376 [(set (match_dup 4)
10377 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10378 (lshiftrt:DWIH (match_dup 5)
10379 (minus:QI (match_dup 6) (match_dup 2)))))
10380 (clobber (reg:CC FLAGS_REG))])
10382 [(set (match_dup 5)
10383 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10384 (lshiftrt:DWIH (match_dup 3)
10385 (minus:QI (match_dup 6) (match_dup 2)))))
10386 (clobber (reg:CC FLAGS_REG))])]
10388 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10390 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10393 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10394 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10395 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10396 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10397 (clobber (reg:CC FLAGS_REG))
10398 (clobber (match_scratch:DWIH 3 "=&r"))]
10402 [(set (match_dup 3) (match_dup 4))
10404 [(set (match_dup 4)
10405 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10406 (ashift:DWIH (match_dup 5)
10407 (minus:QI (match_dup 6) (match_dup 2)))))
10408 (clobber (reg:CC FLAGS_REG))])
10410 [(set (match_dup 5)
10411 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10412 (ashift:DWIH (match_dup 3)
10413 (minus:QI (match_dup 6) (match_dup 2)))))
10414 (clobber (reg:CC FLAGS_REG))])]
10416 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10418 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10421 (define_insn "*bmi2_rorx<mode>3_1"
10422 [(set (match_operand:SWI48 0 "register_operand" "=r")
10423 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10424 (match_operand:QI 2 "immediate_operand" "<S>")))]
10426 "rorx\t{%2, %1, %0|%0, %1, %2}"
10427 [(set_attr "type" "rotatex")
10428 (set_attr "mode" "<MODE>")])
10430 (define_insn "*<rotate_insn><mode>3_1"
10431 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10433 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10434 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10438 switch (get_attr_type (insn))
10444 if (operands[2] == const1_rtx
10445 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10446 return "<rotate>{<imodesuffix>}\t%0";
10448 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10451 [(set_attr "isa" "*,bmi2")
10452 (set_attr "type" "rotate,rotatex")
10453 (set (attr "length_immediate")
10455 (and (eq_attr "type" "rotate")
10456 (and (match_operand 2 "const1_operand")
10457 (ior (match_test "TARGET_SHIFT1")
10458 (match_test "optimize_function_for_size_p (cfun)"))))
10460 (const_string "*")))
10461 (set_attr "mode" "<MODE>")])
10463 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10465 [(set (match_operand:SWI48 0 "register_operand")
10466 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10467 (match_operand:QI 2 "immediate_operand")))
10468 (clobber (reg:CC FLAGS_REG))]
10469 "TARGET_BMI2 && reload_completed"
10470 [(set (match_dup 0)
10471 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10474 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10478 [(set (match_operand:SWI48 0 "register_operand")
10479 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10480 (match_operand:QI 2 "immediate_operand")))
10481 (clobber (reg:CC FLAGS_REG))]
10482 "TARGET_BMI2 && reload_completed"
10483 [(set (match_dup 0)
10484 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10486 (define_insn "*bmi2_rorxsi3_1_zext"
10487 [(set (match_operand:DI 0 "register_operand" "=r")
10489 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10490 (match_operand:QI 2 "immediate_operand" "I"))))]
10491 "TARGET_64BIT && TARGET_BMI2"
10492 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10493 [(set_attr "type" "rotatex")
10494 (set_attr "mode" "SI")])
10496 (define_insn "*<rotate_insn>si3_1_zext"
10497 [(set (match_operand:DI 0 "register_operand" "=r,r")
10499 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10500 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10501 (clobber (reg:CC FLAGS_REG))]
10502 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10504 switch (get_attr_type (insn))
10510 if (operands[2] == const1_rtx
10511 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10512 return "<rotate>{l}\t%k0";
10514 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10517 [(set_attr "isa" "*,bmi2")
10518 (set_attr "type" "rotate,rotatex")
10519 (set (attr "length_immediate")
10521 (and (eq_attr "type" "rotate")
10522 (and (match_operand 2 "const1_operand")
10523 (ior (match_test "TARGET_SHIFT1")
10524 (match_test "optimize_function_for_size_p (cfun)"))))
10526 (const_string "*")))
10527 (set_attr "mode" "SI")])
10529 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10531 [(set (match_operand:DI 0 "register_operand")
10533 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10534 (match_operand:QI 2 "immediate_operand"))))
10535 (clobber (reg:CC FLAGS_REG))]
10536 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10537 [(set (match_dup 0)
10538 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10541 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10545 [(set (match_operand:DI 0 "register_operand")
10547 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10548 (match_operand:QI 2 "immediate_operand"))))
10549 (clobber (reg:CC FLAGS_REG))]
10550 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10551 [(set (match_dup 0)
10552 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10554 (define_insn "*<rotate_insn><mode>3_1"
10555 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10556 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10557 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10558 (clobber (reg:CC FLAGS_REG))]
10559 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10561 if (operands[2] == const1_rtx
10562 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10563 return "<rotate>{<imodesuffix>}\t%0";
10565 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10567 [(set_attr "type" "rotate")
10568 (set (attr "length_immediate")
10570 (and (match_operand 2 "const1_operand")
10571 (ior (match_test "TARGET_SHIFT1")
10572 (match_test "optimize_function_for_size_p (cfun)")))
10574 (const_string "*")))
10575 (set_attr "mode" "<MODE>")])
10577 (define_insn "*<rotate_insn>qi3_1_slp"
10578 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10579 (any_rotate:QI (match_dup 0)
10580 (match_operand:QI 1 "nonmemory_operand" "cI")))
10581 (clobber (reg:CC FLAGS_REG))]
10582 "(optimize_function_for_size_p (cfun)
10583 || !TARGET_PARTIAL_REG_STALL
10584 || (operands[1] == const1_rtx
10585 && TARGET_SHIFT1))"
10587 if (operands[1] == const1_rtx
10588 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10589 return "<rotate>{b}\t%0";
10591 return "<rotate>{b}\t{%1, %0|%0, %1}";
10593 [(set_attr "type" "rotate1")
10594 (set (attr "length_immediate")
10596 (and (match_operand 1 "const1_operand")
10597 (ior (match_test "TARGET_SHIFT1")
10598 (match_test "optimize_function_for_size_p (cfun)")))
10600 (const_string "*")))
10601 (set_attr "mode" "QI")])
10604 [(set (match_operand:HI 0 "register_operand")
10605 (any_rotate:HI (match_dup 0) (const_int 8)))
10606 (clobber (reg:CC FLAGS_REG))]
10608 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10609 [(parallel [(set (strict_low_part (match_dup 0))
10610 (bswap:HI (match_dup 0)))
10611 (clobber (reg:CC FLAGS_REG))])])
10613 ;; Bit set / bit test instructions
10615 (define_expand "extv"
10616 [(set (match_operand:SI 0 "register_operand")
10617 (sign_extract:SI (match_operand:SI 1 "register_operand")
10618 (match_operand:SI 2 "const8_operand")
10619 (match_operand:SI 3 "const8_operand")))]
10622 /* Handle extractions from %ah et al. */
10623 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10626 /* From mips.md: extract_bit_field doesn't verify that our source
10627 matches the predicate, so check it again here. */
10628 if (! ext_register_operand (operands[1], VOIDmode))
10632 (define_expand "extzv"
10633 [(set (match_operand:SI 0 "register_operand")
10634 (zero_extract:SI (match_operand 1 "ext_register_operand")
10635 (match_operand:SI 2 "const8_operand")
10636 (match_operand:SI 3 "const8_operand")))]
10639 /* Handle extractions from %ah et al. */
10640 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10643 /* From mips.md: extract_bit_field doesn't verify that our source
10644 matches the predicate, so check it again here. */
10645 if (! ext_register_operand (operands[1], VOIDmode))
10649 (define_expand "insv"
10650 [(set (zero_extract (match_operand 0 "register_operand")
10651 (match_operand 1 "const_int_operand")
10652 (match_operand 2 "const_int_operand"))
10653 (match_operand 3 "register_operand"))]
10656 rtx (*gen_mov_insv_1) (rtx, rtx);
10658 if (ix86_expand_pinsr (operands))
10661 /* Handle insertions to %ah et al. */
10662 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10665 /* From mips.md: insert_bit_field doesn't verify that our source
10666 matches the predicate, so check it again here. */
10667 if (! ext_register_operand (operands[0], VOIDmode))
10670 gen_mov_insv_1 = (TARGET_64BIT
10671 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10673 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10677 ;; %%% bts, btr, btc, bt.
10678 ;; In general these instructions are *slow* when applied to memory,
10679 ;; since they enforce atomic operation. When applied to registers,
10680 ;; it depends on the cpu implementation. They're never faster than
10681 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10682 ;; no point. But in 64-bit, we can't hold the relevant immediates
10683 ;; within the instruction itself, so operating on bits in the high
10684 ;; 32-bits of a register becomes easier.
10686 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10687 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10688 ;; negdf respectively, so they can never be disabled entirely.
10690 (define_insn "*btsq"
10691 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10693 (match_operand:DI 1 "const_0_to_63_operand"))
10695 (clobber (reg:CC FLAGS_REG))]
10696 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10697 "bts{q}\t{%1, %0|%0, %1}"
10698 [(set_attr "type" "alu1")
10699 (set_attr "prefix_0f" "1")
10700 (set_attr "mode" "DI")])
10702 (define_insn "*btrq"
10703 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10705 (match_operand:DI 1 "const_0_to_63_operand"))
10707 (clobber (reg:CC FLAGS_REG))]
10708 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10709 "btr{q}\t{%1, %0|%0, %1}"
10710 [(set_attr "type" "alu1")
10711 (set_attr "prefix_0f" "1")
10712 (set_attr "mode" "DI")])
10714 (define_insn "*btcq"
10715 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10717 (match_operand:DI 1 "const_0_to_63_operand"))
10718 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10719 (clobber (reg:CC FLAGS_REG))]
10720 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10721 "btc{q}\t{%1, %0|%0, %1}"
10722 [(set_attr "type" "alu1")
10723 (set_attr "prefix_0f" "1")
10724 (set_attr "mode" "DI")])
10726 ;; Allow Nocona to avoid these instructions if a register is available.
10729 [(match_scratch:DI 2 "r")
10730 (parallel [(set (zero_extract:DI
10731 (match_operand:DI 0 "register_operand")
10733 (match_operand:DI 1 "const_0_to_63_operand"))
10735 (clobber (reg:CC FLAGS_REG))])]
10736 "TARGET_64BIT && !TARGET_USE_BT"
10739 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10742 if (HOST_BITS_PER_WIDE_INT >= 64)
10743 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10744 else if (i < HOST_BITS_PER_WIDE_INT)
10745 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10747 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10749 op1 = immed_double_const (lo, hi, DImode);
10752 emit_move_insn (operands[2], op1);
10756 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10761 [(match_scratch:DI 2 "r")
10762 (parallel [(set (zero_extract:DI
10763 (match_operand:DI 0 "register_operand")
10765 (match_operand:DI 1 "const_0_to_63_operand"))
10767 (clobber (reg:CC FLAGS_REG))])]
10768 "TARGET_64BIT && !TARGET_USE_BT"
10771 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10774 if (HOST_BITS_PER_WIDE_INT >= 64)
10775 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10776 else if (i < HOST_BITS_PER_WIDE_INT)
10777 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10779 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10781 op1 = immed_double_const (~lo, ~hi, DImode);
10784 emit_move_insn (operands[2], op1);
10788 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10793 [(match_scratch:DI 2 "r")
10794 (parallel [(set (zero_extract:DI
10795 (match_operand:DI 0 "register_operand")
10797 (match_operand:DI 1 "const_0_to_63_operand"))
10798 (not:DI (zero_extract:DI
10799 (match_dup 0) (const_int 1) (match_dup 1))))
10800 (clobber (reg:CC FLAGS_REG))])]
10801 "TARGET_64BIT && !TARGET_USE_BT"
10804 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10807 if (HOST_BITS_PER_WIDE_INT >= 64)
10808 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10809 else if (i < HOST_BITS_PER_WIDE_INT)
10810 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10812 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10814 op1 = immed_double_const (lo, hi, DImode);
10817 emit_move_insn (operands[2], op1);
10821 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10825 (define_insn "*bt<mode>"
10826 [(set (reg:CCC FLAGS_REG)
10828 (zero_extract:SWI48
10829 (match_operand:SWI48 0 "register_operand" "r")
10831 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10833 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10834 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10835 [(set_attr "type" "alu1")
10836 (set_attr "prefix_0f" "1")
10837 (set_attr "mode" "<MODE>")])
10839 ;; Store-flag instructions.
10841 ;; For all sCOND expanders, also expand the compare or test insn that
10842 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10844 (define_insn_and_split "*setcc_di_1"
10845 [(set (match_operand:DI 0 "register_operand" "=q")
10846 (match_operator:DI 1 "ix86_comparison_operator"
10847 [(reg FLAGS_REG) (const_int 0)]))]
10848 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10850 "&& reload_completed"
10851 [(set (match_dup 2) (match_dup 1))
10852 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10854 PUT_MODE (operands[1], QImode);
10855 operands[2] = gen_lowpart (QImode, operands[0]);
10858 (define_insn_and_split "*setcc_si_1_and"
10859 [(set (match_operand:SI 0 "register_operand" "=q")
10860 (match_operator:SI 1 "ix86_comparison_operator"
10861 [(reg FLAGS_REG) (const_int 0)]))
10862 (clobber (reg:CC FLAGS_REG))]
10863 "!TARGET_PARTIAL_REG_STALL
10864 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10866 "&& reload_completed"
10867 [(set (match_dup 2) (match_dup 1))
10868 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10869 (clobber (reg:CC FLAGS_REG))])]
10871 PUT_MODE (operands[1], QImode);
10872 operands[2] = gen_lowpart (QImode, operands[0]);
10875 (define_insn_and_split "*setcc_si_1_movzbl"
10876 [(set (match_operand:SI 0 "register_operand" "=q")
10877 (match_operator:SI 1 "ix86_comparison_operator"
10878 [(reg FLAGS_REG) (const_int 0)]))]
10879 "!TARGET_PARTIAL_REG_STALL
10880 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10882 "&& reload_completed"
10883 [(set (match_dup 2) (match_dup 1))
10884 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10886 PUT_MODE (operands[1], QImode);
10887 operands[2] = gen_lowpart (QImode, operands[0]);
10890 (define_insn "*setcc_qi"
10891 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10892 (match_operator:QI 1 "ix86_comparison_operator"
10893 [(reg FLAGS_REG) (const_int 0)]))]
10896 [(set_attr "type" "setcc")
10897 (set_attr "mode" "QI")])
10899 (define_insn "*setcc_qi_slp"
10900 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10901 (match_operator:QI 1 "ix86_comparison_operator"
10902 [(reg FLAGS_REG) (const_int 0)]))]
10905 [(set_attr "type" "setcc")
10906 (set_attr "mode" "QI")])
10908 ;; In general it is not safe to assume too much about CCmode registers,
10909 ;; so simplify-rtx stops when it sees a second one. Under certain
10910 ;; conditions this is safe on x86, so help combine not create
10917 [(set (match_operand:QI 0 "nonimmediate_operand")
10918 (ne:QI (match_operator 1 "ix86_comparison_operator"
10919 [(reg FLAGS_REG) (const_int 0)])
10922 [(set (match_dup 0) (match_dup 1))]
10923 "PUT_MODE (operands[1], QImode);")
10926 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10927 (ne:QI (match_operator 1 "ix86_comparison_operator"
10928 [(reg FLAGS_REG) (const_int 0)])
10931 [(set (match_dup 0) (match_dup 1))]
10932 "PUT_MODE (operands[1], QImode);")
10935 [(set (match_operand:QI 0 "nonimmediate_operand")
10936 (eq:QI (match_operator 1 "ix86_comparison_operator"
10937 [(reg FLAGS_REG) (const_int 0)])
10940 [(set (match_dup 0) (match_dup 1))]
10942 rtx new_op1 = copy_rtx (operands[1]);
10943 operands[1] = new_op1;
10944 PUT_MODE (new_op1, QImode);
10945 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10946 GET_MODE (XEXP (new_op1, 0))));
10948 /* Make sure that (a) the CCmode we have for the flags is strong
10949 enough for the reversed compare or (b) we have a valid FP compare. */
10950 if (! ix86_comparison_operator (new_op1, VOIDmode))
10955 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10956 (eq:QI (match_operator 1 "ix86_comparison_operator"
10957 [(reg FLAGS_REG) (const_int 0)])
10960 [(set (match_dup 0) (match_dup 1))]
10962 rtx new_op1 = copy_rtx (operands[1]);
10963 operands[1] = new_op1;
10964 PUT_MODE (new_op1, QImode);
10965 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10966 GET_MODE (XEXP (new_op1, 0))));
10968 /* Make sure that (a) the CCmode we have for the flags is strong
10969 enough for the reversed compare or (b) we have a valid FP compare. */
10970 if (! ix86_comparison_operator (new_op1, VOIDmode))
10974 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10975 ;; subsequent logical operations are used to imitate conditional moves.
10976 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10979 (define_insn "setcc_<mode>_sse"
10980 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10981 (match_operator:MODEF 3 "sse_comparison_operator"
10982 [(match_operand:MODEF 1 "register_operand" "0,x")
10983 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10984 "SSE_FLOAT_MODE_P (<MODE>mode)"
10986 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10987 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10988 [(set_attr "isa" "noavx,avx")
10989 (set_attr "type" "ssecmp")
10990 (set_attr "length_immediate" "1")
10991 (set_attr "prefix" "orig,vex")
10992 (set_attr "mode" "<MODE>")])
10994 ;; Basic conditional jump instructions.
10995 ;; We ignore the overflow flag for signed branch instructions.
10997 (define_insn "*jcc_1"
10999 (if_then_else (match_operator 1 "ix86_comparison_operator"
11000 [(reg FLAGS_REG) (const_int 0)])
11001 (label_ref (match_operand 0))
11005 [(set_attr "type" "ibr")
11006 (set_attr "modrm" "0")
11007 (set (attr "length")
11008 (if_then_else (and (ge (minus (match_dup 0) (pc))
11010 (lt (minus (match_dup 0) (pc))
11015 (define_insn "*jcc_2"
11017 (if_then_else (match_operator 1 "ix86_comparison_operator"
11018 [(reg FLAGS_REG) (const_int 0)])
11020 (label_ref (match_operand 0))))]
11023 [(set_attr "type" "ibr")
11024 (set_attr "modrm" "0")
11025 (set (attr "length")
11026 (if_then_else (and (ge (minus (match_dup 0) (pc))
11028 (lt (minus (match_dup 0) (pc))
11033 ;; In general it is not safe to assume too much about CCmode registers,
11034 ;; so simplify-rtx stops when it sees a second one. Under certain
11035 ;; conditions this is safe on x86, so help combine not create
11043 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11044 [(reg FLAGS_REG) (const_int 0)])
11046 (label_ref (match_operand 1))
11050 (if_then_else (match_dup 0)
11051 (label_ref (match_dup 1))
11053 "PUT_MODE (operands[0], VOIDmode);")
11057 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11058 [(reg FLAGS_REG) (const_int 0)])
11060 (label_ref (match_operand 1))
11064 (if_then_else (match_dup 0)
11065 (label_ref (match_dup 1))
11068 rtx new_op0 = copy_rtx (operands[0]);
11069 operands[0] = new_op0;
11070 PUT_MODE (new_op0, VOIDmode);
11071 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11072 GET_MODE (XEXP (new_op0, 0))));
11074 /* Make sure that (a) the CCmode we have for the flags is strong
11075 enough for the reversed compare or (b) we have a valid FP compare. */
11076 if (! ix86_comparison_operator (new_op0, VOIDmode))
11080 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11081 ;; pass generates from shift insn with QImode operand. Actually, the mode
11082 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11083 ;; appropriate modulo of the bit offset value.
11085 (define_insn_and_split "*jcc_bt<mode>"
11087 (if_then_else (match_operator 0 "bt_comparison_operator"
11088 [(zero_extract:SWI48
11089 (match_operand:SWI48 1 "register_operand" "r")
11092 (match_operand:QI 2 "register_operand" "r")))
11094 (label_ref (match_operand 3))
11096 (clobber (reg:CC FLAGS_REG))]
11097 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11100 [(set (reg:CCC FLAGS_REG)
11102 (zero_extract:SWI48
11108 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11109 (label_ref (match_dup 3))
11112 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11114 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11117 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11118 ;; zero extended to SImode.
11119 (define_insn_and_split "*jcc_bt<mode>_1"
11121 (if_then_else (match_operator 0 "bt_comparison_operator"
11122 [(zero_extract:SWI48
11123 (match_operand:SWI48 1 "register_operand" "r")
11125 (match_operand:SI 2 "register_operand" "r"))
11127 (label_ref (match_operand 3))
11129 (clobber (reg:CC FLAGS_REG))]
11130 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11133 [(set (reg:CCC FLAGS_REG)
11135 (zero_extract:SWI48
11141 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11142 (label_ref (match_dup 3))
11145 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11147 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11150 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11151 ;; also for DImode, this is what combine produces.
11152 (define_insn_and_split "*jcc_bt<mode>_mask"
11154 (if_then_else (match_operator 0 "bt_comparison_operator"
11155 [(zero_extract:SWI48
11156 (match_operand:SWI48 1 "register_operand" "r")
11159 (match_operand:SI 2 "register_operand" "r")
11160 (match_operand:SI 3 "const_int_operand" "n")))])
11161 (label_ref (match_operand 4))
11163 (clobber (reg:CC FLAGS_REG))]
11164 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11165 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11166 == GET_MODE_BITSIZE (<MODE>mode)-1"
11169 [(set (reg:CCC FLAGS_REG)
11171 (zero_extract:SWI48
11177 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11178 (label_ref (match_dup 4))
11181 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11183 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11186 (define_insn_and_split "*jcc_btsi_1"
11188 (if_then_else (match_operator 0 "bt_comparison_operator"
11191 (match_operand:SI 1 "register_operand" "r")
11192 (match_operand:QI 2 "register_operand" "r"))
11195 (label_ref (match_operand 3))
11197 (clobber (reg:CC FLAGS_REG))]
11198 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11201 [(set (reg:CCC FLAGS_REG)
11209 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11210 (label_ref (match_dup 3))
11213 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11215 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11218 ;; avoid useless masking of bit offset operand
11219 (define_insn_and_split "*jcc_btsi_mask_1"
11222 (match_operator 0 "bt_comparison_operator"
11225 (match_operand:SI 1 "register_operand" "r")
11228 (match_operand:SI 2 "register_operand" "r")
11229 (match_operand:SI 3 "const_int_operand" "n")) 0))
11232 (label_ref (match_operand 4))
11234 (clobber (reg:CC FLAGS_REG))]
11235 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11236 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11239 [(set (reg:CCC FLAGS_REG)
11247 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11248 (label_ref (match_dup 4))
11250 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11252 ;; Define combination compare-and-branch fp compare instructions to help
11255 (define_insn "*jcc<mode>_0_i387"
11257 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11258 [(match_operand:X87MODEF 1 "register_operand" "f")
11259 (match_operand:X87MODEF 2 "const0_operand")])
11260 (label_ref (match_operand 3))
11262 (clobber (reg:CCFP FPSR_REG))
11263 (clobber (reg:CCFP FLAGS_REG))
11264 (clobber (match_scratch:HI 4 "=a"))]
11265 "TARGET_80387 && !TARGET_CMOVE"
11268 (define_insn "*jcc<mode>_0_r_i387"
11270 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11271 [(match_operand:X87MODEF 1 "register_operand" "f")
11272 (match_operand:X87MODEF 2 "const0_operand")])
11274 (label_ref (match_operand 3))))
11275 (clobber (reg:CCFP FPSR_REG))
11276 (clobber (reg:CCFP FLAGS_REG))
11277 (clobber (match_scratch:HI 4 "=a"))]
11278 "TARGET_80387 && !TARGET_CMOVE"
11281 (define_insn "*jccxf_i387"
11283 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11284 [(match_operand:XF 1 "register_operand" "f")
11285 (match_operand:XF 2 "register_operand" "f")])
11286 (label_ref (match_operand 3))
11288 (clobber (reg:CCFP FPSR_REG))
11289 (clobber (reg:CCFP FLAGS_REG))
11290 (clobber (match_scratch:HI 4 "=a"))]
11291 "TARGET_80387 && !TARGET_CMOVE"
11294 (define_insn "*jccxf_r_i387"
11296 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11297 [(match_operand:XF 1 "register_operand" "f")
11298 (match_operand:XF 2 "register_operand" "f")])
11300 (label_ref (match_operand 3))))
11301 (clobber (reg:CCFP FPSR_REG))
11302 (clobber (reg:CCFP FLAGS_REG))
11303 (clobber (match_scratch:HI 4 "=a"))]
11304 "TARGET_80387 && !TARGET_CMOVE"
11307 (define_insn "*jcc<mode>_i387"
11309 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11310 [(match_operand:MODEF 1 "register_operand" "f")
11311 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11312 (label_ref (match_operand 3))
11314 (clobber (reg:CCFP FPSR_REG))
11315 (clobber (reg:CCFP FLAGS_REG))
11316 (clobber (match_scratch:HI 4 "=a"))]
11317 "TARGET_80387 && !TARGET_CMOVE"
11320 (define_insn "*jcc<mode>_r_i387"
11322 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11323 [(match_operand:MODEF 1 "register_operand" "f")
11324 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11326 (label_ref (match_operand 3))))
11327 (clobber (reg:CCFP FPSR_REG))
11328 (clobber (reg:CCFP FLAGS_REG))
11329 (clobber (match_scratch:HI 4 "=a"))]
11330 "TARGET_80387 && !TARGET_CMOVE"
11333 (define_insn "*jccu<mode>_i387"
11335 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11336 [(match_operand:X87MODEF 1 "register_operand" "f")
11337 (match_operand:X87MODEF 2 "register_operand" "f")])
11338 (label_ref (match_operand 3))
11340 (clobber (reg:CCFP FPSR_REG))
11341 (clobber (reg:CCFP FLAGS_REG))
11342 (clobber (match_scratch:HI 4 "=a"))]
11343 "TARGET_80387 && !TARGET_CMOVE"
11346 (define_insn "*jccu<mode>_r_i387"
11348 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11349 [(match_operand:X87MODEF 1 "register_operand" "f")
11350 (match_operand:X87MODEF 2 "register_operand" "f")])
11352 (label_ref (match_operand 3))))
11353 (clobber (reg:CCFP FPSR_REG))
11354 (clobber (reg:CCFP FLAGS_REG))
11355 (clobber (match_scratch:HI 4 "=a"))]
11356 "TARGET_80387 && !TARGET_CMOVE"
11361 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11362 [(match_operand:X87MODEF 1 "register_operand")
11363 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11365 (match_operand 4)))
11366 (clobber (reg:CCFP FPSR_REG))
11367 (clobber (reg:CCFP FLAGS_REG))]
11368 "TARGET_80387 && !TARGET_CMOVE
11369 && reload_completed"
11372 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11373 operands[3], operands[4], NULL_RTX, NULL_RTX);
11379 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11380 [(match_operand:X87MODEF 1 "register_operand")
11381 (match_operand:X87MODEF 2 "general_operand")])
11383 (match_operand 4)))
11384 (clobber (reg:CCFP FPSR_REG))
11385 (clobber (reg:CCFP FLAGS_REG))
11386 (clobber (match_scratch:HI 5))]
11387 "TARGET_80387 && !TARGET_CMOVE
11388 && reload_completed"
11391 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11392 operands[3], operands[4], operands[5], NULL_RTX);
11396 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11397 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11398 ;; with a precedence over other operators and is always put in the first
11399 ;; place. Swap condition and operands to match ficom instruction.
11401 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11404 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11405 [(match_operator:X87MODEF 1 "float_operator"
11406 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11407 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11408 (label_ref (match_operand 4))
11410 (clobber (reg:CCFP FPSR_REG))
11411 (clobber (reg:CCFP FLAGS_REG))
11412 (clobber (match_scratch:HI 5 "=a,a"))]
11413 "TARGET_80387 && !TARGET_CMOVE
11414 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11415 || optimize_function_for_size_p (cfun))"
11418 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11421 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11422 [(match_operator:X87MODEF 1 "float_operator"
11423 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11424 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11426 (label_ref (match_operand 4))))
11427 (clobber (reg:CCFP FPSR_REG))
11428 (clobber (reg:CCFP FLAGS_REG))
11429 (clobber (match_scratch:HI 5 "=a,a"))]
11430 "TARGET_80387 && !TARGET_CMOVE
11431 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11432 || optimize_function_for_size_p (cfun))"
11438 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11439 [(match_operator:X87MODEF 1 "float_operator"
11440 [(match_operand:SWI24 2 "memory_operand")])
11441 (match_operand:X87MODEF 3 "register_operand")])
11443 (match_operand 5)))
11444 (clobber (reg:CCFP FPSR_REG))
11445 (clobber (reg:CCFP FLAGS_REG))
11446 (clobber (match_scratch:HI 6))]
11447 "TARGET_80387 && !TARGET_CMOVE
11448 && reload_completed"
11451 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11452 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11453 operands[4], operands[5], operands[6], NULL_RTX);
11457 ;; %%% Kill this when reload knows how to do it.
11461 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11462 [(match_operator:X87MODEF 1 "float_operator"
11463 [(match_operand:SWI24 2 "register_operand")])
11464 (match_operand:X87MODEF 3 "register_operand")])
11466 (match_operand 5)))
11467 (clobber (reg:CCFP FPSR_REG))
11468 (clobber (reg:CCFP FLAGS_REG))
11469 (clobber (match_scratch:HI 6))]
11470 "TARGET_80387 && !TARGET_CMOVE
11471 && reload_completed"
11474 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11476 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11477 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
11478 operands[4], operands[5], operands[6], operands[2]);
11482 ;; Unconditional and other jump instructions
11484 (define_insn "jump"
11486 (label_ref (match_operand 0)))]
11489 [(set_attr "type" "ibr")
11490 (set (attr "length")
11491 (if_then_else (and (ge (minus (match_dup 0) (pc))
11493 (lt (minus (match_dup 0) (pc))
11497 (set_attr "modrm" "0")])
11499 (define_expand "indirect_jump"
11500 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11504 operands[0] = convert_memory_address (word_mode, operands[0]);
11507 (define_insn "*indirect_jump"
11508 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11511 [(set_attr "type" "ibr")
11512 (set_attr "length_immediate" "0")])
11514 (define_expand "tablejump"
11515 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11516 (use (label_ref (match_operand 1)))])]
11519 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11520 relative. Convert the relative address to an absolute address. */
11524 enum rtx_code code;
11526 /* We can't use @GOTOFF for text labels on VxWorks;
11527 see gotoff_operand. */
11528 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11532 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11534 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11538 op1 = pic_offset_table_rtx;
11543 op0 = pic_offset_table_rtx;
11547 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11552 operands[0] = convert_memory_address (word_mode, operands[0]);
11555 (define_insn "*tablejump_1"
11556 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11557 (use (label_ref (match_operand 1)))]
11560 [(set_attr "type" "ibr")
11561 (set_attr "length_immediate" "0")])
11563 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11566 [(set (reg FLAGS_REG) (match_operand 0))
11567 (set (match_operand:QI 1 "register_operand")
11568 (match_operator:QI 2 "ix86_comparison_operator"
11569 [(reg FLAGS_REG) (const_int 0)]))
11570 (set (match_operand 3 "q_regs_operand")
11571 (zero_extend (match_dup 1)))]
11572 "(peep2_reg_dead_p (3, operands[1])
11573 || operands_match_p (operands[1], operands[3]))
11574 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11575 [(set (match_dup 4) (match_dup 0))
11576 (set (strict_low_part (match_dup 5))
11579 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11580 operands[5] = gen_lowpart (QImode, operands[3]);
11581 ix86_expand_clear (operands[3]);
11585 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11586 (match_operand 4)])
11587 (set (match_operand:QI 1 "register_operand")
11588 (match_operator:QI 2 "ix86_comparison_operator"
11589 [(reg FLAGS_REG) (const_int 0)]))
11590 (set (match_operand 3 "q_regs_operand")
11591 (zero_extend (match_dup 1)))]
11592 "(peep2_reg_dead_p (3, operands[1])
11593 || operands_match_p (operands[1], operands[3]))
11594 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11595 [(parallel [(set (match_dup 5) (match_dup 0))
11597 (set (strict_low_part (match_dup 6))
11600 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11601 operands[6] = gen_lowpart (QImode, operands[3]);
11602 ix86_expand_clear (operands[3]);
11605 ;; Similar, but match zero extend with andsi3.
11608 [(set (reg FLAGS_REG) (match_operand 0))
11609 (set (match_operand:QI 1 "register_operand")
11610 (match_operator:QI 2 "ix86_comparison_operator"
11611 [(reg FLAGS_REG) (const_int 0)]))
11612 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11613 (and:SI (match_dup 3) (const_int 255)))
11614 (clobber (reg:CC FLAGS_REG))])]
11615 "REGNO (operands[1]) == REGNO (operands[3])
11616 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11617 [(set (match_dup 4) (match_dup 0))
11618 (set (strict_low_part (match_dup 5))
11621 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11622 operands[5] = gen_lowpart (QImode, operands[3]);
11623 ix86_expand_clear (operands[3]);
11627 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11628 (match_operand 4)])
11629 (set (match_operand:QI 1 "register_operand")
11630 (match_operator:QI 2 "ix86_comparison_operator"
11631 [(reg FLAGS_REG) (const_int 0)]))
11632 (parallel [(set (match_operand 3 "q_regs_operand")
11633 (zero_extend (match_dup 1)))
11634 (clobber (reg:CC FLAGS_REG))])]
11635 "(peep2_reg_dead_p (3, operands[1])
11636 || operands_match_p (operands[1], operands[3]))
11637 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11638 [(parallel [(set (match_dup 5) (match_dup 0))
11640 (set (strict_low_part (match_dup 6))
11643 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11644 operands[6] = gen_lowpart (QImode, operands[3]);
11645 ix86_expand_clear (operands[3]);
11648 ;; Call instructions.
11650 ;; The predicates normally associated with named expanders are not properly
11651 ;; checked for calls. This is a bug in the generic code, but it isn't that
11652 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11654 ;; P6 processors will jump to the address after the decrement when %esp
11655 ;; is used as a call operand, so they will execute return address as a code.
11656 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11658 ;; Register constraint for call instruction.
11659 (define_mode_attr c [(SI "l") (DI "r")])
11661 ;; Call subroutine returning no value.
11663 (define_expand "call"
11664 [(call (match_operand:QI 0)
11666 (use (match_operand 2))]
11669 ix86_expand_call (NULL, operands[0], operands[1],
11670 operands[2], NULL, false);
11674 (define_expand "sibcall"
11675 [(call (match_operand:QI 0)
11677 (use (match_operand 2))]
11680 ix86_expand_call (NULL, operands[0], operands[1],
11681 operands[2], NULL, true);
11685 (define_insn "*call"
11686 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11687 (match_operand 1))]
11688 "!SIBLING_CALL_P (insn)"
11689 "* return ix86_output_call_insn (insn, operands[0]);"
11690 [(set_attr "type" "call")])
11692 (define_insn "*call_rex64_ms_sysv"
11693 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11694 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11696 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11697 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11698 "* return ix86_output_call_insn (insn, operands[0]);"
11699 [(set_attr "type" "call")])
11701 (define_insn "*sibcall"
11702 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11703 (match_operand 1))]
11704 "SIBLING_CALL_P (insn)"
11705 "* return ix86_output_call_insn (insn, operands[0]);"
11706 [(set_attr "type" "call")])
11708 (define_expand "call_pop"
11709 [(parallel [(call (match_operand:QI 0)
11710 (match_operand:SI 1))
11711 (set (reg:SI SP_REG)
11712 (plus:SI (reg:SI SP_REG)
11713 (match_operand:SI 3)))])]
11716 ix86_expand_call (NULL, operands[0], operands[1],
11717 operands[2], operands[3], false);
11721 (define_insn "*call_pop"
11722 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11724 (set (reg:SI SP_REG)
11725 (plus:SI (reg:SI SP_REG)
11726 (match_operand:SI 2 "immediate_operand" "i")))]
11727 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11728 "* return ix86_output_call_insn (insn, operands[0]);"
11729 [(set_attr "type" "call")])
11731 (define_insn "*sibcall_pop"
11732 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11734 (set (reg:SI SP_REG)
11735 (plus:SI (reg:SI SP_REG)
11736 (match_operand:SI 2 "immediate_operand" "i")))]
11737 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11738 "* return ix86_output_call_insn (insn, operands[0]);"
11739 [(set_attr "type" "call")])
11741 ;; Call subroutine, returning value in operand 0
11743 (define_expand "call_value"
11744 [(set (match_operand 0)
11745 (call (match_operand:QI 1)
11746 (match_operand 2)))
11747 (use (match_operand 3))]
11750 ix86_expand_call (operands[0], operands[1], operands[2],
11751 operands[3], NULL, false);
11755 (define_expand "sibcall_value"
11756 [(set (match_operand 0)
11757 (call (match_operand:QI 1)
11758 (match_operand 2)))
11759 (use (match_operand 3))]
11762 ix86_expand_call (operands[0], operands[1], operands[2],
11763 operands[3], NULL, true);
11767 (define_insn "*call_value"
11768 [(set (match_operand 0)
11769 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11770 (match_operand 2)))]
11771 "!SIBLING_CALL_P (insn)"
11772 "* return ix86_output_call_insn (insn, operands[1]);"
11773 [(set_attr "type" "callv")])
11775 (define_insn "*sibcall_value"
11776 [(set (match_operand 0)
11777 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11778 (match_operand 2)))]
11779 "SIBLING_CALL_P (insn)"
11780 "* return ix86_output_call_insn (insn, operands[1]);"
11781 [(set_attr "type" "callv")])
11783 (define_insn "*call_value_rex64_ms_sysv"
11784 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11785 [(set (match_operand 0)
11786 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11787 (match_operand 2)))
11788 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11789 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11790 "* return ix86_output_call_insn (insn, operands[1]);"
11791 [(set_attr "type" "callv")])
11793 (define_expand "call_value_pop"
11794 [(parallel [(set (match_operand 0)
11795 (call (match_operand:QI 1)
11796 (match_operand:SI 2)))
11797 (set (reg:SI SP_REG)
11798 (plus:SI (reg:SI SP_REG)
11799 (match_operand:SI 4)))])]
11802 ix86_expand_call (operands[0], operands[1], operands[2],
11803 operands[3], operands[4], false);
11807 (define_insn "*call_value_pop"
11808 [(set (match_operand 0)
11809 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11810 (match_operand 2)))
11811 (set (reg:SI SP_REG)
11812 (plus:SI (reg:SI SP_REG)
11813 (match_operand:SI 3 "immediate_operand" "i")))]
11814 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11815 "* return ix86_output_call_insn (insn, operands[1]);"
11816 [(set_attr "type" "callv")])
11818 (define_insn "*sibcall_value_pop"
11819 [(set (match_operand 0)
11820 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11821 (match_operand 2)))
11822 (set (reg:SI SP_REG)
11823 (plus:SI (reg:SI SP_REG)
11824 (match_operand:SI 3 "immediate_operand" "i")))]
11825 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11826 "* return ix86_output_call_insn (insn, operands[1]);"
11827 [(set_attr "type" "callv")])
11829 ;; Call subroutine returning any type.
11831 (define_expand "untyped_call"
11832 [(parallel [(call (match_operand 0)
11835 (match_operand 2)])]
11840 /* In order to give reg-stack an easier job in validating two
11841 coprocessor registers as containing a possible return value,
11842 simply pretend the untyped call returns a complex long double
11845 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11846 and should have the default ABI. */
11848 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11849 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11850 operands[0], const0_rtx,
11851 GEN_INT ((TARGET_64BIT
11852 ? (ix86_abi == SYSV_ABI
11853 ? X86_64_SSE_REGPARM_MAX
11854 : X86_64_MS_SSE_REGPARM_MAX)
11855 : X86_32_SSE_REGPARM_MAX)
11859 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11861 rtx set = XVECEXP (operands[2], 0, i);
11862 emit_move_insn (SET_DEST (set), SET_SRC (set));
11865 /* The optimizer does not know that the call sets the function value
11866 registers we stored in the result block. We avoid problems by
11867 claiming that all hard registers are used and clobbered at this
11869 emit_insn (gen_blockage ());
11874 ;; Prologue and epilogue instructions
11876 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11877 ;; all of memory. This blocks insns from being moved across this point.
11879 (define_insn "blockage"
11880 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11883 [(set_attr "length" "0")])
11885 ;; Do not schedule instructions accessing memory across this point.
11887 (define_expand "memory_blockage"
11888 [(set (match_dup 0)
11889 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11892 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11893 MEM_VOLATILE_P (operands[0]) = 1;
11896 (define_insn "*memory_blockage"
11897 [(set (match_operand:BLK 0)
11898 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11901 [(set_attr "length" "0")])
11903 ;; As USE insns aren't meaningful after reload, this is used instead
11904 ;; to prevent deleting instructions setting registers for PIC code
11905 (define_insn "prologue_use"
11906 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11909 [(set_attr "length" "0")])
11911 ;; Insn emitted into the body of a function to return from a function.
11912 ;; This is only done if the function's epilogue is known to be simple.
11913 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11915 (define_expand "return"
11917 "ix86_can_use_return_insn_p ()"
11919 if (crtl->args.pops_args)
11921 rtx popc = GEN_INT (crtl->args.pops_args);
11922 emit_jump_insn (gen_simple_return_pop_internal (popc));
11927 ;; We need to disable this for TARGET_SEH, as otherwise
11928 ;; shrink-wrapped prologue gets enabled too. This might exceed
11929 ;; the maximum size of prologue in unwind information.
11931 (define_expand "simple_return"
11935 if (crtl->args.pops_args)
11937 rtx popc = GEN_INT (crtl->args.pops_args);
11938 emit_jump_insn (gen_simple_return_pop_internal (popc));
11943 (define_insn "simple_return_internal"
11947 [(set_attr "length" "1")
11948 (set_attr "atom_unit" "jeu")
11949 (set_attr "length_immediate" "0")
11950 (set_attr "modrm" "0")])
11952 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11953 ;; instruction Athlon and K8 have.
11955 (define_insn "simple_return_internal_long"
11957 (unspec [(const_int 0)] UNSPEC_REP)]
11960 [(set_attr "length" "2")
11961 (set_attr "atom_unit" "jeu")
11962 (set_attr "length_immediate" "0")
11963 (set_attr "prefix_rep" "1")
11964 (set_attr "modrm" "0")])
11966 (define_insn "simple_return_pop_internal"
11968 (use (match_operand:SI 0 "const_int_operand"))]
11971 [(set_attr "length" "3")
11972 (set_attr "atom_unit" "jeu")
11973 (set_attr "length_immediate" "2")
11974 (set_attr "modrm" "0")])
11976 (define_insn "simple_return_indirect_internal"
11978 (use (match_operand:SI 0 "register_operand" "r"))]
11981 [(set_attr "type" "ibr")
11982 (set_attr "length_immediate" "0")])
11988 [(set_attr "length" "1")
11989 (set_attr "length_immediate" "0")
11990 (set_attr "modrm" "0")])
11992 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11993 (define_insn "nops"
11994 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11998 int num = INTVAL (operands[0]);
12000 gcc_assert (IN_RANGE (num, 1, 8));
12003 fputs ("\tnop\n", asm_out_file);
12007 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12008 (set_attr "length_immediate" "0")
12009 (set_attr "modrm" "0")])
12011 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12012 ;; branch prediction penalty for the third jump in a 16-byte
12016 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12019 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12020 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12022 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12023 The align insn is used to avoid 3 jump instructions in the row to improve
12024 branch prediction and the benefits hardly outweigh the cost of extra 8
12025 nops on the average inserted by full alignment pseudo operation. */
12029 [(set_attr "length" "16")])
12031 (define_expand "prologue"
12034 "ix86_expand_prologue (); DONE;")
12036 (define_insn "set_got"
12037 [(set (match_operand:SI 0 "register_operand" "=r")
12038 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12039 (clobber (reg:CC FLAGS_REG))]
12041 "* return output_set_got (operands[0], NULL_RTX);"
12042 [(set_attr "type" "multi")
12043 (set_attr "length" "12")])
12045 (define_insn "set_got_labelled"
12046 [(set (match_operand:SI 0 "register_operand" "=r")
12047 (unspec:SI [(label_ref (match_operand 1))]
12049 (clobber (reg:CC FLAGS_REG))]
12051 "* return output_set_got (operands[0], operands[1]);"
12052 [(set_attr "type" "multi")
12053 (set_attr "length" "12")])
12055 (define_insn "set_got_rex64"
12056 [(set (match_operand:DI 0 "register_operand" "=r")
12057 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12059 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12060 [(set_attr "type" "lea")
12061 (set_attr "length_address" "4")
12062 (set_attr "mode" "DI")])
12064 (define_insn "set_rip_rex64"
12065 [(set (match_operand:DI 0 "register_operand" "=r")
12066 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12068 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12069 [(set_attr "type" "lea")
12070 (set_attr "length_address" "4")
12071 (set_attr "mode" "DI")])
12073 (define_insn "set_got_offset_rex64"
12074 [(set (match_operand:DI 0 "register_operand" "=r")
12076 [(label_ref (match_operand 1))]
12077 UNSPEC_SET_GOT_OFFSET))]
12079 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12080 [(set_attr "type" "imov")
12081 (set_attr "length_immediate" "0")
12082 (set_attr "length_address" "8")
12083 (set_attr "mode" "DI")])
12085 (define_expand "epilogue"
12088 "ix86_expand_epilogue (1); DONE;")
12090 (define_expand "sibcall_epilogue"
12093 "ix86_expand_epilogue (0); DONE;")
12095 (define_expand "eh_return"
12096 [(use (match_operand 0 "register_operand"))]
12099 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12101 /* Tricky bit: we write the address of the handler to which we will
12102 be returning into someone else's stack frame, one word below the
12103 stack address we wish to restore. */
12104 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12105 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12106 tmp = gen_rtx_MEM (Pmode, tmp);
12107 emit_move_insn (tmp, ra);
12109 emit_jump_insn (gen_eh_return_internal ());
12114 (define_insn_and_split "eh_return_internal"
12118 "epilogue_completed"
12120 "ix86_expand_epilogue (2); DONE;")
12122 (define_insn "leave"
12123 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12124 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12125 (clobber (mem:BLK (scratch)))]
12128 [(set_attr "type" "leave")])
12130 (define_insn "leave_rex64"
12131 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12132 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12133 (clobber (mem:BLK (scratch)))]
12136 [(set_attr "type" "leave")])
12138 ;; Handle -fsplit-stack.
12140 (define_expand "split_stack_prologue"
12144 ix86_expand_split_stack_prologue ();
12148 ;; In order to support the call/return predictor, we use a return
12149 ;; instruction which the middle-end doesn't see.
12150 (define_insn "split_stack_return"
12151 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12152 UNSPECV_SPLIT_STACK_RETURN)]
12155 if (operands[0] == const0_rtx)
12160 [(set_attr "atom_unit" "jeu")
12161 (set_attr "modrm" "0")
12162 (set (attr "length")
12163 (if_then_else (match_operand:SI 0 "const0_operand")
12166 (set (attr "length_immediate")
12167 (if_then_else (match_operand:SI 0 "const0_operand")
12171 ;; If there are operand 0 bytes available on the stack, jump to
12174 (define_expand "split_stack_space_check"
12175 [(set (pc) (if_then_else
12176 (ltu (minus (reg SP_REG)
12177 (match_operand 0 "register_operand"))
12178 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12179 (label_ref (match_operand 1))
12183 rtx reg, size, limit;
12185 reg = gen_reg_rtx (Pmode);
12186 size = force_reg (Pmode, operands[0]);
12187 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12188 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12189 UNSPEC_STACK_CHECK);
12190 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12191 ix86_expand_branch (GEU, reg, limit, operands[1]);
12196 ;; Bit manipulation instructions.
12198 (define_expand "ffs<mode>2"
12199 [(set (match_dup 2) (const_int -1))
12200 (parallel [(set (match_dup 3) (match_dup 4))
12201 (set (match_operand:SWI48 0 "register_operand")
12203 (match_operand:SWI48 1 "nonimmediate_operand")))])
12204 (set (match_dup 0) (if_then_else:SWI48
12205 (eq (match_dup 3) (const_int 0))
12208 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12209 (clobber (reg:CC FLAGS_REG))])]
12212 enum machine_mode flags_mode;
12214 if (<MODE>mode == SImode && !TARGET_CMOVE)
12216 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12220 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12222 operands[2] = gen_reg_rtx (<MODE>mode);
12223 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12224 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12227 (define_insn_and_split "ffssi2_no_cmove"
12228 [(set (match_operand:SI 0 "register_operand" "=r")
12229 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12230 (clobber (match_scratch:SI 2 "=&q"))
12231 (clobber (reg:CC FLAGS_REG))]
12234 "&& reload_completed"
12235 [(parallel [(set (match_dup 4) (match_dup 5))
12236 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12237 (set (strict_low_part (match_dup 3))
12238 (eq:QI (match_dup 4) (const_int 0)))
12239 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12240 (clobber (reg:CC FLAGS_REG))])
12241 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12242 (clobber (reg:CC FLAGS_REG))])
12243 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12244 (clobber (reg:CC FLAGS_REG))])]
12246 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12248 operands[3] = gen_lowpart (QImode, operands[2]);
12249 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12250 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12252 ix86_expand_clear (operands[2]);
12255 (define_insn "*tzcnt<mode>_1"
12256 [(set (reg:CCC FLAGS_REG)
12257 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12259 (set (match_operand:SWI48 0 "register_operand" "=r")
12260 (ctz:SWI48 (match_dup 1)))]
12262 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12263 [(set_attr "type" "alu1")
12264 (set_attr "prefix_0f" "1")
12265 (set_attr "prefix_rep" "1")
12266 (set_attr "btver2_decode" "double")
12267 (set_attr "mode" "<MODE>")])
12269 (define_insn "*bsf<mode>_1"
12270 [(set (reg:CCZ FLAGS_REG)
12271 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12273 (set (match_operand:SWI48 0 "register_operand" "=r")
12274 (ctz:SWI48 (match_dup 1)))]
12276 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12277 [(set_attr "type" "alu1")
12278 (set_attr "prefix_0f" "1")
12279 (set_attr "btver2_decode" "double")
12280 (set_attr "mode" "<MODE>")])
12282 (define_insn "ctz<mode>2"
12283 [(set (match_operand:SWI248 0 "register_operand" "=r")
12284 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12285 (clobber (reg:CC FLAGS_REG))]
12289 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12290 else if (optimize_function_for_size_p (cfun))
12292 else if (TARGET_GENERIC)
12293 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12294 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12296 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12298 [(set_attr "type" "alu1")
12299 (set_attr "prefix_0f" "1")
12300 (set (attr "prefix_rep")
12302 (ior (match_test "TARGET_BMI")
12303 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12304 (match_test "TARGET_GENERIC")))
12306 (const_string "0")))
12307 (set_attr "mode" "<MODE>")])
12309 (define_expand "clz<mode>2"
12311 [(set (match_operand:SWI248 0 "register_operand")
12314 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12315 (clobber (reg:CC FLAGS_REG))])
12317 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12318 (clobber (reg:CC FLAGS_REG))])]
12323 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12326 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12329 (define_insn "clz<mode>2_lzcnt"
12330 [(set (match_operand:SWI248 0 "register_operand" "=r")
12331 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12332 (clobber (reg:CC FLAGS_REG))]
12334 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12335 [(set_attr "prefix_rep" "1")
12336 (set_attr "type" "bitmanip")
12337 (set_attr "mode" "<MODE>")])
12339 ;; BMI instructions.
12340 (define_insn "*bmi_andn_<mode>"
12341 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12344 (match_operand:SWI48 1 "register_operand" "r,r"))
12345 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12346 (clobber (reg:CC FLAGS_REG))]
12348 "andn\t{%2, %1, %0|%0, %1, %2}"
12349 [(set_attr "type" "bitmanip")
12350 (set_attr "btver2_decode" "direct, double")
12351 (set_attr "mode" "<MODE>")])
12353 (define_insn "bmi_bextr_<mode>"
12354 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12355 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12356 (match_operand:SWI48 2 "register_operand" "r,r")]
12358 (clobber (reg:CC FLAGS_REG))]
12360 "bextr\t{%2, %1, %0|%0, %1, %2}"
12361 [(set_attr "type" "bitmanip")
12362 (set_attr "btver2_decode" "direct, double")
12363 (set_attr "mode" "<MODE>")])
12365 (define_insn "*bmi_blsi_<mode>"
12366 [(set (match_operand:SWI48 0 "register_operand" "=r")
12369 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12371 (clobber (reg:CC FLAGS_REG))]
12373 "blsi\t{%1, %0|%0, %1}"
12374 [(set_attr "type" "bitmanip")
12375 (set_attr "btver2_decode" "double")
12376 (set_attr "mode" "<MODE>")])
12378 (define_insn "*bmi_blsmsk_<mode>"
12379 [(set (match_operand:SWI48 0 "register_operand" "=r")
12382 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12385 (clobber (reg:CC FLAGS_REG))]
12387 "blsmsk\t{%1, %0|%0, %1}"
12388 [(set_attr "type" "bitmanip")
12389 (set_attr "btver2_decode" "double")
12390 (set_attr "mode" "<MODE>")])
12392 (define_insn "*bmi_blsr_<mode>"
12393 [(set (match_operand:SWI48 0 "register_operand" "=r")
12396 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12399 (clobber (reg:CC FLAGS_REG))]
12401 "blsr\t{%1, %0|%0, %1}"
12402 [(set_attr "type" "bitmanip")
12403 (set_attr "btver2_decode" "double")
12404 (set_attr "mode" "<MODE>")])
12406 ;; BMI2 instructions.
12407 (define_insn "bmi2_bzhi_<mode>3"
12408 [(set (match_operand:SWI48 0 "register_operand" "=r")
12409 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12410 (match_operand:SWI48 2 "register_operand" "r"))
12411 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12412 (clobber (reg:CC FLAGS_REG))]
12414 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12415 [(set_attr "type" "bitmanip")
12416 (set_attr "prefix" "vex")
12417 (set_attr "mode" "<MODE>")])
12419 (define_insn "bmi2_pdep_<mode>3"
12420 [(set (match_operand:SWI48 0 "register_operand" "=r")
12421 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12422 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12425 "pdep\t{%2, %1, %0|%0, %1, %2}"
12426 [(set_attr "type" "bitmanip")
12427 (set_attr "prefix" "vex")
12428 (set_attr "mode" "<MODE>")])
12430 (define_insn "bmi2_pext_<mode>3"
12431 [(set (match_operand:SWI48 0 "register_operand" "=r")
12432 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12433 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12436 "pext\t{%2, %1, %0|%0, %1, %2}"
12437 [(set_attr "type" "bitmanip")
12438 (set_attr "prefix" "vex")
12439 (set_attr "mode" "<MODE>")])
12441 ;; TBM instructions.
12442 (define_insn "tbm_bextri_<mode>"
12443 [(set (match_operand:SWI48 0 "register_operand" "=r")
12444 (zero_extract:SWI48
12445 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12446 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12447 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12448 (clobber (reg:CC FLAGS_REG))]
12451 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12452 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12454 [(set_attr "type" "bitmanip")
12455 (set_attr "mode" "<MODE>")])
12457 (define_insn "*tbm_blcfill_<mode>"
12458 [(set (match_operand:SWI48 0 "register_operand" "=r")
12461 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12464 (clobber (reg:CC FLAGS_REG))]
12466 "blcfill\t{%1, %0|%0, %1}"
12467 [(set_attr "type" "bitmanip")
12468 (set_attr "mode" "<MODE>")])
12470 (define_insn "*tbm_blci_<mode>"
12471 [(set (match_operand:SWI48 0 "register_operand" "=r")
12475 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12478 (clobber (reg:CC FLAGS_REG))]
12480 "blci\t{%1, %0|%0, %1}"
12481 [(set_attr "type" "bitmanip")
12482 (set_attr "mode" "<MODE>")])
12484 (define_insn "*tbm_blcic_<mode>"
12485 [(set (match_operand:SWI48 0 "register_operand" "=r")
12488 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12492 (clobber (reg:CC FLAGS_REG))]
12494 "blcic\t{%1, %0|%0, %1}"
12495 [(set_attr "type" "bitmanip")
12496 (set_attr "mode" "<MODE>")])
12498 (define_insn "*tbm_blcmsk_<mode>"
12499 [(set (match_operand:SWI48 0 "register_operand" "=r")
12502 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12505 (clobber (reg:CC FLAGS_REG))]
12507 "blcmsk\t{%1, %0|%0, %1}"
12508 [(set_attr "type" "bitmanip")
12509 (set_attr "mode" "<MODE>")])
12511 (define_insn "*tbm_blcs_<mode>"
12512 [(set (match_operand:SWI48 0 "register_operand" "=r")
12515 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12518 (clobber (reg:CC FLAGS_REG))]
12520 "blcs\t{%1, %0|%0, %1}"
12521 [(set_attr "type" "bitmanip")
12522 (set_attr "mode" "<MODE>")])
12524 (define_insn "*tbm_blsfill_<mode>"
12525 [(set (match_operand:SWI48 0 "register_operand" "=r")
12528 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12531 (clobber (reg:CC FLAGS_REG))]
12533 "blsfill\t{%1, %0|%0, %1}"
12534 [(set_attr "type" "bitmanip")
12535 (set_attr "mode" "<MODE>")])
12537 (define_insn "*tbm_blsic_<mode>"
12538 [(set (match_operand:SWI48 0 "register_operand" "=r")
12541 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12545 (clobber (reg:CC FLAGS_REG))]
12547 "blsic\t{%1, %0|%0, %1}"
12548 [(set_attr "type" "bitmanip")
12549 (set_attr "mode" "<MODE>")])
12551 (define_insn "*tbm_t1mskc_<mode>"
12552 [(set (match_operand:SWI48 0 "register_operand" "=r")
12555 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12559 (clobber (reg:CC FLAGS_REG))]
12561 "t1mskc\t{%1, %0|%0, %1}"
12562 [(set_attr "type" "bitmanip")
12563 (set_attr "mode" "<MODE>")])
12565 (define_insn "*tbm_tzmsk_<mode>"
12566 [(set (match_operand:SWI48 0 "register_operand" "=r")
12569 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12573 (clobber (reg:CC FLAGS_REG))]
12575 "tzmsk\t{%1, %0|%0, %1}"
12576 [(set_attr "type" "bitmanip")
12577 (set_attr "mode" "<MODE>")])
12579 (define_insn "bsr_rex64"
12580 [(set (match_operand:DI 0 "register_operand" "=r")
12581 (minus:DI (const_int 63)
12582 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12583 (clobber (reg:CC FLAGS_REG))]
12585 "bsr{q}\t{%1, %0|%0, %1}"
12586 [(set_attr "type" "alu1")
12587 (set_attr "prefix_0f" "1")
12588 (set_attr "mode" "DI")])
12591 [(set (match_operand:SI 0 "register_operand" "=r")
12592 (minus:SI (const_int 31)
12593 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12594 (clobber (reg:CC FLAGS_REG))]
12596 "bsr{l}\t{%1, %0|%0, %1}"
12597 [(set_attr "type" "alu1")
12598 (set_attr "prefix_0f" "1")
12599 (set_attr "mode" "SI")])
12601 (define_insn "*bsrhi"
12602 [(set (match_operand:HI 0 "register_operand" "=r")
12603 (minus:HI (const_int 15)
12604 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12605 (clobber (reg:CC FLAGS_REG))]
12607 "bsr{w}\t{%1, %0|%0, %1}"
12608 [(set_attr "type" "alu1")
12609 (set_attr "prefix_0f" "1")
12610 (set_attr "mode" "HI")])
12612 (define_insn "popcount<mode>2"
12613 [(set (match_operand:SWI248 0 "register_operand" "=r")
12615 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12616 (clobber (reg:CC FLAGS_REG))]
12620 return "popcnt\t{%1, %0|%0, %1}";
12622 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12625 [(set_attr "prefix_rep" "1")
12626 (set_attr "type" "bitmanip")
12627 (set_attr "mode" "<MODE>")])
12629 (define_insn "*popcount<mode>2_cmp"
12630 [(set (reg FLAGS_REG)
12633 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12635 (set (match_operand:SWI248 0 "register_operand" "=r")
12636 (popcount:SWI248 (match_dup 1)))]
12637 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12640 return "popcnt\t{%1, %0|%0, %1}";
12642 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12645 [(set_attr "prefix_rep" "1")
12646 (set_attr "type" "bitmanip")
12647 (set_attr "mode" "<MODE>")])
12649 (define_insn "*popcountsi2_cmp_zext"
12650 [(set (reg FLAGS_REG)
12652 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12654 (set (match_operand:DI 0 "register_operand" "=r")
12655 (zero_extend:DI(popcount:SI (match_dup 1))))]
12656 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12659 return "popcnt\t{%1, %0|%0, %1}";
12661 return "popcnt{l}\t{%1, %0|%0, %1}";
12664 [(set_attr "prefix_rep" "1")
12665 (set_attr "type" "bitmanip")
12666 (set_attr "mode" "SI")])
12668 (define_expand "bswapdi2"
12669 [(set (match_operand:DI 0 "register_operand")
12670 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12674 operands[1] = force_reg (DImode, operands[1]);
12677 (define_expand "bswapsi2"
12678 [(set (match_operand:SI 0 "register_operand")
12679 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12684 else if (TARGET_BSWAP)
12685 operands[1] = force_reg (SImode, operands[1]);
12688 rtx x = operands[0];
12690 emit_move_insn (x, operands[1]);
12691 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12692 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12693 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12698 (define_insn "*bswap<mode>2_movbe"
12699 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12700 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12702 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12705 movbe\t{%1, %0|%0, %1}
12706 movbe\t{%1, %0|%0, %1}"
12707 [(set_attr "type" "bitmanip,imov,imov")
12708 (set_attr "modrm" "0,1,1")
12709 (set_attr "prefix_0f" "*,1,1")
12710 (set_attr "prefix_extra" "*,1,1")
12711 (set_attr "mode" "<MODE>")])
12713 (define_insn "*bswap<mode>2"
12714 [(set (match_operand:SWI48 0 "register_operand" "=r")
12715 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12718 [(set_attr "type" "bitmanip")
12719 (set_attr "modrm" "0")
12720 (set_attr "mode" "<MODE>")])
12722 (define_insn "*bswaphi_lowpart_1"
12723 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12724 (bswap:HI (match_dup 0)))
12725 (clobber (reg:CC FLAGS_REG))]
12726 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12728 xchg{b}\t{%h0, %b0|%b0, %h0}
12729 rol{w}\t{$8, %0|%0, 8}"
12730 [(set_attr "length" "2,4")
12731 (set_attr "mode" "QI,HI")])
12733 (define_insn "bswaphi_lowpart"
12734 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12735 (bswap:HI (match_dup 0)))
12736 (clobber (reg:CC FLAGS_REG))]
12738 "rol{w}\t{$8, %0|%0, 8}"
12739 [(set_attr "length" "4")
12740 (set_attr "mode" "HI")])
12742 (define_expand "paritydi2"
12743 [(set (match_operand:DI 0 "register_operand")
12744 (parity:DI (match_operand:DI 1 "register_operand")))]
12747 rtx scratch = gen_reg_rtx (QImode);
12750 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12751 NULL_RTX, operands[1]));
12753 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12754 gen_rtx_REG (CCmode, FLAGS_REG),
12756 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12759 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12762 rtx tmp = gen_reg_rtx (SImode);
12764 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12765 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12770 (define_expand "paritysi2"
12771 [(set (match_operand:SI 0 "register_operand")
12772 (parity:SI (match_operand:SI 1 "register_operand")))]
12775 rtx scratch = gen_reg_rtx (QImode);
12778 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12780 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12781 gen_rtx_REG (CCmode, FLAGS_REG),
12783 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12785 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12789 (define_insn_and_split "paritydi2_cmp"
12790 [(set (reg:CC FLAGS_REG)
12791 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12793 (clobber (match_scratch:DI 0 "=r"))
12794 (clobber (match_scratch:SI 1 "=&r"))
12795 (clobber (match_scratch:HI 2 "=Q"))]
12798 "&& reload_completed"
12800 [(set (match_dup 1)
12801 (xor:SI (match_dup 1) (match_dup 4)))
12802 (clobber (reg:CC FLAGS_REG))])
12804 [(set (reg:CC FLAGS_REG)
12805 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12806 (clobber (match_dup 1))
12807 (clobber (match_dup 2))])]
12809 operands[4] = gen_lowpart (SImode, operands[3]);
12813 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12814 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12817 operands[1] = gen_highpart (SImode, operands[3]);
12820 (define_insn_and_split "paritysi2_cmp"
12821 [(set (reg:CC FLAGS_REG)
12822 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12824 (clobber (match_scratch:SI 0 "=r"))
12825 (clobber (match_scratch:HI 1 "=&Q"))]
12828 "&& reload_completed"
12830 [(set (match_dup 1)
12831 (xor:HI (match_dup 1) (match_dup 3)))
12832 (clobber (reg:CC FLAGS_REG))])
12834 [(set (reg:CC FLAGS_REG)
12835 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12836 (clobber (match_dup 1))])]
12838 operands[3] = gen_lowpart (HImode, operands[2]);
12840 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12841 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12844 (define_insn "*parityhi2_cmp"
12845 [(set (reg:CC FLAGS_REG)
12846 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12848 (clobber (match_scratch:HI 0 "=Q"))]
12850 "xor{b}\t{%h0, %b0|%b0, %h0}"
12851 [(set_attr "length" "2")
12852 (set_attr "mode" "HI")])
12855 ;; Thread-local storage patterns for ELF.
12857 ;; Note that these code sequences must appear exactly as shown
12858 ;; in order to allow linker relaxation.
12860 (define_insn "*tls_global_dynamic_32_gnu"
12861 [(set (match_operand:SI 0 "register_operand" "=a")
12863 [(match_operand:SI 1 "register_operand" "b")
12864 (match_operand 2 "tls_symbolic_operand")
12865 (match_operand 3 "constant_call_address_operand" "z")]
12867 (clobber (match_scratch:SI 4 "=d"))
12868 (clobber (match_scratch:SI 5 "=c"))
12869 (clobber (reg:CC FLAGS_REG))]
12870 "!TARGET_64BIT && TARGET_GNU_TLS"
12873 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12874 if (TARGET_SUN_TLS)
12875 #ifdef HAVE_AS_IX86_TLSGDPLT
12876 return "call\t%a2@tlsgdplt";
12878 return "call\t%p3@plt";
12880 return "call\t%P3";
12882 [(set_attr "type" "multi")
12883 (set_attr "length" "12")])
12885 (define_expand "tls_global_dynamic_32"
12887 [(set (match_operand:SI 0 "register_operand")
12888 (unspec:SI [(match_operand:SI 2 "register_operand")
12889 (match_operand 1 "tls_symbolic_operand")
12890 (match_operand 3 "constant_call_address_operand")]
12892 (clobber (match_scratch:SI 4))
12893 (clobber (match_scratch:SI 5))
12894 (clobber (reg:CC FLAGS_REG))])])
12896 (define_insn "*tls_global_dynamic_64_<mode>"
12897 [(set (match_operand:P 0 "register_operand" "=a")
12899 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12900 (match_operand 3)))
12901 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12906 fputs (ASM_BYTE "0x66\n", asm_out_file);
12908 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12909 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12910 fputs ("\trex64\n", asm_out_file);
12911 if (TARGET_SUN_TLS)
12912 return "call\t%p2@plt";
12913 return "call\t%P2";
12915 [(set_attr "type" "multi")
12916 (set (attr "length")
12917 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12919 (define_insn "*tls_global_dynamic_64_largepic"
12920 [(set (match_operand:DI 0 "register_operand" "=a")
12922 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12923 (match_operand:DI 3 "immediate_operand" "i")))
12924 (match_operand 4)))
12925 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12927 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12928 && GET_CODE (operands[3]) == CONST
12929 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12930 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12933 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12934 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12935 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12936 return "call\t{*%%rax|rax}";
12938 [(set_attr "type" "multi")
12939 (set_attr "length" "22")])
12941 (define_expand "tls_global_dynamic_64_<mode>"
12943 [(set (match_operand:P 0 "register_operand")
12945 (mem:QI (match_operand 2))
12947 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12951 (define_insn "*tls_local_dynamic_base_32_gnu"
12952 [(set (match_operand:SI 0 "register_operand" "=a")
12954 [(match_operand:SI 1 "register_operand" "b")
12955 (match_operand 2 "constant_call_address_operand" "z")]
12956 UNSPEC_TLS_LD_BASE))
12957 (clobber (match_scratch:SI 3 "=d"))
12958 (clobber (match_scratch:SI 4 "=c"))
12959 (clobber (reg:CC FLAGS_REG))]
12960 "!TARGET_64BIT && TARGET_GNU_TLS"
12963 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12964 if (TARGET_SUN_TLS)
12966 if (HAVE_AS_IX86_TLSLDMPLT)
12967 return "call\t%&@tlsldmplt";
12969 return "call\t%p2@plt";
12971 return "call\t%P2";
12973 [(set_attr "type" "multi")
12974 (set_attr "length" "11")])
12976 (define_expand "tls_local_dynamic_base_32"
12978 [(set (match_operand:SI 0 "register_operand")
12980 [(match_operand:SI 1 "register_operand")
12981 (match_operand 2 "constant_call_address_operand")]
12982 UNSPEC_TLS_LD_BASE))
12983 (clobber (match_scratch:SI 3))
12984 (clobber (match_scratch:SI 4))
12985 (clobber (reg:CC FLAGS_REG))])])
12987 (define_insn "*tls_local_dynamic_base_64_<mode>"
12988 [(set (match_operand:P 0 "register_operand" "=a")
12990 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12991 (match_operand 2)))
12992 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12996 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12997 if (TARGET_SUN_TLS)
12998 return "call\t%p1@plt";
12999 return "call\t%P1";
13001 [(set_attr "type" "multi")
13002 (set_attr "length" "12")])
13004 (define_insn "*tls_local_dynamic_base_64_largepic"
13005 [(set (match_operand:DI 0 "register_operand" "=a")
13007 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13008 (match_operand:DI 2 "immediate_operand" "i")))
13009 (match_operand 3)))
13010 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13011 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13012 && GET_CODE (operands[2]) == CONST
13013 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13014 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13017 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13018 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13019 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13020 return "call\t{*%%rax|rax}";
13022 [(set_attr "type" "multi")
13023 (set_attr "length" "22")])
13025 (define_expand "tls_local_dynamic_base_64_<mode>"
13027 [(set (match_operand:P 0 "register_operand")
13029 (mem:QI (match_operand 1))
13031 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13034 ;; Local dynamic of a single variable is a lose. Show combine how
13035 ;; to convert that back to global dynamic.
13037 (define_insn_and_split "*tls_local_dynamic_32_once"
13038 [(set (match_operand:SI 0 "register_operand" "=a")
13040 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13041 (match_operand 2 "constant_call_address_operand" "z")]
13042 UNSPEC_TLS_LD_BASE)
13043 (const:SI (unspec:SI
13044 [(match_operand 3 "tls_symbolic_operand")]
13046 (clobber (match_scratch:SI 4 "=d"))
13047 (clobber (match_scratch:SI 5 "=c"))
13048 (clobber (reg:CC FLAGS_REG))]
13053 [(set (match_dup 0)
13054 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13056 (clobber (match_dup 4))
13057 (clobber (match_dup 5))
13058 (clobber (reg:CC FLAGS_REG))])])
13060 ;; Segment register for the thread base ptr load
13061 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13063 ;; Load and add the thread base pointer from %<tp_seg>:0.
13064 (define_insn "*load_tp_x32"
13065 [(set (match_operand:SI 0 "register_operand" "=r")
13066 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13068 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13069 [(set_attr "type" "imov")
13070 (set_attr "modrm" "0")
13071 (set_attr "length" "7")
13072 (set_attr "memory" "load")
13073 (set_attr "imm_disp" "false")])
13075 (define_insn "*load_tp_x32_zext"
13076 [(set (match_operand:DI 0 "register_operand" "=r")
13077 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13079 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13080 [(set_attr "type" "imov")
13081 (set_attr "modrm" "0")
13082 (set_attr "length" "7")
13083 (set_attr "memory" "load")
13084 (set_attr "imm_disp" "false")])
13086 (define_insn "*load_tp_<mode>"
13087 [(set (match_operand:P 0 "register_operand" "=r")
13088 (unspec:P [(const_int 0)] UNSPEC_TP))]
13090 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13091 [(set_attr "type" "imov")
13092 (set_attr "modrm" "0")
13093 (set_attr "length" "7")
13094 (set_attr "memory" "load")
13095 (set_attr "imm_disp" "false")])
13097 (define_insn "*add_tp_x32"
13098 [(set (match_operand:SI 0 "register_operand" "=r")
13099 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13100 (match_operand:SI 1 "register_operand" "0")))
13101 (clobber (reg:CC FLAGS_REG))]
13103 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13104 [(set_attr "type" "alu")
13105 (set_attr "modrm" "0")
13106 (set_attr "length" "7")
13107 (set_attr "memory" "load")
13108 (set_attr "imm_disp" "false")])
13110 (define_insn "*add_tp_x32_zext"
13111 [(set (match_operand:DI 0 "register_operand" "=r")
13113 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13114 (match_operand:SI 1 "register_operand" "0"))))
13115 (clobber (reg:CC FLAGS_REG))]
13117 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13118 [(set_attr "type" "alu")
13119 (set_attr "modrm" "0")
13120 (set_attr "length" "7")
13121 (set_attr "memory" "load")
13122 (set_attr "imm_disp" "false")])
13124 (define_insn "*add_tp_<mode>"
13125 [(set (match_operand:P 0 "register_operand" "=r")
13126 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13127 (match_operand:P 1 "register_operand" "0")))
13128 (clobber (reg:CC FLAGS_REG))]
13130 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13131 [(set_attr "type" "alu")
13132 (set_attr "modrm" "0")
13133 (set_attr "length" "7")
13134 (set_attr "memory" "load")
13135 (set_attr "imm_disp" "false")])
13137 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13138 ;; %rax as destination of the initial executable code sequence.
13139 (define_insn "tls_initial_exec_64_sun"
13140 [(set (match_operand:DI 0 "register_operand" "=a")
13142 [(match_operand 1 "tls_symbolic_operand")]
13143 UNSPEC_TLS_IE_SUN))
13144 (clobber (reg:CC FLAGS_REG))]
13145 "TARGET_64BIT && TARGET_SUN_TLS"
13148 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13149 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13151 [(set_attr "type" "multi")])
13153 ;; GNU2 TLS patterns can be split.
13155 (define_expand "tls_dynamic_gnu2_32"
13156 [(set (match_dup 3)
13157 (plus:SI (match_operand:SI 2 "register_operand")
13159 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13162 [(set (match_operand:SI 0 "register_operand")
13163 (unspec:SI [(match_dup 1) (match_dup 3)
13164 (match_dup 2) (reg:SI SP_REG)]
13166 (clobber (reg:CC FLAGS_REG))])]
13167 "!TARGET_64BIT && TARGET_GNU2_TLS"
13169 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13170 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13173 (define_insn "*tls_dynamic_gnu2_lea_32"
13174 [(set (match_operand:SI 0 "register_operand" "=r")
13175 (plus:SI (match_operand:SI 1 "register_operand" "b")
13177 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13178 UNSPEC_TLSDESC))))]
13179 "!TARGET_64BIT && TARGET_GNU2_TLS"
13180 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13181 [(set_attr "type" "lea")
13182 (set_attr "mode" "SI")
13183 (set_attr "length" "6")
13184 (set_attr "length_address" "4")])
13186 (define_insn "*tls_dynamic_gnu2_call_32"
13187 [(set (match_operand:SI 0 "register_operand" "=a")
13188 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13189 (match_operand:SI 2 "register_operand" "0")
13190 ;; we have to make sure %ebx still points to the GOT
13191 (match_operand:SI 3 "register_operand" "b")
13194 (clobber (reg:CC FLAGS_REG))]
13195 "!TARGET_64BIT && TARGET_GNU2_TLS"
13196 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13197 [(set_attr "type" "call")
13198 (set_attr "length" "2")
13199 (set_attr "length_address" "0")])
13201 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13202 [(set (match_operand:SI 0 "register_operand" "=&a")
13204 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13205 (match_operand:SI 4)
13206 (match_operand:SI 2 "register_operand" "b")
13209 (const:SI (unspec:SI
13210 [(match_operand 1 "tls_symbolic_operand")]
13212 (clobber (reg:CC FLAGS_REG))]
13213 "!TARGET_64BIT && TARGET_GNU2_TLS"
13216 [(set (match_dup 0) (match_dup 5))]
13218 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13219 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13222 (define_expand "tls_dynamic_gnu2_64"
13223 [(set (match_dup 2)
13224 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13227 [(set (match_operand:DI 0 "register_operand")
13228 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13230 (clobber (reg:CC FLAGS_REG))])]
13231 "TARGET_64BIT && TARGET_GNU2_TLS"
13233 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13234 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13237 (define_insn "*tls_dynamic_gnu2_lea_64"
13238 [(set (match_operand:DI 0 "register_operand" "=r")
13239 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13241 "TARGET_64BIT && TARGET_GNU2_TLS"
13242 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13243 [(set_attr "type" "lea")
13244 (set_attr "mode" "DI")
13245 (set_attr "length" "7")
13246 (set_attr "length_address" "4")])
13248 (define_insn "*tls_dynamic_gnu2_call_64"
13249 [(set (match_operand:DI 0 "register_operand" "=a")
13250 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13251 (match_operand:DI 2 "register_operand" "0")
13254 (clobber (reg:CC FLAGS_REG))]
13255 "TARGET_64BIT && TARGET_GNU2_TLS"
13256 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13257 [(set_attr "type" "call")
13258 (set_attr "length" "2")
13259 (set_attr "length_address" "0")])
13261 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13262 [(set (match_operand:DI 0 "register_operand" "=&a")
13264 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13265 (match_operand:DI 3)
13268 (const:DI (unspec:DI
13269 [(match_operand 1 "tls_symbolic_operand")]
13271 (clobber (reg:CC FLAGS_REG))]
13272 "TARGET_64BIT && TARGET_GNU2_TLS"
13275 [(set (match_dup 0) (match_dup 4))]
13277 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13278 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13281 ;; These patterns match the binary 387 instructions for addM3, subM3,
13282 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13283 ;; SFmode. The first is the normal insn, the second the same insn but
13284 ;; with one operand a conversion, and the third the same insn but with
13285 ;; the other operand a conversion. The conversion may be SFmode or
13286 ;; SImode if the target mode DFmode, but only SImode if the target mode
13289 ;; Gcc is slightly more smart about handling normal two address instructions
13290 ;; so use special patterns for add and mull.
13292 (define_insn "*fop_<mode>_comm_mixed"
13293 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13294 (match_operator:MODEF 3 "binary_fp_operator"
13295 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13296 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13297 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13298 && COMMUTATIVE_ARITH_P (operands[3])
13299 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13300 "* return output_387_binary_op (insn, operands);"
13301 [(set (attr "type")
13302 (if_then_else (eq_attr "alternative" "1,2")
13303 (if_then_else (match_operand:MODEF 3 "mult_operator")
13304 (const_string "ssemul")
13305 (const_string "sseadd"))
13306 (if_then_else (match_operand:MODEF 3 "mult_operator")
13307 (const_string "fmul")
13308 (const_string "fop"))))
13309 (set_attr "isa" "*,noavx,avx")
13310 (set_attr "prefix" "orig,orig,vex")
13311 (set_attr "mode" "<MODE>")])
13313 (define_insn "*fop_<mode>_comm_sse"
13314 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13315 (match_operator:MODEF 3 "binary_fp_operator"
13316 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13317 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13318 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13319 && COMMUTATIVE_ARITH_P (operands[3])
13320 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13321 "* return output_387_binary_op (insn, operands);"
13322 [(set (attr "type")
13323 (if_then_else (match_operand:MODEF 3 "mult_operator")
13324 (const_string "ssemul")
13325 (const_string "sseadd")))
13326 (set_attr "isa" "noavx,avx")
13327 (set_attr "prefix" "orig,vex")
13328 (set_attr "mode" "<MODE>")])
13330 (define_insn "*fop_<mode>_comm_i387"
13331 [(set (match_operand:MODEF 0 "register_operand" "=f")
13332 (match_operator:MODEF 3 "binary_fp_operator"
13333 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13334 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13335 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13336 && COMMUTATIVE_ARITH_P (operands[3])
13337 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13338 "* return output_387_binary_op (insn, operands);"
13339 [(set (attr "type")
13340 (if_then_else (match_operand:MODEF 3 "mult_operator")
13341 (const_string "fmul")
13342 (const_string "fop")))
13343 (set_attr "mode" "<MODE>")])
13345 (define_insn "*fop_<mode>_1_mixed"
13346 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13347 (match_operator:MODEF 3 "binary_fp_operator"
13348 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13349 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13350 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13351 && !COMMUTATIVE_ARITH_P (operands[3])
13352 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13353 "* return output_387_binary_op (insn, operands);"
13354 [(set (attr "type")
13355 (cond [(and (eq_attr "alternative" "2,3")
13356 (match_operand:MODEF 3 "mult_operator"))
13357 (const_string "ssemul")
13358 (and (eq_attr "alternative" "2,3")
13359 (match_operand:MODEF 3 "div_operator"))
13360 (const_string "ssediv")
13361 (eq_attr "alternative" "2,3")
13362 (const_string "sseadd")
13363 (match_operand:MODEF 3 "mult_operator")
13364 (const_string "fmul")
13365 (match_operand:MODEF 3 "div_operator")
13366 (const_string "fdiv")
13368 (const_string "fop")))
13369 (set_attr "isa" "*,*,noavx,avx")
13370 (set_attr "prefix" "orig,orig,orig,vex")
13371 (set_attr "mode" "<MODE>")])
13373 (define_insn "*rcpsf2_sse"
13374 [(set (match_operand:SF 0 "register_operand" "=x")
13375 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13378 "%vrcpss\t{%1, %d0|%d0, %1}"
13379 [(set_attr "type" "sse")
13380 (set_attr "atom_sse_attr" "rcp")
13381 (set_attr "btver2_sse_attr" "rcp")
13382 (set_attr "prefix" "maybe_vex")
13383 (set_attr "mode" "SF")])
13385 (define_insn "*fop_<mode>_1_sse"
13386 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13387 (match_operator:MODEF 3 "binary_fp_operator"
13388 [(match_operand:MODEF 1 "register_operand" "0,x")
13389 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13390 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13391 && !COMMUTATIVE_ARITH_P (operands[3])"
13392 "* return output_387_binary_op (insn, operands);"
13393 [(set (attr "type")
13394 (cond [(match_operand:MODEF 3 "mult_operator")
13395 (const_string "ssemul")
13396 (match_operand:MODEF 3 "div_operator")
13397 (const_string "ssediv")
13399 (const_string "sseadd")))
13400 (set_attr "isa" "noavx,avx")
13401 (set_attr "prefix" "orig,vex")
13402 (set_attr "mode" "<MODE>")])
13404 ;; This pattern is not fully shadowed by the pattern above.
13405 (define_insn "*fop_<mode>_1_i387"
13406 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13407 (match_operator:MODEF 3 "binary_fp_operator"
13408 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13409 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13410 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13411 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13412 && !COMMUTATIVE_ARITH_P (operands[3])
13413 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13414 "* return output_387_binary_op (insn, operands);"
13415 [(set (attr "type")
13416 (cond [(match_operand:MODEF 3 "mult_operator")
13417 (const_string "fmul")
13418 (match_operand:MODEF 3 "div_operator")
13419 (const_string "fdiv")
13421 (const_string "fop")))
13422 (set_attr "mode" "<MODE>")])
13424 ;; ??? Add SSE splitters for these!
13425 (define_insn "*fop_<MODEF:mode>_2_i387"
13426 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13427 (match_operator:MODEF 3 "binary_fp_operator"
13429 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13430 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13431 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13432 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13433 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13434 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13435 [(set (attr "type")
13436 (cond [(match_operand:MODEF 3 "mult_operator")
13437 (const_string "fmul")
13438 (match_operand:MODEF 3 "div_operator")
13439 (const_string "fdiv")
13441 (const_string "fop")))
13442 (set_attr "fp_int_src" "true")
13443 (set_attr "mode" "<SWI24:MODE>")])
13445 (define_insn "*fop_<MODEF:mode>_3_i387"
13446 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13447 (match_operator:MODEF 3 "binary_fp_operator"
13448 [(match_operand:MODEF 1 "register_operand" "0,0")
13450 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13451 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13452 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13453 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13454 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13455 [(set (attr "type")
13456 (cond [(match_operand:MODEF 3 "mult_operator")
13457 (const_string "fmul")
13458 (match_operand:MODEF 3 "div_operator")
13459 (const_string "fdiv")
13461 (const_string "fop")))
13462 (set_attr "fp_int_src" "true")
13463 (set_attr "mode" "<MODE>")])
13465 (define_insn "*fop_df_4_i387"
13466 [(set (match_operand:DF 0 "register_operand" "=f,f")
13467 (match_operator:DF 3 "binary_fp_operator"
13469 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13470 (match_operand:DF 2 "register_operand" "0,f")]))]
13471 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13472 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13473 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13474 "* return output_387_binary_op (insn, operands);"
13475 [(set (attr "type")
13476 (cond [(match_operand:DF 3 "mult_operator")
13477 (const_string "fmul")
13478 (match_operand:DF 3 "div_operator")
13479 (const_string "fdiv")
13481 (const_string "fop")))
13482 (set_attr "mode" "SF")])
13484 (define_insn "*fop_df_5_i387"
13485 [(set (match_operand:DF 0 "register_operand" "=f,f")
13486 (match_operator:DF 3 "binary_fp_operator"
13487 [(match_operand:DF 1 "register_operand" "0,f")
13489 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13490 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13491 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13492 "* return output_387_binary_op (insn, operands);"
13493 [(set (attr "type")
13494 (cond [(match_operand:DF 3 "mult_operator")
13495 (const_string "fmul")
13496 (match_operand:DF 3 "div_operator")
13497 (const_string "fdiv")
13499 (const_string "fop")))
13500 (set_attr "mode" "SF")])
13502 (define_insn "*fop_df_6_i387"
13503 [(set (match_operand:DF 0 "register_operand" "=f,f")
13504 (match_operator:DF 3 "binary_fp_operator"
13506 (match_operand:SF 1 "register_operand" "0,f"))
13508 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13509 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13510 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13511 "* return output_387_binary_op (insn, operands);"
13512 [(set (attr "type")
13513 (cond [(match_operand:DF 3 "mult_operator")
13514 (const_string "fmul")
13515 (match_operand:DF 3 "div_operator")
13516 (const_string "fdiv")
13518 (const_string "fop")))
13519 (set_attr "mode" "SF")])
13521 (define_insn "*fop_xf_comm_i387"
13522 [(set (match_operand:XF 0 "register_operand" "=f")
13523 (match_operator:XF 3 "binary_fp_operator"
13524 [(match_operand:XF 1 "register_operand" "%0")
13525 (match_operand:XF 2 "register_operand" "f")]))]
13527 && COMMUTATIVE_ARITH_P (operands[3])"
13528 "* return output_387_binary_op (insn, operands);"
13529 [(set (attr "type")
13530 (if_then_else (match_operand:XF 3 "mult_operator")
13531 (const_string "fmul")
13532 (const_string "fop")))
13533 (set_attr "mode" "XF")])
13535 (define_insn "*fop_xf_1_i387"
13536 [(set (match_operand:XF 0 "register_operand" "=f,f")
13537 (match_operator:XF 3 "binary_fp_operator"
13538 [(match_operand:XF 1 "register_operand" "0,f")
13539 (match_operand:XF 2 "register_operand" "f,0")]))]
13541 && !COMMUTATIVE_ARITH_P (operands[3])"
13542 "* return output_387_binary_op (insn, operands);"
13543 [(set (attr "type")
13544 (cond [(match_operand:XF 3 "mult_operator")
13545 (const_string "fmul")
13546 (match_operand:XF 3 "div_operator")
13547 (const_string "fdiv")
13549 (const_string "fop")))
13550 (set_attr "mode" "XF")])
13552 (define_insn "*fop_xf_2_i387"
13553 [(set (match_operand:XF 0 "register_operand" "=f,f")
13554 (match_operator:XF 3 "binary_fp_operator"
13556 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13557 (match_operand:XF 2 "register_operand" "0,0")]))]
13558 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13559 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13560 [(set (attr "type")
13561 (cond [(match_operand:XF 3 "mult_operator")
13562 (const_string "fmul")
13563 (match_operand:XF 3 "div_operator")
13564 (const_string "fdiv")
13566 (const_string "fop")))
13567 (set_attr "fp_int_src" "true")
13568 (set_attr "mode" "<MODE>")])
13570 (define_insn "*fop_xf_3_i387"
13571 [(set (match_operand:XF 0 "register_operand" "=f,f")
13572 (match_operator:XF 3 "binary_fp_operator"
13573 [(match_operand:XF 1 "register_operand" "0,0")
13575 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13576 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13577 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13578 [(set (attr "type")
13579 (cond [(match_operand:XF 3 "mult_operator")
13580 (const_string "fmul")
13581 (match_operand:XF 3 "div_operator")
13582 (const_string "fdiv")
13584 (const_string "fop")))
13585 (set_attr "fp_int_src" "true")
13586 (set_attr "mode" "<MODE>")])
13588 (define_insn "*fop_xf_4_i387"
13589 [(set (match_operand:XF 0 "register_operand" "=f,f")
13590 (match_operator:XF 3 "binary_fp_operator"
13592 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13593 (match_operand:XF 2 "register_operand" "0,f")]))]
13595 "* return output_387_binary_op (insn, operands);"
13596 [(set (attr "type")
13597 (cond [(match_operand:XF 3 "mult_operator")
13598 (const_string "fmul")
13599 (match_operand:XF 3 "div_operator")
13600 (const_string "fdiv")
13602 (const_string "fop")))
13603 (set_attr "mode" "<MODE>")])
13605 (define_insn "*fop_xf_5_i387"
13606 [(set (match_operand:XF 0 "register_operand" "=f,f")
13607 (match_operator:XF 3 "binary_fp_operator"
13608 [(match_operand:XF 1 "register_operand" "0,f")
13610 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13612 "* return output_387_binary_op (insn, operands);"
13613 [(set (attr "type")
13614 (cond [(match_operand:XF 3 "mult_operator")
13615 (const_string "fmul")
13616 (match_operand:XF 3 "div_operator")
13617 (const_string "fdiv")
13619 (const_string "fop")))
13620 (set_attr "mode" "<MODE>")])
13622 (define_insn "*fop_xf_6_i387"
13623 [(set (match_operand:XF 0 "register_operand" "=f,f")
13624 (match_operator:XF 3 "binary_fp_operator"
13626 (match_operand:MODEF 1 "register_operand" "0,f"))
13628 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13630 "* return output_387_binary_op (insn, operands);"
13631 [(set (attr "type")
13632 (cond [(match_operand:XF 3 "mult_operator")
13633 (const_string "fmul")
13634 (match_operand:XF 3 "div_operator")
13635 (const_string "fdiv")
13637 (const_string "fop")))
13638 (set_attr "mode" "<MODE>")])
13641 [(set (match_operand 0 "register_operand")
13642 (match_operator 3 "binary_fp_operator"
13643 [(float (match_operand:SWI24 1 "register_operand"))
13644 (match_operand 2 "register_operand")]))]
13646 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13647 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13650 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13651 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13652 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13653 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13654 GET_MODE (operands[3]),
13657 ix86_free_from_memory (GET_MODE (operands[1]));
13662 [(set (match_operand 0 "register_operand")
13663 (match_operator 3 "binary_fp_operator"
13664 [(match_operand 1 "register_operand")
13665 (float (match_operand:SWI24 2 "register_operand"))]))]
13667 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13668 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13671 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13672 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13673 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13674 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13675 GET_MODE (operands[3]),
13678 ix86_free_from_memory (GET_MODE (operands[2]));
13682 ;; FPU special functions.
13684 ;; This pattern implements a no-op XFmode truncation for
13685 ;; all fancy i386 XFmode math functions.
13687 (define_insn "truncxf<mode>2_i387_noop_unspec"
13688 [(set (match_operand:MODEF 0 "register_operand" "=f")
13689 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13690 UNSPEC_TRUNC_NOOP))]
13691 "TARGET_USE_FANCY_MATH_387"
13692 "* return output_387_reg_move (insn, operands);"
13693 [(set_attr "type" "fmov")
13694 (set_attr "mode" "<MODE>")])
13696 (define_insn "sqrtxf2"
13697 [(set (match_operand:XF 0 "register_operand" "=f")
13698 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13699 "TARGET_USE_FANCY_MATH_387"
13701 [(set_attr "type" "fpspc")
13702 (set_attr "mode" "XF")
13703 (set_attr "athlon_decode" "direct")
13704 (set_attr "amdfam10_decode" "direct")
13705 (set_attr "bdver1_decode" "direct")])
13707 (define_insn "sqrt_extend<mode>xf2_i387"
13708 [(set (match_operand:XF 0 "register_operand" "=f")
13711 (match_operand:MODEF 1 "register_operand" "0"))))]
13712 "TARGET_USE_FANCY_MATH_387"
13714 [(set_attr "type" "fpspc")
13715 (set_attr "mode" "XF")
13716 (set_attr "athlon_decode" "direct")
13717 (set_attr "amdfam10_decode" "direct")
13718 (set_attr "bdver1_decode" "direct")])
13720 (define_insn "*rsqrtsf2_sse"
13721 [(set (match_operand:SF 0 "register_operand" "=x")
13722 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13725 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13726 [(set_attr "type" "sse")
13727 (set_attr "atom_sse_attr" "rcp")
13728 (set_attr "btver2_sse_attr" "rcp")
13729 (set_attr "prefix" "maybe_vex")
13730 (set_attr "mode" "SF")])
13732 (define_expand "rsqrtsf2"
13733 [(set (match_operand:SF 0 "register_operand")
13734 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13738 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13742 (define_insn "*sqrt<mode>2_sse"
13743 [(set (match_operand:MODEF 0 "register_operand" "=x")
13745 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13746 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13747 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13748 [(set_attr "type" "sse")
13749 (set_attr "atom_sse_attr" "sqrt")
13750 (set_attr "btver2_sse_attr" "sqrt")
13751 (set_attr "prefix" "maybe_vex")
13752 (set_attr "mode" "<MODE>")
13753 (set_attr "athlon_decode" "*")
13754 (set_attr "amdfam10_decode" "*")
13755 (set_attr "bdver1_decode" "*")])
13757 (define_expand "sqrt<mode>2"
13758 [(set (match_operand:MODEF 0 "register_operand")
13760 (match_operand:MODEF 1 "nonimmediate_operand")))]
13761 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13762 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13764 if (<MODE>mode == SFmode
13766 && TARGET_RECIP_SQRT
13767 && !optimize_function_for_size_p (cfun)
13768 && flag_finite_math_only && !flag_trapping_math
13769 && flag_unsafe_math_optimizations)
13771 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13775 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13777 rtx op0 = gen_reg_rtx (XFmode);
13778 rtx op1 = force_reg (<MODE>mode, operands[1]);
13780 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13781 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13786 (define_insn "fpremxf4_i387"
13787 [(set (match_operand:XF 0 "register_operand" "=f")
13788 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13789 (match_operand:XF 3 "register_operand" "1")]
13791 (set (match_operand:XF 1 "register_operand" "=u")
13792 (unspec:XF [(match_dup 2) (match_dup 3)]
13794 (set (reg:CCFP FPSR_REG)
13795 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13797 "TARGET_USE_FANCY_MATH_387"
13799 [(set_attr "type" "fpspc")
13800 (set_attr "mode" "XF")])
13802 (define_expand "fmodxf3"
13803 [(use (match_operand:XF 0 "register_operand"))
13804 (use (match_operand:XF 1 "general_operand"))
13805 (use (match_operand:XF 2 "general_operand"))]
13806 "TARGET_USE_FANCY_MATH_387"
13808 rtx label = gen_label_rtx ();
13810 rtx op1 = gen_reg_rtx (XFmode);
13811 rtx op2 = gen_reg_rtx (XFmode);
13813 emit_move_insn (op2, operands[2]);
13814 emit_move_insn (op1, operands[1]);
13816 emit_label (label);
13817 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13818 ix86_emit_fp_unordered_jump (label);
13819 LABEL_NUSES (label) = 1;
13821 emit_move_insn (operands[0], op1);
13825 (define_expand "fmod<mode>3"
13826 [(use (match_operand:MODEF 0 "register_operand"))
13827 (use (match_operand:MODEF 1 "general_operand"))
13828 (use (match_operand:MODEF 2 "general_operand"))]
13829 "TARGET_USE_FANCY_MATH_387"
13831 rtx (*gen_truncxf) (rtx, rtx);
13833 rtx label = gen_label_rtx ();
13835 rtx op1 = gen_reg_rtx (XFmode);
13836 rtx op2 = gen_reg_rtx (XFmode);
13838 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13839 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13841 emit_label (label);
13842 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13843 ix86_emit_fp_unordered_jump (label);
13844 LABEL_NUSES (label) = 1;
13846 /* Truncate the result properly for strict SSE math. */
13847 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13848 && !TARGET_MIX_SSE_I387)
13849 gen_truncxf = gen_truncxf<mode>2;
13851 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13853 emit_insn (gen_truncxf (operands[0], op1));
13857 (define_insn "fprem1xf4_i387"
13858 [(set (match_operand:XF 0 "register_operand" "=f")
13859 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13860 (match_operand:XF 3 "register_operand" "1")]
13862 (set (match_operand:XF 1 "register_operand" "=u")
13863 (unspec:XF [(match_dup 2) (match_dup 3)]
13865 (set (reg:CCFP FPSR_REG)
13866 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13868 "TARGET_USE_FANCY_MATH_387"
13870 [(set_attr "type" "fpspc")
13871 (set_attr "mode" "XF")])
13873 (define_expand "remainderxf3"
13874 [(use (match_operand:XF 0 "register_operand"))
13875 (use (match_operand:XF 1 "general_operand"))
13876 (use (match_operand:XF 2 "general_operand"))]
13877 "TARGET_USE_FANCY_MATH_387"
13879 rtx label = gen_label_rtx ();
13881 rtx op1 = gen_reg_rtx (XFmode);
13882 rtx op2 = gen_reg_rtx (XFmode);
13884 emit_move_insn (op2, operands[2]);
13885 emit_move_insn (op1, operands[1]);
13887 emit_label (label);
13888 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13889 ix86_emit_fp_unordered_jump (label);
13890 LABEL_NUSES (label) = 1;
13892 emit_move_insn (operands[0], op1);
13896 (define_expand "remainder<mode>3"
13897 [(use (match_operand:MODEF 0 "register_operand"))
13898 (use (match_operand:MODEF 1 "general_operand"))
13899 (use (match_operand:MODEF 2 "general_operand"))]
13900 "TARGET_USE_FANCY_MATH_387"
13902 rtx (*gen_truncxf) (rtx, rtx);
13904 rtx label = gen_label_rtx ();
13906 rtx op1 = gen_reg_rtx (XFmode);
13907 rtx op2 = gen_reg_rtx (XFmode);
13909 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13910 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13912 emit_label (label);
13914 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13915 ix86_emit_fp_unordered_jump (label);
13916 LABEL_NUSES (label) = 1;
13918 /* Truncate the result properly for strict SSE math. */
13919 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13920 && !TARGET_MIX_SSE_I387)
13921 gen_truncxf = gen_truncxf<mode>2;
13923 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13925 emit_insn (gen_truncxf (operands[0], op1));
13929 (define_int_iterator SINCOS
13933 (define_int_attr sincos
13934 [(UNSPEC_SIN "sin")
13935 (UNSPEC_COS "cos")])
13937 (define_insn "*<sincos>xf2_i387"
13938 [(set (match_operand:XF 0 "register_operand" "=f")
13939 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13941 "TARGET_USE_FANCY_MATH_387
13942 && flag_unsafe_math_optimizations"
13944 [(set_attr "type" "fpspc")
13945 (set_attr "mode" "XF")])
13947 (define_insn "*<sincos>_extend<mode>xf2_i387"
13948 [(set (match_operand:XF 0 "register_operand" "=f")
13949 (unspec:XF [(float_extend:XF
13950 (match_operand:MODEF 1 "register_operand" "0"))]
13952 "TARGET_USE_FANCY_MATH_387
13953 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13954 || TARGET_MIX_SSE_I387)
13955 && flag_unsafe_math_optimizations"
13957 [(set_attr "type" "fpspc")
13958 (set_attr "mode" "XF")])
13960 ;; When sincos pattern is defined, sin and cos builtin functions will be
13961 ;; expanded to sincos pattern with one of its outputs left unused.
13962 ;; CSE pass will figure out if two sincos patterns can be combined,
13963 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13964 ;; depending on the unused output.
13966 (define_insn "sincosxf3"
13967 [(set (match_operand:XF 0 "register_operand" "=f")
13968 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13969 UNSPEC_SINCOS_COS))
13970 (set (match_operand:XF 1 "register_operand" "=u")
13971 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13972 "TARGET_USE_FANCY_MATH_387
13973 && flag_unsafe_math_optimizations"
13975 [(set_attr "type" "fpspc")
13976 (set_attr "mode" "XF")])
13979 [(set (match_operand:XF 0 "register_operand")
13980 (unspec:XF [(match_operand:XF 2 "register_operand")]
13981 UNSPEC_SINCOS_COS))
13982 (set (match_operand:XF 1 "register_operand")
13983 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13984 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13985 && can_create_pseudo_p ()"
13986 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13989 [(set (match_operand:XF 0 "register_operand")
13990 (unspec:XF [(match_operand:XF 2 "register_operand")]
13991 UNSPEC_SINCOS_COS))
13992 (set (match_operand:XF 1 "register_operand")
13993 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13994 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13995 && can_create_pseudo_p ()"
13996 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13998 (define_insn "sincos_extend<mode>xf3_i387"
13999 [(set (match_operand:XF 0 "register_operand" "=f")
14000 (unspec:XF [(float_extend:XF
14001 (match_operand:MODEF 2 "register_operand" "0"))]
14002 UNSPEC_SINCOS_COS))
14003 (set (match_operand:XF 1 "register_operand" "=u")
14004 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14005 "TARGET_USE_FANCY_MATH_387
14006 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14007 || TARGET_MIX_SSE_I387)
14008 && flag_unsafe_math_optimizations"
14010 [(set_attr "type" "fpspc")
14011 (set_attr "mode" "XF")])
14014 [(set (match_operand:XF 0 "register_operand")
14015 (unspec:XF [(float_extend:XF
14016 (match_operand:MODEF 2 "register_operand"))]
14017 UNSPEC_SINCOS_COS))
14018 (set (match_operand:XF 1 "register_operand")
14019 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14020 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14021 && can_create_pseudo_p ()"
14022 [(set (match_dup 1)
14023 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14026 [(set (match_operand:XF 0 "register_operand")
14027 (unspec:XF [(float_extend:XF
14028 (match_operand:MODEF 2 "register_operand"))]
14029 UNSPEC_SINCOS_COS))
14030 (set (match_operand:XF 1 "register_operand")
14031 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14032 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14033 && can_create_pseudo_p ()"
14034 [(set (match_dup 0)
14035 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14037 (define_expand "sincos<mode>3"
14038 [(use (match_operand:MODEF 0 "register_operand"))
14039 (use (match_operand:MODEF 1 "register_operand"))
14040 (use (match_operand:MODEF 2 "register_operand"))]
14041 "TARGET_USE_FANCY_MATH_387
14042 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14043 || TARGET_MIX_SSE_I387)
14044 && flag_unsafe_math_optimizations"
14046 rtx op0 = gen_reg_rtx (XFmode);
14047 rtx op1 = gen_reg_rtx (XFmode);
14049 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14051 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14055 (define_insn "fptanxf4_i387"
14056 [(set (match_operand:XF 0 "register_operand" "=f")
14057 (match_operand:XF 3 "const_double_operand" "F"))
14058 (set (match_operand:XF 1 "register_operand" "=u")
14059 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14061 "TARGET_USE_FANCY_MATH_387
14062 && flag_unsafe_math_optimizations
14063 && standard_80387_constant_p (operands[3]) == 2"
14065 [(set_attr "type" "fpspc")
14066 (set_attr "mode" "XF")])
14068 (define_insn "fptan_extend<mode>xf4_i387"
14069 [(set (match_operand:MODEF 0 "register_operand" "=f")
14070 (match_operand:MODEF 3 "const_double_operand" "F"))
14071 (set (match_operand:XF 1 "register_operand" "=u")
14072 (unspec:XF [(float_extend:XF
14073 (match_operand:MODEF 2 "register_operand" "0"))]
14075 "TARGET_USE_FANCY_MATH_387
14076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14077 || TARGET_MIX_SSE_I387)
14078 && flag_unsafe_math_optimizations
14079 && standard_80387_constant_p (operands[3]) == 2"
14081 [(set_attr "type" "fpspc")
14082 (set_attr "mode" "XF")])
14084 (define_expand "tanxf2"
14085 [(use (match_operand:XF 0 "register_operand"))
14086 (use (match_operand:XF 1 "register_operand"))]
14087 "TARGET_USE_FANCY_MATH_387
14088 && flag_unsafe_math_optimizations"
14090 rtx one = gen_reg_rtx (XFmode);
14091 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14093 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14097 (define_expand "tan<mode>2"
14098 [(use (match_operand:MODEF 0 "register_operand"))
14099 (use (match_operand:MODEF 1 "register_operand"))]
14100 "TARGET_USE_FANCY_MATH_387
14101 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14102 || TARGET_MIX_SSE_I387)
14103 && flag_unsafe_math_optimizations"
14105 rtx op0 = gen_reg_rtx (XFmode);
14107 rtx one = gen_reg_rtx (<MODE>mode);
14108 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14110 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14111 operands[1], op2));
14112 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14116 (define_insn "*fpatanxf3_i387"
14117 [(set (match_operand:XF 0 "register_operand" "=f")
14118 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14119 (match_operand:XF 2 "register_operand" "u")]
14121 (clobber (match_scratch:XF 3 "=2"))]
14122 "TARGET_USE_FANCY_MATH_387
14123 && flag_unsafe_math_optimizations"
14125 [(set_attr "type" "fpspc")
14126 (set_attr "mode" "XF")])
14128 (define_insn "fpatan_extend<mode>xf3_i387"
14129 [(set (match_operand:XF 0 "register_operand" "=f")
14130 (unspec:XF [(float_extend:XF
14131 (match_operand:MODEF 1 "register_operand" "0"))
14133 (match_operand:MODEF 2 "register_operand" "u"))]
14135 (clobber (match_scratch:XF 3 "=2"))]
14136 "TARGET_USE_FANCY_MATH_387
14137 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14138 || TARGET_MIX_SSE_I387)
14139 && flag_unsafe_math_optimizations"
14141 [(set_attr "type" "fpspc")
14142 (set_attr "mode" "XF")])
14144 (define_expand "atan2xf3"
14145 [(parallel [(set (match_operand:XF 0 "register_operand")
14146 (unspec:XF [(match_operand:XF 2 "register_operand")
14147 (match_operand:XF 1 "register_operand")]
14149 (clobber (match_scratch:XF 3))])]
14150 "TARGET_USE_FANCY_MATH_387
14151 && flag_unsafe_math_optimizations")
14153 (define_expand "atan2<mode>3"
14154 [(use (match_operand:MODEF 0 "register_operand"))
14155 (use (match_operand:MODEF 1 "register_operand"))
14156 (use (match_operand:MODEF 2 "register_operand"))]
14157 "TARGET_USE_FANCY_MATH_387
14158 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14159 || TARGET_MIX_SSE_I387)
14160 && flag_unsafe_math_optimizations"
14162 rtx op0 = gen_reg_rtx (XFmode);
14164 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14165 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14169 (define_expand "atanxf2"
14170 [(parallel [(set (match_operand:XF 0 "register_operand")
14171 (unspec:XF [(match_dup 2)
14172 (match_operand:XF 1 "register_operand")]
14174 (clobber (match_scratch:XF 3))])]
14175 "TARGET_USE_FANCY_MATH_387
14176 && flag_unsafe_math_optimizations"
14178 operands[2] = gen_reg_rtx (XFmode);
14179 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14182 (define_expand "atan<mode>2"
14183 [(use (match_operand:MODEF 0 "register_operand"))
14184 (use (match_operand:MODEF 1 "register_operand"))]
14185 "TARGET_USE_FANCY_MATH_387
14186 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14187 || TARGET_MIX_SSE_I387)
14188 && flag_unsafe_math_optimizations"
14190 rtx op0 = gen_reg_rtx (XFmode);
14192 rtx op2 = gen_reg_rtx (<MODE>mode);
14193 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14195 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14196 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14200 (define_expand "asinxf2"
14201 [(set (match_dup 2)
14202 (mult:XF (match_operand:XF 1 "register_operand")
14204 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14205 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14206 (parallel [(set (match_operand:XF 0 "register_operand")
14207 (unspec:XF [(match_dup 5) (match_dup 1)]
14209 (clobber (match_scratch:XF 6))])]
14210 "TARGET_USE_FANCY_MATH_387
14211 && flag_unsafe_math_optimizations"
14215 if (optimize_insn_for_size_p ())
14218 for (i = 2; i < 6; i++)
14219 operands[i] = gen_reg_rtx (XFmode);
14221 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14224 (define_expand "asin<mode>2"
14225 [(use (match_operand:MODEF 0 "register_operand"))
14226 (use (match_operand:MODEF 1 "general_operand"))]
14227 "TARGET_USE_FANCY_MATH_387
14228 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14229 || TARGET_MIX_SSE_I387)
14230 && flag_unsafe_math_optimizations"
14232 rtx op0 = gen_reg_rtx (XFmode);
14233 rtx op1 = gen_reg_rtx (XFmode);
14235 if (optimize_insn_for_size_p ())
14238 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14239 emit_insn (gen_asinxf2 (op0, op1));
14240 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14244 (define_expand "acosxf2"
14245 [(set (match_dup 2)
14246 (mult:XF (match_operand:XF 1 "register_operand")
14248 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14249 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14250 (parallel [(set (match_operand:XF 0 "register_operand")
14251 (unspec:XF [(match_dup 1) (match_dup 5)]
14253 (clobber (match_scratch:XF 6))])]
14254 "TARGET_USE_FANCY_MATH_387
14255 && flag_unsafe_math_optimizations"
14259 if (optimize_insn_for_size_p ())
14262 for (i = 2; i < 6; i++)
14263 operands[i] = gen_reg_rtx (XFmode);
14265 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14268 (define_expand "acos<mode>2"
14269 [(use (match_operand:MODEF 0 "register_operand"))
14270 (use (match_operand:MODEF 1 "general_operand"))]
14271 "TARGET_USE_FANCY_MATH_387
14272 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14273 || TARGET_MIX_SSE_I387)
14274 && flag_unsafe_math_optimizations"
14276 rtx op0 = gen_reg_rtx (XFmode);
14277 rtx op1 = gen_reg_rtx (XFmode);
14279 if (optimize_insn_for_size_p ())
14282 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14283 emit_insn (gen_acosxf2 (op0, op1));
14284 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14288 (define_insn "fyl2xxf3_i387"
14289 [(set (match_operand:XF 0 "register_operand" "=f")
14290 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14291 (match_operand:XF 2 "register_operand" "u")]
14293 (clobber (match_scratch:XF 3 "=2"))]
14294 "TARGET_USE_FANCY_MATH_387
14295 && flag_unsafe_math_optimizations"
14297 [(set_attr "type" "fpspc")
14298 (set_attr "mode" "XF")])
14300 (define_insn "fyl2x_extend<mode>xf3_i387"
14301 [(set (match_operand:XF 0 "register_operand" "=f")
14302 (unspec:XF [(float_extend:XF
14303 (match_operand:MODEF 1 "register_operand" "0"))
14304 (match_operand:XF 2 "register_operand" "u")]
14306 (clobber (match_scratch:XF 3 "=2"))]
14307 "TARGET_USE_FANCY_MATH_387
14308 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14309 || TARGET_MIX_SSE_I387)
14310 && flag_unsafe_math_optimizations"
14312 [(set_attr "type" "fpspc")
14313 (set_attr "mode" "XF")])
14315 (define_expand "logxf2"
14316 [(parallel [(set (match_operand:XF 0 "register_operand")
14317 (unspec:XF [(match_operand:XF 1 "register_operand")
14318 (match_dup 2)] UNSPEC_FYL2X))
14319 (clobber (match_scratch:XF 3))])]
14320 "TARGET_USE_FANCY_MATH_387
14321 && flag_unsafe_math_optimizations"
14323 operands[2] = gen_reg_rtx (XFmode);
14324 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14327 (define_expand "log<mode>2"
14328 [(use (match_operand:MODEF 0 "register_operand"))
14329 (use (match_operand:MODEF 1 "register_operand"))]
14330 "TARGET_USE_FANCY_MATH_387
14331 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14332 || TARGET_MIX_SSE_I387)
14333 && flag_unsafe_math_optimizations"
14335 rtx op0 = gen_reg_rtx (XFmode);
14337 rtx op2 = gen_reg_rtx (XFmode);
14338 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14340 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14341 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14345 (define_expand "log10xf2"
14346 [(parallel [(set (match_operand:XF 0 "register_operand")
14347 (unspec:XF [(match_operand:XF 1 "register_operand")
14348 (match_dup 2)] UNSPEC_FYL2X))
14349 (clobber (match_scratch:XF 3))])]
14350 "TARGET_USE_FANCY_MATH_387
14351 && flag_unsafe_math_optimizations"
14353 operands[2] = gen_reg_rtx (XFmode);
14354 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14357 (define_expand "log10<mode>2"
14358 [(use (match_operand:MODEF 0 "register_operand"))
14359 (use (match_operand:MODEF 1 "register_operand"))]
14360 "TARGET_USE_FANCY_MATH_387
14361 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14362 || TARGET_MIX_SSE_I387)
14363 && flag_unsafe_math_optimizations"
14365 rtx op0 = gen_reg_rtx (XFmode);
14367 rtx op2 = gen_reg_rtx (XFmode);
14368 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14370 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14371 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14375 (define_expand "log2xf2"
14376 [(parallel [(set (match_operand:XF 0 "register_operand")
14377 (unspec:XF [(match_operand:XF 1 "register_operand")
14378 (match_dup 2)] UNSPEC_FYL2X))
14379 (clobber (match_scratch:XF 3))])]
14380 "TARGET_USE_FANCY_MATH_387
14381 && flag_unsafe_math_optimizations"
14383 operands[2] = gen_reg_rtx (XFmode);
14384 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14387 (define_expand "log2<mode>2"
14388 [(use (match_operand:MODEF 0 "register_operand"))
14389 (use (match_operand:MODEF 1 "register_operand"))]
14390 "TARGET_USE_FANCY_MATH_387
14391 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14392 || TARGET_MIX_SSE_I387)
14393 && flag_unsafe_math_optimizations"
14395 rtx op0 = gen_reg_rtx (XFmode);
14397 rtx op2 = gen_reg_rtx (XFmode);
14398 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14400 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14401 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14405 (define_insn "fyl2xp1xf3_i387"
14406 [(set (match_operand:XF 0 "register_operand" "=f")
14407 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14408 (match_operand:XF 2 "register_operand" "u")]
14410 (clobber (match_scratch:XF 3 "=2"))]
14411 "TARGET_USE_FANCY_MATH_387
14412 && flag_unsafe_math_optimizations"
14414 [(set_attr "type" "fpspc")
14415 (set_attr "mode" "XF")])
14417 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14418 [(set (match_operand:XF 0 "register_operand" "=f")
14419 (unspec:XF [(float_extend:XF
14420 (match_operand:MODEF 1 "register_operand" "0"))
14421 (match_operand:XF 2 "register_operand" "u")]
14423 (clobber (match_scratch:XF 3 "=2"))]
14424 "TARGET_USE_FANCY_MATH_387
14425 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14426 || TARGET_MIX_SSE_I387)
14427 && flag_unsafe_math_optimizations"
14429 [(set_attr "type" "fpspc")
14430 (set_attr "mode" "XF")])
14432 (define_expand "log1pxf2"
14433 [(use (match_operand:XF 0 "register_operand"))
14434 (use (match_operand:XF 1 "register_operand"))]
14435 "TARGET_USE_FANCY_MATH_387
14436 && flag_unsafe_math_optimizations"
14438 if (optimize_insn_for_size_p ())
14441 ix86_emit_i387_log1p (operands[0], operands[1]);
14445 (define_expand "log1p<mode>2"
14446 [(use (match_operand:MODEF 0 "register_operand"))
14447 (use (match_operand:MODEF 1 "register_operand"))]
14448 "TARGET_USE_FANCY_MATH_387
14449 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14450 || TARGET_MIX_SSE_I387)
14451 && flag_unsafe_math_optimizations"
14455 if (optimize_insn_for_size_p ())
14458 op0 = gen_reg_rtx (XFmode);
14460 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14462 ix86_emit_i387_log1p (op0, operands[1]);
14463 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14467 (define_insn "fxtractxf3_i387"
14468 [(set (match_operand:XF 0 "register_operand" "=f")
14469 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14470 UNSPEC_XTRACT_FRACT))
14471 (set (match_operand:XF 1 "register_operand" "=u")
14472 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14473 "TARGET_USE_FANCY_MATH_387
14474 && flag_unsafe_math_optimizations"
14476 [(set_attr "type" "fpspc")
14477 (set_attr "mode" "XF")])
14479 (define_insn "fxtract_extend<mode>xf3_i387"
14480 [(set (match_operand:XF 0 "register_operand" "=f")
14481 (unspec:XF [(float_extend:XF
14482 (match_operand:MODEF 2 "register_operand" "0"))]
14483 UNSPEC_XTRACT_FRACT))
14484 (set (match_operand:XF 1 "register_operand" "=u")
14485 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14486 "TARGET_USE_FANCY_MATH_387
14487 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14488 || TARGET_MIX_SSE_I387)
14489 && flag_unsafe_math_optimizations"
14491 [(set_attr "type" "fpspc")
14492 (set_attr "mode" "XF")])
14494 (define_expand "logbxf2"
14495 [(parallel [(set (match_dup 2)
14496 (unspec:XF [(match_operand:XF 1 "register_operand")]
14497 UNSPEC_XTRACT_FRACT))
14498 (set (match_operand:XF 0 "register_operand")
14499 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14500 "TARGET_USE_FANCY_MATH_387
14501 && flag_unsafe_math_optimizations"
14502 "operands[2] = gen_reg_rtx (XFmode);")
14504 (define_expand "logb<mode>2"
14505 [(use (match_operand:MODEF 0 "register_operand"))
14506 (use (match_operand:MODEF 1 "register_operand"))]
14507 "TARGET_USE_FANCY_MATH_387
14508 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14509 || TARGET_MIX_SSE_I387)
14510 && flag_unsafe_math_optimizations"
14512 rtx op0 = gen_reg_rtx (XFmode);
14513 rtx op1 = gen_reg_rtx (XFmode);
14515 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14516 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14520 (define_expand "ilogbxf2"
14521 [(use (match_operand:SI 0 "register_operand"))
14522 (use (match_operand:XF 1 "register_operand"))]
14523 "TARGET_USE_FANCY_MATH_387
14524 && flag_unsafe_math_optimizations"
14528 if (optimize_insn_for_size_p ())
14531 op0 = gen_reg_rtx (XFmode);
14532 op1 = gen_reg_rtx (XFmode);
14534 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14535 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14539 (define_expand "ilogb<mode>2"
14540 [(use (match_operand:SI 0 "register_operand"))
14541 (use (match_operand:MODEF 1 "register_operand"))]
14542 "TARGET_USE_FANCY_MATH_387
14543 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14544 || TARGET_MIX_SSE_I387)
14545 && flag_unsafe_math_optimizations"
14549 if (optimize_insn_for_size_p ())
14552 op0 = gen_reg_rtx (XFmode);
14553 op1 = gen_reg_rtx (XFmode);
14555 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14556 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14560 (define_insn "*f2xm1xf2_i387"
14561 [(set (match_operand:XF 0 "register_operand" "=f")
14562 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14564 "TARGET_USE_FANCY_MATH_387
14565 && flag_unsafe_math_optimizations"
14567 [(set_attr "type" "fpspc")
14568 (set_attr "mode" "XF")])
14570 (define_insn "*fscalexf4_i387"
14571 [(set (match_operand:XF 0 "register_operand" "=f")
14572 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14573 (match_operand:XF 3 "register_operand" "1")]
14574 UNSPEC_FSCALE_FRACT))
14575 (set (match_operand:XF 1 "register_operand" "=u")
14576 (unspec:XF [(match_dup 2) (match_dup 3)]
14577 UNSPEC_FSCALE_EXP))]
14578 "TARGET_USE_FANCY_MATH_387
14579 && flag_unsafe_math_optimizations"
14581 [(set_attr "type" "fpspc")
14582 (set_attr "mode" "XF")])
14584 (define_expand "expNcorexf3"
14585 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14586 (match_operand:XF 2 "register_operand")))
14587 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14588 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14589 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14590 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14591 (parallel [(set (match_operand:XF 0 "register_operand")
14592 (unspec:XF [(match_dup 8) (match_dup 4)]
14593 UNSPEC_FSCALE_FRACT))
14595 (unspec:XF [(match_dup 8) (match_dup 4)]
14596 UNSPEC_FSCALE_EXP))])]
14597 "TARGET_USE_FANCY_MATH_387
14598 && flag_unsafe_math_optimizations"
14602 if (optimize_insn_for_size_p ())
14605 for (i = 3; i < 10; i++)
14606 operands[i] = gen_reg_rtx (XFmode);
14608 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14611 (define_expand "expxf2"
14612 [(use (match_operand:XF 0 "register_operand"))
14613 (use (match_operand:XF 1 "register_operand"))]
14614 "TARGET_USE_FANCY_MATH_387
14615 && flag_unsafe_math_optimizations"
14619 if (optimize_insn_for_size_p ())
14622 op2 = gen_reg_rtx (XFmode);
14623 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14625 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14629 (define_expand "exp<mode>2"
14630 [(use (match_operand:MODEF 0 "register_operand"))
14631 (use (match_operand:MODEF 1 "general_operand"))]
14632 "TARGET_USE_FANCY_MATH_387
14633 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14634 || TARGET_MIX_SSE_I387)
14635 && flag_unsafe_math_optimizations"
14639 if (optimize_insn_for_size_p ())
14642 op0 = gen_reg_rtx (XFmode);
14643 op1 = gen_reg_rtx (XFmode);
14645 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14646 emit_insn (gen_expxf2 (op0, op1));
14647 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14651 (define_expand "exp10xf2"
14652 [(use (match_operand:XF 0 "register_operand"))
14653 (use (match_operand:XF 1 "register_operand"))]
14654 "TARGET_USE_FANCY_MATH_387
14655 && flag_unsafe_math_optimizations"
14659 if (optimize_insn_for_size_p ())
14662 op2 = gen_reg_rtx (XFmode);
14663 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14665 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14669 (define_expand "exp10<mode>2"
14670 [(use (match_operand:MODEF 0 "register_operand"))
14671 (use (match_operand:MODEF 1 "general_operand"))]
14672 "TARGET_USE_FANCY_MATH_387
14673 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14674 || TARGET_MIX_SSE_I387)
14675 && flag_unsafe_math_optimizations"
14679 if (optimize_insn_for_size_p ())
14682 op0 = gen_reg_rtx (XFmode);
14683 op1 = gen_reg_rtx (XFmode);
14685 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14686 emit_insn (gen_exp10xf2 (op0, op1));
14687 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14691 (define_expand "exp2xf2"
14692 [(use (match_operand:XF 0 "register_operand"))
14693 (use (match_operand:XF 1 "register_operand"))]
14694 "TARGET_USE_FANCY_MATH_387
14695 && flag_unsafe_math_optimizations"
14699 if (optimize_insn_for_size_p ())
14702 op2 = gen_reg_rtx (XFmode);
14703 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14705 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14709 (define_expand "exp2<mode>2"
14710 [(use (match_operand:MODEF 0 "register_operand"))
14711 (use (match_operand:MODEF 1 "general_operand"))]
14712 "TARGET_USE_FANCY_MATH_387
14713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14714 || TARGET_MIX_SSE_I387)
14715 && flag_unsafe_math_optimizations"
14719 if (optimize_insn_for_size_p ())
14722 op0 = gen_reg_rtx (XFmode);
14723 op1 = gen_reg_rtx (XFmode);
14725 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14726 emit_insn (gen_exp2xf2 (op0, op1));
14727 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14731 (define_expand "expm1xf2"
14732 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14734 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14735 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14736 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14737 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14738 (parallel [(set (match_dup 7)
14739 (unspec:XF [(match_dup 6) (match_dup 4)]
14740 UNSPEC_FSCALE_FRACT))
14742 (unspec:XF [(match_dup 6) (match_dup 4)]
14743 UNSPEC_FSCALE_EXP))])
14744 (parallel [(set (match_dup 10)
14745 (unspec:XF [(match_dup 9) (match_dup 8)]
14746 UNSPEC_FSCALE_FRACT))
14747 (set (match_dup 11)
14748 (unspec:XF [(match_dup 9) (match_dup 8)]
14749 UNSPEC_FSCALE_EXP))])
14750 (set (match_dup 12) (minus:XF (match_dup 10)
14751 (float_extend:XF (match_dup 13))))
14752 (set (match_operand:XF 0 "register_operand")
14753 (plus:XF (match_dup 12) (match_dup 7)))]
14754 "TARGET_USE_FANCY_MATH_387
14755 && flag_unsafe_math_optimizations"
14759 if (optimize_insn_for_size_p ())
14762 for (i = 2; i < 13; i++)
14763 operands[i] = gen_reg_rtx (XFmode);
14766 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14768 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14771 (define_expand "expm1<mode>2"
14772 [(use (match_operand:MODEF 0 "register_operand"))
14773 (use (match_operand:MODEF 1 "general_operand"))]
14774 "TARGET_USE_FANCY_MATH_387
14775 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14776 || TARGET_MIX_SSE_I387)
14777 && flag_unsafe_math_optimizations"
14781 if (optimize_insn_for_size_p ())
14784 op0 = gen_reg_rtx (XFmode);
14785 op1 = gen_reg_rtx (XFmode);
14787 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14788 emit_insn (gen_expm1xf2 (op0, op1));
14789 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14793 (define_expand "ldexpxf3"
14794 [(set (match_dup 3)
14795 (float:XF (match_operand:SI 2 "register_operand")))
14796 (parallel [(set (match_operand:XF 0 " register_operand")
14797 (unspec:XF [(match_operand:XF 1 "register_operand")
14799 UNSPEC_FSCALE_FRACT))
14801 (unspec:XF [(match_dup 1) (match_dup 3)]
14802 UNSPEC_FSCALE_EXP))])]
14803 "TARGET_USE_FANCY_MATH_387
14804 && flag_unsafe_math_optimizations"
14806 if (optimize_insn_for_size_p ())
14809 operands[3] = gen_reg_rtx (XFmode);
14810 operands[4] = gen_reg_rtx (XFmode);
14813 (define_expand "ldexp<mode>3"
14814 [(use (match_operand:MODEF 0 "register_operand"))
14815 (use (match_operand:MODEF 1 "general_operand"))
14816 (use (match_operand:SI 2 "register_operand"))]
14817 "TARGET_USE_FANCY_MATH_387
14818 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14819 || TARGET_MIX_SSE_I387)
14820 && flag_unsafe_math_optimizations"
14824 if (optimize_insn_for_size_p ())
14827 op0 = gen_reg_rtx (XFmode);
14828 op1 = gen_reg_rtx (XFmode);
14830 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14831 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14832 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14836 (define_expand "scalbxf3"
14837 [(parallel [(set (match_operand:XF 0 " register_operand")
14838 (unspec:XF [(match_operand:XF 1 "register_operand")
14839 (match_operand:XF 2 "register_operand")]
14840 UNSPEC_FSCALE_FRACT))
14842 (unspec:XF [(match_dup 1) (match_dup 2)]
14843 UNSPEC_FSCALE_EXP))])]
14844 "TARGET_USE_FANCY_MATH_387
14845 && flag_unsafe_math_optimizations"
14847 if (optimize_insn_for_size_p ())
14850 operands[3] = gen_reg_rtx (XFmode);
14853 (define_expand "scalb<mode>3"
14854 [(use (match_operand:MODEF 0 "register_operand"))
14855 (use (match_operand:MODEF 1 "general_operand"))
14856 (use (match_operand:MODEF 2 "general_operand"))]
14857 "TARGET_USE_FANCY_MATH_387
14858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14859 || TARGET_MIX_SSE_I387)
14860 && flag_unsafe_math_optimizations"
14864 if (optimize_insn_for_size_p ())
14867 op0 = gen_reg_rtx (XFmode);
14868 op1 = gen_reg_rtx (XFmode);
14869 op2 = gen_reg_rtx (XFmode);
14871 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14872 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14873 emit_insn (gen_scalbxf3 (op0, op1, op2));
14874 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14878 (define_expand "significandxf2"
14879 [(parallel [(set (match_operand:XF 0 "register_operand")
14880 (unspec:XF [(match_operand:XF 1 "register_operand")]
14881 UNSPEC_XTRACT_FRACT))
14883 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14884 "TARGET_USE_FANCY_MATH_387
14885 && flag_unsafe_math_optimizations"
14886 "operands[2] = gen_reg_rtx (XFmode);")
14888 (define_expand "significand<mode>2"
14889 [(use (match_operand:MODEF 0 "register_operand"))
14890 (use (match_operand:MODEF 1 "register_operand"))]
14891 "TARGET_USE_FANCY_MATH_387
14892 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14893 || TARGET_MIX_SSE_I387)
14894 && flag_unsafe_math_optimizations"
14896 rtx op0 = gen_reg_rtx (XFmode);
14897 rtx op1 = gen_reg_rtx (XFmode);
14899 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14900 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14905 (define_insn "sse4_1_round<mode>2"
14906 [(set (match_operand:MODEF 0 "register_operand" "=x")
14907 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14908 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14911 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14912 [(set_attr "type" "ssecvt")
14913 (set_attr "prefix_extra" "1")
14914 (set_attr "prefix" "maybe_vex")
14915 (set_attr "mode" "<MODE>")])
14917 (define_insn "rintxf2"
14918 [(set (match_operand:XF 0 "register_operand" "=f")
14919 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14921 "TARGET_USE_FANCY_MATH_387
14922 && flag_unsafe_math_optimizations"
14924 [(set_attr "type" "fpspc")
14925 (set_attr "mode" "XF")])
14927 (define_expand "rint<mode>2"
14928 [(use (match_operand:MODEF 0 "register_operand"))
14929 (use (match_operand:MODEF 1 "register_operand"))]
14930 "(TARGET_USE_FANCY_MATH_387
14931 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14932 || TARGET_MIX_SSE_I387)
14933 && flag_unsafe_math_optimizations)
14934 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14935 && !flag_trapping_math)"
14937 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14938 && !flag_trapping_math)
14941 emit_insn (gen_sse4_1_round<mode>2
14942 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14943 else if (optimize_insn_for_size_p ())
14946 ix86_expand_rint (operands[0], operands[1]);
14950 rtx op0 = gen_reg_rtx (XFmode);
14951 rtx op1 = gen_reg_rtx (XFmode);
14953 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14954 emit_insn (gen_rintxf2 (op0, op1));
14956 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14961 (define_expand "round<mode>2"
14962 [(match_operand:X87MODEF 0 "register_operand")
14963 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14964 "(TARGET_USE_FANCY_MATH_387
14965 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14966 || TARGET_MIX_SSE_I387)
14967 && flag_unsafe_math_optimizations)
14968 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14969 && !flag_trapping_math && !flag_rounding_math)"
14971 if (optimize_insn_for_size_p ())
14974 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14975 && !flag_trapping_math && !flag_rounding_math)
14979 operands[1] = force_reg (<MODE>mode, operands[1]);
14980 ix86_expand_round_sse4 (operands[0], operands[1]);
14982 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14983 ix86_expand_round (operands[0], operands[1]);
14985 ix86_expand_rounddf_32 (operands[0], operands[1]);
14989 operands[1] = force_reg (<MODE>mode, operands[1]);
14990 ix86_emit_i387_round (operands[0], operands[1]);
14995 (define_insn_and_split "*fistdi2_1"
14996 [(set (match_operand:DI 0 "nonimmediate_operand")
14997 (unspec:DI [(match_operand:XF 1 "register_operand")]
14999 "TARGET_USE_FANCY_MATH_387
15000 && can_create_pseudo_p ()"
15005 if (memory_operand (operands[0], VOIDmode))
15006 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15009 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15010 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15015 [(set_attr "type" "fpspc")
15016 (set_attr "mode" "DI")])
15018 (define_insn "fistdi2"
15019 [(set (match_operand:DI 0 "memory_operand" "=m")
15020 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15022 (clobber (match_scratch:XF 2 "=&1f"))]
15023 "TARGET_USE_FANCY_MATH_387"
15024 "* return output_fix_trunc (insn, operands, false);"
15025 [(set_attr "type" "fpspc")
15026 (set_attr "mode" "DI")])
15028 (define_insn "fistdi2_with_temp"
15029 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15030 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15032 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15033 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15034 "TARGET_USE_FANCY_MATH_387"
15036 [(set_attr "type" "fpspc")
15037 (set_attr "mode" "DI")])
15040 [(set (match_operand:DI 0 "register_operand")
15041 (unspec:DI [(match_operand:XF 1 "register_operand")]
15043 (clobber (match_operand:DI 2 "memory_operand"))
15044 (clobber (match_scratch 3))]
15046 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15047 (clobber (match_dup 3))])
15048 (set (match_dup 0) (match_dup 2))])
15051 [(set (match_operand:DI 0 "memory_operand")
15052 (unspec:DI [(match_operand:XF 1 "register_operand")]
15054 (clobber (match_operand:DI 2 "memory_operand"))
15055 (clobber (match_scratch 3))]
15057 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15058 (clobber (match_dup 3))])])
15060 (define_insn_and_split "*fist<mode>2_1"
15061 [(set (match_operand:SWI24 0 "register_operand")
15062 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15064 "TARGET_USE_FANCY_MATH_387
15065 && can_create_pseudo_p ()"
15070 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15071 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15075 [(set_attr "type" "fpspc")
15076 (set_attr "mode" "<MODE>")])
15078 (define_insn "fist<mode>2"
15079 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15080 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15082 "TARGET_USE_FANCY_MATH_387"
15083 "* return output_fix_trunc (insn, operands, false);"
15084 [(set_attr "type" "fpspc")
15085 (set_attr "mode" "<MODE>")])
15087 (define_insn "fist<mode>2_with_temp"
15088 [(set (match_operand:SWI24 0 "register_operand" "=r")
15089 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15091 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15092 "TARGET_USE_FANCY_MATH_387"
15094 [(set_attr "type" "fpspc")
15095 (set_attr "mode" "<MODE>")])
15098 [(set (match_operand:SWI24 0 "register_operand")
15099 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15101 (clobber (match_operand:SWI24 2 "memory_operand"))]
15103 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15104 (set (match_dup 0) (match_dup 2))])
15107 [(set (match_operand:SWI24 0 "memory_operand")
15108 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15110 (clobber (match_operand:SWI24 2 "memory_operand"))]
15112 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15114 (define_expand "lrintxf<mode>2"
15115 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15116 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15118 "TARGET_USE_FANCY_MATH_387")
15120 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15121 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15122 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15123 UNSPEC_FIX_NOTRUNC))]
15124 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15126 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15127 [(match_operand:SWI248x 0 "nonimmediate_operand")
15128 (match_operand:X87MODEF 1 "register_operand")]
15129 "(TARGET_USE_FANCY_MATH_387
15130 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15131 || TARGET_MIX_SSE_I387)
15132 && flag_unsafe_math_optimizations)
15133 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15134 && <SWI248x:MODE>mode != HImode
15135 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15136 && !flag_trapping_math && !flag_rounding_math)"
15138 if (optimize_insn_for_size_p ())
15141 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15142 && <SWI248x:MODE>mode != HImode
15143 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15144 && !flag_trapping_math && !flag_rounding_math)
15145 ix86_expand_lround (operands[0], operands[1]);
15147 ix86_emit_i387_round (operands[0], operands[1]);
15151 (define_int_iterator FRNDINT_ROUNDING
15152 [UNSPEC_FRNDINT_FLOOR
15153 UNSPEC_FRNDINT_CEIL
15154 UNSPEC_FRNDINT_TRUNC])
15156 (define_int_iterator FIST_ROUNDING
15160 ;; Base name for define_insn
15161 (define_int_attr rounding_insn
15162 [(UNSPEC_FRNDINT_FLOOR "floor")
15163 (UNSPEC_FRNDINT_CEIL "ceil")
15164 (UNSPEC_FRNDINT_TRUNC "btrunc")
15165 (UNSPEC_FIST_FLOOR "floor")
15166 (UNSPEC_FIST_CEIL "ceil")])
15168 (define_int_attr rounding
15169 [(UNSPEC_FRNDINT_FLOOR "floor")
15170 (UNSPEC_FRNDINT_CEIL "ceil")
15171 (UNSPEC_FRNDINT_TRUNC "trunc")
15172 (UNSPEC_FIST_FLOOR "floor")
15173 (UNSPEC_FIST_CEIL "ceil")])
15175 (define_int_attr ROUNDING
15176 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15177 (UNSPEC_FRNDINT_CEIL "CEIL")
15178 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15179 (UNSPEC_FIST_FLOOR "FLOOR")
15180 (UNSPEC_FIST_CEIL "CEIL")])
15182 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15183 (define_insn_and_split "frndintxf2_<rounding>"
15184 [(set (match_operand:XF 0 "register_operand")
15185 (unspec:XF [(match_operand:XF 1 "register_operand")]
15187 (clobber (reg:CC FLAGS_REG))]
15188 "TARGET_USE_FANCY_MATH_387
15189 && flag_unsafe_math_optimizations
15190 && can_create_pseudo_p ()"
15195 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15197 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15198 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15200 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15201 operands[2], operands[3]));
15204 [(set_attr "type" "frndint")
15205 (set_attr "i387_cw" "<rounding>")
15206 (set_attr "mode" "XF")])
15208 (define_insn "frndintxf2_<rounding>_i387"
15209 [(set (match_operand:XF 0 "register_operand" "=f")
15210 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15212 (use (match_operand:HI 2 "memory_operand" "m"))
15213 (use (match_operand:HI 3 "memory_operand" "m"))]
15214 "TARGET_USE_FANCY_MATH_387
15215 && flag_unsafe_math_optimizations"
15216 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15217 [(set_attr "type" "frndint")
15218 (set_attr "i387_cw" "<rounding>")
15219 (set_attr "mode" "XF")])
15221 (define_expand "<rounding_insn>xf2"
15222 [(parallel [(set (match_operand:XF 0 "register_operand")
15223 (unspec:XF [(match_operand:XF 1 "register_operand")]
15225 (clobber (reg:CC FLAGS_REG))])]
15226 "TARGET_USE_FANCY_MATH_387
15227 && flag_unsafe_math_optimizations
15228 && !optimize_insn_for_size_p ()")
15230 (define_expand "<rounding_insn><mode>2"
15231 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15232 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15234 (clobber (reg:CC FLAGS_REG))])]
15235 "(TARGET_USE_FANCY_MATH_387
15236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15237 || TARGET_MIX_SSE_I387)
15238 && flag_unsafe_math_optimizations)
15239 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15240 && !flag_trapping_math)"
15242 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15243 && !flag_trapping_math)
15246 emit_insn (gen_sse4_1_round<mode>2
15247 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15248 else if (optimize_insn_for_size_p ())
15250 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15252 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15253 ix86_expand_floorceil (operands[0], operands[1], true);
15254 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15255 ix86_expand_floorceil (operands[0], operands[1], false);
15256 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15257 ix86_expand_trunc (operands[0], operands[1]);
15259 gcc_unreachable ();
15263 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15264 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15265 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15266 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15267 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15268 ix86_expand_truncdf_32 (operands[0], operands[1]);
15270 gcc_unreachable ();
15277 if (optimize_insn_for_size_p ())
15280 op0 = gen_reg_rtx (XFmode);
15281 op1 = gen_reg_rtx (XFmode);
15282 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15283 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15285 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15290 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15291 (define_insn_and_split "frndintxf2_mask_pm"
15292 [(set (match_operand:XF 0 "register_operand")
15293 (unspec:XF [(match_operand:XF 1 "register_operand")]
15294 UNSPEC_FRNDINT_MASK_PM))
15295 (clobber (reg:CC FLAGS_REG))]
15296 "TARGET_USE_FANCY_MATH_387
15297 && flag_unsafe_math_optimizations
15298 && can_create_pseudo_p ()"
15303 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15305 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15306 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15308 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15309 operands[2], operands[3]));
15312 [(set_attr "type" "frndint")
15313 (set_attr "i387_cw" "mask_pm")
15314 (set_attr "mode" "XF")])
15316 (define_insn "frndintxf2_mask_pm_i387"
15317 [(set (match_operand:XF 0 "register_operand" "=f")
15318 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15319 UNSPEC_FRNDINT_MASK_PM))
15320 (use (match_operand:HI 2 "memory_operand" "m"))
15321 (use (match_operand:HI 3 "memory_operand" "m"))]
15322 "TARGET_USE_FANCY_MATH_387
15323 && flag_unsafe_math_optimizations"
15324 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15325 [(set_attr "type" "frndint")
15326 (set_attr "i387_cw" "mask_pm")
15327 (set_attr "mode" "XF")])
15329 (define_expand "nearbyintxf2"
15330 [(parallel [(set (match_operand:XF 0 "register_operand")
15331 (unspec:XF [(match_operand:XF 1 "register_operand")]
15332 UNSPEC_FRNDINT_MASK_PM))
15333 (clobber (reg:CC FLAGS_REG))])]
15334 "TARGET_USE_FANCY_MATH_387
15335 && flag_unsafe_math_optimizations")
15337 (define_expand "nearbyint<mode>2"
15338 [(use (match_operand:MODEF 0 "register_operand"))
15339 (use (match_operand:MODEF 1 "register_operand"))]
15340 "TARGET_USE_FANCY_MATH_387
15341 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15342 || TARGET_MIX_SSE_I387)
15343 && flag_unsafe_math_optimizations"
15345 rtx op0 = gen_reg_rtx (XFmode);
15346 rtx op1 = gen_reg_rtx (XFmode);
15348 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15349 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15351 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15355 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15356 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15357 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15358 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15360 (clobber (reg:CC FLAGS_REG))]
15361 "TARGET_USE_FANCY_MATH_387
15362 && flag_unsafe_math_optimizations
15363 && can_create_pseudo_p ()"
15368 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15370 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15371 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15372 if (memory_operand (operands[0], VOIDmode))
15373 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15374 operands[2], operands[3]));
15377 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15378 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15379 (operands[0], operands[1], operands[2],
15380 operands[3], operands[4]));
15384 [(set_attr "type" "fistp")
15385 (set_attr "i387_cw" "<rounding>")
15386 (set_attr "mode" "<MODE>")])
15388 (define_insn "fistdi2_<rounding>"
15389 [(set (match_operand:DI 0 "memory_operand" "=m")
15390 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15392 (use (match_operand:HI 2 "memory_operand" "m"))
15393 (use (match_operand:HI 3 "memory_operand" "m"))
15394 (clobber (match_scratch:XF 4 "=&1f"))]
15395 "TARGET_USE_FANCY_MATH_387
15396 && flag_unsafe_math_optimizations"
15397 "* return output_fix_trunc (insn, operands, false);"
15398 [(set_attr "type" "fistp")
15399 (set_attr "i387_cw" "<rounding>")
15400 (set_attr "mode" "DI")])
15402 (define_insn "fistdi2_<rounding>_with_temp"
15403 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15404 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15406 (use (match_operand:HI 2 "memory_operand" "m,m"))
15407 (use (match_operand:HI 3 "memory_operand" "m,m"))
15408 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15409 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15410 "TARGET_USE_FANCY_MATH_387
15411 && flag_unsafe_math_optimizations"
15413 [(set_attr "type" "fistp")
15414 (set_attr "i387_cw" "<rounding>")
15415 (set_attr "mode" "DI")])
15418 [(set (match_operand:DI 0 "register_operand")
15419 (unspec:DI [(match_operand:XF 1 "register_operand")]
15421 (use (match_operand:HI 2 "memory_operand"))
15422 (use (match_operand:HI 3 "memory_operand"))
15423 (clobber (match_operand:DI 4 "memory_operand"))
15424 (clobber (match_scratch 5))]
15426 [(parallel [(set (match_dup 4)
15427 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15428 (use (match_dup 2))
15429 (use (match_dup 3))
15430 (clobber (match_dup 5))])
15431 (set (match_dup 0) (match_dup 4))])
15434 [(set (match_operand:DI 0 "memory_operand")
15435 (unspec:DI [(match_operand:XF 1 "register_operand")]
15437 (use (match_operand:HI 2 "memory_operand"))
15438 (use (match_operand:HI 3 "memory_operand"))
15439 (clobber (match_operand:DI 4 "memory_operand"))
15440 (clobber (match_scratch 5))]
15442 [(parallel [(set (match_dup 0)
15443 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15444 (use (match_dup 2))
15445 (use (match_dup 3))
15446 (clobber (match_dup 5))])])
15448 (define_insn "fist<mode>2_<rounding>"
15449 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15450 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15452 (use (match_operand:HI 2 "memory_operand" "m"))
15453 (use (match_operand:HI 3 "memory_operand" "m"))]
15454 "TARGET_USE_FANCY_MATH_387
15455 && flag_unsafe_math_optimizations"
15456 "* return output_fix_trunc (insn, operands, false);"
15457 [(set_attr "type" "fistp")
15458 (set_attr "i387_cw" "<rounding>")
15459 (set_attr "mode" "<MODE>")])
15461 (define_insn "fist<mode>2_<rounding>_with_temp"
15462 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15463 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15465 (use (match_operand:HI 2 "memory_operand" "m,m"))
15466 (use (match_operand:HI 3 "memory_operand" "m,m"))
15467 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15468 "TARGET_USE_FANCY_MATH_387
15469 && flag_unsafe_math_optimizations"
15471 [(set_attr "type" "fistp")
15472 (set_attr "i387_cw" "<rounding>")
15473 (set_attr "mode" "<MODE>")])
15476 [(set (match_operand:SWI24 0 "register_operand")
15477 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15479 (use (match_operand:HI 2 "memory_operand"))
15480 (use (match_operand:HI 3 "memory_operand"))
15481 (clobber (match_operand:SWI24 4 "memory_operand"))]
15483 [(parallel [(set (match_dup 4)
15484 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15485 (use (match_dup 2))
15486 (use (match_dup 3))])
15487 (set (match_dup 0) (match_dup 4))])
15490 [(set (match_operand:SWI24 0 "memory_operand")
15491 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15493 (use (match_operand:HI 2 "memory_operand"))
15494 (use (match_operand:HI 3 "memory_operand"))
15495 (clobber (match_operand:SWI24 4 "memory_operand"))]
15497 [(parallel [(set (match_dup 0)
15498 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15499 (use (match_dup 2))
15500 (use (match_dup 3))])])
15502 (define_expand "l<rounding_insn>xf<mode>2"
15503 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15504 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15506 (clobber (reg:CC FLAGS_REG))])]
15507 "TARGET_USE_FANCY_MATH_387
15508 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15509 && flag_unsafe_math_optimizations")
15511 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15512 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15513 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15515 (clobber (reg:CC FLAGS_REG))])]
15516 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15517 && !flag_trapping_math"
15519 if (TARGET_64BIT && optimize_insn_for_size_p ())
15522 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15523 ix86_expand_lfloorceil (operands[0], operands[1], true);
15524 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15525 ix86_expand_lfloorceil (operands[0], operands[1], false);
15527 gcc_unreachable ();
15532 (define_insn "fxam<mode>2_i387"
15533 [(set (match_operand:HI 0 "register_operand" "=a")
15535 [(match_operand:X87MODEF 1 "register_operand" "f")]
15537 "TARGET_USE_FANCY_MATH_387"
15538 "fxam\n\tfnstsw\t%0"
15539 [(set_attr "type" "multi")
15540 (set_attr "length" "4")
15541 (set_attr "unit" "i387")
15542 (set_attr "mode" "<MODE>")])
15544 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15545 [(set (match_operand:HI 0 "register_operand")
15547 [(match_operand:MODEF 1 "memory_operand")]
15549 "TARGET_USE_FANCY_MATH_387
15550 && can_create_pseudo_p ()"
15553 [(set (match_dup 2)(match_dup 1))
15555 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15557 operands[2] = gen_reg_rtx (<MODE>mode);
15559 MEM_VOLATILE_P (operands[1]) = 1;
15561 [(set_attr "type" "multi")
15562 (set_attr "unit" "i387")
15563 (set_attr "mode" "<MODE>")])
15565 (define_expand "isinfxf2"
15566 [(use (match_operand:SI 0 "register_operand"))
15567 (use (match_operand:XF 1 "register_operand"))]
15568 "TARGET_USE_FANCY_MATH_387
15569 && ix86_libc_has_function (function_c99_misc)"
15571 rtx mask = GEN_INT (0x45);
15572 rtx val = GEN_INT (0x05);
15576 rtx scratch = gen_reg_rtx (HImode);
15577 rtx res = gen_reg_rtx (QImode);
15579 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15581 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15582 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15583 cond = gen_rtx_fmt_ee (EQ, QImode,
15584 gen_rtx_REG (CCmode, FLAGS_REG),
15586 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15587 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15591 (define_expand "isinf<mode>2"
15592 [(use (match_operand:SI 0 "register_operand"))
15593 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15594 "TARGET_USE_FANCY_MATH_387
15595 && ix86_libc_has_function (function_c99_misc)
15596 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15598 rtx mask = GEN_INT (0x45);
15599 rtx val = GEN_INT (0x05);
15603 rtx scratch = gen_reg_rtx (HImode);
15604 rtx res = gen_reg_rtx (QImode);
15606 /* Remove excess precision by forcing value through memory. */
15607 if (memory_operand (operands[1], VOIDmode))
15608 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15611 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15613 emit_move_insn (temp, operands[1]);
15614 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15617 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15618 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15619 cond = gen_rtx_fmt_ee (EQ, QImode,
15620 gen_rtx_REG (CCmode, FLAGS_REG),
15622 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15623 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15627 (define_expand "signbitxf2"
15628 [(use (match_operand:SI 0 "register_operand"))
15629 (use (match_operand:XF 1 "register_operand"))]
15630 "TARGET_USE_FANCY_MATH_387"
15632 rtx scratch = gen_reg_rtx (HImode);
15634 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15635 emit_insn (gen_andsi3 (operands[0],
15636 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15640 (define_insn "movmsk_df"
15641 [(set (match_operand:SI 0 "register_operand" "=r")
15643 [(match_operand:DF 1 "register_operand" "x")]
15645 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15646 "%vmovmskpd\t{%1, %0|%0, %1}"
15647 [(set_attr "type" "ssemov")
15648 (set_attr "prefix" "maybe_vex")
15649 (set_attr "mode" "DF")])
15651 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15652 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15653 (define_expand "signbitdf2"
15654 [(use (match_operand:SI 0 "register_operand"))
15655 (use (match_operand:DF 1 "register_operand"))]
15656 "TARGET_USE_FANCY_MATH_387
15657 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15659 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15661 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15662 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15666 rtx scratch = gen_reg_rtx (HImode);
15668 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15669 emit_insn (gen_andsi3 (operands[0],
15670 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15675 (define_expand "signbitsf2"
15676 [(use (match_operand:SI 0 "register_operand"))
15677 (use (match_operand:SF 1 "register_operand"))]
15678 "TARGET_USE_FANCY_MATH_387
15679 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15681 rtx scratch = gen_reg_rtx (HImode);
15683 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15684 emit_insn (gen_andsi3 (operands[0],
15685 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15689 ;; Block operation instructions
15692 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15695 [(set_attr "length" "1")
15696 (set_attr "length_immediate" "0")
15697 (set_attr "modrm" "0")])
15699 (define_expand "movmem<mode>"
15700 [(use (match_operand:BLK 0 "memory_operand"))
15701 (use (match_operand:BLK 1 "memory_operand"))
15702 (use (match_operand:SWI48 2 "nonmemory_operand"))
15703 (use (match_operand:SWI48 3 "const_int_operand"))
15704 (use (match_operand:SI 4 "const_int_operand"))
15705 (use (match_operand:SI 5 "const_int_operand"))
15706 (use (match_operand:SI 6 ""))
15707 (use (match_operand:SI 7 ""))
15708 (use (match_operand:SI 8 ""))]
15711 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15712 operands[2], NULL, operands[3],
15713 operands[4], operands[5],
15714 operands[6], operands[7],
15715 operands[8], false))
15721 ;; Most CPUs don't like single string operations
15722 ;; Handle this case here to simplify previous expander.
15724 (define_expand "strmov"
15725 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15726 (set (match_operand 1 "memory_operand") (match_dup 4))
15727 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15728 (clobber (reg:CC FLAGS_REG))])
15729 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15730 (clobber (reg:CC FLAGS_REG))])]
15733 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15735 /* If .md ever supports :P for Pmode, these can be directly
15736 in the pattern above. */
15737 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15738 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15740 /* Can't use this if the user has appropriated esi or edi. */
15741 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15742 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15744 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15745 operands[2], operands[3],
15746 operands[5], operands[6]));
15750 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15753 (define_expand "strmov_singleop"
15754 [(parallel [(set (match_operand 1 "memory_operand")
15755 (match_operand 3 "memory_operand"))
15756 (set (match_operand 0 "register_operand")
15758 (set (match_operand 2 "register_operand")
15759 (match_operand 5))])]
15761 "ix86_current_function_needs_cld = 1;")
15763 (define_insn "*strmovdi_rex_1"
15764 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15765 (mem:DI (match_operand:P 3 "register_operand" "1")))
15766 (set (match_operand:P 0 "register_operand" "=D")
15767 (plus:P (match_dup 2)
15769 (set (match_operand:P 1 "register_operand" "=S")
15770 (plus:P (match_dup 3)
15773 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15775 [(set_attr "type" "str")
15776 (set_attr "memory" "both")
15777 (set_attr "mode" "DI")])
15779 (define_insn "*strmovsi_1"
15780 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15781 (mem:SI (match_operand:P 3 "register_operand" "1")))
15782 (set (match_operand:P 0 "register_operand" "=D")
15783 (plus:P (match_dup 2)
15785 (set (match_operand:P 1 "register_operand" "=S")
15786 (plus:P (match_dup 3)
15788 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15790 [(set_attr "type" "str")
15791 (set_attr "memory" "both")
15792 (set_attr "mode" "SI")])
15794 (define_insn "*strmovhi_1"
15795 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15796 (mem:HI (match_operand:P 3 "register_operand" "1")))
15797 (set (match_operand:P 0 "register_operand" "=D")
15798 (plus:P (match_dup 2)
15800 (set (match_operand:P 1 "register_operand" "=S")
15801 (plus:P (match_dup 3)
15803 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15805 [(set_attr "type" "str")
15806 (set_attr "memory" "both")
15807 (set_attr "mode" "HI")])
15809 (define_insn "*strmovqi_1"
15810 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15811 (mem:QI (match_operand:P 3 "register_operand" "1")))
15812 (set (match_operand:P 0 "register_operand" "=D")
15813 (plus:P (match_dup 2)
15815 (set (match_operand:P 1 "register_operand" "=S")
15816 (plus:P (match_dup 3)
15818 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15820 [(set_attr "type" "str")
15821 (set_attr "memory" "both")
15822 (set (attr "prefix_rex")
15824 (match_test "<P:MODE>mode == DImode")
15826 (const_string "*")))
15827 (set_attr "mode" "QI")])
15829 (define_expand "rep_mov"
15830 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15831 (set (match_operand 0 "register_operand")
15833 (set (match_operand 2 "register_operand")
15835 (set (match_operand 1 "memory_operand")
15836 (match_operand 3 "memory_operand"))
15837 (use (match_dup 4))])]
15839 "ix86_current_function_needs_cld = 1;")
15841 (define_insn "*rep_movdi_rex64"
15842 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15843 (set (match_operand:P 0 "register_operand" "=D")
15844 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15846 (match_operand:P 3 "register_operand" "0")))
15847 (set (match_operand:P 1 "register_operand" "=S")
15848 (plus:P (ashift:P (match_dup 5) (const_int 3))
15849 (match_operand:P 4 "register_operand" "1")))
15850 (set (mem:BLK (match_dup 3))
15851 (mem:BLK (match_dup 4)))
15852 (use (match_dup 5))]
15854 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15856 [(set_attr "type" "str")
15857 (set_attr "prefix_rep" "1")
15858 (set_attr "memory" "both")
15859 (set_attr "mode" "DI")])
15861 (define_insn "*rep_movsi"
15862 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15863 (set (match_operand:P 0 "register_operand" "=D")
15864 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15866 (match_operand:P 3 "register_operand" "0")))
15867 (set (match_operand:P 1 "register_operand" "=S")
15868 (plus:P (ashift:P (match_dup 5) (const_int 2))
15869 (match_operand:P 4 "register_operand" "1")))
15870 (set (mem:BLK (match_dup 3))
15871 (mem:BLK (match_dup 4)))
15872 (use (match_dup 5))]
15873 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15874 "%^rep{%;} movs{l|d}"
15875 [(set_attr "type" "str")
15876 (set_attr "prefix_rep" "1")
15877 (set_attr "memory" "both")
15878 (set_attr "mode" "SI")])
15880 (define_insn "*rep_movqi"
15881 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15882 (set (match_operand:P 0 "register_operand" "=D")
15883 (plus:P (match_operand:P 3 "register_operand" "0")
15884 (match_operand:P 5 "register_operand" "2")))
15885 (set (match_operand:P 1 "register_operand" "=S")
15886 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15887 (set (mem:BLK (match_dup 3))
15888 (mem:BLK (match_dup 4)))
15889 (use (match_dup 5))]
15890 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15892 [(set_attr "type" "str")
15893 (set_attr "prefix_rep" "1")
15894 (set_attr "memory" "both")
15895 (set_attr "mode" "QI")])
15897 (define_expand "setmem<mode>"
15898 [(use (match_operand:BLK 0 "memory_operand"))
15899 (use (match_operand:SWI48 1 "nonmemory_operand"))
15900 (use (match_operand:QI 2 "nonmemory_operand"))
15901 (use (match_operand 3 "const_int_operand"))
15902 (use (match_operand:SI 4 "const_int_operand"))
15903 (use (match_operand:SI 5 "const_int_operand"))
15904 (use (match_operand:SI 6 ""))
15905 (use (match_operand:SI 7 ""))
15906 (use (match_operand:SI 8 ""))]
15909 if (ix86_expand_set_or_movmem (operands[0], NULL,
15910 operands[1], operands[2],
15911 operands[3], operands[4],
15912 operands[5], operands[6],
15913 operands[7], operands[8], true))
15919 ;; Most CPUs don't like single string operations
15920 ;; Handle this case here to simplify previous expander.
15922 (define_expand "strset"
15923 [(set (match_operand 1 "memory_operand")
15924 (match_operand 2 "register_operand"))
15925 (parallel [(set (match_operand 0 "register_operand")
15927 (clobber (reg:CC FLAGS_REG))])]
15930 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15931 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15933 /* If .md ever supports :P for Pmode, this can be directly
15934 in the pattern above. */
15935 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15936 GEN_INT (GET_MODE_SIZE (GET_MODE
15938 /* Can't use this if the user has appropriated eax or edi. */
15939 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15940 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15942 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15948 (define_expand "strset_singleop"
15949 [(parallel [(set (match_operand 1 "memory_operand")
15950 (match_operand 2 "register_operand"))
15951 (set (match_operand 0 "register_operand")
15953 (unspec [(const_int 0)] UNSPEC_STOS)])]
15955 "ix86_current_function_needs_cld = 1;")
15957 (define_insn "*strsetdi_rex_1"
15958 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15959 (match_operand:DI 2 "register_operand" "a"))
15960 (set (match_operand:P 0 "register_operand" "=D")
15961 (plus:P (match_dup 1)
15963 (unspec [(const_int 0)] UNSPEC_STOS)]
15965 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15967 [(set_attr "type" "str")
15968 (set_attr "memory" "store")
15969 (set_attr "mode" "DI")])
15971 (define_insn "*strsetsi_1"
15972 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15973 (match_operand:SI 2 "register_operand" "a"))
15974 (set (match_operand:P 0 "register_operand" "=D")
15975 (plus:P (match_dup 1)
15977 (unspec [(const_int 0)] UNSPEC_STOS)]
15978 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15980 [(set_attr "type" "str")
15981 (set_attr "memory" "store")
15982 (set_attr "mode" "SI")])
15984 (define_insn "*strsethi_1"
15985 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15986 (match_operand:HI 2 "register_operand" "a"))
15987 (set (match_operand:P 0 "register_operand" "=D")
15988 (plus:P (match_dup 1)
15990 (unspec [(const_int 0)] UNSPEC_STOS)]
15991 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15993 [(set_attr "type" "str")
15994 (set_attr "memory" "store")
15995 (set_attr "mode" "HI")])
15997 (define_insn "*strsetqi_1"
15998 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15999 (match_operand:QI 2 "register_operand" "a"))
16000 (set (match_operand:P 0 "register_operand" "=D")
16001 (plus:P (match_dup 1)
16003 (unspec [(const_int 0)] UNSPEC_STOS)]
16004 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16006 [(set_attr "type" "str")
16007 (set_attr "memory" "store")
16008 (set (attr "prefix_rex")
16010 (match_test "<P:MODE>mode == DImode")
16012 (const_string "*")))
16013 (set_attr "mode" "QI")])
16015 (define_expand "rep_stos"
16016 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16017 (set (match_operand 0 "register_operand")
16019 (set (match_operand 2 "memory_operand") (const_int 0))
16020 (use (match_operand 3 "register_operand"))
16021 (use (match_dup 1))])]
16023 "ix86_current_function_needs_cld = 1;")
16025 (define_insn "*rep_stosdi_rex64"
16026 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16027 (set (match_operand:P 0 "register_operand" "=D")
16028 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16030 (match_operand:P 3 "register_operand" "0")))
16031 (set (mem:BLK (match_dup 3))
16033 (use (match_operand:DI 2 "register_operand" "a"))
16034 (use (match_dup 4))]
16036 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16038 [(set_attr "type" "str")
16039 (set_attr "prefix_rep" "1")
16040 (set_attr "memory" "store")
16041 (set_attr "mode" "DI")])
16043 (define_insn "*rep_stossi"
16044 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16045 (set (match_operand:P 0 "register_operand" "=D")
16046 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16048 (match_operand:P 3 "register_operand" "0")))
16049 (set (mem:BLK (match_dup 3))
16051 (use (match_operand:SI 2 "register_operand" "a"))
16052 (use (match_dup 4))]
16053 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16054 "%^rep{%;} stos{l|d}"
16055 [(set_attr "type" "str")
16056 (set_attr "prefix_rep" "1")
16057 (set_attr "memory" "store")
16058 (set_attr "mode" "SI")])
16060 (define_insn "*rep_stosqi"
16061 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16062 (set (match_operand:P 0 "register_operand" "=D")
16063 (plus:P (match_operand:P 3 "register_operand" "0")
16064 (match_operand:P 4 "register_operand" "1")))
16065 (set (mem:BLK (match_dup 3))
16067 (use (match_operand:QI 2 "register_operand" "a"))
16068 (use (match_dup 4))]
16069 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16071 [(set_attr "type" "str")
16072 (set_attr "prefix_rep" "1")
16073 (set_attr "memory" "store")
16074 (set (attr "prefix_rex")
16076 (match_test "<P:MODE>mode == DImode")
16078 (const_string "*")))
16079 (set_attr "mode" "QI")])
16081 (define_expand "cmpstrnsi"
16082 [(set (match_operand:SI 0 "register_operand")
16083 (compare:SI (match_operand:BLK 1 "general_operand")
16084 (match_operand:BLK 2 "general_operand")))
16085 (use (match_operand 3 "general_operand"))
16086 (use (match_operand 4 "immediate_operand"))]
16089 rtx addr1, addr2, out, outlow, count, countreg, align;
16091 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16094 /* Can't use this if the user has appropriated ecx, esi or edi. */
16095 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16100 out = gen_reg_rtx (SImode);
16102 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16103 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16104 if (addr1 != XEXP (operands[1], 0))
16105 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16106 if (addr2 != XEXP (operands[2], 0))
16107 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16109 count = operands[3];
16110 countreg = ix86_zero_extend_to_Pmode (count);
16112 /* %%% Iff we are testing strict equality, we can use known alignment
16113 to good advantage. This may be possible with combine, particularly
16114 once cc0 is dead. */
16115 align = operands[4];
16117 if (CONST_INT_P (count))
16119 if (INTVAL (count) == 0)
16121 emit_move_insn (operands[0], const0_rtx);
16124 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16125 operands[1], operands[2]));
16129 rtx (*gen_cmp) (rtx, rtx);
16131 gen_cmp = (TARGET_64BIT
16132 ? gen_cmpdi_1 : gen_cmpsi_1);
16134 emit_insn (gen_cmp (countreg, countreg));
16135 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16136 operands[1], operands[2]));
16139 outlow = gen_lowpart (QImode, out);
16140 emit_insn (gen_cmpintqi (outlow));
16141 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16143 if (operands[0] != out)
16144 emit_move_insn (operands[0], out);
16149 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16151 (define_expand "cmpintqi"
16152 [(set (match_dup 1)
16153 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16155 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16156 (parallel [(set (match_operand:QI 0 "register_operand")
16157 (minus:QI (match_dup 1)
16159 (clobber (reg:CC FLAGS_REG))])]
16162 operands[1] = gen_reg_rtx (QImode);
16163 operands[2] = gen_reg_rtx (QImode);
16166 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16167 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16169 (define_expand "cmpstrnqi_nz_1"
16170 [(parallel [(set (reg:CC FLAGS_REG)
16171 (compare:CC (match_operand 4 "memory_operand")
16172 (match_operand 5 "memory_operand")))
16173 (use (match_operand 2 "register_operand"))
16174 (use (match_operand:SI 3 "immediate_operand"))
16175 (clobber (match_operand 0 "register_operand"))
16176 (clobber (match_operand 1 "register_operand"))
16177 (clobber (match_dup 2))])]
16179 "ix86_current_function_needs_cld = 1;")
16181 (define_insn "*cmpstrnqi_nz_1"
16182 [(set (reg:CC FLAGS_REG)
16183 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16184 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16185 (use (match_operand:P 6 "register_operand" "2"))
16186 (use (match_operand:SI 3 "immediate_operand" "i"))
16187 (clobber (match_operand:P 0 "register_operand" "=S"))
16188 (clobber (match_operand:P 1 "register_operand" "=D"))
16189 (clobber (match_operand:P 2 "register_operand" "=c"))]
16190 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16192 [(set_attr "type" "str")
16193 (set_attr "mode" "QI")
16194 (set (attr "prefix_rex")
16196 (match_test "<P:MODE>mode == DImode")
16198 (const_string "*")))
16199 (set_attr "prefix_rep" "1")])
16201 ;; The same, but the count is not known to not be zero.
16203 (define_expand "cmpstrnqi_1"
16204 [(parallel [(set (reg:CC FLAGS_REG)
16205 (if_then_else:CC (ne (match_operand 2 "register_operand")
16207 (compare:CC (match_operand 4 "memory_operand")
16208 (match_operand 5 "memory_operand"))
16210 (use (match_operand:SI 3 "immediate_operand"))
16211 (use (reg:CC FLAGS_REG))
16212 (clobber (match_operand 0 "register_operand"))
16213 (clobber (match_operand 1 "register_operand"))
16214 (clobber (match_dup 2))])]
16216 "ix86_current_function_needs_cld = 1;")
16218 (define_insn "*cmpstrnqi_1"
16219 [(set (reg:CC FLAGS_REG)
16220 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16222 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16223 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16225 (use (match_operand:SI 3 "immediate_operand" "i"))
16226 (use (reg:CC FLAGS_REG))
16227 (clobber (match_operand:P 0 "register_operand" "=S"))
16228 (clobber (match_operand:P 1 "register_operand" "=D"))
16229 (clobber (match_operand:P 2 "register_operand" "=c"))]
16230 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16232 [(set_attr "type" "str")
16233 (set_attr "mode" "QI")
16234 (set (attr "prefix_rex")
16236 (match_test "<P:MODE>mode == DImode")
16238 (const_string "*")))
16239 (set_attr "prefix_rep" "1")])
16241 (define_expand "strlen<mode>"
16242 [(set (match_operand:P 0 "register_operand")
16243 (unspec:P [(match_operand:BLK 1 "general_operand")
16244 (match_operand:QI 2 "immediate_operand")
16245 (match_operand 3 "immediate_operand")]
16249 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16255 (define_expand "strlenqi_1"
16256 [(parallel [(set (match_operand 0 "register_operand")
16258 (clobber (match_operand 1 "register_operand"))
16259 (clobber (reg:CC FLAGS_REG))])]
16261 "ix86_current_function_needs_cld = 1;")
16263 (define_insn "*strlenqi_1"
16264 [(set (match_operand:P 0 "register_operand" "=&c")
16265 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16266 (match_operand:QI 2 "register_operand" "a")
16267 (match_operand:P 3 "immediate_operand" "i")
16268 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16269 (clobber (match_operand:P 1 "register_operand" "=D"))
16270 (clobber (reg:CC FLAGS_REG))]
16271 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16272 "%^repnz{%;} scasb"
16273 [(set_attr "type" "str")
16274 (set_attr "mode" "QI")
16275 (set (attr "prefix_rex")
16277 (match_test "<P:MODE>mode == DImode")
16279 (const_string "*")))
16280 (set_attr "prefix_rep" "1")])
16282 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16283 ;; handled in combine, but it is not currently up to the task.
16284 ;; When used for their truth value, the cmpstrn* expanders generate
16293 ;; The intermediate three instructions are unnecessary.
16295 ;; This one handles cmpstrn*_nz_1...
16298 (set (reg:CC FLAGS_REG)
16299 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16300 (mem:BLK (match_operand 5 "register_operand"))))
16301 (use (match_operand 6 "register_operand"))
16302 (use (match_operand:SI 3 "immediate_operand"))
16303 (clobber (match_operand 0 "register_operand"))
16304 (clobber (match_operand 1 "register_operand"))
16305 (clobber (match_operand 2 "register_operand"))])
16306 (set (match_operand:QI 7 "register_operand")
16307 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16308 (set (match_operand:QI 8 "register_operand")
16309 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16310 (set (reg FLAGS_REG)
16311 (compare (match_dup 7) (match_dup 8)))
16313 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16315 (set (reg:CC FLAGS_REG)
16316 (compare:CC (mem:BLK (match_dup 4))
16317 (mem:BLK (match_dup 5))))
16318 (use (match_dup 6))
16319 (use (match_dup 3))
16320 (clobber (match_dup 0))
16321 (clobber (match_dup 1))
16322 (clobber (match_dup 2))])])
16324 ;; ...and this one handles cmpstrn*_1.
16327 (set (reg:CC FLAGS_REG)
16328 (if_then_else:CC (ne (match_operand 6 "register_operand")
16330 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16331 (mem:BLK (match_operand 5 "register_operand")))
16333 (use (match_operand:SI 3 "immediate_operand"))
16334 (use (reg:CC FLAGS_REG))
16335 (clobber (match_operand 0 "register_operand"))
16336 (clobber (match_operand 1 "register_operand"))
16337 (clobber (match_operand 2 "register_operand"))])
16338 (set (match_operand:QI 7 "register_operand")
16339 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16340 (set (match_operand:QI 8 "register_operand")
16341 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16342 (set (reg FLAGS_REG)
16343 (compare (match_dup 7) (match_dup 8)))
16345 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16347 (set (reg:CC FLAGS_REG)
16348 (if_then_else:CC (ne (match_dup 6)
16350 (compare:CC (mem:BLK (match_dup 4))
16351 (mem:BLK (match_dup 5)))
16353 (use (match_dup 3))
16354 (use (reg:CC FLAGS_REG))
16355 (clobber (match_dup 0))
16356 (clobber (match_dup 1))
16357 (clobber (match_dup 2))])])
16359 ;; Conditional move instructions.
16361 (define_expand "mov<mode>cc"
16362 [(set (match_operand:SWIM 0 "register_operand")
16363 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16364 (match_operand:SWIM 2 "<general_operand>")
16365 (match_operand:SWIM 3 "<general_operand>")))]
16367 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16369 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16370 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16371 ;; So just document what we're doing explicitly.
16373 (define_expand "x86_mov<mode>cc_0_m1"
16375 [(set (match_operand:SWI48 0 "register_operand")
16376 (if_then_else:SWI48
16377 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16378 [(match_operand 1 "flags_reg_operand")
16382 (clobber (reg:CC FLAGS_REG))])])
16384 (define_insn "*x86_mov<mode>cc_0_m1"
16385 [(set (match_operand:SWI48 0 "register_operand" "=r")
16386 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16387 [(reg FLAGS_REG) (const_int 0)])
16390 (clobber (reg:CC FLAGS_REG))]
16392 "sbb{<imodesuffix>}\t%0, %0"
16393 ; Since we don't have the proper number of operands for an alu insn,
16394 ; fill in all the blanks.
16395 [(set_attr "type" "alu")
16396 (set_attr "use_carry" "1")
16397 (set_attr "pent_pair" "pu")
16398 (set_attr "memory" "none")
16399 (set_attr "imm_disp" "false")
16400 (set_attr "mode" "<MODE>")
16401 (set_attr "length_immediate" "0")])
16403 (define_insn "*x86_mov<mode>cc_0_m1_se"
16404 [(set (match_operand:SWI48 0 "register_operand" "=r")
16405 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16406 [(reg FLAGS_REG) (const_int 0)])
16409 (clobber (reg:CC FLAGS_REG))]
16411 "sbb{<imodesuffix>}\t%0, %0"
16412 [(set_attr "type" "alu")
16413 (set_attr "use_carry" "1")
16414 (set_attr "pent_pair" "pu")
16415 (set_attr "memory" "none")
16416 (set_attr "imm_disp" "false")
16417 (set_attr "mode" "<MODE>")
16418 (set_attr "length_immediate" "0")])
16420 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16421 [(set (match_operand:SWI48 0 "register_operand" "=r")
16422 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16423 [(reg FLAGS_REG) (const_int 0)])))
16424 (clobber (reg:CC FLAGS_REG))]
16426 "sbb{<imodesuffix>}\t%0, %0"
16427 [(set_attr "type" "alu")
16428 (set_attr "use_carry" "1")
16429 (set_attr "pent_pair" "pu")
16430 (set_attr "memory" "none")
16431 (set_attr "imm_disp" "false")
16432 (set_attr "mode" "<MODE>")
16433 (set_attr "length_immediate" "0")])
16435 (define_insn "*mov<mode>cc_noc"
16436 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16437 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16438 [(reg FLAGS_REG) (const_int 0)])
16439 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16440 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16441 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16443 cmov%O2%C1\t{%2, %0|%0, %2}
16444 cmov%O2%c1\t{%3, %0|%0, %3}"
16445 [(set_attr "type" "icmov")
16446 (set_attr "mode" "<MODE>")])
16448 ;; Don't do conditional moves with memory inputs. This splitter helps
16449 ;; register starved x86_32 by forcing inputs into registers before reload.
16451 [(set (match_operand:SWI248 0 "register_operand")
16452 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16453 [(reg FLAGS_REG) (const_int 0)])
16454 (match_operand:SWI248 2 "nonimmediate_operand")
16455 (match_operand:SWI248 3 "nonimmediate_operand")))]
16456 "!TARGET_64BIT && TARGET_CMOVE
16457 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16458 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16459 && can_create_pseudo_p ()
16460 && optimize_insn_for_speed_p ()"
16461 [(set (match_dup 0)
16462 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16464 if (MEM_P (operands[2]))
16465 operands[2] = force_reg (<MODE>mode, operands[2]);
16466 if (MEM_P (operands[3]))
16467 operands[3] = force_reg (<MODE>mode, operands[3]);
16470 (define_insn "*movqicc_noc"
16471 [(set (match_operand:QI 0 "register_operand" "=r,r")
16472 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16473 [(reg FLAGS_REG) (const_int 0)])
16474 (match_operand:QI 2 "register_operand" "r,0")
16475 (match_operand:QI 3 "register_operand" "0,r")))]
16476 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16478 [(set_attr "type" "icmov")
16479 (set_attr "mode" "QI")])
16482 [(set (match_operand:SWI12 0 "register_operand")
16483 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16484 [(reg FLAGS_REG) (const_int 0)])
16485 (match_operand:SWI12 2 "register_operand")
16486 (match_operand:SWI12 3 "register_operand")))]
16487 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16488 && reload_completed"
16489 [(set (match_dup 0)
16490 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16492 operands[0] = gen_lowpart (SImode, operands[0]);
16493 operands[2] = gen_lowpart (SImode, operands[2]);
16494 operands[3] = gen_lowpart (SImode, operands[3]);
16497 ;; Don't do conditional moves with memory inputs
16499 [(match_scratch:SWI248 2 "r")
16500 (set (match_operand:SWI248 0 "register_operand")
16501 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16502 [(reg FLAGS_REG) (const_int 0)])
16504 (match_operand:SWI248 3 "memory_operand")))]
16505 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16506 && optimize_insn_for_speed_p ()"
16507 [(set (match_dup 2) (match_dup 3))
16509 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16512 [(match_scratch:SWI248 2 "r")
16513 (set (match_operand:SWI248 0 "register_operand")
16514 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16515 [(reg FLAGS_REG) (const_int 0)])
16516 (match_operand:SWI248 3 "memory_operand")
16518 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16519 && optimize_insn_for_speed_p ()"
16520 [(set (match_dup 2) (match_dup 3))
16522 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16524 (define_expand "mov<mode>cc"
16525 [(set (match_operand:X87MODEF 0 "register_operand")
16526 (if_then_else:X87MODEF
16527 (match_operand 1 "comparison_operator")
16528 (match_operand:X87MODEF 2 "register_operand")
16529 (match_operand:X87MODEF 3 "register_operand")))]
16530 "(TARGET_80387 && TARGET_CMOVE)
16531 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16532 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16534 (define_insn "*movxfcc_1"
16535 [(set (match_operand:XF 0 "register_operand" "=f,f")
16536 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16537 [(reg FLAGS_REG) (const_int 0)])
16538 (match_operand:XF 2 "register_operand" "f,0")
16539 (match_operand:XF 3 "register_operand" "0,f")))]
16540 "TARGET_80387 && TARGET_CMOVE"
16542 fcmov%F1\t{%2, %0|%0, %2}
16543 fcmov%f1\t{%3, %0|%0, %3}"
16544 [(set_attr "type" "fcmov")
16545 (set_attr "mode" "XF")])
16547 (define_insn "*movdfcc_1"
16548 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16549 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16550 [(reg FLAGS_REG) (const_int 0)])
16551 (match_operand:DF 2 "nonimmediate_operand"
16553 (match_operand:DF 3 "nonimmediate_operand"
16554 "0 ,f,0 ,rm,0, rm")))]
16555 "TARGET_80387 && TARGET_CMOVE
16556 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16558 fcmov%F1\t{%2, %0|%0, %2}
16559 fcmov%f1\t{%3, %0|%0, %3}
16562 cmov%O2%C1\t{%2, %0|%0, %2}
16563 cmov%O2%c1\t{%3, %0|%0, %3}"
16564 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16565 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16566 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16569 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16570 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16571 [(reg FLAGS_REG) (const_int 0)])
16572 (match_operand:DF 2 "nonimmediate_operand")
16573 (match_operand:DF 3 "nonimmediate_operand")))]
16574 "!TARGET_64BIT && reload_completed"
16575 [(set (match_dup 2)
16576 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16578 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16580 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16581 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16584 (define_insn "*movsfcc_1_387"
16585 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16586 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16587 [(reg FLAGS_REG) (const_int 0)])
16588 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16589 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16590 "TARGET_80387 && TARGET_CMOVE
16591 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16593 fcmov%F1\t{%2, %0|%0, %2}
16594 fcmov%f1\t{%3, %0|%0, %3}
16595 cmov%O2%C1\t{%2, %0|%0, %2}
16596 cmov%O2%c1\t{%3, %0|%0, %3}"
16597 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16598 (set_attr "mode" "SF,SF,SI,SI")])
16600 ;; Don't do conditional moves with memory inputs. This splitter helps
16601 ;; register starved x86_32 by forcing inputs into registers before reload.
16603 [(set (match_operand:MODEF 0 "register_operand")
16604 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16605 [(reg FLAGS_REG) (const_int 0)])
16606 (match_operand:MODEF 2 "nonimmediate_operand")
16607 (match_operand:MODEF 3 "nonimmediate_operand")))]
16608 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16609 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16610 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16611 && can_create_pseudo_p ()
16612 && optimize_insn_for_speed_p ()"
16613 [(set (match_dup 0)
16614 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16616 if (MEM_P (operands[2]))
16617 operands[2] = force_reg (<MODE>mode, operands[2]);
16618 if (MEM_P (operands[3]))
16619 operands[3] = force_reg (<MODE>mode, operands[3]);
16622 ;; Don't do conditional moves with memory inputs
16624 [(match_scratch:MODEF 2 "r")
16625 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16626 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16627 [(reg FLAGS_REG) (const_int 0)])
16629 (match_operand:MODEF 3 "memory_operand")))]
16630 "(<MODE>mode != DFmode || TARGET_64BIT)
16631 && TARGET_80387 && TARGET_CMOVE
16632 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16633 && optimize_insn_for_speed_p ()"
16634 [(set (match_dup 2) (match_dup 3))
16636 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16639 [(match_scratch:MODEF 2 "r")
16640 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16641 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16642 [(reg FLAGS_REG) (const_int 0)])
16643 (match_operand:MODEF 3 "memory_operand")
16645 "(<MODE>mode != DFmode || TARGET_64BIT)
16646 && TARGET_80387 && TARGET_CMOVE
16647 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16648 && optimize_insn_for_speed_p ()"
16649 [(set (match_dup 2) (match_dup 3))
16651 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16653 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16654 ;; the scalar versions to have only XMM registers as operands.
16656 ;; XOP conditional move
16657 (define_insn "*xop_pcmov_<mode>"
16658 [(set (match_operand:MODEF 0 "register_operand" "=x")
16659 (if_then_else:MODEF
16660 (match_operand:MODEF 1 "register_operand" "x")
16661 (match_operand:MODEF 2 "register_operand" "x")
16662 (match_operand:MODEF 3 "register_operand" "x")))]
16664 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16665 [(set_attr "type" "sse4arg")])
16667 ;; These versions of the min/max patterns are intentionally ignorant of
16668 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16669 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16670 ;; are undefined in this condition, we're certain this is correct.
16672 (define_insn "<code><mode>3"
16673 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16675 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16676 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16677 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16679 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16680 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16681 [(set_attr "isa" "noavx,avx")
16682 (set_attr "prefix" "orig,vex")
16683 (set_attr "type" "sseadd")
16684 (set_attr "mode" "<MODE>")])
16686 ;; These versions of the min/max patterns implement exactly the operations
16687 ;; min = (op1 < op2 ? op1 : op2)
16688 ;; max = (!(op1 < op2) ? op1 : op2)
16689 ;; Their operands are not commutative, and thus they may be used in the
16690 ;; presence of -0.0 and NaN.
16692 (define_int_iterator IEEE_MAXMIN
16696 (define_int_attr ieee_maxmin
16697 [(UNSPEC_IEEE_MAX "max")
16698 (UNSPEC_IEEE_MIN "min")])
16700 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16701 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16703 [(match_operand:MODEF 1 "register_operand" "0,x")
16704 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16706 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16708 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16709 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16710 [(set_attr "isa" "noavx,avx")
16711 (set_attr "prefix" "orig,vex")
16712 (set_attr "type" "sseadd")
16713 (set_attr "mode" "<MODE>")])
16715 ;; Make two stack loads independent:
16717 ;; fld %st(0) -> fld bb
16718 ;; fmul bb fmul %st(1), %st
16720 ;; Actually we only match the last two instructions for simplicity.
16722 [(set (match_operand 0 "fp_register_operand")
16723 (match_operand 1 "fp_register_operand"))
16725 (match_operator 2 "binary_fp_operator"
16727 (match_operand 3 "memory_operand")]))]
16728 "REGNO (operands[0]) != REGNO (operands[1])"
16729 [(set (match_dup 0) (match_dup 3))
16730 (set (match_dup 0) (match_dup 4))]
16732 ;; The % modifier is not operational anymore in peephole2's, so we have to
16733 ;; swap the operands manually in the case of addition and multiplication.
16737 if (COMMUTATIVE_ARITH_P (operands[2]))
16738 op0 = operands[0], op1 = operands[1];
16740 op0 = operands[1], op1 = operands[0];
16742 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16743 GET_MODE (operands[2]),
16747 ;; Conditional addition patterns
16748 (define_expand "add<mode>cc"
16749 [(match_operand:SWI 0 "register_operand")
16750 (match_operand 1 "ordered_comparison_operator")
16751 (match_operand:SWI 2 "register_operand")
16752 (match_operand:SWI 3 "const_int_operand")]
16754 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16756 ;; Misc patterns (?)
16758 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16759 ;; Otherwise there will be nothing to keep
16761 ;; [(set (reg ebp) (reg esp))]
16762 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16763 ;; (clobber (eflags)]
16764 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16766 ;; in proper program order.
16768 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16769 [(set (match_operand:P 0 "register_operand" "=r,r")
16770 (plus:P (match_operand:P 1 "register_operand" "0,r")
16771 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16772 (clobber (reg:CC FLAGS_REG))
16773 (clobber (mem:BLK (scratch)))]
16776 switch (get_attr_type (insn))
16779 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16782 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16783 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16784 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16786 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16789 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16790 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16793 [(set (attr "type")
16794 (cond [(and (eq_attr "alternative" "0")
16795 (not (match_test "TARGET_OPT_AGU")))
16796 (const_string "alu")
16797 (match_operand:<MODE> 2 "const0_operand")
16798 (const_string "imov")
16800 (const_string "lea")))
16801 (set (attr "length_immediate")
16802 (cond [(eq_attr "type" "imov")
16804 (and (eq_attr "type" "alu")
16805 (match_operand 2 "const128_operand"))
16808 (const_string "*")))
16809 (set_attr "mode" "<MODE>")])
16811 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16812 [(set (match_operand:P 0 "register_operand" "=r")
16813 (minus:P (match_operand:P 1 "register_operand" "0")
16814 (match_operand:P 2 "register_operand" "r")))
16815 (clobber (reg:CC FLAGS_REG))
16816 (clobber (mem:BLK (scratch)))]
16818 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16819 [(set_attr "type" "alu")
16820 (set_attr "mode" "<MODE>")])
16822 (define_insn "allocate_stack_worker_probe_<mode>"
16823 [(set (match_operand:P 0 "register_operand" "=a")
16824 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16825 UNSPECV_STACK_PROBE))
16826 (clobber (reg:CC FLAGS_REG))]
16827 "ix86_target_stack_probe ()"
16828 "call\t___chkstk_ms"
16829 [(set_attr "type" "multi")
16830 (set_attr "length" "5")])
16832 (define_expand "allocate_stack"
16833 [(match_operand 0 "register_operand")
16834 (match_operand 1 "general_operand")]
16835 "ix86_target_stack_probe ()"
16839 #ifndef CHECK_STACK_LIMIT
16840 #define CHECK_STACK_LIMIT 0
16843 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16844 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16848 rtx (*insn) (rtx, rtx);
16850 x = copy_to_mode_reg (Pmode, operands[1]);
16852 insn = (TARGET_64BIT
16853 ? gen_allocate_stack_worker_probe_di
16854 : gen_allocate_stack_worker_probe_si);
16856 emit_insn (insn (x, x));
16859 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16860 stack_pointer_rtx, 0, OPTAB_DIRECT);
16862 if (x != stack_pointer_rtx)
16863 emit_move_insn (stack_pointer_rtx, x);
16865 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16869 ;; Use IOR for stack probes, this is shorter.
16870 (define_expand "probe_stack"
16871 [(match_operand 0 "memory_operand")]
16874 rtx (*gen_ior3) (rtx, rtx, rtx);
16876 gen_ior3 = (GET_MODE (operands[0]) == DImode
16877 ? gen_iordi3 : gen_iorsi3);
16879 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16883 (define_insn "adjust_stack_and_probe<mode>"
16884 [(set (match_operand:P 0 "register_operand" "=r")
16885 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16886 UNSPECV_PROBE_STACK_RANGE))
16887 (set (reg:P SP_REG)
16888 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16889 (clobber (reg:CC FLAGS_REG))
16890 (clobber (mem:BLK (scratch)))]
16892 "* return output_adjust_stack_and_probe (operands[0]);"
16893 [(set_attr "type" "multi")])
16895 (define_insn "probe_stack_range<mode>"
16896 [(set (match_operand:P 0 "register_operand" "=r")
16897 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16898 (match_operand:P 2 "const_int_operand" "n")]
16899 UNSPECV_PROBE_STACK_RANGE))
16900 (clobber (reg:CC FLAGS_REG))]
16902 "* return output_probe_stack_range (operands[0], operands[2]);"
16903 [(set_attr "type" "multi")])
16905 (define_expand "builtin_setjmp_receiver"
16906 [(label_ref (match_operand 0))]
16907 "!TARGET_64BIT && flag_pic"
16913 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16914 rtx label_rtx = gen_label_rtx ();
16915 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16916 xops[0] = xops[1] = picreg;
16917 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16918 ix86_expand_binary_operator (MINUS, SImode, xops);
16922 emit_insn (gen_set_got (pic_offset_table_rtx));
16926 (define_insn_and_split "nonlocal_goto_receiver"
16927 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16928 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16930 "&& reload_completed"
16933 if (crtl->uses_pic_offset_table)
16936 rtx label_rtx = gen_label_rtx ();
16939 /* Get a new pic base. */
16940 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16941 /* Correct this with the offset from the new to the old. */
16942 xops[0] = xops[1] = pic_offset_table_rtx;
16943 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16944 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16945 UNSPEC_MACHOPIC_OFFSET);
16946 xops[2] = gen_rtx_CONST (Pmode, tmp);
16947 ix86_expand_binary_operator (MINUS, SImode, xops);
16950 /* No pic reg restore needed. */
16951 emit_note (NOTE_INSN_DELETED);
16956 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16957 ;; Do not split instructions with mask registers.
16959 [(set (match_operand 0 "general_reg_operand")
16960 (match_operator 3 "promotable_binary_operator"
16961 [(match_operand 1 "general_reg_operand")
16962 (match_operand 2 "aligned_operand")]))
16963 (clobber (reg:CC FLAGS_REG))]
16964 "! TARGET_PARTIAL_REG_STALL && reload_completed
16965 && ((GET_MODE (operands[0]) == HImode
16966 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16967 /* ??? next two lines just !satisfies_constraint_K (...) */
16968 || !CONST_INT_P (operands[2])
16969 || satisfies_constraint_K (operands[2])))
16970 || (GET_MODE (operands[0]) == QImode
16971 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16972 [(parallel [(set (match_dup 0)
16973 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16974 (clobber (reg:CC FLAGS_REG))])]
16976 operands[0] = gen_lowpart (SImode, operands[0]);
16977 operands[1] = gen_lowpart (SImode, operands[1]);
16978 if (GET_CODE (operands[3]) != ASHIFT)
16979 operands[2] = gen_lowpart (SImode, operands[2]);
16980 PUT_MODE (operands[3], SImode);
16983 ; Promote the QImode tests, as i386 has encoding of the AND
16984 ; instruction with 32-bit sign-extended immediate and thus the
16985 ; instruction size is unchanged, except in the %eax case for
16986 ; which it is increased by one byte, hence the ! optimize_size.
16988 [(set (match_operand 0 "flags_reg_operand")
16989 (match_operator 2 "compare_operator"
16990 [(and (match_operand 3 "aligned_operand")
16991 (match_operand 4 "const_int_operand"))
16993 (set (match_operand 1 "register_operand")
16994 (and (match_dup 3) (match_dup 4)))]
16995 "! TARGET_PARTIAL_REG_STALL && reload_completed
16996 && optimize_insn_for_speed_p ()
16997 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16998 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16999 /* Ensure that the operand will remain sign-extended immediate. */
17000 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17001 [(parallel [(set (match_dup 0)
17002 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17005 (and:SI (match_dup 3) (match_dup 4)))])]
17008 = gen_int_mode (INTVAL (operands[4])
17009 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17010 operands[1] = gen_lowpart (SImode, operands[1]);
17011 operands[3] = gen_lowpart (SImode, operands[3]);
17014 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17015 ; the TEST instruction with 32-bit sign-extended immediate and thus
17016 ; the instruction size would at least double, which is not what we
17017 ; want even with ! optimize_size.
17019 [(set (match_operand 0 "flags_reg_operand")
17020 (match_operator 1 "compare_operator"
17021 [(and (match_operand:HI 2 "aligned_operand")
17022 (match_operand:HI 3 "const_int_operand"))
17024 "! TARGET_PARTIAL_REG_STALL && reload_completed
17025 && ! TARGET_FAST_PREFIX
17026 && optimize_insn_for_speed_p ()
17027 /* Ensure that the operand will remain sign-extended immediate. */
17028 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17029 [(set (match_dup 0)
17030 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17034 = gen_int_mode (INTVAL (operands[3])
17035 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17036 operands[2] = gen_lowpart (SImode, operands[2]);
17040 [(set (match_operand 0 "register_operand")
17041 (neg (match_operand 1 "register_operand")))
17042 (clobber (reg:CC FLAGS_REG))]
17043 "! TARGET_PARTIAL_REG_STALL && reload_completed
17044 && (GET_MODE (operands[0]) == HImode
17045 || (GET_MODE (operands[0]) == QImode
17046 && (TARGET_PROMOTE_QImode
17047 || optimize_insn_for_size_p ())))"
17048 [(parallel [(set (match_dup 0)
17049 (neg:SI (match_dup 1)))
17050 (clobber (reg:CC FLAGS_REG))])]
17052 operands[0] = gen_lowpart (SImode, operands[0]);
17053 operands[1] = gen_lowpart (SImode, operands[1]);
17056 ;; Do not split instructions with mask regs.
17058 [(set (match_operand 0 "general_reg_operand")
17059 (not (match_operand 1 "general_reg_operand")))]
17060 "! TARGET_PARTIAL_REG_STALL && reload_completed
17061 && (GET_MODE (operands[0]) == HImode
17062 || (GET_MODE (operands[0]) == QImode
17063 && (TARGET_PROMOTE_QImode
17064 || optimize_insn_for_size_p ())))"
17065 [(set (match_dup 0)
17066 (not:SI (match_dup 1)))]
17068 operands[0] = gen_lowpart (SImode, operands[0]);
17069 operands[1] = gen_lowpart (SImode, operands[1]);
17072 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17073 ;; transform a complex memory operation into two memory to register operations.
17075 ;; Don't push memory operands
17077 [(set (match_operand:SWI 0 "push_operand")
17078 (match_operand:SWI 1 "memory_operand"))
17079 (match_scratch:SWI 2 "<r>")]
17080 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17081 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17082 [(set (match_dup 2) (match_dup 1))
17083 (set (match_dup 0) (match_dup 2))])
17085 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17088 [(set (match_operand:SF 0 "push_operand")
17089 (match_operand:SF 1 "memory_operand"))
17090 (match_scratch:SF 2 "r")]
17091 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17092 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17093 [(set (match_dup 2) (match_dup 1))
17094 (set (match_dup 0) (match_dup 2))])
17096 ;; Don't move an immediate directly to memory when the instruction
17097 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17099 [(match_scratch:SWI124 1 "<r>")
17100 (set (match_operand:SWI124 0 "memory_operand")
17102 "optimize_insn_for_speed_p ()
17103 && ((<MODE>mode == HImode
17104 && TARGET_LCP_STALL)
17105 || (!TARGET_USE_MOV0
17106 && TARGET_SPLIT_LONG_MOVES
17107 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17108 && peep2_regno_dead_p (0, FLAGS_REG)"
17109 [(parallel [(set (match_dup 2) (const_int 0))
17110 (clobber (reg:CC FLAGS_REG))])
17111 (set (match_dup 0) (match_dup 1))]
17112 "operands[2] = gen_lowpart (SImode, operands[1]);")
17115 [(match_scratch:SWI124 2 "<r>")
17116 (set (match_operand:SWI124 0 "memory_operand")
17117 (match_operand:SWI124 1 "immediate_operand"))]
17118 "optimize_insn_for_speed_p ()
17119 && ((<MODE>mode == HImode
17120 && TARGET_LCP_STALL)
17121 || (TARGET_SPLIT_LONG_MOVES
17122 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17123 [(set (match_dup 2) (match_dup 1))
17124 (set (match_dup 0) (match_dup 2))])
17126 ;; Don't compare memory with zero, load and use a test instead.
17128 [(set (match_operand 0 "flags_reg_operand")
17129 (match_operator 1 "compare_operator"
17130 [(match_operand:SI 2 "memory_operand")
17132 (match_scratch:SI 3 "r")]
17133 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17134 [(set (match_dup 3) (match_dup 2))
17135 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17137 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17138 ;; Don't split NOTs with a displacement operand, because resulting XOR
17139 ;; will not be pairable anyway.
17141 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17142 ;; represented using a modRM byte. The XOR replacement is long decoded,
17143 ;; so this split helps here as well.
17145 ;; Note: Can't do this as a regular split because we can't get proper
17146 ;; lifetime information then.
17149 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17150 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17151 "optimize_insn_for_speed_p ()
17152 && ((TARGET_NOT_UNPAIRABLE
17153 && (!MEM_P (operands[0])
17154 || !memory_displacement_operand (operands[0], <MODE>mode)))
17155 || (TARGET_NOT_VECTORMODE
17156 && long_memory_operand (operands[0], <MODE>mode)))
17157 && peep2_regno_dead_p (0, FLAGS_REG)"
17158 [(parallel [(set (match_dup 0)
17159 (xor:SWI124 (match_dup 1) (const_int -1)))
17160 (clobber (reg:CC FLAGS_REG))])])
17162 ;; Non pairable "test imm, reg" instructions can be translated to
17163 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17164 ;; byte opcode instead of two, have a short form for byte operands),
17165 ;; so do it for other CPUs as well. Given that the value was dead,
17166 ;; this should not create any new dependencies. Pass on the sub-word
17167 ;; versions if we're concerned about partial register stalls.
17170 [(set (match_operand 0 "flags_reg_operand")
17171 (match_operator 1 "compare_operator"
17172 [(and:SI (match_operand:SI 2 "register_operand")
17173 (match_operand:SI 3 "immediate_operand"))
17175 "ix86_match_ccmode (insn, CCNOmode)
17176 && (true_regnum (operands[2]) != AX_REG
17177 || satisfies_constraint_K (operands[3]))
17178 && peep2_reg_dead_p (1, operands[2])"
17180 [(set (match_dup 0)
17181 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17184 (and:SI (match_dup 2) (match_dup 3)))])])
17186 ;; We don't need to handle HImode case, because it will be promoted to SImode
17187 ;; on ! TARGET_PARTIAL_REG_STALL
17190 [(set (match_operand 0 "flags_reg_operand")
17191 (match_operator 1 "compare_operator"
17192 [(and:QI (match_operand:QI 2 "register_operand")
17193 (match_operand:QI 3 "immediate_operand"))
17195 "! TARGET_PARTIAL_REG_STALL
17196 && ix86_match_ccmode (insn, CCNOmode)
17197 && true_regnum (operands[2]) != AX_REG
17198 && peep2_reg_dead_p (1, operands[2])"
17200 [(set (match_dup 0)
17201 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17204 (and:QI (match_dup 2) (match_dup 3)))])])
17207 [(set (match_operand 0 "flags_reg_operand")
17208 (match_operator 1 "compare_operator"
17211 (match_operand 2 "ext_register_operand")
17214 (match_operand 3 "const_int_operand"))
17216 "! TARGET_PARTIAL_REG_STALL
17217 && ix86_match_ccmode (insn, CCNOmode)
17218 && true_regnum (operands[2]) != AX_REG
17219 && peep2_reg_dead_p (1, operands[2])"
17220 [(parallel [(set (match_dup 0)
17229 (set (zero_extract:SI (match_dup 2)
17237 (match_dup 3)))])])
17239 ;; Don't do logical operations with memory inputs.
17241 [(match_scratch:SI 2 "r")
17242 (parallel [(set (match_operand:SI 0 "register_operand")
17243 (match_operator:SI 3 "arith_or_logical_operator"
17245 (match_operand:SI 1 "memory_operand")]))
17246 (clobber (reg:CC FLAGS_REG))])]
17247 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17248 [(set (match_dup 2) (match_dup 1))
17249 (parallel [(set (match_dup 0)
17250 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17251 (clobber (reg:CC FLAGS_REG))])])
17254 [(match_scratch:SI 2 "r")
17255 (parallel [(set (match_operand:SI 0 "register_operand")
17256 (match_operator:SI 3 "arith_or_logical_operator"
17257 [(match_operand:SI 1 "memory_operand")
17259 (clobber (reg:CC FLAGS_REG))])]
17260 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17261 [(set (match_dup 2) (match_dup 1))
17262 (parallel [(set (match_dup 0)
17263 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17264 (clobber (reg:CC FLAGS_REG))])])
17266 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17267 ;; refers to the destination of the load!
17270 [(set (match_operand:SI 0 "register_operand")
17271 (match_operand:SI 1 "register_operand"))
17272 (parallel [(set (match_dup 0)
17273 (match_operator:SI 3 "commutative_operator"
17275 (match_operand:SI 2 "memory_operand")]))
17276 (clobber (reg:CC FLAGS_REG))])]
17277 "REGNO (operands[0]) != REGNO (operands[1])
17278 && GENERAL_REGNO_P (REGNO (operands[0]))
17279 && GENERAL_REGNO_P (REGNO (operands[1]))"
17280 [(set (match_dup 0) (match_dup 4))
17281 (parallel [(set (match_dup 0)
17282 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17283 (clobber (reg:CC FLAGS_REG))])]
17284 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17287 [(set (match_operand 0 "register_operand")
17288 (match_operand 1 "register_operand"))
17290 (match_operator 3 "commutative_operator"
17292 (match_operand 2 "memory_operand")]))]
17293 "REGNO (operands[0]) != REGNO (operands[1])
17294 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17295 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17296 [(set (match_dup 0) (match_dup 2))
17298 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17300 ; Don't do logical operations with memory outputs
17302 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17303 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17304 ; the same decoder scheduling characteristics as the original.
17307 [(match_scratch:SI 2 "r")
17308 (parallel [(set (match_operand:SI 0 "memory_operand")
17309 (match_operator:SI 3 "arith_or_logical_operator"
17311 (match_operand:SI 1 "nonmemory_operand")]))
17312 (clobber (reg:CC FLAGS_REG))])]
17313 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17314 /* Do not split stack checking probes. */
17315 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17316 [(set (match_dup 2) (match_dup 0))
17317 (parallel [(set (match_dup 2)
17318 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17319 (clobber (reg:CC FLAGS_REG))])
17320 (set (match_dup 0) (match_dup 2))])
17323 [(match_scratch:SI 2 "r")
17324 (parallel [(set (match_operand:SI 0 "memory_operand")
17325 (match_operator:SI 3 "arith_or_logical_operator"
17326 [(match_operand:SI 1 "nonmemory_operand")
17328 (clobber (reg:CC FLAGS_REG))])]
17329 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17330 /* Do not split stack checking probes. */
17331 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17332 [(set (match_dup 2) (match_dup 0))
17333 (parallel [(set (match_dup 2)
17334 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17335 (clobber (reg:CC FLAGS_REG))])
17336 (set (match_dup 0) (match_dup 2))])
17338 ;; Attempt to use arith or logical operations with memory outputs with
17339 ;; setting of flags.
17341 [(set (match_operand:SWI 0 "register_operand")
17342 (match_operand:SWI 1 "memory_operand"))
17343 (parallel [(set (match_dup 0)
17344 (match_operator:SWI 3 "plusminuslogic_operator"
17346 (match_operand:SWI 2 "<nonmemory_operand>")]))
17347 (clobber (reg:CC FLAGS_REG))])
17348 (set (match_dup 1) (match_dup 0))
17349 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17350 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17351 && peep2_reg_dead_p (4, operands[0])
17352 && !reg_overlap_mentioned_p (operands[0], operands[1])
17353 && !reg_overlap_mentioned_p (operands[0], operands[2])
17354 && (<MODE>mode != QImode
17355 || immediate_operand (operands[2], QImode)
17356 || q_regs_operand (operands[2], QImode))
17357 && ix86_match_ccmode (peep2_next_insn (3),
17358 (GET_CODE (operands[3]) == PLUS
17359 || GET_CODE (operands[3]) == MINUS)
17360 ? CCGOCmode : CCNOmode)"
17361 [(parallel [(set (match_dup 4) (match_dup 5))
17362 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17363 (match_dup 2)]))])]
17365 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17366 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17367 copy_rtx (operands[1]),
17368 copy_rtx (operands[2]));
17369 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17370 operands[5], const0_rtx);
17374 [(parallel [(set (match_operand:SWI 0 "register_operand")
17375 (match_operator:SWI 2 "plusminuslogic_operator"
17377 (match_operand:SWI 1 "memory_operand")]))
17378 (clobber (reg:CC FLAGS_REG))])
17379 (set (match_dup 1) (match_dup 0))
17380 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17381 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17382 && GET_CODE (operands[2]) != MINUS
17383 && peep2_reg_dead_p (3, operands[0])
17384 && !reg_overlap_mentioned_p (operands[0], operands[1])
17385 && ix86_match_ccmode (peep2_next_insn (2),
17386 GET_CODE (operands[2]) == PLUS
17387 ? CCGOCmode : CCNOmode)"
17388 [(parallel [(set (match_dup 3) (match_dup 4))
17389 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17390 (match_dup 0)]))])]
17392 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17393 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17394 copy_rtx (operands[1]),
17395 copy_rtx (operands[0]));
17396 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17397 operands[4], const0_rtx);
17401 [(set (match_operand:SWI12 0 "register_operand")
17402 (match_operand:SWI12 1 "memory_operand"))
17403 (parallel [(set (match_operand:SI 4 "register_operand")
17404 (match_operator:SI 3 "plusminuslogic_operator"
17406 (match_operand:SI 2 "nonmemory_operand")]))
17407 (clobber (reg:CC FLAGS_REG))])
17408 (set (match_dup 1) (match_dup 0))
17409 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17410 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17411 && REG_P (operands[0]) && REG_P (operands[4])
17412 && REGNO (operands[0]) == REGNO (operands[4])
17413 && peep2_reg_dead_p (4, operands[0])
17414 && (<MODE>mode != QImode
17415 || immediate_operand (operands[2], SImode)
17416 || q_regs_operand (operands[2], SImode))
17417 && !reg_overlap_mentioned_p (operands[0], operands[1])
17418 && !reg_overlap_mentioned_p (operands[0], operands[2])
17419 && ix86_match_ccmode (peep2_next_insn (3),
17420 (GET_CODE (operands[3]) == PLUS
17421 || GET_CODE (operands[3]) == MINUS)
17422 ? CCGOCmode : CCNOmode)"
17423 [(parallel [(set (match_dup 4) (match_dup 5))
17424 (set (match_dup 1) (match_dup 6))])]
17426 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17427 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17428 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17429 copy_rtx (operands[1]), operands[2]);
17430 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17431 operands[5], const0_rtx);
17432 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17433 copy_rtx (operands[1]),
17434 copy_rtx (operands[2]));
17437 ;; Attempt to always use XOR for zeroing registers.
17439 [(set (match_operand 0 "register_operand")
17440 (match_operand 1 "const0_operand"))]
17441 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17442 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17443 && GENERAL_REG_P (operands[0])
17444 && peep2_regno_dead_p (0, FLAGS_REG)"
17445 [(parallel [(set (match_dup 0) (const_int 0))
17446 (clobber (reg:CC FLAGS_REG))])]
17447 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17450 [(set (strict_low_part (match_operand 0 "register_operand"))
17452 "(GET_MODE (operands[0]) == QImode
17453 || GET_MODE (operands[0]) == HImode)
17454 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17455 && peep2_regno_dead_p (0, FLAGS_REG)"
17456 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17457 (clobber (reg:CC FLAGS_REG))])])
17459 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17461 [(set (match_operand:SWI248 0 "register_operand")
17463 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17464 && peep2_regno_dead_p (0, FLAGS_REG)"
17465 [(parallel [(set (match_dup 0) (const_int -1))
17466 (clobber (reg:CC FLAGS_REG))])]
17468 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17469 operands[0] = gen_lowpart (SImode, operands[0]);
17472 ;; Attempt to convert simple lea to add/shift.
17473 ;; These can be created by move expanders.
17474 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17475 ;; relevant lea instructions were already split.
17478 [(set (match_operand:SWI48 0 "register_operand")
17479 (plus:SWI48 (match_dup 0)
17480 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17482 && peep2_regno_dead_p (0, FLAGS_REG)"
17483 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17484 (clobber (reg:CC FLAGS_REG))])])
17487 [(set (match_operand:SWI48 0 "register_operand")
17488 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17491 && peep2_regno_dead_p (0, FLAGS_REG)"
17492 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17493 (clobber (reg:CC FLAGS_REG))])])
17496 [(set (match_operand:DI 0 "register_operand")
17498 (plus:SI (match_operand:SI 1 "register_operand")
17499 (match_operand:SI 2 "nonmemory_operand"))))]
17500 "TARGET_64BIT && !TARGET_OPT_AGU
17501 && REGNO (operands[0]) == REGNO (operands[1])
17502 && peep2_regno_dead_p (0, FLAGS_REG)"
17503 [(parallel [(set (match_dup 0)
17504 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17505 (clobber (reg:CC FLAGS_REG))])])
17508 [(set (match_operand:DI 0 "register_operand")
17510 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17511 (match_operand:SI 2 "register_operand"))))]
17512 "TARGET_64BIT && !TARGET_OPT_AGU
17513 && REGNO (operands[0]) == REGNO (operands[2])
17514 && peep2_regno_dead_p (0, FLAGS_REG)"
17515 [(parallel [(set (match_dup 0)
17516 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17517 (clobber (reg:CC FLAGS_REG))])])
17520 [(set (match_operand:SWI48 0 "register_operand")
17521 (mult:SWI48 (match_dup 0)
17522 (match_operand:SWI48 1 "const_int_operand")))]
17523 "exact_log2 (INTVAL (operands[1])) >= 0
17524 && peep2_regno_dead_p (0, FLAGS_REG)"
17525 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17526 (clobber (reg:CC FLAGS_REG))])]
17527 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17530 [(set (match_operand:DI 0 "register_operand")
17532 (mult:SI (match_operand:SI 1 "register_operand")
17533 (match_operand:SI 2 "const_int_operand"))))]
17535 && exact_log2 (INTVAL (operands[2])) >= 0
17536 && REGNO (operands[0]) == REGNO (operands[1])
17537 && peep2_regno_dead_p (0, FLAGS_REG)"
17538 [(parallel [(set (match_dup 0)
17539 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17540 (clobber (reg:CC FLAGS_REG))])]
17541 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17543 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17544 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17545 ;; On many CPUs it is also faster, since special hardware to avoid esp
17546 ;; dependencies is present.
17548 ;; While some of these conversions may be done using splitters, we use
17549 ;; peepholes in order to allow combine_stack_adjustments pass to see
17550 ;; nonobfuscated RTL.
17552 ;; Convert prologue esp subtractions to push.
17553 ;; We need register to push. In order to keep verify_flow_info happy we have
17555 ;; - use scratch and clobber it in order to avoid dependencies
17556 ;; - use already live register
17557 ;; We can't use the second way right now, since there is no reliable way how to
17558 ;; verify that given register is live. First choice will also most likely in
17559 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17560 ;; call clobbered registers are dead. We may want to use base pointer as an
17561 ;; alternative when no register is available later.
17564 [(match_scratch:W 1 "r")
17565 (parallel [(set (reg:P SP_REG)
17566 (plus:P (reg:P SP_REG)
17567 (match_operand:P 0 "const_int_operand")))
17568 (clobber (reg:CC FLAGS_REG))
17569 (clobber (mem:BLK (scratch)))])]
17570 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17571 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17572 [(clobber (match_dup 1))
17573 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17574 (clobber (mem:BLK (scratch)))])])
17577 [(match_scratch:W 1 "r")
17578 (parallel [(set (reg:P SP_REG)
17579 (plus:P (reg:P SP_REG)
17580 (match_operand:P 0 "const_int_operand")))
17581 (clobber (reg:CC FLAGS_REG))
17582 (clobber (mem:BLK (scratch)))])]
17583 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17584 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17585 [(clobber (match_dup 1))
17586 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17587 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17588 (clobber (mem:BLK (scratch)))])])
17590 ;; Convert esp subtractions to push.
17592 [(match_scratch:W 1 "r")
17593 (parallel [(set (reg:P SP_REG)
17594 (plus:P (reg:P SP_REG)
17595 (match_operand:P 0 "const_int_operand")))
17596 (clobber (reg:CC FLAGS_REG))])]
17597 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17598 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17599 [(clobber (match_dup 1))
17600 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17603 [(match_scratch:W 1 "r")
17604 (parallel [(set (reg:P SP_REG)
17605 (plus:P (reg:P SP_REG)
17606 (match_operand:P 0 "const_int_operand")))
17607 (clobber (reg:CC FLAGS_REG))])]
17608 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17609 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17610 [(clobber (match_dup 1))
17611 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17612 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17614 ;; Convert epilogue deallocator to pop.
17616 [(match_scratch:W 1 "r")
17617 (parallel [(set (reg:P SP_REG)
17618 (plus:P (reg:P SP_REG)
17619 (match_operand:P 0 "const_int_operand")))
17620 (clobber (reg:CC FLAGS_REG))
17621 (clobber (mem:BLK (scratch)))])]
17622 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17623 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17624 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17625 (clobber (mem:BLK (scratch)))])])
17627 ;; Two pops case is tricky, since pop causes dependency
17628 ;; on destination register. We use two registers if available.
17630 [(match_scratch:W 1 "r")
17631 (match_scratch:W 2 "r")
17632 (parallel [(set (reg:P SP_REG)
17633 (plus:P (reg:P SP_REG)
17634 (match_operand:P 0 "const_int_operand")))
17635 (clobber (reg:CC FLAGS_REG))
17636 (clobber (mem:BLK (scratch)))])]
17637 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17638 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17639 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17640 (clobber (mem:BLK (scratch)))])
17641 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17644 [(match_scratch:W 1 "r")
17645 (parallel [(set (reg:P SP_REG)
17646 (plus:P (reg:P SP_REG)
17647 (match_operand:P 0 "const_int_operand")))
17648 (clobber (reg:CC FLAGS_REG))
17649 (clobber (mem:BLK (scratch)))])]
17650 "optimize_insn_for_size_p ()
17651 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17652 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17653 (clobber (mem:BLK (scratch)))])
17654 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17656 ;; Convert esp additions to pop.
17658 [(match_scratch:W 1 "r")
17659 (parallel [(set (reg:P SP_REG)
17660 (plus:P (reg:P SP_REG)
17661 (match_operand:P 0 "const_int_operand")))
17662 (clobber (reg:CC FLAGS_REG))])]
17663 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17664 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17666 ;; Two pops case is tricky, since pop causes dependency
17667 ;; on destination register. We use two registers if available.
17669 [(match_scratch:W 1 "r")
17670 (match_scratch:W 2 "r")
17671 (parallel [(set (reg:P SP_REG)
17672 (plus:P (reg:P SP_REG)
17673 (match_operand:P 0 "const_int_operand")))
17674 (clobber (reg:CC FLAGS_REG))])]
17675 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17676 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17677 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17680 [(match_scratch:W 1 "r")
17681 (parallel [(set (reg:P SP_REG)
17682 (plus:P (reg:P SP_REG)
17683 (match_operand:P 0 "const_int_operand")))
17684 (clobber (reg:CC FLAGS_REG))])]
17685 "optimize_insn_for_size_p ()
17686 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17687 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17688 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17690 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17691 ;; required and register dies. Similarly for 128 to -128.
17693 [(set (match_operand 0 "flags_reg_operand")
17694 (match_operator 1 "compare_operator"
17695 [(match_operand 2 "register_operand")
17696 (match_operand 3 "const_int_operand")]))]
17697 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17698 && incdec_operand (operands[3], GET_MODE (operands[3])))
17699 || (!TARGET_FUSE_CMP_AND_BRANCH
17700 && INTVAL (operands[3]) == 128))
17701 && ix86_match_ccmode (insn, CCGCmode)
17702 && peep2_reg_dead_p (1, operands[2])"
17703 [(parallel [(set (match_dup 0)
17704 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17705 (clobber (match_dup 2))])])
17707 ;; Convert imul by three, five and nine into lea
17710 [(set (match_operand:SWI48 0 "register_operand")
17711 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17712 (match_operand:SWI48 2 "const359_operand")))
17713 (clobber (reg:CC FLAGS_REG))])]
17714 "!TARGET_PARTIAL_REG_STALL
17715 || <MODE>mode == SImode
17716 || optimize_function_for_size_p (cfun)"
17717 [(set (match_dup 0)
17718 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17720 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17724 [(set (match_operand:SWI48 0 "register_operand")
17725 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17726 (match_operand:SWI48 2 "const359_operand")))
17727 (clobber (reg:CC FLAGS_REG))])]
17728 "optimize_insn_for_speed_p ()
17729 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17730 [(set (match_dup 0) (match_dup 1))
17732 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17734 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17736 ;; imul $32bit_imm, mem, reg is vector decoded, while
17737 ;; imul $32bit_imm, reg, reg is direct decoded.
17739 [(match_scratch:SWI48 3 "r")
17740 (parallel [(set (match_operand:SWI48 0 "register_operand")
17741 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17742 (match_operand:SWI48 2 "immediate_operand")))
17743 (clobber (reg:CC FLAGS_REG))])]
17744 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17745 && !satisfies_constraint_K (operands[2])"
17746 [(set (match_dup 3) (match_dup 1))
17747 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17748 (clobber (reg:CC FLAGS_REG))])])
17751 [(match_scratch:SI 3 "r")
17752 (parallel [(set (match_operand:DI 0 "register_operand")
17754 (mult:SI (match_operand:SI 1 "memory_operand")
17755 (match_operand:SI 2 "immediate_operand"))))
17756 (clobber (reg:CC FLAGS_REG))])]
17758 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17759 && !satisfies_constraint_K (operands[2])"
17760 [(set (match_dup 3) (match_dup 1))
17761 (parallel [(set (match_dup 0)
17762 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17763 (clobber (reg:CC FLAGS_REG))])])
17765 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17766 ;; Convert it into imul reg, reg
17767 ;; It would be better to force assembler to encode instruction using long
17768 ;; immediate, but there is apparently no way to do so.
17770 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17772 (match_operand:SWI248 1 "nonimmediate_operand")
17773 (match_operand:SWI248 2 "const_int_operand")))
17774 (clobber (reg:CC FLAGS_REG))])
17775 (match_scratch:SWI248 3 "r")]
17776 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17777 && satisfies_constraint_K (operands[2])"
17778 [(set (match_dup 3) (match_dup 2))
17779 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17780 (clobber (reg:CC FLAGS_REG))])]
17782 if (!rtx_equal_p (operands[0], operands[1]))
17783 emit_move_insn (operands[0], operands[1]);
17786 ;; After splitting up read-modify operations, array accesses with memory
17787 ;; operands might end up in form:
17789 ;; movl 4(%esp), %edx
17791 ;; instead of pre-splitting:
17793 ;; addl 4(%esp), %eax
17795 ;; movl 4(%esp), %edx
17796 ;; leal (%edx,%eax,4), %eax
17799 [(match_scratch:W 5 "r")
17800 (parallel [(set (match_operand 0 "register_operand")
17801 (ashift (match_operand 1 "register_operand")
17802 (match_operand 2 "const_int_operand")))
17803 (clobber (reg:CC FLAGS_REG))])
17804 (parallel [(set (match_operand 3 "register_operand")
17805 (plus (match_dup 0)
17806 (match_operand 4 "x86_64_general_operand")))
17807 (clobber (reg:CC FLAGS_REG))])]
17808 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17809 /* Validate MODE for lea. */
17810 && ((!TARGET_PARTIAL_REG_STALL
17811 && (GET_MODE (operands[0]) == QImode
17812 || GET_MODE (operands[0]) == HImode))
17813 || GET_MODE (operands[0]) == SImode
17814 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17815 && (rtx_equal_p (operands[0], operands[3])
17816 || peep2_reg_dead_p (2, operands[0]))
17817 /* We reorder load and the shift. */
17818 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17819 [(set (match_dup 5) (match_dup 4))
17820 (set (match_dup 0) (match_dup 1))]
17822 enum machine_mode op1mode = GET_MODE (operands[1]);
17823 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17824 int scale = 1 << INTVAL (operands[2]);
17825 rtx index = gen_lowpart (word_mode, operands[1]);
17826 rtx base = gen_lowpart (word_mode, operands[5]);
17827 rtx dest = gen_lowpart (mode, operands[3]);
17829 operands[1] = gen_rtx_PLUS (word_mode, base,
17830 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17831 operands[5] = base;
17832 if (mode != word_mode)
17833 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17834 if (op1mode != word_mode)
17835 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17836 operands[0] = dest;
17839 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17840 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17841 ;; caught for use by garbage collectors and the like. Using an insn that
17842 ;; maps to SIGILL makes it more likely the program will rightfully die.
17843 ;; Keeping with tradition, "6" is in honor of #UD.
17844 (define_insn "trap"
17845 [(trap_if (const_int 1) (const_int 6))]
17848 #ifdef HAVE_AS_IX86_UD2
17851 return ASM_SHORT "0x0b0f";
17854 [(set_attr "length" "2")])
17856 (define_expand "prefetch"
17857 [(prefetch (match_operand 0 "address_operand")
17858 (match_operand:SI 1 "const_int_operand")
17859 (match_operand:SI 2 "const_int_operand"))]
17860 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17862 bool write = INTVAL (operands[1]) != 0;
17863 int locality = INTVAL (operands[2]);
17865 gcc_assert (IN_RANGE (locality, 0, 3));
17867 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17868 supported by SSE counterpart or the SSE prefetch is not available
17869 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17871 if (TARGET_PREFETCHWT1 && write && locality <= 2)
17872 operands[2] = const2_rtx;
17873 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17874 operands[2] = GEN_INT (3);
17876 operands[1] = const0_rtx;
17879 (define_insn "*prefetch_sse"
17880 [(prefetch (match_operand 0 "address_operand" "p")
17882 (match_operand:SI 1 "const_int_operand"))]
17883 "TARGET_PREFETCH_SSE"
17885 static const char * const patterns[4] = {
17886 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17889 int locality = INTVAL (operands[1]);
17890 gcc_assert (IN_RANGE (locality, 0, 3));
17892 return patterns[locality];
17894 [(set_attr "type" "sse")
17895 (set_attr "atom_sse_attr" "prefetch")
17896 (set (attr "length_address")
17897 (symbol_ref "memory_address_length (operands[0], false)"))
17898 (set_attr "memory" "none")])
17900 (define_insn "*prefetch_3dnow"
17901 [(prefetch (match_operand 0 "address_operand" "p")
17902 (match_operand:SI 1 "const_int_operand" "n")
17906 if (INTVAL (operands[1]) == 0)
17907 return "prefetch\t%a0";
17909 return "prefetchw\t%a0";
17911 [(set_attr "type" "mmx")
17912 (set (attr "length_address")
17913 (symbol_ref "memory_address_length (operands[0], false)"))
17914 (set_attr "memory" "none")])
17916 (define_insn "*prefetch_prefetchwt1_<mode>"
17917 [(prefetch (match_operand:P 0 "address_operand" "p")
17920 "TARGET_PREFETCHWT1"
17921 "prefetchwt1\t%a0";
17922 [(set_attr "type" "sse")
17923 (set (attr "length_address")
17924 (symbol_ref "memory_address_length (operands[0], false)"))
17925 (set_attr "memory" "none")])
17927 (define_expand "stack_protect_set"
17928 [(match_operand 0 "memory_operand")
17929 (match_operand 1 "memory_operand")]
17930 "TARGET_SSP_TLS_GUARD"
17932 rtx (*insn)(rtx, rtx);
17934 #ifdef TARGET_THREAD_SSP_OFFSET
17935 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17936 insn = (TARGET_LP64
17937 ? gen_stack_tls_protect_set_di
17938 : gen_stack_tls_protect_set_si);
17940 insn = (TARGET_LP64
17941 ? gen_stack_protect_set_di
17942 : gen_stack_protect_set_si);
17945 emit_insn (insn (operands[0], operands[1]));
17949 (define_insn "stack_protect_set_<mode>"
17950 [(set (match_operand:PTR 0 "memory_operand" "=m")
17951 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17953 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17954 (clobber (reg:CC FLAGS_REG))]
17955 "TARGET_SSP_TLS_GUARD"
17956 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17957 [(set_attr "type" "multi")])
17959 (define_insn "stack_tls_protect_set_<mode>"
17960 [(set (match_operand:PTR 0 "memory_operand" "=m")
17961 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17962 UNSPEC_SP_TLS_SET))
17963 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17964 (clobber (reg:CC FLAGS_REG))]
17966 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17967 [(set_attr "type" "multi")])
17969 (define_expand "stack_protect_test"
17970 [(match_operand 0 "memory_operand")
17971 (match_operand 1 "memory_operand")
17973 "TARGET_SSP_TLS_GUARD"
17975 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17977 rtx (*insn)(rtx, rtx, rtx);
17979 #ifdef TARGET_THREAD_SSP_OFFSET
17980 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17981 insn = (TARGET_LP64
17982 ? gen_stack_tls_protect_test_di
17983 : gen_stack_tls_protect_test_si);
17985 insn = (TARGET_LP64
17986 ? gen_stack_protect_test_di
17987 : gen_stack_protect_test_si);
17990 emit_insn (insn (flags, operands[0], operands[1]));
17992 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17993 flags, const0_rtx, operands[2]));
17997 (define_insn "stack_protect_test_<mode>"
17998 [(set (match_operand:CCZ 0 "flags_reg_operand")
17999 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18000 (match_operand:PTR 2 "memory_operand" "m")]
18002 (clobber (match_scratch:PTR 3 "=&r"))]
18003 "TARGET_SSP_TLS_GUARD"
18004 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18005 [(set_attr "type" "multi")])
18007 (define_insn "stack_tls_protect_test_<mode>"
18008 [(set (match_operand:CCZ 0 "flags_reg_operand")
18009 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18010 (match_operand:PTR 2 "const_int_operand" "i")]
18011 UNSPEC_SP_TLS_TEST))
18012 (clobber (match_scratch:PTR 3 "=r"))]
18014 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18015 [(set_attr "type" "multi")])
18017 (define_insn "sse4_2_crc32<mode>"
18018 [(set (match_operand:SI 0 "register_operand" "=r")
18020 [(match_operand:SI 1 "register_operand" "0")
18021 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18023 "TARGET_SSE4_2 || TARGET_CRC32"
18024 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18025 [(set_attr "type" "sselog1")
18026 (set_attr "prefix_rep" "1")
18027 (set_attr "prefix_extra" "1")
18028 (set (attr "prefix_data16")
18029 (if_then_else (match_operand:HI 2)
18031 (const_string "*")))
18032 (set (attr "prefix_rex")
18033 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18035 (const_string "*")))
18036 (set_attr "mode" "SI")])
18038 (define_insn "sse4_2_crc32di"
18039 [(set (match_operand:DI 0 "register_operand" "=r")
18041 [(match_operand:DI 1 "register_operand" "0")
18042 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18044 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18045 "crc32{q}\t{%2, %0|%0, %2}"
18046 [(set_attr "type" "sselog1")
18047 (set_attr "prefix_rep" "1")
18048 (set_attr "prefix_extra" "1")
18049 (set_attr "mode" "DI")])
18051 (define_insn "rdpmc"
18052 [(set (match_operand:DI 0 "register_operand" "=A")
18053 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18057 [(set_attr "type" "other")
18058 (set_attr "length" "2")])
18060 (define_insn "rdpmc_rex64"
18061 [(set (match_operand:DI 0 "register_operand" "=a")
18062 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18064 (set (match_operand:DI 1 "register_operand" "=d")
18065 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18068 [(set_attr "type" "other")
18069 (set_attr "length" "2")])
18071 (define_insn "rdtsc"
18072 [(set (match_operand:DI 0 "register_operand" "=A")
18073 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18076 [(set_attr "type" "other")
18077 (set_attr "length" "2")])
18079 (define_insn "rdtsc_rex64"
18080 [(set (match_operand:DI 0 "register_operand" "=a")
18081 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18082 (set (match_operand:DI 1 "register_operand" "=d")
18083 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18086 [(set_attr "type" "other")
18087 (set_attr "length" "2")])
18089 (define_insn "rdtscp"
18090 [(set (match_operand:DI 0 "register_operand" "=A")
18091 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18092 (set (match_operand:SI 1 "register_operand" "=c")
18093 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18096 [(set_attr "type" "other")
18097 (set_attr "length" "3")])
18099 (define_insn "rdtscp_rex64"
18100 [(set (match_operand:DI 0 "register_operand" "=a")
18101 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18102 (set (match_operand:DI 1 "register_operand" "=d")
18103 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18104 (set (match_operand:SI 2 "register_operand" "=c")
18105 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18108 [(set_attr "type" "other")
18109 (set_attr "length" "3")])
18111 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18113 ;; FXSR, XSAVE and XSAVEOPT instructions
18115 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18117 (define_insn "fxsave"
18118 [(set (match_operand:BLK 0 "memory_operand" "=m")
18119 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18122 [(set_attr "type" "other")
18123 (set_attr "memory" "store")
18124 (set (attr "length")
18125 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18127 (define_insn "fxsave64"
18128 [(set (match_operand:BLK 0 "memory_operand" "=m")
18129 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18130 "TARGET_64BIT && TARGET_FXSR"
18132 [(set_attr "type" "other")
18133 (set_attr "memory" "store")
18134 (set (attr "length")
18135 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18137 (define_insn "fxrstor"
18138 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18142 [(set_attr "type" "other")
18143 (set_attr "memory" "load")
18144 (set (attr "length")
18145 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18147 (define_insn "fxrstor64"
18148 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18149 UNSPECV_FXRSTOR64)]
18150 "TARGET_64BIT && TARGET_FXSR"
18152 [(set_attr "type" "other")
18153 (set_attr "memory" "load")
18154 (set (attr "length")
18155 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18157 (define_int_iterator ANY_XSAVE
18159 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
18161 (define_int_iterator ANY_XSAVE64
18163 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
18165 (define_int_attr xsave
18166 [(UNSPECV_XSAVE "xsave")
18167 (UNSPECV_XSAVE64 "xsave64")
18168 (UNSPECV_XSAVEOPT "xsaveopt")
18169 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
18171 (define_insn "<xsave>"
18172 [(set (match_operand:BLK 0 "memory_operand" "=m")
18173 (unspec_volatile:BLK
18174 [(match_operand:DI 1 "register_operand" "A")]
18176 "!TARGET_64BIT && TARGET_XSAVE"
18178 [(set_attr "type" "other")
18179 (set_attr "memory" "store")
18180 (set (attr "length")
18181 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18183 (define_insn "<xsave>_rex64"
18184 [(set (match_operand:BLK 0 "memory_operand" "=m")
18185 (unspec_volatile:BLK
18186 [(match_operand:SI 1 "register_operand" "a")
18187 (match_operand:SI 2 "register_operand" "d")]
18189 "TARGET_64BIT && TARGET_XSAVE"
18191 [(set_attr "type" "other")
18192 (set_attr "memory" "store")
18193 (set (attr "length")
18194 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18196 (define_insn "<xsave>"
18197 [(set (match_operand:BLK 0 "memory_operand" "=m")
18198 (unspec_volatile:BLK
18199 [(match_operand:SI 1 "register_operand" "a")
18200 (match_operand:SI 2 "register_operand" "d")]
18202 "TARGET_64BIT && TARGET_XSAVE"
18204 [(set_attr "type" "other")
18205 (set_attr "memory" "store")
18206 (set (attr "length")
18207 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18209 (define_insn "xrstor"
18210 [(unspec_volatile:BLK
18211 [(match_operand:BLK 0 "memory_operand" "m")
18212 (match_operand:DI 1 "register_operand" "A")]
18214 "!TARGET_64BIT && TARGET_XSAVE"
18216 [(set_attr "type" "other")
18217 (set_attr "memory" "load")
18218 (set (attr "length")
18219 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18221 (define_insn "xrstor_rex64"
18222 [(unspec_volatile:BLK
18223 [(match_operand:BLK 0 "memory_operand" "m")
18224 (match_operand:SI 1 "register_operand" "a")
18225 (match_operand:SI 2 "register_operand" "d")]
18227 "TARGET_64BIT && TARGET_XSAVE"
18229 [(set_attr "type" "other")
18230 (set_attr "memory" "load")
18231 (set (attr "length")
18232 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18234 (define_insn "xrstor64"
18235 [(unspec_volatile:BLK
18236 [(match_operand:BLK 0 "memory_operand" "m")
18237 (match_operand:SI 1 "register_operand" "a")
18238 (match_operand:SI 2 "register_operand" "d")]
18240 "TARGET_64BIT && TARGET_XSAVE"
18242 [(set_attr "type" "other")
18243 (set_attr "memory" "load")
18244 (set (attr "length")
18245 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18247 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18249 ;; Floating-point instructions for atomic compound assignments
18251 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18253 ; Clobber all floating-point registers on environment save and restore
18254 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18255 (define_insn "fnstenv"
18256 [(set (match_operand:BLK 0 "memory_operand" "=m")
18257 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18258 (clobber (reg:HI FPCR_REG))
18259 (clobber (reg:XF ST0_REG))
18260 (clobber (reg:XF ST1_REG))
18261 (clobber (reg:XF ST2_REG))
18262 (clobber (reg:XF ST3_REG))
18263 (clobber (reg:XF ST4_REG))
18264 (clobber (reg:XF ST5_REG))
18265 (clobber (reg:XF ST6_REG))
18266 (clobber (reg:XF ST7_REG))]
18269 [(set_attr "type" "other")
18270 (set_attr "memory" "store")
18271 (set (attr "length")
18272 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18274 (define_insn "fldenv"
18275 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18277 (clobber (reg:CCFP FPSR_REG))
18278 (clobber (reg:HI FPCR_REG))
18279 (clobber (reg:XF ST0_REG))
18280 (clobber (reg:XF ST1_REG))
18281 (clobber (reg:XF ST2_REG))
18282 (clobber (reg:XF ST3_REG))
18283 (clobber (reg:XF ST4_REG))
18284 (clobber (reg:XF ST5_REG))
18285 (clobber (reg:XF ST6_REG))
18286 (clobber (reg:XF ST7_REG))]
18289 [(set_attr "type" "other")
18290 (set_attr "memory" "load")
18291 (set (attr "length")
18292 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18294 (define_insn "fnstsw"
18295 [(set (match_operand:HI 0 "memory_operand" "=m")
18296 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18299 [(set_attr "type" "other")
18300 (set_attr "memory" "store")
18301 (set (attr "length")
18302 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18304 (define_insn "fnclex"
18305 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18308 [(set_attr "type" "other")
18309 (set_attr "memory" "none")
18310 (set_attr "length" "2")])
18312 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18314 ;; LWP instructions
18316 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18318 (define_expand "lwp_llwpcb"
18319 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18320 UNSPECV_LLWP_INTRINSIC)]
18323 (define_insn "*lwp_llwpcb<mode>1"
18324 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18325 UNSPECV_LLWP_INTRINSIC)]
18328 [(set_attr "type" "lwp")
18329 (set_attr "mode" "<MODE>")
18330 (set_attr "length" "5")])
18332 (define_expand "lwp_slwpcb"
18333 [(set (match_operand 0 "register_operand" "=r")
18334 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18339 insn = (Pmode == DImode
18341 : gen_lwp_slwpcbsi);
18343 emit_insn (insn (operands[0]));
18347 (define_insn "lwp_slwpcb<mode>"
18348 [(set (match_operand:P 0 "register_operand" "=r")
18349 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18352 [(set_attr "type" "lwp")
18353 (set_attr "mode" "<MODE>")
18354 (set_attr "length" "5")])
18356 (define_expand "lwp_lwpval<mode>3"
18357 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18358 (match_operand:SI 2 "nonimmediate_operand" "rm")
18359 (match_operand:SI 3 "const_int_operand" "i")]
18360 UNSPECV_LWPVAL_INTRINSIC)]
18362 ;; Avoid unused variable warning.
18363 "(void) operands[0];")
18365 (define_insn "*lwp_lwpval<mode>3_1"
18366 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18367 (match_operand:SI 1 "nonimmediate_operand" "rm")
18368 (match_operand:SI 2 "const_int_operand" "i")]
18369 UNSPECV_LWPVAL_INTRINSIC)]
18371 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18372 [(set_attr "type" "lwp")
18373 (set_attr "mode" "<MODE>")
18374 (set (attr "length")
18375 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18377 (define_expand "lwp_lwpins<mode>3"
18378 [(set (reg:CCC FLAGS_REG)
18379 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18380 (match_operand:SI 2 "nonimmediate_operand" "rm")
18381 (match_operand:SI 3 "const_int_operand" "i")]
18382 UNSPECV_LWPINS_INTRINSIC))
18383 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18384 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18387 (define_insn "*lwp_lwpins<mode>3_1"
18388 [(set (reg:CCC FLAGS_REG)
18389 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18390 (match_operand:SI 1 "nonimmediate_operand" "rm")
18391 (match_operand:SI 2 "const_int_operand" "i")]
18392 UNSPECV_LWPINS_INTRINSIC))]
18394 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18395 [(set_attr "type" "lwp")
18396 (set_attr "mode" "<MODE>")
18397 (set (attr "length")
18398 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18400 (define_int_iterator RDFSGSBASE
18404 (define_int_iterator WRFSGSBASE
18408 (define_int_attr fsgs
18409 [(UNSPECV_RDFSBASE "fs")
18410 (UNSPECV_RDGSBASE "gs")
18411 (UNSPECV_WRFSBASE "fs")
18412 (UNSPECV_WRGSBASE "gs")])
18414 (define_insn "rd<fsgs>base<mode>"
18415 [(set (match_operand:SWI48 0 "register_operand" "=r")
18416 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18417 "TARGET_64BIT && TARGET_FSGSBASE"
18419 [(set_attr "type" "other")
18420 (set_attr "prefix_extra" "2")])
18422 (define_insn "wr<fsgs>base<mode>"
18423 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18425 "TARGET_64BIT && TARGET_FSGSBASE"
18427 [(set_attr "type" "other")
18428 (set_attr "prefix_extra" "2")])
18430 (define_insn "rdrand<mode>_1"
18431 [(set (match_operand:SWI248 0 "register_operand" "=r")
18432 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18433 (set (reg:CCC FLAGS_REG)
18434 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18437 [(set_attr "type" "other")
18438 (set_attr "prefix_extra" "1")])
18440 (define_insn "rdseed<mode>_1"
18441 [(set (match_operand:SWI248 0 "register_operand" "=r")
18442 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18443 (set (reg:CCC FLAGS_REG)
18444 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18447 [(set_attr "type" "other")
18448 (set_attr "prefix_extra" "1")])
18450 (define_expand "pause"
18451 [(set (match_dup 0)
18452 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18455 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18456 MEM_VOLATILE_P (operands[0]) = 1;
18459 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18460 ;; They have the same encoding.
18461 (define_insn "*pause"
18462 [(set (match_operand:BLK 0)
18463 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18466 [(set_attr "length" "2")
18467 (set_attr "memory" "unknown")])
18469 (define_expand "xbegin"
18470 [(set (match_operand:SI 0 "register_operand")
18471 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18474 rtx label = gen_label_rtx ();
18476 /* xbegin is emitted as jump_insn, so reload won't be able
18477 to reload its operand. Force the value into AX hard register. */
18478 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18479 emit_move_insn (ax_reg, constm1_rtx);
18481 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18483 emit_label (label);
18484 LABEL_NUSES (label) = 1;
18486 emit_move_insn (operands[0], ax_reg);
18491 (define_insn "xbegin_1"
18493 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18495 (label_ref (match_operand 1))
18497 (set (match_operand:SI 0 "register_operand" "+a")
18498 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18501 [(set_attr "type" "other")
18502 (set_attr "length" "6")])
18504 (define_insn "xend"
18505 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18508 [(set_attr "type" "other")
18509 (set_attr "length" "3")])
18511 (define_insn "xabort"
18512 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18516 [(set_attr "type" "other")
18517 (set_attr "length" "3")])
18519 (define_expand "xtest"
18520 [(set (match_operand:QI 0 "register_operand")
18521 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18524 emit_insn (gen_xtest_1 ());
18526 ix86_expand_setcc (operands[0], NE,
18527 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18531 (define_insn "xtest_1"
18532 [(set (reg:CCZ FLAGS_REG)
18533 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18536 [(set_attr "type" "other")
18537 (set_attr "length" "3")])
18541 (include "sync.md")