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 extend operand predicate for integer modes,
975 ;; which disallows VOIDmode operands and thus it is suitable
976 ;; for use inside sign_extend.
977 (define_mode_attr general_sext_operand
980 (SI "x86_64_sext_operand")
981 (DI "x86_64_sext_operand")])
983 ;; General sign/zero extend operand predicate for integer modes.
984 (define_mode_attr general_szext_operand
985 [(QI "general_operand")
986 (HI "general_operand")
987 (SI "x86_64_szext_general_operand")
988 (DI "x86_64_szext_general_operand")])
990 ;; Immediate operand predicate for integer modes.
991 (define_mode_attr immediate_operand
992 [(QI "immediate_operand")
993 (HI "immediate_operand")
994 (SI "x86_64_immediate_operand")
995 (DI "x86_64_immediate_operand")])
997 ;; Nonmemory operand predicate for integer modes.
998 (define_mode_attr nonmemory_operand
999 [(QI "nonmemory_operand")
1000 (HI "nonmemory_operand")
1001 (SI "x86_64_nonmemory_operand")
1002 (DI "x86_64_nonmemory_operand")])
1004 ;; Operand predicate for shifts.
1005 (define_mode_attr shift_operand
1006 [(QI "nonimmediate_operand")
1007 (HI "nonimmediate_operand")
1008 (SI "nonimmediate_operand")
1009 (DI "shiftdi_operand")
1010 (TI "register_operand")])
1012 ;; Operand predicate for shift argument.
1013 (define_mode_attr shift_immediate_operand
1014 [(QI "const_1_to_31_operand")
1015 (HI "const_1_to_31_operand")
1016 (SI "const_1_to_31_operand")
1017 (DI "const_1_to_63_operand")])
1019 ;; Input operand predicate for arithmetic left shifts.
1020 (define_mode_attr ashl_input_operand
1021 [(QI "nonimmediate_operand")
1022 (HI "nonimmediate_operand")
1023 (SI "nonimmediate_operand")
1024 (DI "ashldi_input_operand")
1025 (TI "reg_or_pm1_operand")])
1027 ;; SSE and x87 SFmode and DFmode floating point modes
1028 (define_mode_iterator MODEF [SF DF])
1030 ;; All x87 floating point modes
1031 (define_mode_iterator X87MODEF [SF DF XF])
1033 ;; SSE instruction suffix for various modes
1034 (define_mode_attr ssemodesuffix
1035 [(SF "ss") (DF "sd")
1036 (V16SF "ps") (V8DF "pd")
1037 (V8SF "ps") (V4DF "pd")
1038 (V4SF "ps") (V2DF "pd")
1039 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1040 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1041 (V64QI "b") (V16SI "d") (V8DI "q")])
1043 ;; SSE vector suffix for floating point modes
1044 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1046 ;; SSE vector mode corresponding to a scalar mode
1047 (define_mode_attr ssevecmode
1048 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1049 (define_mode_attr ssevecmodelower
1050 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1052 ;; Instruction suffix for REX 64bit operators.
1053 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1055 ;; This mode iterator allows :P to be used for patterns that operate on
1056 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1057 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1059 ;; This mode iterator allows :W to be used for patterns that operate on
1060 ;; word_mode sized quantities.
1061 (define_mode_iterator W
1062 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1064 ;; This mode iterator allows :PTR to be used for patterns that operate on
1065 ;; ptr_mode sized quantities.
1066 (define_mode_iterator PTR
1067 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1069 ;; Scheduling descriptions
1071 (include "pentium.md")
1074 (include "athlon.md")
1075 (include "bdver1.md")
1076 (include "bdver3.md")
1077 (include "btver2.md")
1078 (include "geode.md")
1081 (include "core2.md")
1084 ;; Operand and operator predicates and constraints
1086 (include "predicates.md")
1087 (include "constraints.md")
1090 ;; Compare and branch/compare and store instructions.
1092 (define_expand "cbranch<mode>4"
1093 [(set (reg:CC FLAGS_REG)
1094 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1095 (match_operand:SDWIM 2 "<general_operand>")))
1096 (set (pc) (if_then_else
1097 (match_operator 0 "ordered_comparison_operator"
1098 [(reg:CC FLAGS_REG) (const_int 0)])
1099 (label_ref (match_operand 3))
1103 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1104 operands[1] = force_reg (<MODE>mode, operands[1]);
1105 ix86_expand_branch (GET_CODE (operands[0]),
1106 operands[1], operands[2], operands[3]);
1110 (define_expand "cstore<mode>4"
1111 [(set (reg:CC FLAGS_REG)
1112 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1113 (match_operand:SWIM 3 "<general_operand>")))
1114 (set (match_operand:QI 0 "register_operand")
1115 (match_operator 1 "ordered_comparison_operator"
1116 [(reg:CC FLAGS_REG) (const_int 0)]))]
1119 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1120 operands[2] = force_reg (<MODE>mode, operands[2]);
1121 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1122 operands[2], operands[3]);
1126 (define_expand "cmp<mode>_1"
1127 [(set (reg:CC FLAGS_REG)
1128 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1129 (match_operand:SWI48 1 "<general_operand>")))])
1131 (define_insn "*cmp<mode>_ccno_1"
1132 [(set (reg FLAGS_REG)
1133 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1134 (match_operand:SWI 1 "const0_operand")))]
1135 "ix86_match_ccmode (insn, CCNOmode)"
1137 test{<imodesuffix>}\t%0, %0
1138 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1139 [(set_attr "type" "test,icmp")
1140 (set_attr "length_immediate" "0,1")
1141 (set_attr "mode" "<MODE>")])
1143 (define_insn "*cmp<mode>_1"
1144 [(set (reg FLAGS_REG)
1145 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1146 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1147 "ix86_match_ccmode (insn, CCmode)"
1148 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1149 [(set_attr "type" "icmp")
1150 (set_attr "mode" "<MODE>")])
1152 (define_insn "*cmp<mode>_minus_1"
1153 [(set (reg FLAGS_REG)
1155 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1156 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1158 "ix86_match_ccmode (insn, CCGOCmode)"
1159 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1160 [(set_attr "type" "icmp")
1161 (set_attr "mode" "<MODE>")])
1163 (define_insn "*cmpqi_ext_1"
1164 [(set (reg FLAGS_REG)
1166 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1169 (match_operand 1 "ext_register_operand" "Q,Q")
1171 (const_int 8)) 0)))]
1172 "ix86_match_ccmode (insn, CCmode)"
1173 "cmp{b}\t{%h1, %0|%0, %h1}"
1174 [(set_attr "isa" "*,nox64")
1175 (set_attr "type" "icmp")
1176 (set_attr "mode" "QI")])
1178 (define_insn "*cmpqi_ext_2"
1179 [(set (reg FLAGS_REG)
1183 (match_operand 0 "ext_register_operand" "Q")
1186 (match_operand:QI 1 "const0_operand")))]
1187 "ix86_match_ccmode (insn, CCNOmode)"
1189 [(set_attr "type" "test")
1190 (set_attr "length_immediate" "0")
1191 (set_attr "mode" "QI")])
1193 (define_expand "cmpqi_ext_3"
1194 [(set (reg:CC FLAGS_REG)
1198 (match_operand 0 "ext_register_operand")
1201 (match_operand:QI 1 "const_int_operand")))])
1203 (define_insn "*cmpqi_ext_3"
1204 [(set (reg FLAGS_REG)
1208 (match_operand 0 "ext_register_operand" "Q,Q")
1211 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1212 "ix86_match_ccmode (insn, CCmode)"
1213 "cmp{b}\t{%1, %h0|%h0, %1}"
1214 [(set_attr "isa" "*,nox64")
1215 (set_attr "type" "icmp")
1216 (set_attr "modrm" "1")
1217 (set_attr "mode" "QI")])
1219 (define_insn "*cmpqi_ext_4"
1220 [(set (reg FLAGS_REG)
1224 (match_operand 0 "ext_register_operand" "Q")
1229 (match_operand 1 "ext_register_operand" "Q")
1231 (const_int 8)) 0)))]
1232 "ix86_match_ccmode (insn, CCmode)"
1233 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1234 [(set_attr "type" "icmp")
1235 (set_attr "mode" "QI")])
1237 ;; These implement float point compares.
1238 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1239 ;; which would allow mix and match FP modes on the compares. Which is what
1240 ;; the old patterns did, but with many more of them.
1242 (define_expand "cbranchxf4"
1243 [(set (reg:CC FLAGS_REG)
1244 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1245 (match_operand:XF 2 "nonmemory_operand")))
1246 (set (pc) (if_then_else
1247 (match_operator 0 "ix86_fp_comparison_operator"
1250 (label_ref (match_operand 3))
1254 ix86_expand_branch (GET_CODE (operands[0]),
1255 operands[1], operands[2], operands[3]);
1259 (define_expand "cstorexf4"
1260 [(set (reg:CC FLAGS_REG)
1261 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1262 (match_operand:XF 3 "nonmemory_operand")))
1263 (set (match_operand:QI 0 "register_operand")
1264 (match_operator 1 "ix86_fp_comparison_operator"
1269 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1270 operands[2], operands[3]);
1274 (define_expand "cbranch<mode>4"
1275 [(set (reg:CC FLAGS_REG)
1276 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1277 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1278 (set (pc) (if_then_else
1279 (match_operator 0 "ix86_fp_comparison_operator"
1282 (label_ref (match_operand 3))
1284 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1286 ix86_expand_branch (GET_CODE (operands[0]),
1287 operands[1], operands[2], operands[3]);
1291 (define_expand "cstore<mode>4"
1292 [(set (reg:CC FLAGS_REG)
1293 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1294 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1295 (set (match_operand:QI 0 "register_operand")
1296 (match_operator 1 "ix86_fp_comparison_operator"
1299 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1301 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1302 operands[2], operands[3]);
1306 (define_expand "cbranchcc4"
1307 [(set (pc) (if_then_else
1308 (match_operator 0 "comparison_operator"
1309 [(match_operand 1 "flags_reg_operand")
1310 (match_operand 2 "const0_operand")])
1311 (label_ref (match_operand 3))
1315 ix86_expand_branch (GET_CODE (operands[0]),
1316 operands[1], operands[2], operands[3]);
1320 (define_expand "cstorecc4"
1321 [(set (match_operand:QI 0 "register_operand")
1322 (match_operator 1 "comparison_operator"
1323 [(match_operand 2 "flags_reg_operand")
1324 (match_operand 3 "const0_operand")]))]
1327 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1328 operands[2], operands[3]);
1333 ;; FP compares, step 1:
1334 ;; Set the FP condition codes.
1336 ;; CCFPmode compare with exceptions
1337 ;; CCFPUmode compare with no exceptions
1339 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1340 ;; used to manage the reg stack popping would not be preserved.
1342 (define_insn "*cmp<mode>_0_i387"
1343 [(set (match_operand:HI 0 "register_operand" "=a")
1346 (match_operand:X87MODEF 1 "register_operand" "f")
1347 (match_operand:X87MODEF 2 "const0_operand"))]
1350 "* return output_fp_compare (insn, operands, false, false);"
1351 [(set_attr "type" "multi")
1352 (set_attr "unit" "i387")
1353 (set_attr "mode" "<MODE>")])
1355 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1356 [(set (reg:CCFP FLAGS_REG)
1358 (match_operand:X87MODEF 1 "register_operand" "f")
1359 (match_operand:X87MODEF 2 "const0_operand")))
1360 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1361 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1363 "&& reload_completed"
1366 [(compare:CCFP (match_dup 1)(match_dup 2))]
1368 (set (reg:CC FLAGS_REG)
1369 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1371 [(set_attr "type" "multi")
1372 (set_attr "unit" "i387")
1373 (set_attr "mode" "<MODE>")])
1375 (define_insn "*cmpxf_i387"
1376 [(set (match_operand:HI 0 "register_operand" "=a")
1379 (match_operand:XF 1 "register_operand" "f")
1380 (match_operand:XF 2 "register_operand" "f"))]
1383 "* return output_fp_compare (insn, operands, false, false);"
1384 [(set_attr "type" "multi")
1385 (set_attr "unit" "i387")
1386 (set_attr "mode" "XF")])
1388 (define_insn_and_split "*cmpxf_cc_i387"
1389 [(set (reg:CCFP FLAGS_REG)
1391 (match_operand:XF 1 "register_operand" "f")
1392 (match_operand:XF 2 "register_operand" "f")))
1393 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1396 "&& reload_completed"
1399 [(compare:CCFP (match_dup 1)(match_dup 2))]
1401 (set (reg:CC FLAGS_REG)
1402 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1404 [(set_attr "type" "multi")
1405 (set_attr "unit" "i387")
1406 (set_attr "mode" "XF")])
1408 (define_insn "*cmp<mode>_i387"
1409 [(set (match_operand:HI 0 "register_operand" "=a")
1412 (match_operand:MODEF 1 "register_operand" "f")
1413 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1416 "* return output_fp_compare (insn, operands, false, false);"
1417 [(set_attr "type" "multi")
1418 (set_attr "unit" "i387")
1419 (set_attr "mode" "<MODE>")])
1421 (define_insn_and_split "*cmp<mode>_cc_i387"
1422 [(set (reg:CCFP FLAGS_REG)
1424 (match_operand:MODEF 1 "register_operand" "f")
1425 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1426 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1427 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1429 "&& reload_completed"
1432 [(compare:CCFP (match_dup 1)(match_dup 2))]
1434 (set (reg:CC FLAGS_REG)
1435 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1437 [(set_attr "type" "multi")
1438 (set_attr "unit" "i387")
1439 (set_attr "mode" "<MODE>")])
1441 (define_insn "*cmpu<mode>_i387"
1442 [(set (match_operand:HI 0 "register_operand" "=a")
1445 (match_operand:X87MODEF 1 "register_operand" "f")
1446 (match_operand:X87MODEF 2 "register_operand" "f"))]
1449 "* return output_fp_compare (insn, operands, false, true);"
1450 [(set_attr "type" "multi")
1451 (set_attr "unit" "i387")
1452 (set_attr "mode" "<MODE>")])
1454 (define_insn_and_split "*cmpu<mode>_cc_i387"
1455 [(set (reg:CCFPU FLAGS_REG)
1457 (match_operand:X87MODEF 1 "register_operand" "f")
1458 (match_operand:X87MODEF 2 "register_operand" "f")))
1459 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1460 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1462 "&& reload_completed"
1465 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1467 (set (reg:CC FLAGS_REG)
1468 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1470 [(set_attr "type" "multi")
1471 (set_attr "unit" "i387")
1472 (set_attr "mode" "<MODE>")])
1474 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1475 [(set (match_operand:HI 0 "register_operand" "=a")
1478 (match_operand:X87MODEF 1 "register_operand" "f")
1479 (match_operator:X87MODEF 3 "float_operator"
1480 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1483 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1484 || optimize_function_for_size_p (cfun))"
1485 "* return output_fp_compare (insn, operands, false, false);"
1486 [(set_attr "type" "multi")
1487 (set_attr "unit" "i387")
1488 (set_attr "fp_int_src" "true")
1489 (set_attr "mode" "<SWI24:MODE>")])
1491 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1492 [(set (reg:CCFP FLAGS_REG)
1494 (match_operand:X87MODEF 1 "register_operand" "f")
1495 (match_operator:X87MODEF 3 "float_operator"
1496 [(match_operand:SWI24 2 "memory_operand" "m")])))
1497 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1498 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1499 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1500 || optimize_function_for_size_p (cfun))"
1502 "&& reload_completed"
1507 (match_op_dup 3 [(match_dup 2)]))]
1509 (set (reg:CC FLAGS_REG)
1510 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1512 [(set_attr "type" "multi")
1513 (set_attr "unit" "i387")
1514 (set_attr "fp_int_src" "true")
1515 (set_attr "mode" "<SWI24:MODE>")])
1517 ;; FP compares, step 2
1518 ;; Move the fpsw to ax.
1520 (define_insn "x86_fnstsw_1"
1521 [(set (match_operand:HI 0 "register_operand" "=a")
1522 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1525 [(set (attr "length")
1526 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1527 (set_attr "mode" "SI")
1528 (set_attr "unit" "i387")])
1530 ;; FP compares, step 3
1531 ;; Get ax into flags, general case.
1533 (define_insn "x86_sahf_1"
1534 [(set (reg:CC FLAGS_REG)
1535 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1539 #ifndef HAVE_AS_IX86_SAHF
1541 return ASM_BYTE "0x9e";
1546 [(set_attr "length" "1")
1547 (set_attr "athlon_decode" "vector")
1548 (set_attr "amdfam10_decode" "direct")
1549 (set_attr "bdver1_decode" "direct")
1550 (set_attr "mode" "SI")])
1552 ;; Pentium Pro can do steps 1 through 3 in one go.
1553 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1554 ;; (these i387 instructions set flags directly)
1556 (define_mode_iterator FPCMP [CCFP CCFPU])
1557 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1559 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1560 [(set (reg:FPCMP FLAGS_REG)
1562 (match_operand:MODEF 0 "register_operand" "f,x")
1563 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1564 "TARGET_MIX_SSE_I387
1565 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1566 "* return output_fp_compare (insn, operands, true,
1567 <FPCMP:MODE>mode == CCFPUmode);"
1568 [(set_attr "type" "fcmp,ssecomi")
1569 (set_attr "prefix" "orig,maybe_vex")
1570 (set_attr "mode" "<MODEF:MODE>")
1571 (set (attr "prefix_rep")
1572 (if_then_else (eq_attr "type" "ssecomi")
1574 (const_string "*")))
1575 (set (attr "prefix_data16")
1576 (cond [(eq_attr "type" "fcmp")
1578 (eq_attr "mode" "DF")
1581 (const_string "0")))
1582 (set_attr "athlon_decode" "vector")
1583 (set_attr "amdfam10_decode" "direct")
1584 (set_attr "bdver1_decode" "double")])
1586 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1587 [(set (reg:FPCMP FLAGS_REG)
1589 (match_operand:MODEF 0 "register_operand" "x")
1590 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1592 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1593 "* return output_fp_compare (insn, operands, true,
1594 <FPCMP:MODE>mode == CCFPUmode);"
1595 [(set_attr "type" "ssecomi")
1596 (set_attr "prefix" "maybe_vex")
1597 (set_attr "mode" "<MODEF:MODE>")
1598 (set_attr "prefix_rep" "0")
1599 (set (attr "prefix_data16")
1600 (if_then_else (eq_attr "mode" "DF")
1602 (const_string "0")))
1603 (set_attr "athlon_decode" "vector")
1604 (set_attr "amdfam10_decode" "direct")
1605 (set_attr "bdver1_decode" "double")])
1607 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1608 [(set (reg:FPCMP FLAGS_REG)
1610 (match_operand:X87MODEF 0 "register_operand" "f")
1611 (match_operand:X87MODEF 1 "register_operand" "f")))]
1612 "TARGET_80387 && TARGET_CMOVE
1613 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1614 "* return output_fp_compare (insn, operands, true,
1615 <FPCMP:MODE>mode == CCFPUmode);"
1616 [(set_attr "type" "fcmp")
1617 (set_attr "mode" "<X87MODEF:MODE>")
1618 (set_attr "athlon_decode" "vector")
1619 (set_attr "amdfam10_decode" "direct")
1620 (set_attr "bdver1_decode" "double")])
1622 ;; Push/pop instructions.
1624 (define_insn "*push<mode>2"
1625 [(set (match_operand:DWI 0 "push_operand" "=<")
1626 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1629 [(set_attr "type" "multi")
1630 (set_attr "mode" "<MODE>")])
1633 [(set (match_operand:TI 0 "push_operand")
1634 (match_operand:TI 1 "general_operand"))]
1635 "TARGET_64BIT && reload_completed
1636 && !SSE_REG_P (operands[1])"
1638 "ix86_split_long_move (operands); DONE;")
1640 (define_insn "*pushdi2_rex64"
1641 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1642 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1647 [(set_attr "type" "push,multi")
1648 (set_attr "mode" "DI")])
1650 ;; Convert impossible pushes of immediate to existing instructions.
1651 ;; First try to get scratch register and go through it. In case this
1652 ;; fails, push sign extended lower part first and then overwrite
1653 ;; upper part by 32bit move.
1655 [(match_scratch:DI 2 "r")
1656 (set (match_operand:DI 0 "push_operand")
1657 (match_operand:DI 1 "immediate_operand"))]
1658 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1659 && !x86_64_immediate_operand (operands[1], DImode)"
1660 [(set (match_dup 2) (match_dup 1))
1661 (set (match_dup 0) (match_dup 2))])
1663 ;; We need to define this as both peepholer and splitter for case
1664 ;; peephole2 pass is not run.
1665 ;; "&& 1" is needed to keep it from matching the previous pattern.
1667 [(set (match_operand:DI 0 "push_operand")
1668 (match_operand:DI 1 "immediate_operand"))]
1669 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1670 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1671 [(set (match_dup 0) (match_dup 1))
1672 (set (match_dup 2) (match_dup 3))]
1674 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1676 operands[1] = gen_lowpart (DImode, operands[2]);
1677 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1682 [(set (match_operand:DI 0 "push_operand")
1683 (match_operand:DI 1 "immediate_operand"))]
1684 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1685 ? epilogue_completed : reload_completed)
1686 && !symbolic_operand (operands[1], DImode)
1687 && !x86_64_immediate_operand (operands[1], DImode)"
1688 [(set (match_dup 0) (match_dup 1))
1689 (set (match_dup 2) (match_dup 3))]
1691 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1693 operands[1] = gen_lowpart (DImode, operands[2]);
1694 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1699 [(set (match_operand:DI 0 "push_operand")
1700 (match_operand:DI 1 "general_operand"))]
1701 "!TARGET_64BIT && reload_completed
1702 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1704 "ix86_split_long_move (operands); DONE;")
1706 (define_insn "*pushsi2"
1707 [(set (match_operand:SI 0 "push_operand" "=<")
1708 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1711 [(set_attr "type" "push")
1712 (set_attr "mode" "SI")])
1714 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1715 ;; "push a byte/word". But actually we use pushl, which has the effect
1716 ;; of rounding the amount pushed up to a word.
1718 ;; For TARGET_64BIT we always round up to 8 bytes.
1719 (define_insn "*push<mode>2_rex64"
1720 [(set (match_operand:SWI124 0 "push_operand" "=X")
1721 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1724 [(set_attr "type" "push")
1725 (set_attr "mode" "DI")])
1727 (define_insn "*push<mode>2"
1728 [(set (match_operand:SWI12 0 "push_operand" "=X")
1729 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1732 [(set_attr "type" "push")
1733 (set_attr "mode" "SI")])
1735 (define_insn "*push<mode>2_prologue"
1736 [(set (match_operand:W 0 "push_operand" "=<")
1737 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1738 (clobber (mem:BLK (scratch)))]
1740 "push{<imodesuffix>}\t%1"
1741 [(set_attr "type" "push")
1742 (set_attr "mode" "<MODE>")])
1744 (define_insn "*pop<mode>1"
1745 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1746 (match_operand:W 1 "pop_operand" ">"))]
1748 "pop{<imodesuffix>}\t%0"
1749 [(set_attr "type" "pop")
1750 (set_attr "mode" "<MODE>")])
1752 (define_insn "*pop<mode>1_epilogue"
1753 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1754 (match_operand:W 1 "pop_operand" ">"))
1755 (clobber (mem:BLK (scratch)))]
1757 "pop{<imodesuffix>}\t%0"
1758 [(set_attr "type" "pop")
1759 (set_attr "mode" "<MODE>")])
1761 (define_insn "*pushfl<mode>2"
1762 [(set (match_operand:W 0 "push_operand" "=<")
1763 (match_operand:W 1 "flags_reg_operand"))]
1765 "pushf{<imodesuffix>}"
1766 [(set_attr "type" "push")
1767 (set_attr "mode" "<MODE>")])
1769 (define_insn "*popfl<mode>1"
1770 [(set (match_operand:W 0 "flags_reg_operand")
1771 (match_operand:W 1 "pop_operand" ">"))]
1773 "popf{<imodesuffix>}"
1774 [(set_attr "type" "pop")
1775 (set_attr "mode" "<MODE>")])
1778 ;; Move instructions.
1780 (define_expand "movxi"
1781 [(set (match_operand:XI 0 "nonimmediate_operand")
1782 (match_operand:XI 1 "general_operand"))]
1784 "ix86_expand_move (XImode, operands); DONE;")
1786 ;; Reload patterns to support multi-word load/store
1787 ;; with non-offsetable address.
1788 (define_expand "reload_noff_store"
1789 [(parallel [(match_operand 0 "memory_operand" "=m")
1790 (match_operand 1 "register_operand" "r")
1791 (match_operand:DI 2 "register_operand" "=&r")])]
1794 rtx mem = operands[0];
1795 rtx addr = XEXP (mem, 0);
1797 emit_move_insn (operands[2], addr);
1798 mem = replace_equiv_address_nv (mem, operands[2]);
1800 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1804 (define_expand "reload_noff_load"
1805 [(parallel [(match_operand 0 "register_operand" "=r")
1806 (match_operand 1 "memory_operand" "m")
1807 (match_operand:DI 2 "register_operand" "=r")])]
1810 rtx mem = operands[1];
1811 rtx addr = XEXP (mem, 0);
1813 emit_move_insn (operands[2], addr);
1814 mem = replace_equiv_address_nv (mem, operands[2]);
1816 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1820 (define_expand "movoi"
1821 [(set (match_operand:OI 0 "nonimmediate_operand")
1822 (match_operand:OI 1 "general_operand"))]
1824 "ix86_expand_move (OImode, operands); DONE;")
1826 (define_expand "movti"
1827 [(set (match_operand:TI 0 "nonimmediate_operand")
1828 (match_operand:TI 1 "nonimmediate_operand"))]
1829 "TARGET_64BIT || TARGET_SSE"
1832 ix86_expand_move (TImode, operands);
1834 ix86_expand_vector_move (TImode, operands);
1838 ;; This expands to what emit_move_complex would generate if we didn't
1839 ;; have a movti pattern. Having this avoids problems with reload on
1840 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1841 ;; to have around all the time.
1842 (define_expand "movcdi"
1843 [(set (match_operand:CDI 0 "nonimmediate_operand")
1844 (match_operand:CDI 1 "general_operand"))]
1847 if (push_operand (operands[0], CDImode))
1848 emit_move_complex_push (CDImode, operands[0], operands[1]);
1850 emit_move_complex_parts (operands[0], operands[1]);
1854 (define_expand "mov<mode>"
1855 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1856 (match_operand:SWI1248x 1 "general_operand"))]
1858 "ix86_expand_move (<MODE>mode, operands); DONE;")
1860 (define_insn "*mov<mode>_xor"
1861 [(set (match_operand:SWI48 0 "register_operand" "=r")
1862 (match_operand:SWI48 1 "const0_operand"))
1863 (clobber (reg:CC FLAGS_REG))]
1866 [(set_attr "type" "alu1")
1867 (set_attr "mode" "SI")
1868 (set_attr "length_immediate" "0")])
1870 (define_insn "*mov<mode>_or"
1871 [(set (match_operand:SWI48 0 "register_operand" "=r")
1872 (match_operand:SWI48 1 "const_int_operand"))
1873 (clobber (reg:CC FLAGS_REG))]
1875 && operands[1] == constm1_rtx"
1876 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1877 [(set_attr "type" "alu1")
1878 (set_attr "mode" "<MODE>")
1879 (set_attr "length_immediate" "1")])
1881 (define_insn "*movxi_internal_avx512f"
1882 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1883 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1884 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1886 switch (which_alternative)
1889 return standard_sse_constant_opcode (insn, operands[1]);
1892 if (misaligned_operand (operands[0], XImode)
1893 || misaligned_operand (operands[1], XImode))
1894 return "vmovdqu32\t{%1, %0|%0, %1}";
1896 return "vmovdqa32\t{%1, %0|%0, %1}";
1901 [(set_attr "type" "sselog1,ssemov,ssemov")
1902 (set_attr "prefix" "evex")
1903 (set_attr "mode" "XI")])
1905 (define_insn "*movoi_internal_avx"
1906 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1907 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1908 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1910 switch (get_attr_type (insn))
1913 return standard_sse_constant_opcode (insn, operands[1]);
1916 if (misaligned_operand (operands[0], OImode)
1917 || misaligned_operand (operands[1], OImode))
1919 if (get_attr_mode (insn) == MODE_V8SF)
1920 return "vmovups\t{%1, %0|%0, %1}";
1922 return "vmovdqu\t{%1, %0|%0, %1}";
1926 if (get_attr_mode (insn) == MODE_V8SF)
1927 return "vmovaps\t{%1, %0|%0, %1}";
1929 return "vmovdqa\t{%1, %0|%0, %1}";
1936 [(set_attr "type" "sselog1,ssemov,ssemov")
1937 (set_attr "prefix" "vex")
1939 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1940 (const_string "V8SF")
1941 (and (eq_attr "alternative" "2")
1942 (match_test "TARGET_SSE_TYPELESS_STORES"))
1943 (const_string "V8SF")
1945 (const_string "OI")))])
1947 (define_insn "*movti_internal"
1948 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1949 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1950 "(TARGET_64BIT || TARGET_SSE)
1951 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1953 switch (get_attr_type (insn))
1959 return standard_sse_constant_opcode (insn, operands[1]);
1962 /* TDmode values are passed as TImode on the stack. Moving them
1963 to stack may result in unaligned memory access. */
1964 if (misaligned_operand (operands[0], TImode)
1965 || misaligned_operand (operands[1], TImode))
1967 if (get_attr_mode (insn) == MODE_V4SF)
1968 return "%vmovups\t{%1, %0|%0, %1}";
1970 return "%vmovdqu\t{%1, %0|%0, %1}";
1974 if (get_attr_mode (insn) == MODE_V4SF)
1975 return "%vmovaps\t{%1, %0|%0, %1}";
1977 return "%vmovdqa\t{%1, %0|%0, %1}";
1984 [(set_attr "isa" "x64,x64,*,*,*")
1985 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1986 (set (attr "prefix")
1987 (if_then_else (eq_attr "type" "sselog1,ssemov")
1988 (const_string "maybe_vex")
1989 (const_string "orig")))
1991 (cond [(eq_attr "alternative" "0,1")
1993 (ior (not (match_test "TARGET_SSE2"))
1994 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1995 (const_string "V4SF")
1996 (and (eq_attr "alternative" "4")
1997 (match_test "TARGET_SSE_TYPELESS_STORES"))
1998 (const_string "V4SF")
1999 (match_test "TARGET_AVX")
2001 (match_test "optimize_function_for_size_p (cfun)")
2002 (const_string "V4SF")
2004 (const_string "TI")))])
2007 [(set (match_operand:TI 0 "nonimmediate_operand")
2008 (match_operand:TI 1 "general_operand"))]
2010 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2012 "ix86_split_long_move (operands); DONE;")
2014 (define_insn "*movdi_internal"
2015 [(set (match_operand:DI 0 "nonimmediate_operand"
2016 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
2017 (match_operand:DI 1 "general_operand"
2018 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn"))]
2019 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2021 switch (get_attr_type (insn))
2027 return "pxor\t%0, %0";
2030 /* Handle broken assemblers that require movd instead of movq. */
2031 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2032 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2033 return "movd\t{%1, %0|%0, %1}";
2034 return "movq\t{%1, %0|%0, %1}";
2037 if (GENERAL_REG_P (operands[0]))
2038 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2040 return standard_sse_constant_opcode (insn, operands[1]);
2043 switch (get_attr_mode (insn))
2046 /* Handle broken assemblers that require movd instead of movq. */
2047 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2048 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2049 return "%vmovd\t{%1, %0|%0, %1}";
2050 return "%vmovq\t{%1, %0|%0, %1}";
2052 return "%vmovdqa\t{%1, %0|%0, %1}";
2054 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2057 gcc_assert (!TARGET_AVX);
2058 return "movlps\t{%1, %0|%0, %1}";
2060 return "%vmovaps\t{%1, %0|%0, %1}";
2067 if (SSE_REG_P (operands[0]))
2068 return "movq2dq\t{%1, %0|%0, %1}";
2070 return "movdq2q\t{%1, %0|%0, %1}";
2073 return "lea{q}\t{%E1, %0|%0, %E1}";
2076 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2077 if (get_attr_mode (insn) == MODE_SI)
2078 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2079 else if (which_alternative == 4)
2080 return "movabs{q}\t{%1, %0|%0, %1}";
2081 else if (ix86_use_lea_for_mov (insn, operands))
2082 return "lea{q}\t{%E1, %0|%0, %E1}";
2084 return "mov{q}\t{%1, %0|%0, %1}";
2091 (cond [(eq_attr "alternative" "0,1")
2092 (const_string "nox64")
2093 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
2094 (const_string "x64")
2095 (eq_attr "alternative" "17")
2096 (const_string "x64_sse4")
2098 (const_string "*")))
2100 (cond [(eq_attr "alternative" "0,1")
2101 (const_string "multi")
2102 (eq_attr "alternative" "6")
2103 (const_string "mmx")
2104 (eq_attr "alternative" "7,8,9,10,11")
2105 (const_string "mmxmov")
2106 (eq_attr "alternative" "12,17")
2107 (const_string "sselog1")
2108 (eq_attr "alternative" "13,14,15,16,18")
2109 (const_string "ssemov")
2110 (eq_attr "alternative" "19,20")
2111 (const_string "ssecvt")
2112 (match_operand 1 "pic_32bit_operand")
2113 (const_string "lea")
2115 (const_string "imov")))
2118 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2120 (const_string "*")))
2121 (set (attr "length_immediate")
2122 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2124 (eq_attr "alternative" "17")
2127 (const_string "*")))
2128 (set (attr "prefix_rex")
2129 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2131 (const_string "*")))
2132 (set (attr "prefix_extra")
2133 (if_then_else (eq_attr "alternative" "17")
2135 (const_string "*")))
2136 (set (attr "prefix")
2137 (if_then_else (eq_attr "type" "sselog1,ssemov")
2138 (const_string "maybe_vex")
2139 (const_string "orig")))
2140 (set (attr "prefix_data16")
2141 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2143 (const_string "*")))
2145 (cond [(eq_attr "alternative" "2")
2147 (eq_attr "alternative" "12,13")
2148 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2149 (match_operand 1 "ext_sse_reg_operand"))
2151 (ior (not (match_test "TARGET_SSE2"))
2152 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2153 (const_string "V4SF")
2154 (match_test "TARGET_AVX")
2156 (match_test "optimize_function_for_size_p (cfun)")
2157 (const_string "V4SF")
2159 (const_string "TI"))
2161 (and (eq_attr "alternative" "14,15")
2162 (not (match_test "TARGET_SSE2")))
2163 (const_string "V2SF")
2164 (eq_attr "alternative" "17")
2167 (const_string "DI")))])
2170 [(set (match_operand:DI 0 "nonimmediate_operand")
2171 (match_operand:DI 1 "general_operand"))]
2172 "!TARGET_64BIT && reload_completed
2173 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2174 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2176 "ix86_split_long_move (operands); DONE;")
2178 (define_insn "*movsi_internal"
2179 [(set (match_operand:SI 0 "nonimmediate_operand"
2180 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi")
2181 (match_operand:SI 1 "general_operand"
2182 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r"))]
2183 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2185 switch (get_attr_type (insn))
2188 if (GENERAL_REG_P (operands[0]))
2189 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2191 return standard_sse_constant_opcode (insn, operands[1]);
2194 switch (get_attr_mode (insn))
2197 return "%vmovd\t{%1, %0|%0, %1}";
2199 return "%vmovdqa\t{%1, %0|%0, %1}";
2201 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2204 return "%vmovaps\t{%1, %0|%0, %1}";
2207 gcc_assert (!TARGET_AVX);
2208 return "movss\t{%1, %0|%0, %1}";
2215 return "pxor\t%0, %0";
2218 switch (get_attr_mode (insn))
2221 return "movq\t{%1, %0|%0, %1}";
2223 return "movd\t{%1, %0|%0, %1}";
2230 return "lea{l}\t{%E1, %0|%0, %E1}";
2233 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2234 if (ix86_use_lea_for_mov (insn, operands))
2235 return "lea{l}\t{%E1, %0|%0, %E1}";
2237 return "mov{l}\t{%1, %0|%0, %1}";
2244 (if_then_else (eq_attr "alternative" "11")
2245 (const_string "sse4")
2246 (const_string "*")))
2248 (cond [(eq_attr "alternative" "2")
2249 (const_string "mmx")
2250 (eq_attr "alternative" "3,4,5")
2251 (const_string "mmxmov")
2252 (eq_attr "alternative" "6,11")
2253 (const_string "sselog1")
2254 (eq_attr "alternative" "7,8,9,10,12")
2255 (const_string "ssemov")
2256 (match_operand 1 "pic_32bit_operand")
2257 (const_string "lea")
2259 (const_string "imov")))
2260 (set (attr "length_immediate")
2261 (if_then_else (eq_attr "alternative" "11")
2263 (const_string "*")))
2264 (set (attr "prefix_extra")
2265 (if_then_else (eq_attr "alternative" "11")
2267 (const_string "*")))
2268 (set (attr "prefix")
2269 (if_then_else (eq_attr "type" "sselog1,ssemov")
2270 (const_string "maybe_vex")
2271 (const_string "orig")))
2272 (set (attr "prefix_data16")
2273 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2275 (const_string "*")))
2277 (cond [(eq_attr "alternative" "2,3")
2279 (eq_attr "alternative" "6,7")
2280 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2281 (match_operand 1 "ext_sse_reg_operand"))
2283 (ior (not (match_test "TARGET_SSE2"))
2284 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2285 (const_string "V4SF")
2286 (match_test "TARGET_AVX")
2288 (match_test "optimize_function_for_size_p (cfun)")
2289 (const_string "V4SF")
2291 (const_string "TI"))
2293 (and (eq_attr "alternative" "8,9")
2294 (not (match_test "TARGET_SSE2")))
2296 (eq_attr "alternative" "11")
2299 (const_string "SI")))])
2301 (define_insn "kmovw"
2302 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2304 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2306 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2308 kmovw\t{%k1, %0|%0, %k1}
2309 kmovw\t{%1, %0|%0, %1}";
2310 [(set_attr "mode" "HI")
2311 (set_attr "type" "mskmov")
2312 (set_attr "prefix" "vex")])
2315 (define_insn "*movhi_internal"
2316 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2317 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2318 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2320 switch (get_attr_type (insn))
2323 /* movzwl is faster than movw on p2 due to partial word stalls,
2324 though not as fast as an aligned movl. */
2325 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2328 switch (which_alternative)
2330 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2331 case 5: return "kmovw\t{%1, %0|%0, %1}";
2332 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2333 default: gcc_unreachable ();
2337 if (get_attr_mode (insn) == MODE_SI)
2338 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2340 return "mov{w}\t{%1, %0|%0, %1}";
2344 (cond [(match_test "optimize_function_for_size_p (cfun)")
2345 (const_string "imov")
2346 (and (eq_attr "alternative" "0")
2347 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2348 (not (match_test "TARGET_HIMODE_MATH"))))
2349 (const_string "imov")
2350 (and (eq_attr "alternative" "1,2")
2351 (match_operand:HI 1 "aligned_operand"))
2352 (const_string "imov")
2353 (eq_attr "alternative" "4,5,6")
2354 (const_string "mskmov")
2355 (and (match_test "TARGET_MOVX")
2356 (eq_attr "alternative" "0,2"))
2357 (const_string "imovx")
2359 (const_string "imov")))
2360 (set (attr "prefix")
2361 (if_then_else (eq_attr "alternative" "4,5,6")
2362 (const_string "vex")
2363 (const_string "orig")))
2365 (cond [(eq_attr "type" "imovx")
2367 (and (eq_attr "alternative" "1,2")
2368 (match_operand:HI 1 "aligned_operand"))
2370 (and (eq_attr "alternative" "0")
2371 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2372 (not (match_test "TARGET_HIMODE_MATH"))))
2375 (const_string "HI")))])
2377 ;; Situation is quite tricky about when to choose full sized (SImode) move
2378 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2379 ;; partial register dependency machines (such as AMD Athlon), where QImode
2380 ;; moves issue extra dependency and for partial register stalls machines
2381 ;; that don't use QImode patterns (and QImode move cause stall on the next
2384 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2385 ;; register stall machines with, where we use QImode instructions, since
2386 ;; partial register stall can be caused there. Then we use movzx.
2388 (define_insn "*movqi_internal"
2389 [(set (match_operand:QI 0 "nonimmediate_operand"
2390 "=q,q ,q ,r,r ,?r,m ,k,k,r")
2391 (match_operand:QI 1 "general_operand"
2392 "q ,qn,qm,q,rn,qm,qn,r ,k,k"))]
2393 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2395 switch (get_attr_type (insn))
2398 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2399 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2402 switch (which_alternative)
2404 case 7: return "kmovw\t{%k1, %0|%0, %k1}";
2405 case 8: return "kmovw\t{%1, %0|%0, %1}";
2406 case 9: return "kmovw\t{%1, %k0|%k0, %1}";
2407 default: gcc_unreachable ();
2411 if (get_attr_mode (insn) == MODE_SI)
2412 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2414 return "mov{b}\t{%1, %0|%0, %1}";
2418 (cond [(and (eq_attr "alternative" "5")
2419 (not (match_operand:QI 1 "aligned_operand")))
2420 (const_string "imovx")
2421 (match_test "optimize_function_for_size_p (cfun)")
2422 (const_string "imov")
2423 (and (eq_attr "alternative" "3")
2424 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2425 (not (match_test "TARGET_QIMODE_MATH"))))
2426 (const_string "imov")
2427 (eq_attr "alternative" "3,5")
2428 (const_string "imovx")
2429 (eq_attr "alternative" "7,8,9")
2430 (const_string "mskmov")
2431 (and (match_test "TARGET_MOVX")
2432 (eq_attr "alternative" "2"))
2433 (const_string "imovx")
2435 (const_string "imov")))
2436 (set (attr "prefix")
2437 (if_then_else (eq_attr "alternative" "7,8,9")
2438 (const_string "vex")
2439 (const_string "orig")))
2441 (cond [(eq_attr "alternative" "3,4,5")
2443 (eq_attr "alternative" "6")
2445 (eq_attr "type" "imovx")
2447 (and (eq_attr "type" "imov")
2448 (and (eq_attr "alternative" "0,1")
2449 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2450 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2451 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2453 ;; Avoid partial register stalls when not using QImode arithmetic
2454 (and (eq_attr "type" "imov")
2455 (and (eq_attr "alternative" "0,1")
2456 (and (match_test "TARGET_PARTIAL_REG_STALL")
2457 (not (match_test "TARGET_QIMODE_MATH")))))
2460 (const_string "QI")))])
2462 ;; Stores and loads of ax to arbitrary constant address.
2463 ;; We fake an second form of instruction to force reload to load address
2464 ;; into register when rax is not available
2465 (define_insn "*movabs<mode>_1"
2466 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2467 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2468 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2470 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2471 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2472 [(set_attr "type" "imov")
2473 (set_attr "modrm" "0,*")
2474 (set_attr "length_address" "8,0")
2475 (set_attr "length_immediate" "0,*")
2476 (set_attr "memory" "store")
2477 (set_attr "mode" "<MODE>")])
2479 (define_insn "*movabs<mode>_2"
2480 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2481 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2482 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2484 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2485 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2486 [(set_attr "type" "imov")
2487 (set_attr "modrm" "0,*")
2488 (set_attr "length_address" "8,0")
2489 (set_attr "length_immediate" "0")
2490 (set_attr "memory" "load")
2491 (set_attr "mode" "<MODE>")])
2493 (define_insn "*swap<mode>"
2494 [(set (match_operand:SWI48 0 "register_operand" "+r")
2495 (match_operand:SWI48 1 "register_operand" "+r"))
2499 "xchg{<imodesuffix>}\t%1, %0"
2500 [(set_attr "type" "imov")
2501 (set_attr "mode" "<MODE>")
2502 (set_attr "pent_pair" "np")
2503 (set_attr "athlon_decode" "vector")
2504 (set_attr "amdfam10_decode" "double")
2505 (set_attr "bdver1_decode" "double")])
2507 (define_insn "*swap<mode>_1"
2508 [(set (match_operand:SWI12 0 "register_operand" "+r")
2509 (match_operand:SWI12 1 "register_operand" "+r"))
2512 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2514 [(set_attr "type" "imov")
2515 (set_attr "mode" "SI")
2516 (set_attr "pent_pair" "np")
2517 (set_attr "athlon_decode" "vector")
2518 (set_attr "amdfam10_decode" "double")
2519 (set_attr "bdver1_decode" "double")])
2521 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2522 ;; is disabled for AMDFAM10
2523 (define_insn "*swap<mode>_2"
2524 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2525 (match_operand:SWI12 1 "register_operand" "+<r>"))
2528 "TARGET_PARTIAL_REG_STALL"
2529 "xchg{<imodesuffix>}\t%1, %0"
2530 [(set_attr "type" "imov")
2531 (set_attr "mode" "<MODE>")
2532 (set_attr "pent_pair" "np")
2533 (set_attr "athlon_decode" "vector")])
2535 (define_expand "movstrict<mode>"
2536 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2537 (match_operand:SWI12 1 "general_operand"))]
2540 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2542 if (GET_CODE (operands[0]) == SUBREG
2543 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2545 /* Don't generate memory->memory moves, go through a register */
2546 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2547 operands[1] = force_reg (<MODE>mode, operands[1]);
2550 (define_insn "*movstrict<mode>_1"
2551 [(set (strict_low_part
2552 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2553 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2554 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2555 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2556 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2557 [(set_attr "type" "imov")
2558 (set_attr "mode" "<MODE>")])
2560 (define_insn "*movstrict<mode>_xor"
2561 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2562 (match_operand:SWI12 1 "const0_operand"))
2563 (clobber (reg:CC FLAGS_REG))]
2565 "xor{<imodesuffix>}\t%0, %0"
2566 [(set_attr "type" "alu1")
2567 (set_attr "mode" "<MODE>")
2568 (set_attr "length_immediate" "0")])
2570 (define_insn "*mov<mode>_extv_1"
2571 [(set (match_operand:SWI24 0 "register_operand" "=R")
2572 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2576 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2577 [(set_attr "type" "imovx")
2578 (set_attr "mode" "SI")])
2580 (define_insn "*movqi_extv_1"
2581 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2582 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2587 switch (get_attr_type (insn))
2590 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2592 return "mov{b}\t{%h1, %0|%0, %h1}";
2595 [(set_attr "isa" "*,*,nox64")
2597 (if_then_else (and (match_operand:QI 0 "register_operand")
2598 (ior (not (match_operand:QI 0 "QIreg_operand"))
2599 (match_test "TARGET_MOVX")))
2600 (const_string "imovx")
2601 (const_string "imov")))
2603 (if_then_else (eq_attr "type" "imovx")
2605 (const_string "QI")))])
2607 (define_insn "*mov<mode>_extzv_1"
2608 [(set (match_operand:SWI48 0 "register_operand" "=R")
2609 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2613 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2614 [(set_attr "type" "imovx")
2615 (set_attr "mode" "SI")])
2617 (define_insn "*movqi_extzv_2"
2618 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2620 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2625 switch (get_attr_type (insn))
2628 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2630 return "mov{b}\t{%h1, %0|%0, %h1}";
2633 [(set_attr "isa" "*,*,nox64")
2635 (if_then_else (and (match_operand:QI 0 "register_operand")
2636 (ior (not (match_operand:QI 0 "QIreg_operand"))
2637 (match_test "TARGET_MOVX")))
2638 (const_string "imovx")
2639 (const_string "imov")))
2641 (if_then_else (eq_attr "type" "imovx")
2643 (const_string "QI")))])
2645 (define_insn "mov<mode>_insv_1"
2646 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2649 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2652 if (CONST_INT_P (operands[1]))
2653 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2654 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2656 [(set_attr "isa" "*,nox64")
2657 (set_attr "type" "imov")
2658 (set_attr "mode" "QI")])
2660 (define_insn "*movqi_insv_2"
2661 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2664 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2667 "mov{b}\t{%h1, %h0|%h0, %h1}"
2668 [(set_attr "type" "imov")
2669 (set_attr "mode" "QI")])
2671 ;; Floating point push instructions.
2673 (define_insn "*pushtf"
2674 [(set (match_operand:TF 0 "push_operand" "=<,<")
2675 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2676 "TARGET_64BIT || TARGET_SSE"
2678 /* This insn should be already split before reg-stack. */
2681 [(set_attr "isa" "*,x64")
2682 (set_attr "type" "multi")
2683 (set_attr "unit" "sse,*")
2684 (set_attr "mode" "TF,DI")])
2686 ;; %%% Kill this when call knows how to work this out.
2688 [(set (match_operand:TF 0 "push_operand")
2689 (match_operand:TF 1 "sse_reg_operand"))]
2690 "TARGET_SSE && reload_completed"
2691 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2692 (set (match_dup 0) (match_dup 1))]
2694 /* Preserve memory attributes. */
2695 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2698 (define_insn "*pushxf"
2699 [(set (match_operand:XF 0 "push_operand" "=<,<")
2700 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2703 /* This insn should be already split before reg-stack. */
2706 [(set_attr "type" "multi")
2707 (set_attr "unit" "i387,*")
2709 (cond [(eq_attr "alternative" "1")
2710 (if_then_else (match_test "TARGET_64BIT")
2712 (const_string "SI"))
2714 (const_string "XF")))])
2716 ;; %%% Kill this when call knows how to work this out.
2718 [(set (match_operand:XF 0 "push_operand")
2719 (match_operand:XF 1 "fp_register_operand"))]
2721 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2722 (set (match_dup 0) (match_dup 1))]
2724 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2725 /* Preserve memory attributes. */
2726 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2729 (define_insn "*pushdf"
2730 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2731 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2734 /* This insn should be already split before reg-stack. */
2737 [(set_attr "isa" "*,nox64,x64,sse2")
2738 (set_attr "type" "multi")
2739 (set_attr "unit" "i387,*,*,sse")
2740 (set_attr "mode" "DF,SI,DI,DF")])
2742 ;; %%% Kill this when call knows how to work this out.
2744 [(set (match_operand:DF 0 "push_operand")
2745 (match_operand:DF 1 "any_fp_register_operand"))]
2747 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2748 (set (match_dup 0) (match_dup 1))]
2750 /* Preserve memory attributes. */
2751 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2754 (define_insn "*pushsf_rex64"
2755 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2756 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2759 /* Anything else should be already split before reg-stack. */
2760 gcc_assert (which_alternative == 1);
2761 return "push{q}\t%q1";
2763 [(set_attr "type" "multi,push,multi")
2764 (set_attr "unit" "i387,*,*")
2765 (set_attr "mode" "SF,DI,SF")])
2767 (define_insn "*pushsf"
2768 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2769 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2772 /* Anything else should be already split before reg-stack. */
2773 gcc_assert (which_alternative == 1);
2774 return "push{l}\t%1";
2776 [(set_attr "type" "multi,push,multi")
2777 (set_attr "unit" "i387,*,*")
2778 (set_attr "mode" "SF,SI,SF")])
2780 ;; %%% Kill this when call knows how to work this out.
2782 [(set (match_operand:SF 0 "push_operand")
2783 (match_operand:SF 1 "any_fp_register_operand"))]
2785 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2786 (set (match_dup 0) (match_dup 1))]
2788 rtx op = XEXP (operands[0], 0);
2789 if (GET_CODE (op) == PRE_DEC)
2791 gcc_assert (!TARGET_64BIT);
2796 op = XEXP (XEXP (op, 1), 1);
2797 gcc_assert (CONST_INT_P (op));
2800 /* Preserve memory attributes. */
2801 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2805 [(set (match_operand:SF 0 "push_operand")
2806 (match_operand:SF 1 "memory_operand"))]
2808 && (operands[2] = find_constant_src (insn))"
2809 [(set (match_dup 0) (match_dup 2))])
2812 [(set (match_operand 0 "push_operand")
2813 (match_operand 1 "general_operand"))]
2815 && (GET_MODE (operands[0]) == TFmode
2816 || GET_MODE (operands[0]) == XFmode
2817 || GET_MODE (operands[0]) == DFmode)
2818 && !ANY_FP_REG_P (operands[1])"
2820 "ix86_split_long_move (operands); DONE;")
2822 ;; Floating point move instructions.
2824 (define_expand "movtf"
2825 [(set (match_operand:TF 0 "nonimmediate_operand")
2826 (match_operand:TF 1 "nonimmediate_operand"))]
2827 "TARGET_64BIT || TARGET_SSE"
2828 "ix86_expand_move (TFmode, operands); DONE;")
2830 (define_expand "mov<mode>"
2831 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2832 (match_operand:X87MODEF 1 "general_operand"))]
2834 "ix86_expand_move (<MODE>mode, operands); DONE;")
2836 (define_insn "*movtf_internal"
2837 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2838 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2839 "(TARGET_64BIT || TARGET_SSE)
2840 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2841 && (!can_create_pseudo_p ()
2842 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2843 || GET_CODE (operands[1]) != CONST_DOUBLE
2844 || (optimize_function_for_size_p (cfun)
2845 && standard_sse_constant_p (operands[1])
2846 && !memory_operand (operands[0], TFmode))
2847 || (!TARGET_MEMORY_MISMATCH_STALL
2848 && memory_operand (operands[0], TFmode)))"
2850 switch (get_attr_type (insn))
2853 return standard_sse_constant_opcode (insn, operands[1]);
2856 /* Handle misaligned load/store since we
2857 don't have movmisaligntf pattern. */
2858 if (misaligned_operand (operands[0], TFmode)
2859 || misaligned_operand (operands[1], TFmode))
2861 if (get_attr_mode (insn) == MODE_V4SF)
2862 return "%vmovups\t{%1, %0|%0, %1}";
2864 return "%vmovdqu\t{%1, %0|%0, %1}";
2868 if (get_attr_mode (insn) == MODE_V4SF)
2869 return "%vmovaps\t{%1, %0|%0, %1}";
2871 return "%vmovdqa\t{%1, %0|%0, %1}";
2881 [(set_attr "isa" "*,*,*,x64,x64")
2882 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2883 (set (attr "prefix")
2884 (if_then_else (eq_attr "type" "sselog1,ssemov")
2885 (const_string "maybe_vex")
2886 (const_string "orig")))
2888 (cond [(eq_attr "alternative" "3,4")
2890 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2891 (const_string "V4SF")
2892 (and (eq_attr "alternative" "2")
2893 (match_test "TARGET_SSE_TYPELESS_STORES"))
2894 (const_string "V4SF")
2895 (match_test "TARGET_AVX")
2897 (ior (not (match_test "TARGET_SSE2"))
2898 (match_test "optimize_function_for_size_p (cfun)"))
2899 (const_string "V4SF")
2901 (const_string "TI")))])
2903 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2904 (define_insn "*movxf_internal"
2905 [(set (match_operand:XF 0 "nonimmediate_operand"
2906 "=f,m,f,?Yx*r ,!o ,!o")
2907 (match_operand:XF 1 "general_operand"
2908 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2909 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2910 && (!can_create_pseudo_p ()
2911 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2912 || GET_CODE (operands[1]) != CONST_DOUBLE
2913 || (optimize_function_for_size_p (cfun)
2914 && standard_80387_constant_p (operands[1]) > 0
2915 && !memory_operand (operands[0], XFmode))
2916 || (!TARGET_MEMORY_MISMATCH_STALL
2917 && memory_operand (operands[0], XFmode)))"
2919 switch (get_attr_type (insn))
2922 if (which_alternative == 2)
2923 return standard_80387_constant_opcode (operands[1]);
2924 return output_387_reg_move (insn, operands);
2933 [(set_attr "isa" "*,*,*,*,nox64,x64")
2934 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2936 (cond [(eq_attr "alternative" "3,4,5")
2937 (if_then_else (match_test "TARGET_64BIT")
2939 (const_string "SI"))
2941 (const_string "XF")))])
2943 ;; Possible store forwarding (partial memory) stall in alternative 4.
2944 (define_insn "*movdf_internal"
2945 [(set (match_operand:DF 0 "nonimmediate_operand"
2946 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2947 (match_operand:DF 1 "general_operand"
2948 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2949 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2950 && (!can_create_pseudo_p ()
2951 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2952 || GET_CODE (operands[1]) != CONST_DOUBLE
2953 || (optimize_function_for_size_p (cfun)
2954 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2955 && standard_80387_constant_p (operands[1]) > 0)
2956 || (TARGET_SSE2 && TARGET_SSE_MATH
2957 && standard_sse_constant_p (operands[1])))
2958 && !memory_operand (operands[0], DFmode))
2959 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2960 && memory_operand (operands[0], DFmode)))"
2962 switch (get_attr_type (insn))
2965 if (which_alternative == 2)
2966 return standard_80387_constant_opcode (operands[1]);
2967 return output_387_reg_move (insn, operands);
2973 if (get_attr_mode (insn) == MODE_SI)
2974 return "mov{l}\t{%1, %k0|%k0, %1}";
2975 else if (which_alternative == 8)
2976 return "movabs{q}\t{%1, %0|%0, %1}";
2978 return "mov{q}\t{%1, %0|%0, %1}";
2981 return standard_sse_constant_opcode (insn, operands[1]);
2984 switch (get_attr_mode (insn))
2987 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2988 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2989 return "%vmovsd\t{%1, %0|%0, %1}";
2992 return "%vmovaps\t{%1, %0|%0, %1}";
2994 return "vmovapd\t{%g1, %g0|%g0, %g1}";
2996 return "%vmovapd\t{%1, %0|%0, %1}";
2999 gcc_assert (!TARGET_AVX);
3000 return "movlps\t{%1, %0|%0, %1}";
3002 gcc_assert (!TARGET_AVX);
3003 return "movlpd\t{%1, %0|%0, %1}";
3006 /* Handle broken assemblers that require movd instead of movq. */
3007 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3008 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3009 return "%vmovd\t{%1, %0|%0, %1}";
3010 return "%vmovq\t{%1, %0|%0, %1}";
3021 (cond [(eq_attr "alternative" "3,4")
3022 (const_string "nox64")
3023 (eq_attr "alternative" "5,6,7,8,17,18")
3024 (const_string "x64")
3025 (eq_attr "alternative" "9,10,11,12")
3026 (const_string "sse2")
3028 (const_string "*")))
3030 (cond [(eq_attr "alternative" "0,1,2")
3031 (const_string "fmov")
3032 (eq_attr "alternative" "3,4")
3033 (const_string "multi")
3034 (eq_attr "alternative" "5,6,7,8")
3035 (const_string "imov")
3036 (eq_attr "alternative" "9,13")
3037 (const_string "sselog1")
3039 (const_string "ssemov")))
3041 (if_then_else (eq_attr "alternative" "8")
3043 (const_string "*")))
3044 (set (attr "length_immediate")
3045 (if_then_else (eq_attr "alternative" "8")
3047 (const_string "*")))
3048 (set (attr "prefix")
3049 (if_then_else (eq_attr "type" "sselog1,ssemov")
3050 (const_string "maybe_vex")
3051 (const_string "orig")))
3052 (set (attr "prefix_data16")
3054 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3055 (eq_attr "mode" "V1DF"))
3057 (const_string "*")))
3059 (cond [(eq_attr "alternative" "3,4,7")
3061 (eq_attr "alternative" "5,6,8,17,18")
3064 /* xorps is one byte shorter for non-AVX targets. */
3065 (eq_attr "alternative" "9,13")
3066 (cond [(not (match_test "TARGET_SSE2"))
3067 (const_string "V4SF")
3068 (match_test "TARGET_AVX512F")
3070 (match_test "TARGET_AVX")
3071 (const_string "V2DF")
3072 (match_test "optimize_function_for_size_p (cfun)")
3073 (const_string "V4SF")
3074 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3077 (const_string "V2DF"))
3079 /* For architectures resolving dependencies on
3080 whole SSE registers use movapd to break dependency
3081 chains, otherwise use short move to avoid extra work. */
3083 /* movaps is one byte shorter for non-AVX targets. */
3084 (eq_attr "alternative" "10,14")
3085 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3086 (match_operand 1 "ext_sse_reg_operand"))
3087 (const_string "V8DF")
3088 (ior (not (match_test "TARGET_SSE2"))
3089 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3090 (const_string "V4SF")
3091 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3092 (const_string "V2DF")
3093 (match_test "TARGET_AVX")
3095 (match_test "optimize_function_for_size_p (cfun)")
3096 (const_string "V4SF")
3098 (const_string "DF"))
3100 /* For architectures resolving dependencies on register
3101 parts we may avoid extra work to zero out upper part
3103 (eq_attr "alternative" "11,15")
3104 (cond [(not (match_test "TARGET_SSE2"))
3105 (const_string "V2SF")
3106 (match_test "TARGET_AVX")
3108 (match_test "TARGET_SSE_SPLIT_REGS")
3109 (const_string "V1DF")
3111 (const_string "DF"))
3113 (and (eq_attr "alternative" "12,16")
3114 (not (match_test "TARGET_SSE2")))
3115 (const_string "V2SF")
3117 (const_string "DF")))])
3119 (define_insn "*movsf_internal"
3120 [(set (match_operand:SF 0 "nonimmediate_operand"
3121 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3122 (match_operand:SF 1 "general_operand"
3123 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3124 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3125 && (!can_create_pseudo_p ()
3126 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3127 || GET_CODE (operands[1]) != CONST_DOUBLE
3128 || (optimize_function_for_size_p (cfun)
3129 && ((!TARGET_SSE_MATH
3130 && standard_80387_constant_p (operands[1]) > 0)
3132 && standard_sse_constant_p (operands[1]))))
3133 || memory_operand (operands[0], SFmode))"
3135 switch (get_attr_type (insn))
3138 if (which_alternative == 2)
3139 return standard_80387_constant_opcode (operands[1]);
3140 return output_387_reg_move (insn, operands);
3143 return "mov{l}\t{%1, %0|%0, %1}";
3146 return standard_sse_constant_opcode (insn, operands[1]);
3149 switch (get_attr_mode (insn))
3152 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3153 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3154 return "%vmovss\t{%1, %0|%0, %1}";
3157 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3159 return "%vmovaps\t{%1, %0|%0, %1}";
3162 return "%vmovd\t{%1, %0|%0, %1}";
3169 switch (get_attr_mode (insn))
3172 return "movq\t{%1, %0|%0, %1}";
3174 return "movd\t{%1, %0|%0, %1}";
3185 (cond [(eq_attr "alternative" "0,1,2")
3186 (const_string "fmov")
3187 (eq_attr "alternative" "3,4")
3188 (const_string "imov")
3189 (eq_attr "alternative" "5")
3190 (const_string "sselog1")
3191 (eq_attr "alternative" "11,12,13,14,15")
3192 (const_string "mmxmov")
3194 (const_string "ssemov")))
3195 (set (attr "prefix")
3196 (if_then_else (eq_attr "type" "sselog1,ssemov")
3197 (const_string "maybe_vex")
3198 (const_string "orig")))
3199 (set (attr "prefix_data16")
3200 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3202 (const_string "*")))
3204 (cond [(eq_attr "alternative" "3,4,9,10,13,14,15")
3206 (eq_attr "alternative" "11")
3208 (eq_attr "alternative" "5")
3209 (cond [(not (match_test "TARGET_SSE2"))
3210 (const_string "V4SF")
3211 (match_test "TARGET_AVX512F")
3212 (const_string "V16SF")
3213 (match_test "TARGET_AVX")
3214 (const_string "V4SF")
3215 (match_test "optimize_function_for_size_p (cfun)")
3216 (const_string "V4SF")
3217 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3220 (const_string "V4SF"))
3222 /* For architectures resolving dependencies on
3223 whole SSE registers use APS move to break dependency
3224 chains, otherwise use short move to avoid extra work.
3226 Do the same for architectures resolving dependencies on
3227 the parts. While in DF mode it is better to always handle
3228 just register parts, the SF mode is different due to lack
3229 of instructions to load just part of the register. It is
3230 better to maintain the whole registers in single format
3231 to avoid problems on using packed logical operations. */
3232 (eq_attr "alternative" "6")
3233 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3234 (match_operand 1 "ext_sse_reg_operand"))
3235 (const_string "V16SF")
3236 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3237 (match_test "TARGET_SSE_SPLIT_REGS"))
3238 (const_string "V4SF")
3240 (const_string "SF"))
3242 (const_string "SF")))])
3245 [(set (match_operand 0 "any_fp_register_operand")
3246 (match_operand 1 "memory_operand"))]
3248 && (GET_MODE (operands[0]) == TFmode
3249 || GET_MODE (operands[0]) == XFmode
3250 || GET_MODE (operands[0]) == DFmode
3251 || GET_MODE (operands[0]) == SFmode)
3252 && (operands[2] = find_constant_src (insn))"
3253 [(set (match_dup 0) (match_dup 2))]
3255 rtx c = operands[2];
3256 int r = REGNO (operands[0]);
3258 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3259 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3264 [(set (match_operand 0 "any_fp_register_operand")
3265 (float_extend (match_operand 1 "memory_operand")))]
3267 && (GET_MODE (operands[0]) == TFmode
3268 || GET_MODE (operands[0]) == XFmode
3269 || GET_MODE (operands[0]) == DFmode)
3270 && (operands[2] = find_constant_src (insn))"
3271 [(set (match_dup 0) (match_dup 2))]
3273 rtx c = operands[2];
3274 int r = REGNO (operands[0]);
3276 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3277 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3281 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3283 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3284 (match_operand:X87MODEF 1 "immediate_operand"))]
3286 && (standard_80387_constant_p (operands[1]) == 8
3287 || standard_80387_constant_p (operands[1]) == 9)"
3288 [(set (match_dup 0)(match_dup 1))
3290 (neg:X87MODEF (match_dup 0)))]
3294 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3295 if (real_isnegzero (&r))
3296 operands[1] = CONST0_RTX (<MODE>mode);
3298 operands[1] = CONST1_RTX (<MODE>mode);
3302 [(set (match_operand 0 "nonimmediate_operand")
3303 (match_operand 1 "general_operand"))]
3305 && (GET_MODE (operands[0]) == TFmode
3306 || GET_MODE (operands[0]) == XFmode
3307 || GET_MODE (operands[0]) == DFmode)
3308 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3310 "ix86_split_long_move (operands); DONE;")
3312 (define_insn "swapxf"
3313 [(set (match_operand:XF 0 "register_operand" "+f")
3314 (match_operand:XF 1 "register_operand" "+f"))
3319 if (STACK_TOP_P (operands[0]))
3324 [(set_attr "type" "fxch")
3325 (set_attr "mode" "XF")])
3327 (define_insn "*swap<mode>"
3328 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3329 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3332 "TARGET_80387 || reload_completed"
3334 if (STACK_TOP_P (operands[0]))
3339 [(set_attr "type" "fxch")
3340 (set_attr "mode" "<MODE>")])
3342 ;; Zero extension instructions
3344 (define_expand "zero_extendsidi2"
3345 [(set (match_operand:DI 0 "nonimmediate_operand")
3346 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3348 (define_insn "*zero_extendsidi2"
3349 [(set (match_operand:DI 0 "nonimmediate_operand"
3350 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3352 (match_operand:SI 1 "x86_64_zext_operand"
3353 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3356 switch (get_attr_type (insn))
3359 if (ix86_use_lea_for_mov (insn, operands))
3360 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3362 return "mov{l}\t{%1, %k0|%k0, %1}";
3368 return "movd\t{%1, %0|%0, %1}";
3371 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3374 if (GENERAL_REG_P (operands[0]))
3375 return "%vmovd\t{%1, %k0|%k0, %1}";
3377 return "%vmovd\t{%1, %0|%0, %1}";
3384 (cond [(eq_attr "alternative" "0,1,2")
3385 (const_string "nox64")
3386 (eq_attr "alternative" "3,7")
3387 (const_string "x64")
3388 (eq_attr "alternative" "8")
3389 (const_string "x64_sse4")
3390 (eq_attr "alternative" "10")
3391 (const_string "sse2")
3393 (const_string "*")))
3395 (cond [(eq_attr "alternative" "0,1,2,4")
3396 (const_string "multi")
3397 (eq_attr "alternative" "5,6")
3398 (const_string "mmxmov")
3399 (eq_attr "alternative" "7,9,10")
3400 (const_string "ssemov")
3401 (eq_attr "alternative" "8")
3402 (const_string "sselog1")
3404 (const_string "imovx")))
3405 (set (attr "prefix_extra")
3406 (if_then_else (eq_attr "alternative" "8")
3408 (const_string "*")))
3409 (set (attr "length_immediate")
3410 (if_then_else (eq_attr "alternative" "8")
3412 (const_string "*")))
3413 (set (attr "prefix")
3414 (if_then_else (eq_attr "type" "ssemov,sselog1")
3415 (const_string "maybe_vex")
3416 (const_string "orig")))
3417 (set (attr "prefix_0f")
3418 (if_then_else (eq_attr "type" "imovx")
3420 (const_string "*")))
3422 (cond [(eq_attr "alternative" "5,6")
3424 (eq_attr "alternative" "7,8,9")
3427 (const_string "SI")))])
3430 [(set (match_operand:DI 0 "memory_operand")
3431 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
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 "register_operand")
3438 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3439 "!TARGET_64BIT && reload_completed
3440 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3441 && true_regnum (operands[0]) == true_regnum (operands[1])"
3442 [(set (match_dup 4) (const_int 0))]
3443 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3446 [(set (match_operand:DI 0 "nonimmediate_operand")
3447 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3448 "!TARGET_64BIT && reload_completed
3449 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3450 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3451 [(set (match_dup 3) (match_dup 1))
3452 (set (match_dup 4) (const_int 0))]
3453 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3455 (define_insn "zero_extend<mode>di2"
3456 [(set (match_operand:DI 0 "register_operand" "=r")
3458 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3460 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3461 [(set_attr "type" "imovx")
3462 (set_attr "mode" "SI")])
3464 (define_expand "zero_extend<mode>si2"
3465 [(set (match_operand:SI 0 "register_operand")
3466 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3469 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3471 operands[1] = force_reg (<MODE>mode, operands[1]);
3472 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3477 (define_insn_and_split "zero_extend<mode>si2_and"
3478 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3480 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3481 (clobber (reg:CC FLAGS_REG))]
3482 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3484 "&& reload_completed"
3485 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3486 (clobber (reg:CC FLAGS_REG))])]
3488 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3490 ix86_expand_clear (operands[0]);
3492 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3493 emit_insn (gen_movstrict<mode>
3494 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3498 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3500 [(set_attr "type" "alu1")
3501 (set_attr "mode" "SI")])
3503 (define_insn "*zero_extend<mode>si2"
3504 [(set (match_operand:SI 0 "register_operand" "=r")
3506 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3507 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3508 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3509 [(set_attr "type" "imovx")
3510 (set_attr "mode" "SI")])
3512 (define_expand "zero_extendqihi2"
3513 [(set (match_operand:HI 0 "register_operand")
3514 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3517 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3519 operands[1] = force_reg (QImode, operands[1]);
3520 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3525 (define_insn_and_split "zero_extendqihi2_and"
3526 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3527 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3528 (clobber (reg:CC FLAGS_REG))]
3529 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3531 "&& reload_completed"
3532 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3533 (clobber (reg:CC FLAGS_REG))])]
3535 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3537 ix86_expand_clear (operands[0]);
3539 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3540 emit_insn (gen_movstrictqi
3541 (gen_lowpart (QImode, operands[0]), operands[1]));
3545 operands[0] = gen_lowpart (SImode, operands[0]);
3547 [(set_attr "type" "alu1")
3548 (set_attr "mode" "SI")])
3550 ; zero extend to SImode to avoid partial register stalls
3551 (define_insn "*zero_extendqihi2"
3552 [(set (match_operand:HI 0 "register_operand" "=r")
3553 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3554 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3555 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3556 [(set_attr "type" "imovx")
3557 (set_attr "mode" "SI")])
3559 ;; Sign extension instructions
3561 (define_expand "extendsidi2"
3562 [(set (match_operand:DI 0 "register_operand")
3563 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3568 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3573 (define_insn "*extendsidi2_rex64"
3574 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3575 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3579 movs{lq|x}\t{%1, %0|%0, %1}"
3580 [(set_attr "type" "imovx")
3581 (set_attr "mode" "DI")
3582 (set_attr "prefix_0f" "0")
3583 (set_attr "modrm" "0,1")])
3585 (define_insn "extendsidi2_1"
3586 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3587 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3588 (clobber (reg:CC FLAGS_REG))
3589 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3593 ;; Split the memory case. If the source register doesn't die, it will stay
3594 ;; this way, if it does die, following peephole2s take care of it.
3596 [(set (match_operand:DI 0 "memory_operand")
3597 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3598 (clobber (reg:CC FLAGS_REG))
3599 (clobber (match_operand:SI 2 "register_operand"))]
3603 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3605 emit_move_insn (operands[3], operands[1]);
3607 /* Generate a cltd if possible and doing so it profitable. */
3608 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3609 && true_regnum (operands[1]) == AX_REG
3610 && true_regnum (operands[2]) == DX_REG)
3612 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3616 emit_move_insn (operands[2], operands[1]);
3617 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3619 emit_move_insn (operands[4], operands[2]);
3623 ;; Peepholes for the case where the source register does die, after
3624 ;; being split with the above splitter.
3626 [(set (match_operand:SI 0 "memory_operand")
3627 (match_operand:SI 1 "register_operand"))
3628 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3629 (parallel [(set (match_dup 2)
3630 (ashiftrt:SI (match_dup 2) (const_int 31)))
3631 (clobber (reg:CC FLAGS_REG))])
3632 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3633 "REGNO (operands[1]) != REGNO (operands[2])
3634 && peep2_reg_dead_p (2, operands[1])
3635 && peep2_reg_dead_p (4, operands[2])
3636 && !reg_mentioned_p (operands[2], operands[3])"
3637 [(set (match_dup 0) (match_dup 1))
3638 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3639 (clobber (reg:CC FLAGS_REG))])
3640 (set (match_dup 3) (match_dup 1))])
3643 [(set (match_operand:SI 0 "memory_operand")
3644 (match_operand:SI 1 "register_operand"))
3645 (parallel [(set (match_operand:SI 2 "register_operand")
3646 (ashiftrt:SI (match_dup 1) (const_int 31)))
3647 (clobber (reg:CC FLAGS_REG))])
3648 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3649 "/* cltd is shorter than sarl $31, %eax */
3650 !optimize_function_for_size_p (cfun)
3651 && true_regnum (operands[1]) == AX_REG
3652 && true_regnum (operands[2]) == DX_REG
3653 && peep2_reg_dead_p (2, operands[1])
3654 && peep2_reg_dead_p (3, operands[2])
3655 && !reg_mentioned_p (operands[2], operands[3])"
3656 [(set (match_dup 0) (match_dup 1))
3657 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3658 (clobber (reg:CC FLAGS_REG))])
3659 (set (match_dup 3) (match_dup 1))])
3661 ;; Extend to register case. Optimize case where source and destination
3662 ;; registers match and cases where we can use cltd.
3664 [(set (match_operand:DI 0 "register_operand")
3665 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3666 (clobber (reg:CC FLAGS_REG))
3667 (clobber (match_scratch:SI 2))]
3671 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3673 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3674 emit_move_insn (operands[3], operands[1]);
3676 /* Generate a cltd if possible and doing so it profitable. */
3677 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3678 && true_regnum (operands[3]) == AX_REG
3679 && true_regnum (operands[4]) == DX_REG)
3681 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3685 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3686 emit_move_insn (operands[4], operands[1]);
3688 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3692 (define_insn "extend<mode>di2"
3693 [(set (match_operand:DI 0 "register_operand" "=r")
3695 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3697 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3698 [(set_attr "type" "imovx")
3699 (set_attr "mode" "DI")])
3701 (define_insn "extendhisi2"
3702 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3703 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3706 switch (get_attr_prefix_0f (insn))
3709 return "{cwtl|cwde}";
3711 return "movs{wl|x}\t{%1, %0|%0, %1}";
3714 [(set_attr "type" "imovx")
3715 (set_attr "mode" "SI")
3716 (set (attr "prefix_0f")
3717 ;; movsx is short decodable while cwtl is vector decoded.
3718 (if_then_else (and (eq_attr "cpu" "!k6")
3719 (eq_attr "alternative" "0"))
3721 (const_string "1")))
3723 (if_then_else (eq_attr "prefix_0f" "0")
3725 (const_string "1")))])
3727 (define_insn "*extendhisi2_zext"
3728 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3731 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3734 switch (get_attr_prefix_0f (insn))
3737 return "{cwtl|cwde}";
3739 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3742 [(set_attr "type" "imovx")
3743 (set_attr "mode" "SI")
3744 (set (attr "prefix_0f")
3745 ;; movsx is short decodable while cwtl is vector decoded.
3746 (if_then_else (and (eq_attr "cpu" "!k6")
3747 (eq_attr "alternative" "0"))
3749 (const_string "1")))
3751 (if_then_else (eq_attr "prefix_0f" "0")
3753 (const_string "1")))])
3755 (define_insn "extendqisi2"
3756 [(set (match_operand:SI 0 "register_operand" "=r")
3757 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3759 "movs{bl|x}\t{%1, %0|%0, %1}"
3760 [(set_attr "type" "imovx")
3761 (set_attr "mode" "SI")])
3763 (define_insn "*extendqisi2_zext"
3764 [(set (match_operand:DI 0 "register_operand" "=r")
3766 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3768 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3769 [(set_attr "type" "imovx")
3770 (set_attr "mode" "SI")])
3772 (define_insn "extendqihi2"
3773 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3774 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3777 switch (get_attr_prefix_0f (insn))
3780 return "{cbtw|cbw}";
3782 return "movs{bw|x}\t{%1, %0|%0, %1}";
3785 [(set_attr "type" "imovx")
3786 (set_attr "mode" "HI")
3787 (set (attr "prefix_0f")
3788 ;; movsx is short decodable while cwtl is vector decoded.
3789 (if_then_else (and (eq_attr "cpu" "!k6")
3790 (eq_attr "alternative" "0"))
3792 (const_string "1")))
3794 (if_then_else (eq_attr "prefix_0f" "0")
3796 (const_string "1")))])
3798 ;; Conversions between float and double.
3800 ;; These are all no-ops in the model used for the 80387.
3801 ;; So just emit moves.
3803 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3805 [(set (match_operand:DF 0 "push_operand")
3806 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3808 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3809 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3812 [(set (match_operand:XF 0 "push_operand")
3813 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3815 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3816 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3817 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3819 (define_expand "extendsfdf2"
3820 [(set (match_operand:DF 0 "nonimmediate_operand")
3821 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3822 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3824 /* ??? Needed for compress_float_constant since all fp constants
3825 are TARGET_LEGITIMATE_CONSTANT_P. */
3826 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3828 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3829 && standard_80387_constant_p (operands[1]) > 0)
3831 operands[1] = simplify_const_unary_operation
3832 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3833 emit_move_insn_1 (operands[0], operands[1]);
3836 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3840 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3842 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3844 We do the conversion post reload to avoid producing of 128bit spills
3845 that might lead to ICE on 32bit target. The sequence unlikely combine
3848 [(set (match_operand:DF 0 "register_operand")
3850 (match_operand:SF 1 "nonimmediate_operand")))]
3851 "TARGET_USE_VECTOR_FP_CONVERTS
3852 && optimize_insn_for_speed_p ()
3853 && reload_completed && SSE_REG_P (operands[0])"
3858 (parallel [(const_int 0) (const_int 1)]))))]
3860 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3861 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3862 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3863 Try to avoid move when unpacking can be done in source. */
3864 if (REG_P (operands[1]))
3866 /* If it is unsafe to overwrite upper half of source, we need
3867 to move to destination and unpack there. */
3868 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3869 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3870 && true_regnum (operands[0]) != true_regnum (operands[1]))
3872 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3873 emit_move_insn (tmp, operands[1]);
3876 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3877 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3881 emit_insn (gen_vec_setv4sf_0 (operands[3],
3882 CONST0_RTX (V4SFmode), operands[1]));
3885 ;; It's more profitable to split and then extend in the same register.
3887 [(set (match_operand:DF 0 "register_operand")
3889 (match_operand:SF 1 "memory_operand")))]
3890 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3891 && optimize_insn_for_speed_p ()
3892 && SSE_REG_P (operands[0])"
3893 [(set (match_dup 2) (match_dup 1))
3894 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3895 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3897 (define_insn "*extendsfdf2_mixed"
3898 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3900 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3901 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3903 switch (which_alternative)
3907 return output_387_reg_move (insn, operands);
3910 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3916 [(set_attr "type" "fmov,fmov,ssecvt")
3917 (set_attr "prefix" "orig,orig,maybe_vex")
3918 (set_attr "mode" "SF,XF,DF")])
3920 (define_insn "*extendsfdf2_sse"
3921 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3922 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3923 "TARGET_SSE2 && TARGET_SSE_MATH"
3924 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3925 [(set_attr "type" "ssecvt")
3926 (set_attr "prefix" "maybe_vex")
3927 (set_attr "mode" "DF")])
3929 (define_insn "*extendsfdf2_i387"
3930 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3931 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3933 "* return output_387_reg_move (insn, operands);"
3934 [(set_attr "type" "fmov")
3935 (set_attr "mode" "SF,XF")])
3937 (define_expand "extend<mode>xf2"
3938 [(set (match_operand:XF 0 "nonimmediate_operand")
3939 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3942 /* ??? Needed for compress_float_constant since all fp constants
3943 are TARGET_LEGITIMATE_CONSTANT_P. */
3944 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3946 if (standard_80387_constant_p (operands[1]) > 0)
3948 operands[1] = simplify_const_unary_operation
3949 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3950 emit_move_insn_1 (operands[0], operands[1]);
3953 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3957 (define_insn "*extend<mode>xf2_i387"
3958 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3960 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3962 "* return output_387_reg_move (insn, operands);"
3963 [(set_attr "type" "fmov")
3964 (set_attr "mode" "<MODE>,XF")])
3966 ;; %%% This seems bad bad news.
3967 ;; This cannot output into an f-reg because there is no way to be sure
3968 ;; of truncating in that case. Otherwise this is just like a simple move
3969 ;; insn. So we pretend we can output to a reg in order to get better
3970 ;; register preferencing, but we really use a stack slot.
3972 ;; Conversion from DFmode to SFmode.
3974 (define_expand "truncdfsf2"
3975 [(set (match_operand:SF 0 "nonimmediate_operand")
3977 (match_operand:DF 1 "nonimmediate_operand")))]
3978 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3980 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3982 else if (flag_unsafe_math_optimizations)
3986 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3987 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3992 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3994 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3996 We do the conversion post reload to avoid producing of 128bit spills
3997 that might lead to ICE on 32bit target. The sequence unlikely combine
4000 [(set (match_operand:SF 0 "register_operand")
4002 (match_operand:DF 1 "nonimmediate_operand")))]
4003 "TARGET_USE_VECTOR_FP_CONVERTS
4004 && optimize_insn_for_speed_p ()
4005 && reload_completed && SSE_REG_P (operands[0])"
4008 (float_truncate:V2SF
4012 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4013 operands[3] = CONST0_RTX (V2SFmode);
4014 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4015 /* Use movsd for loading from memory, unpcklpd for registers.
4016 Try to avoid move when unpacking can be done in source, or SSE3
4017 movddup is available. */
4018 if (REG_P (operands[1]))
4021 && true_regnum (operands[0]) != true_regnum (operands[1])
4022 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4023 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4025 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4026 emit_move_insn (tmp, operands[1]);
4029 else if (!TARGET_SSE3)
4030 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4031 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4034 emit_insn (gen_sse2_loadlpd (operands[4],
4035 CONST0_RTX (V2DFmode), operands[1]));
4038 ;; It's more profitable to split and then extend in the same register.
4040 [(set (match_operand:SF 0 "register_operand")
4042 (match_operand:DF 1 "memory_operand")))]
4043 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4044 && optimize_insn_for_speed_p ()
4045 && SSE_REG_P (operands[0])"
4046 [(set (match_dup 2) (match_dup 1))
4047 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4048 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4050 (define_expand "truncdfsf2_with_temp"
4051 [(parallel [(set (match_operand:SF 0)
4052 (float_truncate:SF (match_operand:DF 1)))
4053 (clobber (match_operand:SF 2))])])
4055 (define_insn "*truncdfsf_fast_mixed"
4056 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4058 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4059 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4061 switch (which_alternative)
4064 return output_387_reg_move (insn, operands);
4066 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4071 [(set_attr "type" "fmov,ssecvt")
4072 (set_attr "prefix" "orig,maybe_vex")
4073 (set_attr "mode" "SF")])
4075 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4076 ;; because nothing we do here is unsafe.
4077 (define_insn "*truncdfsf_fast_sse"
4078 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4080 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4081 "TARGET_SSE2 && TARGET_SSE_MATH"
4082 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4083 [(set_attr "type" "ssecvt")
4084 (set_attr "prefix" "maybe_vex")
4085 (set_attr "mode" "SF")])
4087 (define_insn "*truncdfsf_fast_i387"
4088 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4090 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4091 "TARGET_80387 && flag_unsafe_math_optimizations"
4092 "* return output_387_reg_move (insn, operands);"
4093 [(set_attr "type" "fmov")
4094 (set_attr "mode" "SF")])
4096 (define_insn "*truncdfsf_mixed"
4097 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4099 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4100 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4101 "TARGET_MIX_SSE_I387"
4103 switch (which_alternative)
4106 return output_387_reg_move (insn, operands);
4108 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4114 [(set_attr "isa" "*,sse2,*,*,*")
4115 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4116 (set_attr "unit" "*,*,i387,i387,i387")
4117 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4118 (set_attr "mode" "SF")])
4120 (define_insn "*truncdfsf_i387"
4121 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4123 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4124 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4127 switch (which_alternative)
4130 return output_387_reg_move (insn, operands);
4136 [(set_attr "type" "fmov,multi,multi,multi")
4137 (set_attr "unit" "*,i387,i387,i387")
4138 (set_attr "mode" "SF")])
4140 (define_insn "*truncdfsf2_i387_1"
4141 [(set (match_operand:SF 0 "memory_operand" "=m")
4143 (match_operand:DF 1 "register_operand" "f")))]
4145 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4146 && !TARGET_MIX_SSE_I387"
4147 "* return output_387_reg_move (insn, operands);"
4148 [(set_attr "type" "fmov")
4149 (set_attr "mode" "SF")])
4152 [(set (match_operand:SF 0 "register_operand")
4154 (match_operand:DF 1 "fp_register_operand")))
4155 (clobber (match_operand 2))]
4157 [(set (match_dup 2) (match_dup 1))
4158 (set (match_dup 0) (match_dup 2))]
4159 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4161 ;; Conversion from XFmode to {SF,DF}mode
4163 (define_expand "truncxf<mode>2"
4164 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4165 (float_truncate:MODEF
4166 (match_operand:XF 1 "register_operand")))
4167 (clobber (match_dup 2))])]
4170 if (flag_unsafe_math_optimizations)
4172 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4173 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4174 if (reg != operands[0])
4175 emit_move_insn (operands[0], reg);
4179 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4182 (define_insn "*truncxfsf2_mixed"
4183 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4185 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4186 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4189 gcc_assert (!which_alternative);
4190 return output_387_reg_move (insn, operands);
4192 [(set_attr "type" "fmov,multi,multi,multi")
4193 (set_attr "unit" "*,i387,i387,i387")
4194 (set_attr "mode" "SF")])
4196 (define_insn "*truncxfdf2_mixed"
4197 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4199 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4200 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4203 gcc_assert (!which_alternative);
4204 return output_387_reg_move (insn, operands);
4206 [(set_attr "isa" "*,*,sse2,*")
4207 (set_attr "type" "fmov,multi,multi,multi")
4208 (set_attr "unit" "*,i387,i387,i387")
4209 (set_attr "mode" "DF")])
4211 (define_insn "truncxf<mode>2_i387_noop"
4212 [(set (match_operand:MODEF 0 "register_operand" "=f")
4213 (float_truncate:MODEF
4214 (match_operand:XF 1 "register_operand" "f")))]
4215 "TARGET_80387 && flag_unsafe_math_optimizations"
4216 "* return output_387_reg_move (insn, operands);"
4217 [(set_attr "type" "fmov")
4218 (set_attr "mode" "<MODE>")])
4220 (define_insn "*truncxf<mode>2_i387"
4221 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4222 (float_truncate:MODEF
4223 (match_operand:XF 1 "register_operand" "f")))]
4225 "* return output_387_reg_move (insn, operands);"
4226 [(set_attr "type" "fmov")
4227 (set_attr "mode" "<MODE>")])
4230 [(set (match_operand:MODEF 0 "register_operand")
4231 (float_truncate:MODEF
4232 (match_operand:XF 1 "register_operand")))
4233 (clobber (match_operand:MODEF 2 "memory_operand"))]
4234 "TARGET_80387 && reload_completed"
4235 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4236 (set (match_dup 0) (match_dup 2))])
4239 [(set (match_operand:MODEF 0 "memory_operand")
4240 (float_truncate:MODEF
4241 (match_operand:XF 1 "register_operand")))
4242 (clobber (match_operand:MODEF 2 "memory_operand"))]
4244 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4246 ;; Signed conversion to DImode.
4248 (define_expand "fix_truncxfdi2"
4249 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4250 (fix:DI (match_operand:XF 1 "register_operand")))
4251 (clobber (reg:CC FLAGS_REG))])]
4256 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4261 (define_expand "fix_trunc<mode>di2"
4262 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4263 (fix:DI (match_operand:MODEF 1 "register_operand")))
4264 (clobber (reg:CC FLAGS_REG))])]
4265 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4268 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4270 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4273 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4275 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4276 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4277 if (out != operands[0])
4278 emit_move_insn (operands[0], out);
4283 ;; Signed conversion to SImode.
4285 (define_expand "fix_truncxfsi2"
4286 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4287 (fix:SI (match_operand:XF 1 "register_operand")))
4288 (clobber (reg:CC FLAGS_REG))])]
4293 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4298 (define_expand "fix_trunc<mode>si2"
4299 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4300 (fix:SI (match_operand:MODEF 1 "register_operand")))
4301 (clobber (reg:CC FLAGS_REG))])]
4302 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4305 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4307 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4310 if (SSE_FLOAT_MODE_P (<MODE>mode))
4312 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4313 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4314 if (out != operands[0])
4315 emit_move_insn (operands[0], out);
4320 ;; Signed conversion to HImode.
4322 (define_expand "fix_trunc<mode>hi2"
4323 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4324 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4325 (clobber (reg:CC FLAGS_REG))])]
4327 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4331 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4336 ;; Unsigned conversion to SImode.
4338 (define_expand "fixuns_trunc<mode>si2"
4340 [(set (match_operand:SI 0 "register_operand")
4342 (match_operand:MODEF 1 "nonimmediate_operand")))
4344 (clobber (match_scratch:<ssevecmode> 3))
4345 (clobber (match_scratch:<ssevecmode> 4))])]
4346 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4348 enum machine_mode mode = <MODE>mode;
4349 enum machine_mode vecmode = <ssevecmode>mode;
4350 REAL_VALUE_TYPE TWO31r;
4353 if (optimize_insn_for_size_p ())
4356 real_ldexp (&TWO31r, &dconst1, 31);
4357 two31 = const_double_from_real_value (TWO31r, mode);
4358 two31 = ix86_build_const_vector (vecmode, true, two31);
4359 operands[2] = force_reg (vecmode, two31);
4362 (define_insn_and_split "*fixuns_trunc<mode>_1"
4363 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4365 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4366 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4367 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4368 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4369 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4370 && optimize_function_for_speed_p (cfun)"
4372 "&& reload_completed"
4375 ix86_split_convert_uns_si_sse (operands);
4379 ;; Unsigned conversion to HImode.
4380 ;; Without these patterns, we'll try the unsigned SI conversion which
4381 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4383 (define_expand "fixuns_trunc<mode>hi2"
4385 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4386 (set (match_operand:HI 0 "nonimmediate_operand")
4387 (subreg:HI (match_dup 2) 0))]
4388 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4389 "operands[2] = gen_reg_rtx (SImode);")
4391 ;; When SSE is available, it is always faster to use it!
4392 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4393 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4394 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4395 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4396 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4397 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4398 [(set_attr "type" "sseicvt")
4399 (set_attr "prefix" "maybe_vex")
4400 (set (attr "prefix_rex")
4402 (match_test "<SWI48:MODE>mode == DImode")
4404 (const_string "*")))
4405 (set_attr "mode" "<MODEF:MODE>")
4406 (set_attr "athlon_decode" "double,vector")
4407 (set_attr "amdfam10_decode" "double,double")
4408 (set_attr "bdver1_decode" "double,double")])
4410 ;; Avoid vector decoded forms of the instruction.
4412 [(match_scratch:MODEF 2 "x")
4413 (set (match_operand:SWI48 0 "register_operand")
4414 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4415 "TARGET_AVOID_VECTOR_DECODE
4416 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4417 && optimize_insn_for_speed_p ()"
4418 [(set (match_dup 2) (match_dup 1))
4419 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4421 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4422 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4423 (fix:SWI248x (match_operand 1 "register_operand")))]
4424 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4426 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4427 && (TARGET_64BIT || <MODE>mode != DImode))
4429 && can_create_pseudo_p ()"
4434 if (memory_operand (operands[0], VOIDmode))
4435 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4438 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4439 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4445 [(set_attr "type" "fisttp")
4446 (set_attr "mode" "<MODE>")])
4448 (define_insn "fix_trunc<mode>_i387_fisttp"
4449 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4450 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4451 (clobber (match_scratch:XF 2 "=&1f"))]
4452 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4454 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4455 && (TARGET_64BIT || <MODE>mode != DImode))
4456 && TARGET_SSE_MATH)"
4457 "* return output_fix_trunc (insn, operands, true);"
4458 [(set_attr "type" "fisttp")
4459 (set_attr "mode" "<MODE>")])
4461 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4462 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4463 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4464 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4465 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4466 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4468 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4469 && (TARGET_64BIT || <MODE>mode != DImode))
4470 && TARGET_SSE_MATH)"
4472 [(set_attr "type" "fisttp")
4473 (set_attr "mode" "<MODE>")])
4476 [(set (match_operand:SWI248x 0 "register_operand")
4477 (fix:SWI248x (match_operand 1 "register_operand")))
4478 (clobber (match_operand:SWI248x 2 "memory_operand"))
4479 (clobber (match_scratch 3))]
4481 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4482 (clobber (match_dup 3))])
4483 (set (match_dup 0) (match_dup 2))])
4486 [(set (match_operand:SWI248x 0 "memory_operand")
4487 (fix:SWI248x (match_operand 1 "register_operand")))
4488 (clobber (match_operand:SWI248x 2 "memory_operand"))
4489 (clobber (match_scratch 3))]
4491 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4492 (clobber (match_dup 3))])])
4494 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4495 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4496 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4497 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4498 ;; function in i386.c.
4499 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4500 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4501 (fix:SWI248x (match_operand 1 "register_operand")))
4502 (clobber (reg:CC FLAGS_REG))]
4503 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4505 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4506 && (TARGET_64BIT || <MODE>mode != DImode))
4507 && can_create_pseudo_p ()"
4512 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4514 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4515 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4516 if (memory_operand (operands[0], VOIDmode))
4517 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4518 operands[2], operands[3]));
4521 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4522 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4523 operands[2], operands[3],
4528 [(set_attr "type" "fistp")
4529 (set_attr "i387_cw" "trunc")
4530 (set_attr "mode" "<MODE>")])
4532 (define_insn "fix_truncdi_i387"
4533 [(set (match_operand:DI 0 "memory_operand" "=m")
4534 (fix:DI (match_operand 1 "register_operand" "f")))
4535 (use (match_operand:HI 2 "memory_operand" "m"))
4536 (use (match_operand:HI 3 "memory_operand" "m"))
4537 (clobber (match_scratch:XF 4 "=&1f"))]
4538 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4540 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4541 "* return output_fix_trunc (insn, operands, false);"
4542 [(set_attr "type" "fistp")
4543 (set_attr "i387_cw" "trunc")
4544 (set_attr "mode" "DI")])
4546 (define_insn "fix_truncdi_i387_with_temp"
4547 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4548 (fix:DI (match_operand 1 "register_operand" "f,f")))
4549 (use (match_operand:HI 2 "memory_operand" "m,m"))
4550 (use (match_operand:HI 3 "memory_operand" "m,m"))
4551 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4552 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4553 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4555 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4557 [(set_attr "type" "fistp")
4558 (set_attr "i387_cw" "trunc")
4559 (set_attr "mode" "DI")])
4562 [(set (match_operand:DI 0 "register_operand")
4563 (fix:DI (match_operand 1 "register_operand")))
4564 (use (match_operand:HI 2 "memory_operand"))
4565 (use (match_operand:HI 3 "memory_operand"))
4566 (clobber (match_operand:DI 4 "memory_operand"))
4567 (clobber (match_scratch 5))]
4569 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4572 (clobber (match_dup 5))])
4573 (set (match_dup 0) (match_dup 4))])
4576 [(set (match_operand:DI 0 "memory_operand")
4577 (fix:DI (match_operand 1 "register_operand")))
4578 (use (match_operand:HI 2 "memory_operand"))
4579 (use (match_operand:HI 3 "memory_operand"))
4580 (clobber (match_operand:DI 4 "memory_operand"))
4581 (clobber (match_scratch 5))]
4583 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4586 (clobber (match_dup 5))])])
4588 (define_insn "fix_trunc<mode>_i387"
4589 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4590 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4591 (use (match_operand:HI 2 "memory_operand" "m"))
4592 (use (match_operand:HI 3 "memory_operand" "m"))]
4593 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4595 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4596 "* return output_fix_trunc (insn, operands, false);"
4597 [(set_attr "type" "fistp")
4598 (set_attr "i387_cw" "trunc")
4599 (set_attr "mode" "<MODE>")])
4601 (define_insn "fix_trunc<mode>_i387_with_temp"
4602 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4603 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4604 (use (match_operand:HI 2 "memory_operand" "m,m"))
4605 (use (match_operand:HI 3 "memory_operand" "m,m"))
4606 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4607 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4609 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4611 [(set_attr "type" "fistp")
4612 (set_attr "i387_cw" "trunc")
4613 (set_attr "mode" "<MODE>")])
4616 [(set (match_operand:SWI24 0 "register_operand")
4617 (fix:SWI24 (match_operand 1 "register_operand")))
4618 (use (match_operand:HI 2 "memory_operand"))
4619 (use (match_operand:HI 3 "memory_operand"))
4620 (clobber (match_operand:SWI24 4 "memory_operand"))]
4622 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4624 (use (match_dup 3))])
4625 (set (match_dup 0) (match_dup 4))])
4628 [(set (match_operand:SWI24 0 "memory_operand")
4629 (fix:SWI24 (match_operand 1 "register_operand")))
4630 (use (match_operand:HI 2 "memory_operand"))
4631 (use (match_operand:HI 3 "memory_operand"))
4632 (clobber (match_operand:SWI24 4 "memory_operand"))]
4634 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4636 (use (match_dup 3))])])
4638 (define_insn "x86_fnstcw_1"
4639 [(set (match_operand:HI 0 "memory_operand" "=m")
4640 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4643 [(set (attr "length")
4644 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4645 (set_attr "mode" "HI")
4646 (set_attr "unit" "i387")
4647 (set_attr "bdver1_decode" "vector")])
4649 (define_insn "x86_fldcw_1"
4650 [(set (reg:HI FPCR_REG)
4651 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4654 [(set (attr "length")
4655 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4656 (set_attr "mode" "HI")
4657 (set_attr "unit" "i387")
4658 (set_attr "athlon_decode" "vector")
4659 (set_attr "amdfam10_decode" "vector")
4660 (set_attr "bdver1_decode" "vector")])
4662 ;; Conversion between fixed point and floating point.
4664 ;; Even though we only accept memory inputs, the backend _really_
4665 ;; wants to be able to do this between registers. Thankfully, LRA
4666 ;; will fix this up for us during register allocation.
4668 (define_insn "floathi<mode>2"
4669 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4670 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4673 || TARGET_MIX_SSE_I387)"
4675 [(set_attr "type" "fmov")
4676 (set_attr "mode" "<MODE>")
4677 (set_attr "fp_int_src" "true")])
4679 (define_insn "float<SWI48x:mode>xf2"
4680 [(set (match_operand:XF 0 "register_operand" "=f")
4681 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4684 [(set_attr "type" "fmov")
4685 (set_attr "mode" "XF")
4686 (set_attr "fp_int_src" "true")])
4688 (define_expand "float<SWI48:mode><MODEF:mode>2"
4689 [(set (match_operand:MODEF 0 "register_operand")
4690 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4691 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4693 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4694 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4696 rtx reg = gen_reg_rtx (XFmode);
4697 rtx (*insn)(rtx, rtx);
4699 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4701 if (<MODEF:MODE>mode == SFmode)
4702 insn = gen_truncxfsf2;
4703 else if (<MODEF:MODE>mode == DFmode)
4704 insn = gen_truncxfdf2;
4708 emit_insn (insn (operands[0], reg));
4713 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4714 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4716 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4717 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4720 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4721 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4722 [(set_attr "type" "fmov,sseicvt,sseicvt")
4723 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4724 (set_attr "mode" "<MODEF:MODE>")
4725 (set (attr "prefix_rex")
4727 (and (eq_attr "prefix" "maybe_vex")
4728 (match_test "<SWI48:MODE>mode == DImode"))
4730 (const_string "*")))
4731 (set_attr "unit" "i387,*,*")
4732 (set_attr "athlon_decode" "*,double,direct")
4733 (set_attr "amdfam10_decode" "*,vector,double")
4734 (set_attr "bdver1_decode" "*,double,direct")
4735 (set_attr "fp_int_src" "true")
4736 (set (attr "enabled")
4737 (cond [(eq_attr "alternative" "0")
4738 (symbol_ref "TARGET_MIX_SSE_I387
4739 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4741 (eq_attr "alternative" "1")
4742 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS
4743 || optimize_function_for_size_p (cfun)")
4745 (symbol_ref "true")))
4748 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4749 [(set (match_operand:MODEF 0 "register_operand" "=f")
4750 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4751 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4753 [(set_attr "type" "fmov")
4754 (set_attr "mode" "<MODEF:MODE>")
4755 (set_attr "fp_int_src" "true")])
4757 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4758 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4759 ;; alternative in sse2_loadld.
4761 [(set (match_operand:MODEF 0 "register_operand")
4762 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4763 "TARGET_SSE2 && TARGET_SSE_MATH
4764 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4765 && reload_completed && SSE_REG_P (operands[0])
4766 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4769 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4771 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4773 emit_insn (gen_sse2_loadld (operands[4],
4774 CONST0_RTX (V4SImode), operands[1]));
4776 if (<ssevecmode>mode == V4SFmode)
4777 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4779 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4783 ;; Avoid partial SSE register dependency stalls
4785 [(set (match_operand:MODEF 0 "register_operand")
4786 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4787 "TARGET_SSE2 && TARGET_SSE_MATH
4788 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4789 && optimize_function_for_speed_p (cfun)
4790 && reload_completed && SSE_REG_P (operands[0])"
4793 const enum machine_mode vmode = <MODEF:ssevecmode>mode;
4794 const enum machine_mode mode = <MODEF:MODE>mode;
4795 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4797 emit_move_insn (op0, CONST0_RTX (vmode));
4799 t = gen_rtx_FLOAT (mode, operands[1]);
4800 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4801 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4802 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4806 ;; Break partial reg stall for cvtsd2ss.
4809 [(set (match_operand:SF 0 "register_operand")
4811 (match_operand:DF 1 "nonimmediate_operand")))]
4812 "TARGET_SSE2 && TARGET_SSE_MATH
4813 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4814 && optimize_function_for_speed_p (cfun)
4815 && SSE_REG_P (operands[0])
4816 && (!SSE_REG_P (operands[1])
4817 || REGNO (operands[0]) != REGNO (operands[1]))"
4821 (float_truncate:V2SF
4826 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4828 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4830 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4833 ;; Break partial reg stall for cvtss2sd.
4836 [(set (match_operand:DF 0 "register_operand")
4838 (match_operand:SF 1 "nonimmediate_operand")))]
4839 "TARGET_SSE2 && TARGET_SSE_MATH
4840 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4841 && optimize_function_for_speed_p (cfun)
4842 && SSE_REG_P (operands[0])
4843 && (!SSE_REG_P (operands[1])
4844 || REGNO (operands[0]) != REGNO (operands[1]))"
4850 (parallel [(const_int 0) (const_int 1)])))
4854 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4856 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4858 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4861 ;; Avoid store forwarding (partial memory) stall penalty
4862 ;; by passing DImode value through XMM registers. */
4864 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4865 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4867 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4868 (clobber (match_scratch:V4SI 3 "=X,x"))
4869 (clobber (match_scratch:V4SI 4 "=X,x"))
4870 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4871 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4872 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4873 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4875 [(set_attr "type" "multi")
4876 (set_attr "mode" "<X87MODEF:MODE>")
4877 (set_attr "unit" "i387")
4878 (set_attr "fp_int_src" "true")])
4881 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4882 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4883 (clobber (match_scratch:V4SI 3))
4884 (clobber (match_scratch:V4SI 4))
4885 (clobber (match_operand:DI 2 "memory_operand"))]
4886 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4887 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4888 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4889 && reload_completed"
4890 [(set (match_dup 2) (match_dup 3))
4891 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4893 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4894 Assemble the 64-bit DImode value in an xmm register. */
4895 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4896 gen_rtx_SUBREG (SImode, operands[1], 0)));
4897 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4898 gen_rtx_SUBREG (SImode, operands[1], 4)));
4899 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4902 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4906 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4907 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4908 (clobber (match_scratch:V4SI 3))
4909 (clobber (match_scratch:V4SI 4))
4910 (clobber (match_operand:DI 2 "memory_operand"))]
4911 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4912 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4913 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4914 && reload_completed"
4915 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4917 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
4918 [(set (match_operand:MODEF 0 "register_operand")
4919 (unsigned_float:MODEF
4920 (match_operand:SWI12 1 "nonimmediate_operand")))]
4922 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4924 operands[1] = convert_to_mode (SImode, operands[1], 1);
4925 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
4929 ;; Avoid store forwarding (partial memory) stall penalty by extending
4930 ;; SImode value to DImode through XMM register instead of pushing two
4931 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
4932 ;; targets benefit from this optimization. Also note that fild
4933 ;; loads from memory only.
4935 (define_insn "*floatunssi<mode>2_1"
4936 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4937 (unsigned_float:X87MODEF
4938 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
4939 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
4940 (clobber (match_scratch:SI 3 "=X,x"))]
4942 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4945 [(set_attr "type" "multi")
4946 (set_attr "mode" "<MODE>")])
4949 [(set (match_operand:X87MODEF 0 "register_operand")
4950 (unsigned_float:X87MODEF
4951 (match_operand:SI 1 "register_operand")))
4952 (clobber (match_operand:DI 2 "memory_operand"))
4953 (clobber (match_scratch:SI 3))]
4955 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4957 && reload_completed"
4958 [(set (match_dup 2) (match_dup 1))
4960 (float:X87MODEF (match_dup 2)))]
4961 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
4964 [(set (match_operand:X87MODEF 0 "register_operand")
4965 (unsigned_float:X87MODEF
4966 (match_operand:SI 1 "memory_operand")))
4967 (clobber (match_operand:DI 2 "memory_operand"))
4968 (clobber (match_scratch:SI 3))]
4970 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4972 && reload_completed"
4973 [(set (match_dup 2) (match_dup 3))
4975 (float:X87MODEF (match_dup 2)))]
4977 emit_move_insn (operands[3], operands[1]);
4978 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
4981 (define_expand "floatunssi<mode>2"
4983 [(set (match_operand:X87MODEF 0 "register_operand")
4984 (unsigned_float:X87MODEF
4985 (match_operand:SI 1 "nonimmediate_operand")))
4986 (clobber (match_dup 2))
4987 (clobber (match_scratch:SI 3))])]
4989 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4991 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
4993 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4995 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
4999 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5002 (define_expand "floatunsdisf2"
5003 [(use (match_operand:SF 0 "register_operand"))
5004 (use (match_operand:DI 1 "nonimmediate_operand"))]
5005 "TARGET_64BIT && TARGET_SSE_MATH"
5006 "x86_emit_floatuns (operands); DONE;")
5008 (define_expand "floatunsdidf2"
5009 [(use (match_operand:DF 0 "register_operand"))
5010 (use (match_operand:DI 1 "nonimmediate_operand"))]
5011 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5012 && TARGET_SSE2 && TARGET_SSE_MATH"
5015 x86_emit_floatuns (operands);
5017 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5021 ;; Load effective address instructions
5023 (define_insn_and_split "*lea<mode>"
5024 [(set (match_operand:SWI48 0 "register_operand" "=r")
5025 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5028 if (SImode_address_operand (operands[1], VOIDmode))
5030 gcc_assert (TARGET_64BIT);
5031 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5034 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5036 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5039 enum machine_mode mode = <MODE>mode;
5042 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5043 change operands[] array behind our back. */
5044 pat = PATTERN (curr_insn);
5046 operands[0] = SET_DEST (pat);
5047 operands[1] = SET_SRC (pat);
5049 /* Emit all operations in SImode for zero-extended addresses. */
5050 if (SImode_address_operand (operands[1], VOIDmode))
5053 ix86_split_lea_for_addr (curr_insn, operands, mode);
5055 /* Zero-extend return register to DImode for zero-extended addresses. */
5056 if (mode != <MODE>mode)
5057 emit_insn (gen_zero_extendsidi2
5058 (operands[0], gen_lowpart (mode, operands[0])));
5062 [(set_attr "type" "lea")
5065 (match_operand 1 "SImode_address_operand")
5067 (const_string "<MODE>")))])
5071 (define_expand "add<mode>3"
5072 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5073 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5074 (match_operand:SDWIM 2 "<general_operand>")))]
5076 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5078 (define_insn_and_split "*add<dwi>3_doubleword"
5079 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5081 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5082 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5083 (clobber (reg:CC FLAGS_REG))]
5084 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5087 [(parallel [(set (reg:CC FLAGS_REG)
5088 (unspec:CC [(match_dup 1) (match_dup 2)]
5091 (plus:DWIH (match_dup 1) (match_dup 2)))])
5092 (parallel [(set (match_dup 3)
5096 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5098 (clobber (reg:CC FLAGS_REG))])]
5099 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5101 (define_insn "*add<mode>3_cc"
5102 [(set (reg:CC FLAGS_REG)
5104 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5105 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5107 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5108 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5109 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5110 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5111 [(set_attr "type" "alu")
5112 (set_attr "mode" "<MODE>")])
5114 (define_insn "addqi3_cc"
5115 [(set (reg:CC FLAGS_REG)
5117 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5118 (match_operand:QI 2 "general_operand" "qn,qm")]
5120 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5121 (plus:QI (match_dup 1) (match_dup 2)))]
5122 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5123 "add{b}\t{%2, %0|%0, %2}"
5124 [(set_attr "type" "alu")
5125 (set_attr "mode" "QI")])
5127 (define_insn "*add<mode>_1"
5128 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5130 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5131 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5132 (clobber (reg:CC FLAGS_REG))]
5133 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5135 switch (get_attr_type (insn))
5141 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5142 if (operands[2] == const1_rtx)
5143 return "inc{<imodesuffix>}\t%0";
5146 gcc_assert (operands[2] == constm1_rtx);
5147 return "dec{<imodesuffix>}\t%0";
5151 /* For most processors, ADD is faster than LEA. This alternative
5152 was added to use ADD as much as possible. */
5153 if (which_alternative == 2)
5156 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5159 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5160 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5161 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5163 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5167 (cond [(eq_attr "alternative" "3")
5168 (const_string "lea")
5169 (match_operand:SWI48 2 "incdec_operand")
5170 (const_string "incdec")
5172 (const_string "alu")))
5173 (set (attr "length_immediate")
5175 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5177 (const_string "*")))
5178 (set_attr "mode" "<MODE>")])
5180 ;; It may seem that nonimmediate operand is proper one for operand 1.
5181 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5182 ;; we take care in ix86_binary_operator_ok to not allow two memory
5183 ;; operands so proper swapping will be done in reload. This allow
5184 ;; patterns constructed from addsi_1 to match.
5186 (define_insn "addsi_1_zext"
5187 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5189 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5190 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5191 (clobber (reg:CC FLAGS_REG))]
5192 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5194 switch (get_attr_type (insn))
5200 if (operands[2] == const1_rtx)
5201 return "inc{l}\t%k0";
5204 gcc_assert (operands[2] == constm1_rtx);
5205 return "dec{l}\t%k0";
5209 /* For most processors, ADD is faster than LEA. This alternative
5210 was added to use ADD as much as possible. */
5211 if (which_alternative == 1)
5214 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5217 if (x86_maybe_negate_const_int (&operands[2], SImode))
5218 return "sub{l}\t{%2, %k0|%k0, %2}";
5220 return "add{l}\t{%2, %k0|%k0, %2}";
5224 (cond [(eq_attr "alternative" "2")
5225 (const_string "lea")
5226 (match_operand:SI 2 "incdec_operand")
5227 (const_string "incdec")
5229 (const_string "alu")))
5230 (set (attr "length_immediate")
5232 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5234 (const_string "*")))
5235 (set_attr "mode" "SI")])
5237 (define_insn "*addhi_1"
5238 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5239 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5240 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5241 (clobber (reg:CC FLAGS_REG))]
5242 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5244 switch (get_attr_type (insn))
5250 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5251 if (operands[2] == const1_rtx)
5252 return "inc{w}\t%0";
5255 gcc_assert (operands[2] == constm1_rtx);
5256 return "dec{w}\t%0";
5260 /* For most processors, ADD is faster than LEA. This alternative
5261 was added to use ADD as much as possible. */
5262 if (which_alternative == 2)
5265 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5268 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5269 if (x86_maybe_negate_const_int (&operands[2], HImode))
5270 return "sub{w}\t{%2, %0|%0, %2}";
5272 return "add{w}\t{%2, %0|%0, %2}";
5276 (cond [(eq_attr "alternative" "3")
5277 (const_string "lea")
5278 (match_operand:HI 2 "incdec_operand")
5279 (const_string "incdec")
5281 (const_string "alu")))
5282 (set (attr "length_immediate")
5284 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5286 (const_string "*")))
5287 (set_attr "mode" "HI,HI,HI,SI")])
5289 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5290 (define_insn "*addqi_1"
5291 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5292 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5293 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5294 (clobber (reg:CC FLAGS_REG))]
5295 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5297 bool widen = (which_alternative == 3 || which_alternative == 4);
5299 switch (get_attr_type (insn))
5305 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5306 if (operands[2] == const1_rtx)
5307 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5310 gcc_assert (operands[2] == constm1_rtx);
5311 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5315 /* For most processors, ADD is faster than LEA. These alternatives
5316 were added to use ADD as much as possible. */
5317 if (which_alternative == 2 || which_alternative == 4)
5320 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5323 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5324 if (x86_maybe_negate_const_int (&operands[2], QImode))
5327 return "sub{l}\t{%2, %k0|%k0, %2}";
5329 return "sub{b}\t{%2, %0|%0, %2}";
5332 return "add{l}\t{%k2, %k0|%k0, %k2}";
5334 return "add{b}\t{%2, %0|%0, %2}";
5338 (cond [(eq_attr "alternative" "5")
5339 (const_string "lea")
5340 (match_operand:QI 2 "incdec_operand")
5341 (const_string "incdec")
5343 (const_string "alu")))
5344 (set (attr "length_immediate")
5346 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5348 (const_string "*")))
5349 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5351 (define_insn "*addqi_1_slp"
5352 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5353 (plus:QI (match_dup 0)
5354 (match_operand:QI 1 "general_operand" "qn,qm")))
5355 (clobber (reg:CC FLAGS_REG))]
5356 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5357 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5359 switch (get_attr_type (insn))
5362 if (operands[1] == const1_rtx)
5363 return "inc{b}\t%0";
5366 gcc_assert (operands[1] == constm1_rtx);
5367 return "dec{b}\t%0";
5371 if (x86_maybe_negate_const_int (&operands[1], QImode))
5372 return "sub{b}\t{%1, %0|%0, %1}";
5374 return "add{b}\t{%1, %0|%0, %1}";
5378 (if_then_else (match_operand:QI 1 "incdec_operand")
5379 (const_string "incdec")
5380 (const_string "alu1")))
5381 (set (attr "memory")
5382 (if_then_else (match_operand 1 "memory_operand")
5383 (const_string "load")
5384 (const_string "none")))
5385 (set_attr "mode" "QI")])
5387 ;; Split non destructive adds if we cannot use lea.
5389 [(set (match_operand:SWI48 0 "register_operand")
5390 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5391 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5392 (clobber (reg:CC FLAGS_REG))]
5393 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5394 [(set (match_dup 0) (match_dup 1))
5395 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5396 (clobber (reg:CC FLAGS_REG))])])
5398 ;; Convert add to the lea pattern to avoid flags dependency.
5400 [(set (match_operand:SWI 0 "register_operand")
5401 (plus:SWI (match_operand:SWI 1 "register_operand")
5402 (match_operand:SWI 2 "<nonmemory_operand>")))
5403 (clobber (reg:CC FLAGS_REG))]
5404 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5407 enum machine_mode mode = <MODE>mode;
5410 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5413 operands[0] = gen_lowpart (mode, operands[0]);
5414 operands[1] = gen_lowpart (mode, operands[1]);
5415 operands[2] = gen_lowpart (mode, operands[2]);
5418 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5420 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5424 ;; Split non destructive adds if we cannot use lea.
5426 [(set (match_operand:DI 0 "register_operand")
5428 (plus:SI (match_operand:SI 1 "register_operand")
5429 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5430 (clobber (reg:CC FLAGS_REG))]
5432 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5433 [(set (match_dup 3) (match_dup 1))
5434 (parallel [(set (match_dup 0)
5435 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5436 (clobber (reg:CC FLAGS_REG))])]
5437 "operands[3] = gen_lowpart (SImode, operands[0]);")
5439 ;; Convert add to the lea pattern to avoid flags dependency.
5441 [(set (match_operand:DI 0 "register_operand")
5443 (plus:SI (match_operand:SI 1 "register_operand")
5444 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5445 (clobber (reg:CC FLAGS_REG))]
5446 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5448 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5450 (define_insn "*add<mode>_2"
5451 [(set (reg FLAGS_REG)
5454 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5455 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5457 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5458 (plus:SWI (match_dup 1) (match_dup 2)))]
5459 "ix86_match_ccmode (insn, CCGOCmode)
5460 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5462 switch (get_attr_type (insn))
5465 if (operands[2] == const1_rtx)
5466 return "inc{<imodesuffix>}\t%0";
5469 gcc_assert (operands[2] == constm1_rtx);
5470 return "dec{<imodesuffix>}\t%0";
5474 if (which_alternative == 2)
5477 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5480 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5481 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5482 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5484 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5488 (if_then_else (match_operand:SWI 2 "incdec_operand")
5489 (const_string "incdec")
5490 (const_string "alu")))
5491 (set (attr "length_immediate")
5493 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5495 (const_string "*")))
5496 (set_attr "mode" "<MODE>")])
5498 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5499 (define_insn "*addsi_2_zext"
5500 [(set (reg FLAGS_REG)
5502 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5503 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5505 (set (match_operand:DI 0 "register_operand" "=r,r")
5506 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5507 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5508 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5510 switch (get_attr_type (insn))
5513 if (operands[2] == const1_rtx)
5514 return "inc{l}\t%k0";
5517 gcc_assert (operands[2] == constm1_rtx);
5518 return "dec{l}\t%k0";
5522 if (which_alternative == 1)
5525 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5528 if (x86_maybe_negate_const_int (&operands[2], SImode))
5529 return "sub{l}\t{%2, %k0|%k0, %2}";
5531 return "add{l}\t{%2, %k0|%k0, %2}";
5535 (if_then_else (match_operand:SI 2 "incdec_operand")
5536 (const_string "incdec")
5537 (const_string "alu")))
5538 (set (attr "length_immediate")
5540 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5542 (const_string "*")))
5543 (set_attr "mode" "SI")])
5545 (define_insn "*add<mode>_3"
5546 [(set (reg FLAGS_REG)
5548 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5549 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5550 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5551 "ix86_match_ccmode (insn, CCZmode)
5552 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5554 switch (get_attr_type (insn))
5557 if (operands[2] == const1_rtx)
5558 return "inc{<imodesuffix>}\t%0";
5561 gcc_assert (operands[2] == constm1_rtx);
5562 return "dec{<imodesuffix>}\t%0";
5566 if (which_alternative == 1)
5569 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5572 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5573 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5574 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5576 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5580 (if_then_else (match_operand:SWI 2 "incdec_operand")
5581 (const_string "incdec")
5582 (const_string "alu")))
5583 (set (attr "length_immediate")
5585 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5587 (const_string "*")))
5588 (set_attr "mode" "<MODE>")])
5590 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5591 (define_insn "*addsi_3_zext"
5592 [(set (reg FLAGS_REG)
5594 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5595 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5596 (set (match_operand:DI 0 "register_operand" "=r,r")
5597 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5598 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5599 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5601 switch (get_attr_type (insn))
5604 if (operands[2] == const1_rtx)
5605 return "inc{l}\t%k0";
5608 gcc_assert (operands[2] == constm1_rtx);
5609 return "dec{l}\t%k0";
5613 if (which_alternative == 1)
5616 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5619 if (x86_maybe_negate_const_int (&operands[2], SImode))
5620 return "sub{l}\t{%2, %k0|%k0, %2}";
5622 return "add{l}\t{%2, %k0|%k0, %2}";
5626 (if_then_else (match_operand:SI 2 "incdec_operand")
5627 (const_string "incdec")
5628 (const_string "alu")))
5629 (set (attr "length_immediate")
5631 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5633 (const_string "*")))
5634 (set_attr "mode" "SI")])
5636 ; For comparisons against 1, -1 and 128, we may generate better code
5637 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5638 ; is matched then. We can't accept general immediate, because for
5639 ; case of overflows, the result is messed up.
5640 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5641 ; only for comparisons not depending on it.
5643 (define_insn "*adddi_4"
5644 [(set (reg FLAGS_REG)
5646 (match_operand:DI 1 "nonimmediate_operand" "0")
5647 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5648 (clobber (match_scratch:DI 0 "=rm"))]
5650 && ix86_match_ccmode (insn, CCGCmode)"
5652 switch (get_attr_type (insn))
5655 if (operands[2] == constm1_rtx)
5656 return "inc{q}\t%0";
5659 gcc_assert (operands[2] == const1_rtx);
5660 return "dec{q}\t%0";
5664 if (x86_maybe_negate_const_int (&operands[2], DImode))
5665 return "add{q}\t{%2, %0|%0, %2}";
5667 return "sub{q}\t{%2, %0|%0, %2}";
5671 (if_then_else (match_operand:DI 2 "incdec_operand")
5672 (const_string "incdec")
5673 (const_string "alu")))
5674 (set (attr "length_immediate")
5676 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5678 (const_string "*")))
5679 (set_attr "mode" "DI")])
5681 ; For comparisons against 1, -1 and 128, we may generate better code
5682 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5683 ; is matched then. We can't accept general immediate, because for
5684 ; case of overflows, the result is messed up.
5685 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5686 ; only for comparisons not depending on it.
5688 (define_insn "*add<mode>_4"
5689 [(set (reg FLAGS_REG)
5691 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5692 (match_operand:SWI124 2 "const_int_operand" "n")))
5693 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5694 "ix86_match_ccmode (insn, CCGCmode)"
5696 switch (get_attr_type (insn))
5699 if (operands[2] == constm1_rtx)
5700 return "inc{<imodesuffix>}\t%0";
5703 gcc_assert (operands[2] == const1_rtx);
5704 return "dec{<imodesuffix>}\t%0";
5708 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5709 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5711 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5715 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5716 (const_string "incdec")
5717 (const_string "alu")))
5718 (set (attr "length_immediate")
5720 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5722 (const_string "*")))
5723 (set_attr "mode" "<MODE>")])
5725 (define_insn "*add<mode>_5"
5726 [(set (reg FLAGS_REG)
5729 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5730 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5732 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5733 "ix86_match_ccmode (insn, CCGOCmode)
5734 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5736 switch (get_attr_type (insn))
5739 if (operands[2] == const1_rtx)
5740 return "inc{<imodesuffix>}\t%0";
5743 gcc_assert (operands[2] == constm1_rtx);
5744 return "dec{<imodesuffix>}\t%0";
5748 if (which_alternative == 1)
5751 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5755 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5756 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5758 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5762 (if_then_else (match_operand:SWI 2 "incdec_operand")
5763 (const_string "incdec")
5764 (const_string "alu")))
5765 (set (attr "length_immediate")
5767 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5769 (const_string "*")))
5770 (set_attr "mode" "<MODE>")])
5772 (define_insn "addqi_ext_1"
5773 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5778 (match_operand 1 "ext_register_operand" "0,0")
5781 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5782 (clobber (reg:CC FLAGS_REG))]
5785 switch (get_attr_type (insn))
5788 if (operands[2] == const1_rtx)
5789 return "inc{b}\t%h0";
5792 gcc_assert (operands[2] == constm1_rtx);
5793 return "dec{b}\t%h0";
5797 return "add{b}\t{%2, %h0|%h0, %2}";
5800 [(set_attr "isa" "*,nox64")
5802 (if_then_else (match_operand:QI 2 "incdec_operand")
5803 (const_string "incdec")
5804 (const_string "alu")))
5805 (set_attr "modrm" "1")
5806 (set_attr "mode" "QI")])
5808 (define_insn "*addqi_ext_2"
5809 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5814 (match_operand 1 "ext_register_operand" "%0")
5818 (match_operand 2 "ext_register_operand" "Q")
5821 (clobber (reg:CC FLAGS_REG))]
5823 "add{b}\t{%h2, %h0|%h0, %h2}"
5824 [(set_attr "type" "alu")
5825 (set_attr "mode" "QI")])
5827 ;; Add with jump on overflow.
5828 (define_expand "addv<mode>4"
5829 [(parallel [(set (reg:CCO FLAGS_REG)
5832 (match_operand:SWI 1 "nonimmediate_operand"))
5835 (plus:SWI (match_dup 1)
5836 (match_operand:SWI 2
5837 "<general_operand>")))))
5838 (set (match_operand:SWI 0 "register_operand")
5839 (plus:SWI (match_dup 1) (match_dup 2)))])
5840 (set (pc) (if_then_else
5841 (eq (reg:CCO FLAGS_REG) (const_int 0))
5842 (label_ref (match_operand 3))
5846 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5847 if (CONST_INT_P (operands[2]))
5848 operands[4] = operands[2];
5850 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5853 (define_insn "*addv<mode>4"
5854 [(set (reg:CCO FLAGS_REG)
5857 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5859 (match_operand:SWI 2 "<general_sext_operand>"
5862 (plus:SWI (match_dup 1) (match_dup 2)))))
5863 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5864 (plus:SWI (match_dup 1) (match_dup 2)))]
5865 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5866 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5867 [(set_attr "type" "alu")
5868 (set_attr "mode" "<MODE>")])
5870 (define_insn "*addv<mode>4_1"
5871 [(set (reg:CCO FLAGS_REG)
5874 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5875 (match_operand:<DWI> 3 "const_int_operand" "i"))
5877 (plus:SWI (match_dup 1)
5878 (match_operand:SWI 2 "x86_64_immediate_operand"
5880 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5881 (plus:SWI (match_dup 1) (match_dup 2)))]
5882 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5883 && CONST_INT_P (operands[2])
5884 && INTVAL (operands[2]) == INTVAL (operands[3])"
5885 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5886 [(set_attr "type" "alu")
5887 (set_attr "mode" "<MODE>")
5888 (set (attr "length_immediate")
5889 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5891 (match_test "<MODE_SIZE> == 8")
5893 (const_string "<MODE_SIZE>")))])
5895 ;; The lea patterns for modes less than 32 bits need to be matched by
5896 ;; several insns converted to real lea by splitters.
5898 (define_insn_and_split "*lea_general_1"
5899 [(set (match_operand 0 "register_operand" "=r")
5900 (plus (plus (match_operand 1 "index_register_operand" "l")
5901 (match_operand 2 "register_operand" "r"))
5902 (match_operand 3 "immediate_operand" "i")))]
5903 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5904 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5905 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5906 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5907 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5908 || GET_MODE (operands[3]) == VOIDmode)"
5910 "&& reload_completed"
5913 enum machine_mode mode = SImode;
5916 operands[0] = gen_lowpart (mode, operands[0]);
5917 operands[1] = gen_lowpart (mode, operands[1]);
5918 operands[2] = gen_lowpart (mode, operands[2]);
5919 operands[3] = gen_lowpart (mode, operands[3]);
5921 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5924 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5927 [(set_attr "type" "lea")
5928 (set_attr "mode" "SI")])
5930 (define_insn_and_split "*lea_general_2"
5931 [(set (match_operand 0 "register_operand" "=r")
5932 (plus (mult (match_operand 1 "index_register_operand" "l")
5933 (match_operand 2 "const248_operand" "n"))
5934 (match_operand 3 "nonmemory_operand" "ri")))]
5935 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5936 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5937 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5938 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5939 || GET_MODE (operands[3]) == VOIDmode)"
5941 "&& reload_completed"
5944 enum machine_mode mode = SImode;
5947 operands[0] = gen_lowpart (mode, operands[0]);
5948 operands[1] = gen_lowpart (mode, operands[1]);
5949 operands[3] = gen_lowpart (mode, operands[3]);
5951 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5954 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5957 [(set_attr "type" "lea")
5958 (set_attr "mode" "SI")])
5960 (define_insn_and_split "*lea_general_3"
5961 [(set (match_operand 0 "register_operand" "=r")
5962 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5963 (match_operand 2 "const248_operand" "n"))
5964 (match_operand 3 "register_operand" "r"))
5965 (match_operand 4 "immediate_operand" "i")))]
5966 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5967 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5968 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5969 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5971 "&& reload_completed"
5974 enum machine_mode mode = SImode;
5977 operands[0] = gen_lowpart (mode, operands[0]);
5978 operands[1] = gen_lowpart (mode, operands[1]);
5979 operands[3] = gen_lowpart (mode, operands[3]);
5980 operands[4] = gen_lowpart (mode, operands[4]);
5982 pat = gen_rtx_PLUS (mode,
5984 gen_rtx_MULT (mode, operands[1],
5989 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5992 [(set_attr "type" "lea")
5993 (set_attr "mode" "SI")])
5995 (define_insn_and_split "*lea_general_4"
5996 [(set (match_operand 0 "register_operand" "=r")
5998 (match_operand 1 "index_register_operand" "l")
5999 (match_operand 2 "const_int_operand" "n"))
6000 (match_operand 3 "const_int_operand" "n")))]
6001 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6002 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6003 || GET_MODE (operands[0]) == SImode
6004 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6005 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6006 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6007 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6008 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6010 "&& reload_completed"
6013 enum machine_mode mode = GET_MODE (operands[0]);
6016 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6019 operands[0] = gen_lowpart (mode, operands[0]);
6020 operands[1] = gen_lowpart (mode, operands[1]);
6023 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6025 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6026 INTVAL (operands[3]));
6028 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6031 [(set_attr "type" "lea")
6033 (if_then_else (match_operand:DI 0)
6035 (const_string "SI")))])
6037 ;; Subtract instructions
6039 (define_expand "sub<mode>3"
6040 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6041 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6042 (match_operand:SDWIM 2 "<general_operand>")))]
6044 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6046 (define_insn_and_split "*sub<dwi>3_doubleword"
6047 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6049 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6050 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6051 (clobber (reg:CC FLAGS_REG))]
6052 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6055 [(parallel [(set (reg:CC FLAGS_REG)
6056 (compare:CC (match_dup 1) (match_dup 2)))
6058 (minus:DWIH (match_dup 1) (match_dup 2)))])
6059 (parallel [(set (match_dup 3)
6063 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6065 (clobber (reg:CC FLAGS_REG))])]
6066 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6068 (define_insn "*sub<mode>_1"
6069 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6071 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6072 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6073 (clobber (reg:CC FLAGS_REG))]
6074 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6075 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6076 [(set_attr "type" "alu")
6077 (set_attr "mode" "<MODE>")])
6079 (define_insn "*subsi_1_zext"
6080 [(set (match_operand:DI 0 "register_operand" "=r")
6082 (minus:SI (match_operand:SI 1 "register_operand" "0")
6083 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6084 (clobber (reg:CC FLAGS_REG))]
6085 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6086 "sub{l}\t{%2, %k0|%k0, %2}"
6087 [(set_attr "type" "alu")
6088 (set_attr "mode" "SI")])
6090 (define_insn "*subqi_1_slp"
6091 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6092 (minus:QI (match_dup 0)
6093 (match_operand:QI 1 "general_operand" "qn,qm")))
6094 (clobber (reg:CC FLAGS_REG))]
6095 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6096 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6097 "sub{b}\t{%1, %0|%0, %1}"
6098 [(set_attr "type" "alu1")
6099 (set_attr "mode" "QI")])
6101 (define_insn "*sub<mode>_2"
6102 [(set (reg FLAGS_REG)
6105 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6106 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6108 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6109 (minus:SWI (match_dup 1) (match_dup 2)))]
6110 "ix86_match_ccmode (insn, CCGOCmode)
6111 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6112 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6113 [(set_attr "type" "alu")
6114 (set_attr "mode" "<MODE>")])
6116 (define_insn "*subsi_2_zext"
6117 [(set (reg FLAGS_REG)
6119 (minus:SI (match_operand:SI 1 "register_operand" "0")
6120 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6122 (set (match_operand:DI 0 "register_operand" "=r")
6124 (minus:SI (match_dup 1)
6126 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6127 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6128 "sub{l}\t{%2, %k0|%k0, %2}"
6129 [(set_attr "type" "alu")
6130 (set_attr "mode" "SI")])
6132 ;; Subtract with jump on overflow.
6133 (define_expand "subv<mode>4"
6134 [(parallel [(set (reg:CCO FLAGS_REG)
6135 (eq:CCO (minus:<DWI>
6137 (match_operand:SWI 1 "nonimmediate_operand"))
6140 (minus:SWI (match_dup 1)
6141 (match_operand:SWI 2
6142 "<general_operand>")))))
6143 (set (match_operand:SWI 0 "register_operand")
6144 (minus:SWI (match_dup 1) (match_dup 2)))])
6145 (set (pc) (if_then_else
6146 (eq (reg:CCO FLAGS_REG) (const_int 0))
6147 (label_ref (match_operand 3))
6151 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6152 if (CONST_INT_P (operands[2]))
6153 operands[4] = operands[2];
6155 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6158 (define_insn "*subv<mode>4"
6159 [(set (reg:CCO FLAGS_REG)
6160 (eq:CCO (minus:<DWI>
6162 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6164 (match_operand:SWI 2 "<general_sext_operand>"
6167 (minus:SWI (match_dup 1) (match_dup 2)))))
6168 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6169 (minus:SWI (match_dup 1) (match_dup 2)))]
6170 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6171 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6172 [(set_attr "type" "alu")
6173 (set_attr "mode" "<MODE>")])
6175 (define_insn "*subv<mode>4_1"
6176 [(set (reg:CCO FLAGS_REG)
6177 (eq:CCO (minus:<DWI>
6179 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6180 (match_operand:<DWI> 3 "const_int_operand" "i"))
6182 (minus:SWI (match_dup 1)
6183 (match_operand:SWI 2 "x86_64_immediate_operand"
6185 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6186 (minus:SWI (match_dup 1) (match_dup 2)))]
6187 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6188 && CONST_INT_P (operands[2])
6189 && INTVAL (operands[2]) == INTVAL (operands[3])"
6190 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6191 [(set_attr "type" "alu")
6192 (set_attr "mode" "<MODE>")
6193 (set (attr "length_immediate")
6194 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6196 (match_test "<MODE_SIZE> == 8")
6198 (const_string "<MODE_SIZE>")))])
6200 (define_insn "*sub<mode>_3"
6201 [(set (reg FLAGS_REG)
6202 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6203 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6204 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6205 (minus:SWI (match_dup 1) (match_dup 2)))]
6206 "ix86_match_ccmode (insn, CCmode)
6207 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6208 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6209 [(set_attr "type" "alu")
6210 (set_attr "mode" "<MODE>")])
6212 (define_insn "*subsi_3_zext"
6213 [(set (reg FLAGS_REG)
6214 (compare (match_operand:SI 1 "register_operand" "0")
6215 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6216 (set (match_operand:DI 0 "register_operand" "=r")
6218 (minus:SI (match_dup 1)
6220 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6221 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6222 "sub{l}\t{%2, %1|%1, %2}"
6223 [(set_attr "type" "alu")
6224 (set_attr "mode" "SI")])
6226 ;; Add with carry and subtract with borrow
6228 (define_expand "<plusminus_insn><mode>3_carry"
6230 [(set (match_operand:SWI 0 "nonimmediate_operand")
6232 (match_operand:SWI 1 "nonimmediate_operand")
6233 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6234 [(match_operand 3 "flags_reg_operand")
6236 (match_operand:SWI 2 "<general_operand>"))))
6237 (clobber (reg:CC FLAGS_REG))])]
6238 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6240 (define_insn "*<plusminus_insn><mode>3_carry"
6241 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6243 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6245 (match_operator 3 "ix86_carry_flag_operator"
6246 [(reg FLAGS_REG) (const_int 0)])
6247 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6248 (clobber (reg:CC FLAGS_REG))]
6249 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6250 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6251 [(set_attr "type" "alu")
6252 (set_attr "use_carry" "1")
6253 (set_attr "pent_pair" "pu")
6254 (set_attr "mode" "<MODE>")])
6256 (define_insn "*addsi3_carry_zext"
6257 [(set (match_operand:DI 0 "register_operand" "=r")
6259 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6260 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6261 [(reg FLAGS_REG) (const_int 0)])
6262 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6263 (clobber (reg:CC FLAGS_REG))]
6264 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6265 "adc{l}\t{%2, %k0|%k0, %2}"
6266 [(set_attr "type" "alu")
6267 (set_attr "use_carry" "1")
6268 (set_attr "pent_pair" "pu")
6269 (set_attr "mode" "SI")])
6271 (define_insn "*subsi3_carry_zext"
6272 [(set (match_operand:DI 0 "register_operand" "=r")
6274 (minus:SI (match_operand:SI 1 "register_operand" "0")
6275 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6276 [(reg FLAGS_REG) (const_int 0)])
6277 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6278 (clobber (reg:CC FLAGS_REG))]
6279 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6280 "sbb{l}\t{%2, %k0|%k0, %2}"
6281 [(set_attr "type" "alu")
6282 (set_attr "pent_pair" "pu")
6283 (set_attr "mode" "SI")])
6287 (define_insn "adcx<mode>3"
6288 [(set (reg:CCC FLAGS_REG)
6291 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6293 (match_operator 4 "ix86_carry_flag_operator"
6294 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6295 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6297 (set (match_operand:SWI48 0 "register_operand" "=r")
6298 (plus:SWI48 (match_dup 1)
6299 (plus:SWI48 (match_op_dup 4
6300 [(match_dup 3) (const_int 0)])
6302 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6303 "adcx\t{%2, %0|%0, %2}"
6304 [(set_attr "type" "alu")
6305 (set_attr "use_carry" "1")
6306 (set_attr "mode" "<MODE>")])
6308 ;; Overflow setting add instructions
6310 (define_insn "*add<mode>3_cconly_overflow"
6311 [(set (reg:CCC FLAGS_REG)
6314 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6315 (match_operand:SWI 2 "<general_operand>" "<g>"))
6317 (clobber (match_scratch:SWI 0 "=<r>"))]
6318 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6319 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6320 [(set_attr "type" "alu")
6321 (set_attr "mode" "<MODE>")])
6323 (define_insn "*add<mode>3_cc_overflow"
6324 [(set (reg:CCC FLAGS_REG)
6327 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6328 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6330 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6331 (plus:SWI (match_dup 1) (match_dup 2)))]
6332 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6333 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6334 [(set_attr "type" "alu")
6335 (set_attr "mode" "<MODE>")])
6337 (define_insn "*addsi3_zext_cc_overflow"
6338 [(set (reg:CCC FLAGS_REG)
6341 (match_operand:SI 1 "nonimmediate_operand" "%0")
6342 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6344 (set (match_operand:DI 0 "register_operand" "=r")
6345 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6346 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6347 "add{l}\t{%2, %k0|%k0, %2}"
6348 [(set_attr "type" "alu")
6349 (set_attr "mode" "SI")])
6351 ;; The patterns that match these are at the end of this file.
6353 (define_expand "<plusminus_insn>xf3"
6354 [(set (match_operand:XF 0 "register_operand")
6356 (match_operand:XF 1 "register_operand")
6357 (match_operand:XF 2 "register_operand")))]
6360 (define_expand "<plusminus_insn><mode>3"
6361 [(set (match_operand:MODEF 0 "register_operand")
6363 (match_operand:MODEF 1 "register_operand")
6364 (match_operand:MODEF 2 "nonimmediate_operand")))]
6365 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6366 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6368 ;; Multiply instructions
6370 (define_expand "mul<mode>3"
6371 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6373 (match_operand:SWIM248 1 "register_operand")
6374 (match_operand:SWIM248 2 "<general_operand>")))
6375 (clobber (reg:CC FLAGS_REG))])])
6377 (define_expand "mulqi3"
6378 [(parallel [(set (match_operand:QI 0 "register_operand")
6380 (match_operand:QI 1 "register_operand")
6381 (match_operand:QI 2 "nonimmediate_operand")))
6382 (clobber (reg:CC FLAGS_REG))])]
6383 "TARGET_QIMODE_MATH")
6386 ;; IMUL reg32/64, reg32/64, imm8 Direct
6387 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6388 ;; IMUL reg32/64, reg32/64, imm32 Direct
6389 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6390 ;; IMUL reg32/64, reg32/64 Direct
6391 ;; IMUL reg32/64, mem32/64 Direct
6393 ;; On BDVER1, all above IMULs use DirectPath
6395 (define_insn "*mul<mode>3_1"
6396 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6398 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6399 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6400 (clobber (reg:CC FLAGS_REG))]
6401 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6403 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6404 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6405 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6406 [(set_attr "type" "imul")
6407 (set_attr "prefix_0f" "0,0,1")
6408 (set (attr "athlon_decode")
6409 (cond [(eq_attr "cpu" "athlon")
6410 (const_string "vector")
6411 (eq_attr "alternative" "1")
6412 (const_string "vector")
6413 (and (eq_attr "alternative" "2")
6414 (match_operand 1 "memory_operand"))
6415 (const_string "vector")]
6416 (const_string "direct")))
6417 (set (attr "amdfam10_decode")
6418 (cond [(and (eq_attr "alternative" "0,1")
6419 (match_operand 1 "memory_operand"))
6420 (const_string "vector")]
6421 (const_string "direct")))
6422 (set_attr "bdver1_decode" "direct")
6423 (set_attr "mode" "<MODE>")])
6425 (define_insn "*mulsi3_1_zext"
6426 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6428 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6429 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6430 (clobber (reg:CC FLAGS_REG))]
6432 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6434 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6435 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6436 imul{l}\t{%2, %k0|%k0, %2}"
6437 [(set_attr "type" "imul")
6438 (set_attr "prefix_0f" "0,0,1")
6439 (set (attr "athlon_decode")
6440 (cond [(eq_attr "cpu" "athlon")
6441 (const_string "vector")
6442 (eq_attr "alternative" "1")
6443 (const_string "vector")
6444 (and (eq_attr "alternative" "2")
6445 (match_operand 1 "memory_operand"))
6446 (const_string "vector")]
6447 (const_string "direct")))
6448 (set (attr "amdfam10_decode")
6449 (cond [(and (eq_attr "alternative" "0,1")
6450 (match_operand 1 "memory_operand"))
6451 (const_string "vector")]
6452 (const_string "direct")))
6453 (set_attr "bdver1_decode" "direct")
6454 (set_attr "mode" "SI")])
6457 ;; IMUL reg16, reg16, imm8 VectorPath
6458 ;; IMUL reg16, mem16, imm8 VectorPath
6459 ;; IMUL reg16, reg16, imm16 VectorPath
6460 ;; IMUL reg16, mem16, imm16 VectorPath
6461 ;; IMUL reg16, reg16 Direct
6462 ;; IMUL reg16, mem16 Direct
6464 ;; On BDVER1, all HI MULs use DoublePath
6466 (define_insn "*mulhi3_1"
6467 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6468 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6469 (match_operand:HI 2 "general_operand" "K,n,mr")))
6470 (clobber (reg:CC FLAGS_REG))]
6472 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6474 imul{w}\t{%2, %1, %0|%0, %1, %2}
6475 imul{w}\t{%2, %1, %0|%0, %1, %2}
6476 imul{w}\t{%2, %0|%0, %2}"
6477 [(set_attr "type" "imul")
6478 (set_attr "prefix_0f" "0,0,1")
6479 (set (attr "athlon_decode")
6480 (cond [(eq_attr "cpu" "athlon")
6481 (const_string "vector")
6482 (eq_attr "alternative" "1,2")
6483 (const_string "vector")]
6484 (const_string "direct")))
6485 (set (attr "amdfam10_decode")
6486 (cond [(eq_attr "alternative" "0,1")
6487 (const_string "vector")]
6488 (const_string "direct")))
6489 (set_attr "bdver1_decode" "double")
6490 (set_attr "mode" "HI")])
6492 ;;On AMDFAM10 and BDVER1
6496 (define_insn "*mulqi3_1"
6497 [(set (match_operand:QI 0 "register_operand" "=a")
6498 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6499 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6500 (clobber (reg:CC FLAGS_REG))]
6502 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6504 [(set_attr "type" "imul")
6505 (set_attr "length_immediate" "0")
6506 (set (attr "athlon_decode")
6507 (if_then_else (eq_attr "cpu" "athlon")
6508 (const_string "vector")
6509 (const_string "direct")))
6510 (set_attr "amdfam10_decode" "direct")
6511 (set_attr "bdver1_decode" "direct")
6512 (set_attr "mode" "QI")])
6514 ;; Multiply with jump on overflow.
6515 (define_expand "mulv<mode>4"
6516 [(parallel [(set (reg:CCO FLAGS_REG)
6519 (match_operand:SWI48 1 "register_operand"))
6522 (mult:SWI48 (match_dup 1)
6523 (match_operand:SWI48 2
6524 "<general_operand>")))))
6525 (set (match_operand:SWI48 0 "register_operand")
6526 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6527 (set (pc) (if_then_else
6528 (eq (reg:CCO FLAGS_REG) (const_int 0))
6529 (label_ref (match_operand 3))
6533 if (CONST_INT_P (operands[2]))
6534 operands[4] = operands[2];
6536 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6539 (define_insn "*mulv<mode>4"
6540 [(set (reg:CCO FLAGS_REG)
6543 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6545 (match_operand:SWI48 2 "<general_sext_operand>"
6548 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6549 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6550 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6551 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6553 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6554 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6555 [(set_attr "type" "imul")
6556 (set_attr "prefix_0f" "0,1")
6557 (set (attr "athlon_decode")
6558 (cond [(eq_attr "cpu" "athlon")
6559 (const_string "vector")
6560 (eq_attr "alternative" "0")
6561 (const_string "vector")
6562 (and (eq_attr "alternative" "1")
6563 (match_operand 1 "memory_operand"))
6564 (const_string "vector")]
6565 (const_string "direct")))
6566 (set (attr "amdfam10_decode")
6567 (cond [(and (eq_attr "alternative" "1")
6568 (match_operand 1 "memory_operand"))
6569 (const_string "vector")]
6570 (const_string "direct")))
6571 (set_attr "bdver1_decode" "direct")
6572 (set_attr "mode" "<MODE>")])
6574 (define_insn "*mulv<mode>4_1"
6575 [(set (reg:CCO FLAGS_REG)
6578 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6579 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6581 (mult:SWI48 (match_dup 1)
6582 (match_operand:SWI 2 "x86_64_immediate_operand"
6584 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6585 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6586 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6587 && CONST_INT_P (operands[2])
6588 && INTVAL (operands[2]) == INTVAL (operands[3])"
6590 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6591 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6592 [(set_attr "type" "imul")
6593 (set (attr "athlon_decode")
6594 (cond [(eq_attr "cpu" "athlon")
6595 (const_string "vector")
6596 (eq_attr "alternative" "1")
6597 (const_string "vector")]
6598 (const_string "direct")))
6599 (set (attr "amdfam10_decode")
6600 (cond [(match_operand 1 "memory_operand")
6601 (const_string "vector")]
6602 (const_string "direct")))
6603 (set_attr "bdver1_decode" "direct")
6604 (set_attr "mode" "<MODE>")
6605 (set (attr "length_immediate")
6606 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6608 (match_test "<MODE_SIZE> == 8")
6610 (const_string "<MODE_SIZE>")))])
6612 (define_expand "<u>mul<mode><dwi>3"
6613 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6616 (match_operand:DWIH 1 "nonimmediate_operand"))
6618 (match_operand:DWIH 2 "register_operand"))))
6619 (clobber (reg:CC FLAGS_REG))])])
6621 (define_expand "<u>mulqihi3"
6622 [(parallel [(set (match_operand:HI 0 "register_operand")
6625 (match_operand:QI 1 "nonimmediate_operand"))
6627 (match_operand:QI 2 "register_operand"))))
6628 (clobber (reg:CC FLAGS_REG))])]
6629 "TARGET_QIMODE_MATH")
6631 (define_insn "*bmi2_umulditi3_1"
6632 [(set (match_operand:DI 0 "register_operand" "=r")
6634 (match_operand:DI 2 "nonimmediate_operand" "%d")
6635 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6636 (set (match_operand:DI 1 "register_operand" "=r")
6639 (mult:TI (zero_extend:TI (match_dup 2))
6640 (zero_extend:TI (match_dup 3)))
6642 "TARGET_64BIT && TARGET_BMI2
6643 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6644 "mulx\t{%3, %0, %1|%1, %0, %3}"
6645 [(set_attr "type" "imulx")
6646 (set_attr "prefix" "vex")
6647 (set_attr "mode" "DI")])
6649 (define_insn "*bmi2_umulsidi3_1"
6650 [(set (match_operand:SI 0 "register_operand" "=r")
6652 (match_operand:SI 2 "nonimmediate_operand" "%d")
6653 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6654 (set (match_operand:SI 1 "register_operand" "=r")
6657 (mult:DI (zero_extend:DI (match_dup 2))
6658 (zero_extend:DI (match_dup 3)))
6660 "!TARGET_64BIT && TARGET_BMI2
6661 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6662 "mulx\t{%3, %0, %1|%1, %0, %3}"
6663 [(set_attr "type" "imulx")
6664 (set_attr "prefix" "vex")
6665 (set_attr "mode" "SI")])
6667 (define_insn "*umul<mode><dwi>3_1"
6668 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6671 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6673 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6674 (clobber (reg:CC FLAGS_REG))]
6675 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6678 mul{<imodesuffix>}\t%2"
6679 [(set_attr "isa" "bmi2,*")
6680 (set_attr "type" "imulx,imul")
6681 (set_attr "length_immediate" "*,0")
6682 (set (attr "athlon_decode")
6683 (cond [(eq_attr "alternative" "1")
6684 (if_then_else (eq_attr "cpu" "athlon")
6685 (const_string "vector")
6686 (const_string "double"))]
6687 (const_string "*")))
6688 (set_attr "amdfam10_decode" "*,double")
6689 (set_attr "bdver1_decode" "*,direct")
6690 (set_attr "prefix" "vex,orig")
6691 (set_attr "mode" "<MODE>")])
6693 ;; Convert mul to the mulx pattern to avoid flags dependency.
6695 [(set (match_operand:<DWI> 0 "register_operand")
6698 (match_operand:DWIH 1 "register_operand"))
6700 (match_operand:DWIH 2 "nonimmediate_operand"))))
6701 (clobber (reg:CC FLAGS_REG))]
6702 "TARGET_BMI2 && reload_completed
6703 && true_regnum (operands[1]) == DX_REG"
6704 [(parallel [(set (match_dup 3)
6705 (mult:DWIH (match_dup 1) (match_dup 2)))
6709 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6710 (zero_extend:<DWI> (match_dup 2)))
6713 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6715 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6718 (define_insn "*mul<mode><dwi>3_1"
6719 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6722 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6724 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6725 (clobber (reg:CC FLAGS_REG))]
6726 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6727 "imul{<imodesuffix>}\t%2"
6728 [(set_attr "type" "imul")
6729 (set_attr "length_immediate" "0")
6730 (set (attr "athlon_decode")
6731 (if_then_else (eq_attr "cpu" "athlon")
6732 (const_string "vector")
6733 (const_string "double")))
6734 (set_attr "amdfam10_decode" "double")
6735 (set_attr "bdver1_decode" "direct")
6736 (set_attr "mode" "<MODE>")])
6738 (define_insn "*<u>mulqihi3_1"
6739 [(set (match_operand:HI 0 "register_operand" "=a")
6742 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6744 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6745 (clobber (reg:CC FLAGS_REG))]
6747 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6748 "<sgnprefix>mul{b}\t%2"
6749 [(set_attr "type" "imul")
6750 (set_attr "length_immediate" "0")
6751 (set (attr "athlon_decode")
6752 (if_then_else (eq_attr "cpu" "athlon")
6753 (const_string "vector")
6754 (const_string "direct")))
6755 (set_attr "amdfam10_decode" "direct")
6756 (set_attr "bdver1_decode" "direct")
6757 (set_attr "mode" "QI")])
6759 (define_expand "<s>mul<mode>3_highpart"
6760 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6765 (match_operand:SWI48 1 "nonimmediate_operand"))
6767 (match_operand:SWI48 2 "register_operand")))
6769 (clobber (match_scratch:SWI48 3))
6770 (clobber (reg:CC FLAGS_REG))])]
6772 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6774 (define_insn "*<s>muldi3_highpart_1"
6775 [(set (match_operand:DI 0 "register_operand" "=d")
6780 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6782 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6784 (clobber (match_scratch:DI 3 "=1"))
6785 (clobber (reg:CC FLAGS_REG))]
6787 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6788 "<sgnprefix>mul{q}\t%2"
6789 [(set_attr "type" "imul")
6790 (set_attr "length_immediate" "0")
6791 (set (attr "athlon_decode")
6792 (if_then_else (eq_attr "cpu" "athlon")
6793 (const_string "vector")
6794 (const_string "double")))
6795 (set_attr "amdfam10_decode" "double")
6796 (set_attr "bdver1_decode" "direct")
6797 (set_attr "mode" "DI")])
6799 (define_insn "*<s>mulsi3_highpart_1"
6800 [(set (match_operand:SI 0 "register_operand" "=d")
6805 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6807 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6809 (clobber (match_scratch:SI 3 "=1"))
6810 (clobber (reg:CC FLAGS_REG))]
6811 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6812 "<sgnprefix>mul{l}\t%2"
6813 [(set_attr "type" "imul")
6814 (set_attr "length_immediate" "0")
6815 (set (attr "athlon_decode")
6816 (if_then_else (eq_attr "cpu" "athlon")
6817 (const_string "vector")
6818 (const_string "double")))
6819 (set_attr "amdfam10_decode" "double")
6820 (set_attr "bdver1_decode" "direct")
6821 (set_attr "mode" "SI")])
6823 (define_insn "*<s>mulsi3_highpart_zext"
6824 [(set (match_operand:DI 0 "register_operand" "=d")
6825 (zero_extend:DI (truncate:SI
6827 (mult:DI (any_extend:DI
6828 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6830 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6832 (clobber (match_scratch:SI 3 "=1"))
6833 (clobber (reg:CC FLAGS_REG))]
6835 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6836 "<sgnprefix>mul{l}\t%2"
6837 [(set_attr "type" "imul")
6838 (set_attr "length_immediate" "0")
6839 (set (attr "athlon_decode")
6840 (if_then_else (eq_attr "cpu" "athlon")
6841 (const_string "vector")
6842 (const_string "double")))
6843 (set_attr "amdfam10_decode" "double")
6844 (set_attr "bdver1_decode" "direct")
6845 (set_attr "mode" "SI")])
6847 ;; The patterns that match these are at the end of this file.
6849 (define_expand "mulxf3"
6850 [(set (match_operand:XF 0 "register_operand")
6851 (mult:XF (match_operand:XF 1 "register_operand")
6852 (match_operand:XF 2 "register_operand")))]
6855 (define_expand "mul<mode>3"
6856 [(set (match_operand:MODEF 0 "register_operand")
6857 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6858 (match_operand:MODEF 2 "nonimmediate_operand")))]
6859 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6860 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6862 ;; Divide instructions
6864 ;; The patterns that match these are at the end of this file.
6866 (define_expand "divxf3"
6867 [(set (match_operand:XF 0 "register_operand")
6868 (div:XF (match_operand:XF 1 "register_operand")
6869 (match_operand:XF 2 "register_operand")))]
6872 (define_expand "divdf3"
6873 [(set (match_operand:DF 0 "register_operand")
6874 (div:DF (match_operand:DF 1 "register_operand")
6875 (match_operand:DF 2 "nonimmediate_operand")))]
6876 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6877 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6879 (define_expand "divsf3"
6880 [(set (match_operand:SF 0 "register_operand")
6881 (div:SF (match_operand:SF 1 "register_operand")
6882 (match_operand:SF 2 "nonimmediate_operand")))]
6883 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6888 && optimize_insn_for_speed_p ()
6889 && flag_finite_math_only && !flag_trapping_math
6890 && flag_unsafe_math_optimizations)
6892 ix86_emit_swdivsf (operands[0], operands[1],
6893 operands[2], SFmode);
6898 ;; Divmod instructions.
6900 (define_expand "divmod<mode>4"
6901 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6903 (match_operand:SWIM248 1 "register_operand")
6904 (match_operand:SWIM248 2 "nonimmediate_operand")))
6905 (set (match_operand:SWIM248 3 "register_operand")
6906 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6907 (clobber (reg:CC FLAGS_REG))])])
6909 ;; Split with 8bit unsigned divide:
6910 ;; if (dividend an divisor are in [0-255])
6911 ;; use 8bit unsigned integer divide
6913 ;; use original integer divide
6915 [(set (match_operand:SWI48 0 "register_operand")
6916 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6917 (match_operand:SWI48 3 "nonimmediate_operand")))
6918 (set (match_operand:SWI48 1 "register_operand")
6919 (mod:SWI48 (match_dup 2) (match_dup 3)))
6920 (clobber (reg:CC FLAGS_REG))]
6921 "TARGET_USE_8BIT_IDIV
6922 && TARGET_QIMODE_MATH
6923 && can_create_pseudo_p ()
6924 && !optimize_insn_for_size_p ()"
6926 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6928 (define_insn_and_split "divmod<mode>4_1"
6929 [(set (match_operand:SWI48 0 "register_operand" "=a")
6930 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6931 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6932 (set (match_operand:SWI48 1 "register_operand" "=&d")
6933 (mod:SWI48 (match_dup 2) (match_dup 3)))
6934 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6935 (clobber (reg:CC FLAGS_REG))]
6939 [(parallel [(set (match_dup 1)
6940 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6941 (clobber (reg:CC FLAGS_REG))])
6942 (parallel [(set (match_dup 0)
6943 (div:SWI48 (match_dup 2) (match_dup 3)))
6945 (mod:SWI48 (match_dup 2) (match_dup 3)))
6947 (clobber (reg:CC FLAGS_REG))])]
6949 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6951 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6952 operands[4] = operands[2];
6955 /* Avoid use of cltd in favor of a mov+shift. */
6956 emit_move_insn (operands[1], operands[2]);
6957 operands[4] = operands[1];
6960 [(set_attr "type" "multi")
6961 (set_attr "mode" "<MODE>")])
6963 (define_insn_and_split "*divmod<mode>4"
6964 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6965 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6966 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6967 (set (match_operand:SWIM248 1 "register_operand" "=&d")
6968 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6969 (clobber (reg:CC FLAGS_REG))]
6973 [(parallel [(set (match_dup 1)
6974 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
6975 (clobber (reg:CC FLAGS_REG))])
6976 (parallel [(set (match_dup 0)
6977 (div:SWIM248 (match_dup 2) (match_dup 3)))
6979 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6981 (clobber (reg:CC FLAGS_REG))])]
6983 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6985 if (<MODE>mode != HImode
6986 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
6987 operands[4] = operands[2];
6990 /* Avoid use of cltd in favor of a mov+shift. */
6991 emit_move_insn (operands[1], operands[2]);
6992 operands[4] = operands[1];
6995 [(set_attr "type" "multi")
6996 (set_attr "mode" "<MODE>")])
6998 (define_insn "*divmod<mode>4_noext"
6999 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7000 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7001 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7002 (set (match_operand:SWIM248 1 "register_operand" "=d")
7003 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7004 (use (match_operand:SWIM248 4 "register_operand" "1"))
7005 (clobber (reg:CC FLAGS_REG))]
7007 "idiv{<imodesuffix>}\t%3"
7008 [(set_attr "type" "idiv")
7009 (set_attr "mode" "<MODE>")])
7011 (define_expand "divmodqi4"
7012 [(parallel [(set (match_operand:QI 0 "register_operand")
7014 (match_operand:QI 1 "register_operand")
7015 (match_operand:QI 2 "nonimmediate_operand")))
7016 (set (match_operand:QI 3 "register_operand")
7017 (mod:QI (match_dup 1) (match_dup 2)))
7018 (clobber (reg:CC FLAGS_REG))])]
7019 "TARGET_QIMODE_MATH"
7024 tmp0 = gen_reg_rtx (HImode);
7025 tmp1 = gen_reg_rtx (HImode);
7027 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7029 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7030 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7032 /* Extract remainder from AH. */
7033 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7034 insn = emit_move_insn (operands[3], tmp1);
7036 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7037 set_unique_reg_note (insn, REG_EQUAL, mod);
7039 /* Extract quotient from AL. */
7040 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7042 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7043 set_unique_reg_note (insn, REG_EQUAL, div);
7048 ;; Divide AX by r/m8, with result stored in
7051 ;; Change div/mod to HImode and extend the second argument to HImode
7052 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7053 ;; combine may fail.
7054 (define_insn "divmodhiqi3"
7055 [(set (match_operand:HI 0 "register_operand" "=a")
7060 (mod:HI (match_operand:HI 1 "register_operand" "0")
7062 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7066 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7067 (clobber (reg:CC FLAGS_REG))]
7068 "TARGET_QIMODE_MATH"
7070 [(set_attr "type" "idiv")
7071 (set_attr "mode" "QI")])
7073 (define_expand "udivmod<mode>4"
7074 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7076 (match_operand:SWIM248 1 "register_operand")
7077 (match_operand:SWIM248 2 "nonimmediate_operand")))
7078 (set (match_operand:SWIM248 3 "register_operand")
7079 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7080 (clobber (reg:CC FLAGS_REG))])])
7082 ;; Split with 8bit unsigned divide:
7083 ;; if (dividend an divisor are in [0-255])
7084 ;; use 8bit unsigned integer divide
7086 ;; use original integer divide
7088 [(set (match_operand:SWI48 0 "register_operand")
7089 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7090 (match_operand:SWI48 3 "nonimmediate_operand")))
7091 (set (match_operand:SWI48 1 "register_operand")
7092 (umod:SWI48 (match_dup 2) (match_dup 3)))
7093 (clobber (reg:CC FLAGS_REG))]
7094 "TARGET_USE_8BIT_IDIV
7095 && TARGET_QIMODE_MATH
7096 && can_create_pseudo_p ()
7097 && !optimize_insn_for_size_p ()"
7099 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7101 (define_insn_and_split "udivmod<mode>4_1"
7102 [(set (match_operand:SWI48 0 "register_operand" "=a")
7103 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7104 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7105 (set (match_operand:SWI48 1 "register_operand" "=&d")
7106 (umod:SWI48 (match_dup 2) (match_dup 3)))
7107 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7108 (clobber (reg:CC FLAGS_REG))]
7112 [(set (match_dup 1) (const_int 0))
7113 (parallel [(set (match_dup 0)
7114 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7116 (umod:SWI48 (match_dup 2) (match_dup 3)))
7118 (clobber (reg:CC FLAGS_REG))])]
7120 [(set_attr "type" "multi")
7121 (set_attr "mode" "<MODE>")])
7123 (define_insn_and_split "*udivmod<mode>4"
7124 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7125 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7126 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7127 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7128 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7129 (clobber (reg:CC FLAGS_REG))]
7133 [(set (match_dup 1) (const_int 0))
7134 (parallel [(set (match_dup 0)
7135 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7137 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7139 (clobber (reg:CC FLAGS_REG))])]
7141 [(set_attr "type" "multi")
7142 (set_attr "mode" "<MODE>")])
7144 (define_insn "*udivmod<mode>4_noext"
7145 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7146 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7147 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7148 (set (match_operand:SWIM248 1 "register_operand" "=d")
7149 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7150 (use (match_operand:SWIM248 4 "register_operand" "1"))
7151 (clobber (reg:CC FLAGS_REG))]
7153 "div{<imodesuffix>}\t%3"
7154 [(set_attr "type" "idiv")
7155 (set_attr "mode" "<MODE>")])
7157 (define_expand "udivmodqi4"
7158 [(parallel [(set (match_operand:QI 0 "register_operand")
7160 (match_operand:QI 1 "register_operand")
7161 (match_operand:QI 2 "nonimmediate_operand")))
7162 (set (match_operand:QI 3 "register_operand")
7163 (umod:QI (match_dup 1) (match_dup 2)))
7164 (clobber (reg:CC FLAGS_REG))])]
7165 "TARGET_QIMODE_MATH"
7170 tmp0 = gen_reg_rtx (HImode);
7171 tmp1 = gen_reg_rtx (HImode);
7173 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7175 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7176 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7178 /* Extract remainder from AH. */
7179 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7180 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7181 insn = emit_move_insn (operands[3], tmp1);
7183 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7184 set_unique_reg_note (insn, REG_EQUAL, mod);
7186 /* Extract quotient from AL. */
7187 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7189 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7190 set_unique_reg_note (insn, REG_EQUAL, div);
7195 (define_insn "udivmodhiqi3"
7196 [(set (match_operand:HI 0 "register_operand" "=a")
7201 (mod:HI (match_operand:HI 1 "register_operand" "0")
7203 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7207 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7208 (clobber (reg:CC FLAGS_REG))]
7209 "TARGET_QIMODE_MATH"
7211 [(set_attr "type" "idiv")
7212 (set_attr "mode" "QI")])
7214 ;; We cannot use div/idiv for double division, because it causes
7215 ;; "division by zero" on the overflow and that's not what we expect
7216 ;; from truncate. Because true (non truncating) double division is
7217 ;; never generated, we can't create this insn anyway.
7220 ; [(set (match_operand:SI 0 "register_operand" "=a")
7222 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7224 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7225 ; (set (match_operand:SI 3 "register_operand" "=d")
7227 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7228 ; (clobber (reg:CC FLAGS_REG))]
7230 ; "div{l}\t{%2, %0|%0, %2}"
7231 ; [(set_attr "type" "idiv")])
7233 ;;- Logical AND instructions
7235 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7236 ;; Note that this excludes ah.
7238 (define_expand "testsi_ccno_1"
7239 [(set (reg:CCNO FLAGS_REG)
7241 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7242 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7245 (define_expand "testqi_ccz_1"
7246 [(set (reg:CCZ FLAGS_REG)
7247 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7248 (match_operand:QI 1 "nonmemory_operand"))
7251 (define_expand "testdi_ccno_1"
7252 [(set (reg:CCNO FLAGS_REG)
7254 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7255 (match_operand:DI 1 "x86_64_szext_general_operand"))
7257 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7259 (define_insn "*testdi_1"
7260 [(set (reg FLAGS_REG)
7263 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7264 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7266 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7267 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7269 test{l}\t{%k1, %k0|%k0, %k1}
7270 test{l}\t{%k1, %k0|%k0, %k1}
7271 test{q}\t{%1, %0|%0, %1}
7272 test{q}\t{%1, %0|%0, %1}
7273 test{q}\t{%1, %0|%0, %1}"
7274 [(set_attr "type" "test")
7275 (set_attr "modrm" "0,1,0,1,1")
7276 (set_attr "mode" "SI,SI,DI,DI,DI")])
7278 (define_insn "*testqi_1_maybe_si"
7279 [(set (reg FLAGS_REG)
7282 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7283 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7285 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7286 && ix86_match_ccmode (insn,
7287 CONST_INT_P (operands[1])
7288 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7290 if (which_alternative == 3)
7292 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7293 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7294 return "test{l}\t{%1, %k0|%k0, %1}";
7296 return "test{b}\t{%1, %0|%0, %1}";
7298 [(set_attr "type" "test")
7299 (set_attr "modrm" "0,1,1,1")
7300 (set_attr "mode" "QI,QI,QI,SI")
7301 (set_attr "pent_pair" "uv,np,uv,np")])
7303 (define_insn "*test<mode>_1"
7304 [(set (reg FLAGS_REG)
7307 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7308 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7310 "ix86_match_ccmode (insn, CCNOmode)
7311 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7312 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7313 [(set_attr "type" "test")
7314 (set_attr "modrm" "0,1,1")
7315 (set_attr "mode" "<MODE>")
7316 (set_attr "pent_pair" "uv,np,uv")])
7318 (define_expand "testqi_ext_ccno_0"
7319 [(set (reg:CCNO FLAGS_REG)
7323 (match_operand 0 "ext_register_operand")
7326 (match_operand 1 "const_int_operand"))
7329 (define_insn "*testqi_ext_0"
7330 [(set (reg FLAGS_REG)
7334 (match_operand 0 "ext_register_operand" "Q")
7337 (match_operand 1 "const_int_operand" "n"))
7339 "ix86_match_ccmode (insn, CCNOmode)"
7340 "test{b}\t{%1, %h0|%h0, %1}"
7341 [(set_attr "type" "test")
7342 (set_attr "mode" "QI")
7343 (set_attr "length_immediate" "1")
7344 (set_attr "modrm" "1")
7345 (set_attr "pent_pair" "np")])
7347 (define_insn "*testqi_ext_1"
7348 [(set (reg FLAGS_REG)
7352 (match_operand 0 "ext_register_operand" "Q,Q")
7356 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7358 "ix86_match_ccmode (insn, CCNOmode)"
7359 "test{b}\t{%1, %h0|%h0, %1}"
7360 [(set_attr "isa" "*,nox64")
7361 (set_attr "type" "test")
7362 (set_attr "mode" "QI")])
7364 (define_insn "*testqi_ext_2"
7365 [(set (reg FLAGS_REG)
7369 (match_operand 0 "ext_register_operand" "Q")
7373 (match_operand 1 "ext_register_operand" "Q")
7377 "ix86_match_ccmode (insn, CCNOmode)"
7378 "test{b}\t{%h1, %h0|%h0, %h1}"
7379 [(set_attr "type" "test")
7380 (set_attr "mode" "QI")])
7382 ;; Combine likes to form bit extractions for some tests. Humor it.
7383 (define_insn "*testqi_ext_3"
7384 [(set (reg FLAGS_REG)
7385 (compare (zero_extract:SWI48
7386 (match_operand 0 "nonimmediate_operand" "rm")
7387 (match_operand:SWI48 1 "const_int_operand")
7388 (match_operand:SWI48 2 "const_int_operand"))
7390 "ix86_match_ccmode (insn, CCNOmode)
7391 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7392 || GET_MODE (operands[0]) == SImode
7393 || GET_MODE (operands[0]) == HImode
7394 || GET_MODE (operands[0]) == QImode)
7395 /* Ensure that resulting mask is zero or sign extended operand. */
7396 && INTVAL (operands[2]) >= 0
7397 && ((INTVAL (operands[1]) > 0
7398 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7399 || (<MODE>mode == DImode
7400 && INTVAL (operands[1]) > 32
7401 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7405 [(set (match_operand 0 "flags_reg_operand")
7406 (match_operator 1 "compare_operator"
7408 (match_operand 2 "nonimmediate_operand")
7409 (match_operand 3 "const_int_operand")
7410 (match_operand 4 "const_int_operand"))
7412 "ix86_match_ccmode (insn, CCNOmode)"
7413 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7415 rtx val = operands[2];
7416 HOST_WIDE_INT len = INTVAL (operands[3]);
7417 HOST_WIDE_INT pos = INTVAL (operands[4]);
7419 enum machine_mode mode, submode;
7421 mode = GET_MODE (val);
7424 /* ??? Combine likes to put non-volatile mem extractions in QImode
7425 no matter the size of the test. So find a mode that works. */
7426 if (! MEM_VOLATILE_P (val))
7428 mode = smallest_mode_for_size (pos + len, MODE_INT);
7429 val = adjust_address (val, mode, 0);
7432 else if (GET_CODE (val) == SUBREG
7433 && (submode = GET_MODE (SUBREG_REG (val)),
7434 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7435 && pos + len <= GET_MODE_BITSIZE (submode)
7436 && GET_MODE_CLASS (submode) == MODE_INT)
7438 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7440 val = SUBREG_REG (val);
7442 else if (mode == HImode && pos + len <= 8)
7444 /* Small HImode tests can be converted to QImode. */
7446 val = gen_lowpart (QImode, val);
7449 if (len == HOST_BITS_PER_WIDE_INT)
7452 mask = ((HOST_WIDE_INT)1 << len) - 1;
7455 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7458 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7459 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7460 ;; this is relatively important trick.
7461 ;; Do the conversion only post-reload to avoid limiting of the register class
7464 [(set (match_operand 0 "flags_reg_operand")
7465 (match_operator 1 "compare_operator"
7466 [(and (match_operand 2 "register_operand")
7467 (match_operand 3 "const_int_operand"))
7470 && QI_REG_P (operands[2])
7471 && GET_MODE (operands[2]) != QImode
7472 && ((ix86_match_ccmode (insn, CCZmode)
7473 && !(INTVAL (operands[3]) & ~(255 << 8)))
7474 || (ix86_match_ccmode (insn, CCNOmode)
7475 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7478 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7482 operands[2] = gen_lowpart (SImode, operands[2]);
7483 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7487 [(set (match_operand 0 "flags_reg_operand")
7488 (match_operator 1 "compare_operator"
7489 [(and (match_operand 2 "nonimmediate_operand")
7490 (match_operand 3 "const_int_operand"))
7493 && GET_MODE (operands[2]) != QImode
7494 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7495 && ((ix86_match_ccmode (insn, CCZmode)
7496 && !(INTVAL (operands[3]) & ~255))
7497 || (ix86_match_ccmode (insn, CCNOmode)
7498 && !(INTVAL (operands[3]) & ~127)))"
7500 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7503 operands[2] = gen_lowpart (QImode, operands[2]);
7504 operands[3] = gen_lowpart (QImode, operands[3]);
7508 [(set (match_operand:SWI12 0 "mask_reg_operand")
7509 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand")
7510 (match_operand:SWI12 2 "mask_reg_operand")))
7511 (clobber (reg:CC FLAGS_REG))]
7512 "TARGET_AVX512F && reload_completed"
7514 (any_logic:SWI12 (match_dup 1)
7517 (define_insn "*k<logic><mode>"
7518 [(set (match_operand:SWI12 0 "mask_reg_operand" "=k")
7519 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "k")
7520 (match_operand:SWI12 2 "mask_reg_operand" "k")))]
7522 "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7523 [(set_attr "mode" "<MODE>")
7524 (set_attr "type" "msklog")
7525 (set_attr "prefix" "vex")])
7527 ;; %%% This used to optimize known byte-wide and operations to memory,
7528 ;; and sometimes to QImode registers. If this is considered useful,
7529 ;; it should be done with splitters.
7531 (define_expand "and<mode>3"
7532 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7533 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7534 (match_operand:SWIM 2 "<general_szext_operand>")))]
7537 enum machine_mode mode = <MODE>mode;
7538 rtx (*insn) (rtx, rtx);
7540 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7542 HOST_WIDE_INT ival = INTVAL (operands[2]);
7544 if (ival == (HOST_WIDE_INT) 0xffffffff)
7546 else if (ival == 0xffff)
7548 else if (ival == 0xff)
7552 if (mode == <MODE>mode)
7554 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7558 if (<MODE>mode == DImode)
7559 insn = (mode == SImode)
7560 ? gen_zero_extendsidi2
7562 ? gen_zero_extendhidi2
7563 : gen_zero_extendqidi2;
7564 else if (<MODE>mode == SImode)
7565 insn = (mode == HImode)
7566 ? gen_zero_extendhisi2
7567 : gen_zero_extendqisi2;
7568 else if (<MODE>mode == HImode)
7569 insn = gen_zero_extendqihi2;
7573 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7577 (define_insn "*anddi_1"
7578 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7580 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7581 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7582 (clobber (reg:CC FLAGS_REG))]
7583 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7585 switch (get_attr_type (insn))
7591 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7592 if (get_attr_mode (insn) == MODE_SI)
7593 return "and{l}\t{%k2, %k0|%k0, %k2}";
7595 return "and{q}\t{%2, %0|%0, %2}";
7598 [(set_attr "type" "alu,alu,alu,imovx")
7599 (set_attr "length_immediate" "*,*,*,0")
7600 (set (attr "prefix_rex")
7602 (and (eq_attr "type" "imovx")
7603 (and (match_test "INTVAL (operands[2]) == 0xff")
7604 (match_operand 1 "ext_QIreg_operand")))
7606 (const_string "*")))
7607 (set_attr "mode" "SI,DI,DI,SI")])
7609 (define_insn "*andsi_1"
7610 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7611 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7612 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7613 (clobber (reg:CC FLAGS_REG))]
7614 "ix86_binary_operator_ok (AND, SImode, operands)"
7616 switch (get_attr_type (insn))
7622 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7623 return "and{l}\t{%2, %0|%0, %2}";
7626 [(set_attr "type" "alu,alu,imovx")
7627 (set (attr "prefix_rex")
7629 (and (eq_attr "type" "imovx")
7630 (and (match_test "INTVAL (operands[2]) == 0xff")
7631 (match_operand 1 "ext_QIreg_operand")))
7633 (const_string "*")))
7634 (set_attr "length_immediate" "*,*,0")
7635 (set_attr "mode" "SI")])
7637 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7638 (define_insn "*andsi_1_zext"
7639 [(set (match_operand:DI 0 "register_operand" "=r")
7641 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7642 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7643 (clobber (reg:CC FLAGS_REG))]
7644 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7645 "and{l}\t{%2, %k0|%k0, %2}"
7646 [(set_attr "type" "alu")
7647 (set_attr "mode" "SI")])
7649 (define_insn "*andhi_1"
7650 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7651 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7652 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7653 (clobber (reg:CC FLAGS_REG))]
7654 "ix86_binary_operator_ok (AND, HImode, operands)"
7656 switch (get_attr_type (insn))
7662 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7665 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7666 return "and{w}\t{%2, %0|%0, %2}";
7669 [(set_attr "type" "alu,alu,imovx,msklog")
7670 (set_attr "length_immediate" "*,*,0,*")
7671 (set (attr "prefix_rex")
7673 (and (eq_attr "type" "imovx")
7674 (match_operand 1 "ext_QIreg_operand"))
7676 (const_string "*")))
7677 (set_attr "mode" "HI,HI,SI,HI")])
7679 ;; %%% Potential partial reg stall on alternative 2. What to do?
7680 (define_insn "*andqi_1"
7681 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7682 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7683 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7684 (clobber (reg:CC FLAGS_REG))]
7685 "ix86_binary_operator_ok (AND, QImode, operands)"
7687 and{b}\t{%2, %0|%0, %2}
7688 and{b}\t{%2, %0|%0, %2}
7689 and{l}\t{%k2, %k0|%k0, %k2}
7690 kandw\t{%2, %1, %0|%0, %1, %2}"
7691 [(set_attr "type" "alu,alu,alu,msklog")
7692 (set_attr "mode" "QI,QI,SI,HI")])
7694 (define_insn "*andqi_1_slp"
7695 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7696 (and:QI (match_dup 0)
7697 (match_operand:QI 1 "general_operand" "qn,qmn")))
7698 (clobber (reg:CC FLAGS_REG))]
7699 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7700 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7701 "and{b}\t{%1, %0|%0, %1}"
7702 [(set_attr "type" "alu1")
7703 (set_attr "mode" "QI")])
7705 (define_insn "kandn<mode>"
7706 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7709 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7710 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7711 (clobber (reg:CC FLAGS_REG))]
7714 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
7716 kandnw\t{%2, %1, %0|%0, %1, %2}"
7717 [(set_attr "isa" "bmi,*,avx512f")
7718 (set_attr "type" "bitmanip,*,msklog")
7719 (set_attr "prefix" "*,*,vex")
7720 (set_attr "btver2_decode" "direct,*,*")
7721 (set_attr "mode" "<MODE>")])
7724 [(set (match_operand:SWI12 0 "general_reg_operand")
7728 (match_operand:SWI12 1 "general_reg_operand")))
7729 (clobber (reg:CC FLAGS_REG))]
7730 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7732 (not:HI (match_dup 0)))
7733 (parallel [(set (match_dup 0)
7734 (and:HI (match_dup 0)
7736 (clobber (reg:CC FLAGS_REG))])])
7738 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7740 [(set (match_operand:DI 0 "register_operand")
7741 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7742 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7743 (clobber (reg:CC FLAGS_REG))]
7745 [(parallel [(set (match_dup 0)
7746 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7747 (clobber (reg:CC FLAGS_REG))])]
7748 "operands[2] = gen_lowpart (SImode, operands[2]);")
7751 [(set (match_operand:SWI248 0 "register_operand")
7752 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7753 (match_operand:SWI248 2 "const_int_operand")))
7754 (clobber (reg:CC FLAGS_REG))]
7756 && true_regnum (operands[0]) != true_regnum (operands[1])"
7759 HOST_WIDE_INT ival = INTVAL (operands[2]);
7760 enum machine_mode mode;
7761 rtx (*insn) (rtx, rtx);
7763 if (ival == (HOST_WIDE_INT) 0xffffffff)
7765 else if (ival == 0xffff)
7769 gcc_assert (ival == 0xff);
7773 if (<MODE>mode == DImode)
7774 insn = (mode == SImode)
7775 ? gen_zero_extendsidi2
7777 ? gen_zero_extendhidi2
7778 : gen_zero_extendqidi2;
7781 if (<MODE>mode != SImode)
7782 /* Zero extend to SImode to avoid partial register stalls. */
7783 operands[0] = gen_lowpart (SImode, operands[0]);
7785 insn = (mode == HImode)
7786 ? gen_zero_extendhisi2
7787 : gen_zero_extendqisi2;
7789 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7794 [(set (match_operand 0 "register_operand")
7796 (const_int -65536)))
7797 (clobber (reg:CC FLAGS_REG))]
7798 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7799 || optimize_function_for_size_p (cfun)"
7800 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7801 "operands[1] = gen_lowpart (HImode, operands[0]);")
7804 [(set (match_operand 0 "ext_register_operand")
7807 (clobber (reg:CC FLAGS_REG))]
7808 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7809 && reload_completed"
7810 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7811 "operands[1] = gen_lowpart (QImode, operands[0]);")
7814 [(set (match_operand 0 "ext_register_operand")
7816 (const_int -65281)))
7817 (clobber (reg:CC FLAGS_REG))]
7818 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7819 && reload_completed"
7820 [(parallel [(set (zero_extract:SI (match_dup 0)
7824 (zero_extract:SI (match_dup 0)
7827 (zero_extract:SI (match_dup 0)
7830 (clobber (reg:CC FLAGS_REG))])]
7831 "operands[0] = gen_lowpart (SImode, operands[0]);")
7833 (define_insn "*anddi_2"
7834 [(set (reg FLAGS_REG)
7837 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7838 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7840 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7841 (and:DI (match_dup 1) (match_dup 2)))]
7843 && ix86_match_ccmode
7845 /* If we are going to emit andl instead of andq, and the operands[2]
7846 constant might have the SImode sign bit set, make sure the sign
7847 flag isn't tested, because the instruction will set the sign flag
7848 based on bit 31 rather than bit 63. If it isn't CONST_INT,
7849 conservatively assume it might have bit 31 set. */
7850 (satisfies_constraint_Z (operands[2])
7851 && (!CONST_INT_P (operands[2])
7852 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7853 ? CCZmode : CCNOmode)
7854 && ix86_binary_operator_ok (AND, DImode, operands)"
7856 and{l}\t{%k2, %k0|%k0, %k2}
7857 and{q}\t{%2, %0|%0, %2}
7858 and{q}\t{%2, %0|%0, %2}"
7859 [(set_attr "type" "alu")
7860 (set_attr "mode" "SI,DI,DI")])
7862 (define_insn "*andqi_2_maybe_si"
7863 [(set (reg FLAGS_REG)
7865 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7866 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7868 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7869 (and:QI (match_dup 1) (match_dup 2)))]
7870 "ix86_binary_operator_ok (AND, QImode, operands)
7871 && ix86_match_ccmode (insn,
7872 CONST_INT_P (operands[2])
7873 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7875 if (which_alternative == 2)
7877 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7878 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7879 return "and{l}\t{%2, %k0|%k0, %2}";
7881 return "and{b}\t{%2, %0|%0, %2}";
7883 [(set_attr "type" "alu")
7884 (set_attr "mode" "QI,QI,SI")])
7886 (define_insn "*and<mode>_2"
7887 [(set (reg FLAGS_REG)
7888 (compare (and:SWI124
7889 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7890 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7892 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7893 (and:SWI124 (match_dup 1) (match_dup 2)))]
7894 "ix86_match_ccmode (insn, CCNOmode)
7895 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7896 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7897 [(set_attr "type" "alu")
7898 (set_attr "mode" "<MODE>")])
7900 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7901 (define_insn "*andsi_2_zext"
7902 [(set (reg FLAGS_REG)
7904 (match_operand:SI 1 "nonimmediate_operand" "%0")
7905 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7907 (set (match_operand:DI 0 "register_operand" "=r")
7908 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7909 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7910 && ix86_binary_operator_ok (AND, SImode, operands)"
7911 "and{l}\t{%2, %k0|%k0, %2}"
7912 [(set_attr "type" "alu")
7913 (set_attr "mode" "SI")])
7915 (define_insn "*andqi_2_slp"
7916 [(set (reg FLAGS_REG)
7918 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7919 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7921 (set (strict_low_part (match_dup 0))
7922 (and:QI (match_dup 0) (match_dup 1)))]
7923 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7924 && ix86_match_ccmode (insn, CCNOmode)
7925 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7926 "and{b}\t{%1, %0|%0, %1}"
7927 [(set_attr "type" "alu1")
7928 (set_attr "mode" "QI")])
7930 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7931 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7932 ;; for a QImode operand, which of course failed.
7933 (define_insn "andqi_ext_0"
7934 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7939 (match_operand 1 "ext_register_operand" "0")
7942 (match_operand 2 "const_int_operand" "n")))
7943 (clobber (reg:CC FLAGS_REG))]
7945 "and{b}\t{%2, %h0|%h0, %2}"
7946 [(set_attr "type" "alu")
7947 (set_attr "length_immediate" "1")
7948 (set_attr "modrm" "1")
7949 (set_attr "mode" "QI")])
7951 ;; Generated by peephole translating test to and. This shows up
7952 ;; often in fp comparisons.
7953 (define_insn "*andqi_ext_0_cc"
7954 [(set (reg FLAGS_REG)
7958 (match_operand 1 "ext_register_operand" "0")
7961 (match_operand 2 "const_int_operand" "n"))
7963 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7972 "ix86_match_ccmode (insn, CCNOmode)"
7973 "and{b}\t{%2, %h0|%h0, %2}"
7974 [(set_attr "type" "alu")
7975 (set_attr "length_immediate" "1")
7976 (set_attr "modrm" "1")
7977 (set_attr "mode" "QI")])
7979 (define_insn "*andqi_ext_1"
7980 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
7985 (match_operand 1 "ext_register_operand" "0,0")
7989 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
7990 (clobber (reg:CC FLAGS_REG))]
7992 "and{b}\t{%2, %h0|%h0, %2}"
7993 [(set_attr "isa" "*,nox64")
7994 (set_attr "type" "alu")
7995 (set_attr "length_immediate" "0")
7996 (set_attr "mode" "QI")])
7998 (define_insn "*andqi_ext_2"
7999 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8004 (match_operand 1 "ext_register_operand" "%0")
8008 (match_operand 2 "ext_register_operand" "Q")
8011 (clobber (reg:CC FLAGS_REG))]
8013 "and{b}\t{%h2, %h0|%h0, %h2}"
8014 [(set_attr "type" "alu")
8015 (set_attr "length_immediate" "0")
8016 (set_attr "mode" "QI")])
8018 ;; Convert wide AND instructions with immediate operand to shorter QImode
8019 ;; equivalents when possible.
8020 ;; Don't do the splitting with memory operands, since it introduces risk
8021 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8022 ;; for size, but that can (should?) be handled by generic code instead.
8024 [(set (match_operand 0 "register_operand")
8025 (and (match_operand 1 "register_operand")
8026 (match_operand 2 "const_int_operand")))
8027 (clobber (reg:CC FLAGS_REG))]
8029 && QI_REG_P (operands[0])
8030 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8031 && !(~INTVAL (operands[2]) & ~(255 << 8))
8032 && GET_MODE (operands[0]) != QImode"
8033 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8034 (and:SI (zero_extract:SI (match_dup 1)
8035 (const_int 8) (const_int 8))
8037 (clobber (reg:CC FLAGS_REG))])]
8039 operands[0] = gen_lowpart (SImode, operands[0]);
8040 operands[1] = gen_lowpart (SImode, operands[1]);
8041 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8044 ;; Since AND can be encoded with sign extended immediate, this is only
8045 ;; profitable when 7th bit is not set.
8047 [(set (match_operand 0 "register_operand")
8048 (and (match_operand 1 "general_operand")
8049 (match_operand 2 "const_int_operand")))
8050 (clobber (reg:CC FLAGS_REG))]
8052 && ANY_QI_REG_P (operands[0])
8053 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8054 && !(~INTVAL (operands[2]) & ~255)
8055 && !(INTVAL (operands[2]) & 128)
8056 && GET_MODE (operands[0]) != QImode"
8057 [(parallel [(set (strict_low_part (match_dup 0))
8058 (and:QI (match_dup 1)
8060 (clobber (reg:CC FLAGS_REG))])]
8062 operands[0] = gen_lowpart (QImode, operands[0]);
8063 operands[1] = gen_lowpart (QImode, operands[1]);
8064 operands[2] = gen_lowpart (QImode, operands[2]);
8067 ;; Logical inclusive and exclusive OR instructions
8069 ;; %%% This used to optimize known byte-wide and operations to memory.
8070 ;; If this is considered useful, it should be done with splitters.
8072 (define_expand "<code><mode>3"
8073 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8074 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8075 (match_operand:SWIM 2 "<general_operand>")))]
8077 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8079 (define_insn "*<code><mode>_1"
8080 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
8082 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
8083 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>")))
8084 (clobber (reg:CC FLAGS_REG))]
8085 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8086 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8087 [(set_attr "type" "alu")
8088 (set_attr "mode" "<MODE>")])
8090 (define_insn "*<code>hi_1"
8091 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8093 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8094 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8095 (clobber (reg:CC FLAGS_REG))]
8096 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8098 <logic>{w}\t{%2, %0|%0, %2}
8099 <logic>{w}\t{%2, %0|%0, %2}
8100 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8101 [(set_attr "type" "alu,alu,msklog")
8102 (set_attr "mode" "HI")])
8104 ;; %%% Potential partial reg stall on alternative 2. What to do?
8105 (define_insn "*<code>qi_1"
8106 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8107 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8108 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8109 (clobber (reg:CC FLAGS_REG))]
8110 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8112 <logic>{b}\t{%2, %0|%0, %2}
8113 <logic>{b}\t{%2, %0|%0, %2}
8114 <logic>{l}\t{%k2, %k0|%k0, %k2}
8115 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8116 [(set_attr "type" "alu,alu,alu,msklog")
8117 (set_attr "mode" "QI,QI,SI,HI")])
8119 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8120 (define_insn "*<code>si_1_zext"
8121 [(set (match_operand:DI 0 "register_operand" "=r")
8123 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8124 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8125 (clobber (reg:CC FLAGS_REG))]
8126 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8127 "<logic>{l}\t{%2, %k0|%k0, %2}"
8128 [(set_attr "type" "alu")
8129 (set_attr "mode" "SI")])
8131 (define_insn "*<code>si_1_zext_imm"
8132 [(set (match_operand:DI 0 "register_operand" "=r")
8134 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8135 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8136 (clobber (reg:CC FLAGS_REG))]
8137 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8138 "<logic>{l}\t{%2, %k0|%k0, %2}"
8139 [(set_attr "type" "alu")
8140 (set_attr "mode" "SI")])
8142 (define_insn "*<code>qi_1_slp"
8143 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8144 (any_or:QI (match_dup 0)
8145 (match_operand:QI 1 "general_operand" "qmn,qn")))
8146 (clobber (reg:CC FLAGS_REG))]
8147 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8148 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8149 "<logic>{b}\t{%1, %0|%0, %1}"
8150 [(set_attr "type" "alu1")
8151 (set_attr "mode" "QI")])
8153 (define_insn "*<code><mode>_2"
8154 [(set (reg FLAGS_REG)
8155 (compare (any_or:SWI
8156 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8157 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8159 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8160 (any_or:SWI (match_dup 1) (match_dup 2)))]
8161 "ix86_match_ccmode (insn, CCNOmode)
8162 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8163 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8164 [(set_attr "type" "alu")
8165 (set_attr "mode" "<MODE>")])
8167 (define_insn "kxnor<mode>"
8168 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8171 (match_operand:SWI12 1 "register_operand" "0,k")
8172 (match_operand:SWI12 2 "register_operand" "r,k"))))
8173 (clobber (reg:CC FLAGS_REG))]
8177 kxnorw\t{%2, %1, %0|%0, %1, %2}"
8178 [(set_attr "type" "*,msklog")
8179 (set_attr "prefix" "*,vex")
8180 (set_attr "mode" "<MODE>")])
8183 [(set (match_operand:SWI12 0 "general_reg_operand")
8187 (match_operand:SWI12 1 "general_reg_operand"))))
8188 (clobber (reg:CC FLAGS_REG))]
8189 "TARGET_AVX512F && reload_completed"
8190 [(parallel [(set (match_dup 0)
8191 (xor:HI (match_dup 0)
8193 (clobber (reg:CC FLAGS_REG))])
8195 (not:HI (match_dup 0)))])
8197 (define_insn "kortestzhi"
8198 [(set (reg:CCZ FLAGS_REG)
8201 (match_operand:HI 0 "register_operand" "k")
8202 (match_operand:HI 1 "register_operand" "k"))
8204 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8205 "kortestw\t{%1, %0|%0, %1}"
8206 [(set_attr "mode" "HI")
8207 (set_attr "type" "msklog")
8208 (set_attr "prefix" "vex")])
8210 (define_insn "kortestchi"
8211 [(set (reg:CCC FLAGS_REG)
8214 (match_operand:HI 0 "register_operand" "k")
8215 (match_operand:HI 1 "register_operand" "k"))
8217 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8218 "kortestw\t{%1, %0|%0, %1}"
8219 [(set_attr "mode" "HI")
8220 (set_attr "type" "msklog")
8221 (set_attr "prefix" "vex")])
8223 (define_insn "kunpckhi"
8224 [(set (match_operand:HI 0 "register_operand" "=k")
8227 (match_operand:HI 1 "register_operand" "k")
8229 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8231 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8232 [(set_attr "mode" "HI")
8233 (set_attr "type" "msklog")
8234 (set_attr "prefix" "vex")])
8236 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8237 ;; ??? Special case for immediate operand is missing - it is tricky.
8238 (define_insn "*<code>si_2_zext"
8239 [(set (reg FLAGS_REG)
8240 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8241 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8243 (set (match_operand:DI 0 "register_operand" "=r")
8244 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8245 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8246 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8247 "<logic>{l}\t{%2, %k0|%k0, %2}"
8248 [(set_attr "type" "alu")
8249 (set_attr "mode" "SI")])
8251 (define_insn "*<code>si_2_zext_imm"
8252 [(set (reg FLAGS_REG)
8254 (match_operand:SI 1 "nonimmediate_operand" "%0")
8255 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8257 (set (match_operand:DI 0 "register_operand" "=r")
8258 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8259 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8260 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8261 "<logic>{l}\t{%2, %k0|%k0, %2}"
8262 [(set_attr "type" "alu")
8263 (set_attr "mode" "SI")])
8265 (define_insn "*<code>qi_2_slp"
8266 [(set (reg FLAGS_REG)
8267 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8268 (match_operand:QI 1 "general_operand" "qmn,qn"))
8270 (set (strict_low_part (match_dup 0))
8271 (any_or:QI (match_dup 0) (match_dup 1)))]
8272 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8273 && ix86_match_ccmode (insn, CCNOmode)
8274 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8275 "<logic>{b}\t{%1, %0|%0, %1}"
8276 [(set_attr "type" "alu1")
8277 (set_attr "mode" "QI")])
8279 (define_insn "*<code><mode>_3"
8280 [(set (reg FLAGS_REG)
8281 (compare (any_or:SWI
8282 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8283 (match_operand:SWI 2 "<general_operand>" "<g>"))
8285 (clobber (match_scratch:SWI 0 "=<r>"))]
8286 "ix86_match_ccmode (insn, CCNOmode)
8287 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8288 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8289 [(set_attr "type" "alu")
8290 (set_attr "mode" "<MODE>")])
8292 (define_insn "*<code>qi_ext_0"
8293 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8298 (match_operand 1 "ext_register_operand" "0")
8301 (match_operand 2 "const_int_operand" "n")))
8302 (clobber (reg:CC FLAGS_REG))]
8303 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8304 "<logic>{b}\t{%2, %h0|%h0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "length_immediate" "1")
8307 (set_attr "modrm" "1")
8308 (set_attr "mode" "QI")])
8310 (define_insn "*<code>qi_ext_1"
8311 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8316 (match_operand 1 "ext_register_operand" "0,0")
8320 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8321 (clobber (reg:CC FLAGS_REG))]
8322 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8323 "<logic>{b}\t{%2, %h0|%h0, %2}"
8324 [(set_attr "isa" "*,nox64")
8325 (set_attr "type" "alu")
8326 (set_attr "length_immediate" "0")
8327 (set_attr "mode" "QI")])
8329 (define_insn "*<code>qi_ext_2"
8330 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8334 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8337 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8340 (clobber (reg:CC FLAGS_REG))]
8341 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8342 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8343 [(set_attr "type" "alu")
8344 (set_attr "length_immediate" "0")
8345 (set_attr "mode" "QI")])
8348 [(set (match_operand 0 "register_operand")
8349 (any_or (match_operand 1 "register_operand")
8350 (match_operand 2 "const_int_operand")))
8351 (clobber (reg:CC FLAGS_REG))]
8353 && QI_REG_P (operands[0])
8354 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8355 && !(INTVAL (operands[2]) & ~(255 << 8))
8356 && GET_MODE (operands[0]) != QImode"
8357 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8358 (any_or:SI (zero_extract:SI (match_dup 1)
8359 (const_int 8) (const_int 8))
8361 (clobber (reg:CC FLAGS_REG))])]
8363 operands[0] = gen_lowpart (SImode, operands[0]);
8364 operands[1] = gen_lowpart (SImode, operands[1]);
8365 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8368 ;; Since OR can be encoded with sign extended immediate, this is only
8369 ;; profitable when 7th bit is set.
8371 [(set (match_operand 0 "register_operand")
8372 (any_or (match_operand 1 "general_operand")
8373 (match_operand 2 "const_int_operand")))
8374 (clobber (reg:CC FLAGS_REG))]
8376 && ANY_QI_REG_P (operands[0])
8377 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8378 && !(INTVAL (operands[2]) & ~255)
8379 && (INTVAL (operands[2]) & 128)
8380 && GET_MODE (operands[0]) != QImode"
8381 [(parallel [(set (strict_low_part (match_dup 0))
8382 (any_or:QI (match_dup 1)
8384 (clobber (reg:CC FLAGS_REG))])]
8386 operands[0] = gen_lowpart (QImode, operands[0]);
8387 operands[1] = gen_lowpart (QImode, operands[1]);
8388 operands[2] = gen_lowpart (QImode, operands[2]);
8391 (define_expand "xorqi_cc_ext_1"
8393 (set (reg:CCNO FLAGS_REG)
8397 (match_operand 1 "ext_register_operand")
8400 (match_operand:QI 2 "const_int_operand"))
8402 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8412 (define_insn "*xorqi_cc_ext_1"
8413 [(set (reg FLAGS_REG)
8417 (match_operand 1 "ext_register_operand" "0,0")
8420 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8422 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8431 "ix86_match_ccmode (insn, CCNOmode)"
8432 "xor{b}\t{%2, %h0|%h0, %2}"
8433 [(set_attr "isa" "*,nox64")
8434 (set_attr "type" "alu")
8435 (set_attr "modrm" "1")
8436 (set_attr "mode" "QI")])
8438 ;; Negation instructions
8440 (define_expand "neg<mode>2"
8441 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8442 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8444 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8446 (define_insn_and_split "*neg<dwi>2_doubleword"
8447 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8448 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8449 (clobber (reg:CC FLAGS_REG))]
8450 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8454 [(set (reg:CCZ FLAGS_REG)
8455 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8456 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8459 (plus:DWIH (match_dup 3)
8460 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8462 (clobber (reg:CC FLAGS_REG))])
8465 (neg:DWIH (match_dup 2)))
8466 (clobber (reg:CC FLAGS_REG))])]
8467 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8469 (define_insn "*neg<mode>2_1"
8470 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8471 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8472 (clobber (reg:CC FLAGS_REG))]
8473 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8474 "neg{<imodesuffix>}\t%0"
8475 [(set_attr "type" "negnot")
8476 (set_attr "mode" "<MODE>")])
8478 ;; Combine is quite creative about this pattern.
8479 (define_insn "*negsi2_1_zext"
8480 [(set (match_operand:DI 0 "register_operand" "=r")
8482 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8485 (clobber (reg:CC FLAGS_REG))]
8486 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8488 [(set_attr "type" "negnot")
8489 (set_attr "mode" "SI")])
8491 ;; The problem with neg is that it does not perform (compare x 0),
8492 ;; it really performs (compare 0 x), which leaves us with the zero
8493 ;; flag being the only useful item.
8495 (define_insn "*neg<mode>2_cmpz"
8496 [(set (reg:CCZ FLAGS_REG)
8498 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8500 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8501 (neg:SWI (match_dup 1)))]
8502 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8503 "neg{<imodesuffix>}\t%0"
8504 [(set_attr "type" "negnot")
8505 (set_attr "mode" "<MODE>")])
8507 (define_insn "*negsi2_cmpz_zext"
8508 [(set (reg:CCZ FLAGS_REG)
8512 (match_operand:DI 1 "register_operand" "0")
8516 (set (match_operand:DI 0 "register_operand" "=r")
8517 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8520 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8522 [(set_attr "type" "negnot")
8523 (set_attr "mode" "SI")])
8525 ;; Negate with jump on overflow.
8526 (define_expand "negv<mode>3"
8527 [(parallel [(set (reg:CCO FLAGS_REG)
8528 (ne:CCO (match_operand:SWI 1 "register_operand")
8530 (set (match_operand:SWI 0 "register_operand")
8531 (neg:SWI (match_dup 1)))])
8532 (set (pc) (if_then_else
8533 (eq (reg:CCO FLAGS_REG) (const_int 0))
8534 (label_ref (match_operand 2))
8539 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8543 (define_insn "*negv<mode>3"
8544 [(set (reg:CCO FLAGS_REG)
8545 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8546 (match_operand:SWI 2 "const_int_operand")))
8547 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8548 (neg:SWI (match_dup 1)))]
8549 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8550 && mode_signbit_p (<MODE>mode, operands[2])"
8551 "neg{<imodesuffix>}\t%0"
8552 [(set_attr "type" "negnot")
8553 (set_attr "mode" "<MODE>")])
8555 ;; Changing of sign for FP values is doable using integer unit too.
8557 (define_expand "<code><mode>2"
8558 [(set (match_operand:X87MODEF 0 "register_operand")
8559 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8560 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8561 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8563 (define_insn "*absneg<mode>2_mixed"
8564 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8565 (match_operator:MODEF 3 "absneg_operator"
8566 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8567 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8568 (clobber (reg:CC FLAGS_REG))]
8569 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8572 (define_insn "*absneg<mode>2_sse"
8573 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8574 (match_operator:MODEF 3 "absneg_operator"
8575 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8576 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8577 (clobber (reg:CC FLAGS_REG))]
8578 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8581 (define_insn "*absneg<mode>2_i387"
8582 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8583 (match_operator:X87MODEF 3 "absneg_operator"
8584 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8585 (use (match_operand 2))
8586 (clobber (reg:CC FLAGS_REG))]
8587 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8590 (define_expand "<code>tf2"
8591 [(set (match_operand:TF 0 "register_operand")
8592 (absneg:TF (match_operand:TF 1 "register_operand")))]
8594 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8596 (define_insn "*absnegtf2_sse"
8597 [(set (match_operand:TF 0 "register_operand" "=x,x")
8598 (match_operator:TF 3 "absneg_operator"
8599 [(match_operand:TF 1 "register_operand" "0,x")]))
8600 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8601 (clobber (reg:CC FLAGS_REG))]
8605 ;; Splitters for fp abs and neg.
8608 [(set (match_operand 0 "fp_register_operand")
8609 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8610 (use (match_operand 2))
8611 (clobber (reg:CC FLAGS_REG))]
8613 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8616 [(set (match_operand 0 "register_operand")
8617 (match_operator 3 "absneg_operator"
8618 [(match_operand 1 "register_operand")]))
8619 (use (match_operand 2 "nonimmediate_operand"))
8620 (clobber (reg:CC FLAGS_REG))]
8621 "reload_completed && SSE_REG_P (operands[0])"
8622 [(set (match_dup 0) (match_dup 3))]
8624 enum machine_mode mode = GET_MODE (operands[0]);
8625 enum machine_mode vmode = GET_MODE (operands[2]);
8628 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8629 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8630 if (operands_match_p (operands[0], operands[2]))
8633 operands[1] = operands[2];
8636 if (GET_CODE (operands[3]) == ABS)
8637 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8639 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8644 [(set (match_operand:SF 0 "register_operand")
8645 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8646 (use (match_operand:V4SF 2))
8647 (clobber (reg:CC FLAGS_REG))]
8649 [(parallel [(set (match_dup 0) (match_dup 1))
8650 (clobber (reg:CC FLAGS_REG))])]
8653 operands[0] = gen_lowpart (SImode, operands[0]);
8654 if (GET_CODE (operands[1]) == ABS)
8656 tmp = gen_int_mode (0x7fffffff, SImode);
8657 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8661 tmp = gen_int_mode (0x80000000, SImode);
8662 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8668 [(set (match_operand:DF 0 "register_operand")
8669 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8670 (use (match_operand 2))
8671 (clobber (reg:CC FLAGS_REG))]
8673 [(parallel [(set (match_dup 0) (match_dup 1))
8674 (clobber (reg:CC FLAGS_REG))])]
8679 tmp = gen_lowpart (DImode, operands[0]);
8680 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8683 if (GET_CODE (operands[1]) == ABS)
8686 tmp = gen_rtx_NOT (DImode, tmp);
8690 operands[0] = gen_highpart (SImode, operands[0]);
8691 if (GET_CODE (operands[1]) == ABS)
8693 tmp = gen_int_mode (0x7fffffff, SImode);
8694 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8698 tmp = gen_int_mode (0x80000000, SImode);
8699 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8706 [(set (match_operand:XF 0 "register_operand")
8707 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8708 (use (match_operand 2))
8709 (clobber (reg:CC FLAGS_REG))]
8711 [(parallel [(set (match_dup 0) (match_dup 1))
8712 (clobber (reg:CC FLAGS_REG))])]
8715 operands[0] = gen_rtx_REG (SImode,
8716 true_regnum (operands[0])
8717 + (TARGET_64BIT ? 1 : 2));
8718 if (GET_CODE (operands[1]) == ABS)
8720 tmp = GEN_INT (0x7fff);
8721 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8725 tmp = GEN_INT (0x8000);
8726 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8731 ;; Conditionalize these after reload. If they match before reload, we
8732 ;; lose the clobber and ability to use integer instructions.
8734 (define_insn "*<code><mode>2_1"
8735 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8736 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8738 && (reload_completed
8739 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8740 "f<absneg_mnemonic>"
8741 [(set_attr "type" "fsgn")
8742 (set_attr "mode" "<MODE>")])
8744 (define_insn "*<code>extendsfdf2"
8745 [(set (match_operand:DF 0 "register_operand" "=f")
8746 (absneg:DF (float_extend:DF
8747 (match_operand:SF 1 "register_operand" "0"))))]
8748 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8749 "f<absneg_mnemonic>"
8750 [(set_attr "type" "fsgn")
8751 (set_attr "mode" "DF")])
8753 (define_insn "*<code>extendsfxf2"
8754 [(set (match_operand:XF 0 "register_operand" "=f")
8755 (absneg:XF (float_extend:XF
8756 (match_operand:SF 1 "register_operand" "0"))))]
8758 "f<absneg_mnemonic>"
8759 [(set_attr "type" "fsgn")
8760 (set_attr "mode" "XF")])
8762 (define_insn "*<code>extenddfxf2"
8763 [(set (match_operand:XF 0 "register_operand" "=f")
8764 (absneg:XF (float_extend:XF
8765 (match_operand:DF 1 "register_operand" "0"))))]
8767 "f<absneg_mnemonic>"
8768 [(set_attr "type" "fsgn")
8769 (set_attr "mode" "XF")])
8771 ;; Copysign instructions
8773 (define_mode_iterator CSGNMODE [SF DF TF])
8774 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8776 (define_expand "copysign<mode>3"
8777 [(match_operand:CSGNMODE 0 "register_operand")
8778 (match_operand:CSGNMODE 1 "nonmemory_operand")
8779 (match_operand:CSGNMODE 2 "register_operand")]
8780 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8781 || (TARGET_SSE && (<MODE>mode == TFmode))"
8782 "ix86_expand_copysign (operands); DONE;")
8784 (define_insn_and_split "copysign<mode>3_const"
8785 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8787 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8788 (match_operand:CSGNMODE 2 "register_operand" "0")
8789 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8791 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8792 || (TARGET_SSE && (<MODE>mode == TFmode))"
8794 "&& reload_completed"
8796 "ix86_split_copysign_const (operands); DONE;")
8798 (define_insn "copysign<mode>3_var"
8799 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8801 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8802 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8803 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8804 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8806 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8807 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8808 || (TARGET_SSE && (<MODE>mode == TFmode))"
8812 [(set (match_operand:CSGNMODE 0 "register_operand")
8814 [(match_operand:CSGNMODE 2 "register_operand")
8815 (match_operand:CSGNMODE 3 "register_operand")
8816 (match_operand:<CSGNVMODE> 4)
8817 (match_operand:<CSGNVMODE> 5)]
8819 (clobber (match_scratch:<CSGNVMODE> 1))]
8820 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8821 || (TARGET_SSE && (<MODE>mode == TFmode)))
8822 && reload_completed"
8824 "ix86_split_copysign_var (operands); DONE;")
8826 ;; One complement instructions
8828 (define_expand "one_cmpl<mode>2"
8829 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8830 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8832 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8834 (define_insn "*one_cmpl<mode>2_1"
8835 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8836 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))]
8837 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8838 "not{<imodesuffix>}\t%0"
8839 [(set_attr "type" "negnot")
8840 (set_attr "mode" "<MODE>")])
8842 (define_insn "*one_cmplhi2_1"
8843 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
8844 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
8845 "ix86_unary_operator_ok (NOT, HImode, operands)"
8848 knotw\t{%1, %0|%0, %1}"
8849 [(set_attr "isa" "*,avx512f")
8850 (set_attr "type" "negnot,msklog")
8851 (set_attr "prefix" "*,vex")
8852 (set_attr "mode" "HI")])
8854 ;; %%% Potential partial reg stall on alternative 1. What to do?
8855 (define_insn "*one_cmplqi2_1"
8856 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
8857 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
8858 "ix86_unary_operator_ok (NOT, QImode, operands)"
8862 knotw\t{%1, %0|%0, %1}"
8863 [(set_attr "isa" "*,*,avx512f")
8864 (set_attr "type" "negnot,negnot,msklog")
8865 (set_attr "prefix" "*,*,vex")
8866 (set_attr "mode" "QI,SI,QI")])
8868 ;; ??? Currently never generated - xor is used instead.
8869 (define_insn "*one_cmplsi2_1_zext"
8870 [(set (match_operand:DI 0 "register_operand" "=r")
8872 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8873 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8875 [(set_attr "type" "negnot")
8876 (set_attr "mode" "SI")])
8878 (define_insn "*one_cmpl<mode>2_2"
8879 [(set (reg FLAGS_REG)
8880 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8882 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8883 (not:SWI (match_dup 1)))]
8884 "ix86_match_ccmode (insn, CCNOmode)
8885 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8887 [(set_attr "type" "alu1")
8888 (set_attr "mode" "<MODE>")])
8891 [(set (match_operand 0 "flags_reg_operand")
8892 (match_operator 2 "compare_operator"
8893 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8895 (set (match_operand:SWI 1 "nonimmediate_operand")
8896 (not:SWI (match_dup 3)))]
8897 "ix86_match_ccmode (insn, CCNOmode)"
8898 [(parallel [(set (match_dup 0)
8899 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8902 (xor:SWI (match_dup 3) (const_int -1)))])])
8904 ;; ??? Currently never generated - xor is used instead.
8905 (define_insn "*one_cmplsi2_2_zext"
8906 [(set (reg FLAGS_REG)
8907 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8909 (set (match_operand:DI 0 "register_operand" "=r")
8910 (zero_extend:DI (not:SI (match_dup 1))))]
8911 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8912 && ix86_unary_operator_ok (NOT, SImode, operands)"
8914 [(set_attr "type" "alu1")
8915 (set_attr "mode" "SI")])
8918 [(set (match_operand 0 "flags_reg_operand")
8919 (match_operator 2 "compare_operator"
8920 [(not:SI (match_operand:SI 3 "register_operand"))
8922 (set (match_operand:DI 1 "register_operand")
8923 (zero_extend:DI (not:SI (match_dup 3))))]
8924 "ix86_match_ccmode (insn, CCNOmode)"
8925 [(parallel [(set (match_dup 0)
8926 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8929 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8931 ;; Shift instructions
8933 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8934 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8935 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8936 ;; from the assembler input.
8938 ;; This instruction shifts the target reg/mem as usual, but instead of
8939 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8940 ;; is a left shift double, bits are taken from the high order bits of
8941 ;; reg, else if the insn is a shift right double, bits are taken from the
8942 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8943 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8945 ;; Since sh[lr]d does not change the `reg' operand, that is done
8946 ;; separately, making all shifts emit pairs of shift double and normal
8947 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8948 ;; support a 63 bit shift, each shift where the count is in a reg expands
8949 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8951 ;; If the shift count is a constant, we need never emit more than one
8952 ;; shift pair, instead using moves and sign extension for counts greater
8955 (define_expand "ashl<mode>3"
8956 [(set (match_operand:SDWIM 0 "<shift_operand>")
8957 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
8958 (match_operand:QI 2 "nonmemory_operand")))]
8960 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8962 (define_insn "*ashl<mode>3_doubleword"
8963 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8964 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8965 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8966 (clobber (reg:CC FLAGS_REG))]
8969 [(set_attr "type" "multi")])
8972 [(set (match_operand:DWI 0 "register_operand")
8973 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
8974 (match_operand:QI 2 "nonmemory_operand")))
8975 (clobber (reg:CC FLAGS_REG))]
8976 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8978 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8980 ;; By default we don't ask for a scratch register, because when DWImode
8981 ;; values are manipulated, registers are already at a premium. But if
8982 ;; we have one handy, we won't turn it away.
8985 [(match_scratch:DWIH 3 "r")
8986 (parallel [(set (match_operand:<DWI> 0 "register_operand")
8988 (match_operand:<DWI> 1 "nonmemory_operand")
8989 (match_operand:QI 2 "nonmemory_operand")))
8990 (clobber (reg:CC FLAGS_REG))])
8994 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8996 (define_insn "x86_64_shld"
8997 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8998 (ior:DI (ashift:DI (match_dup 0)
8999 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9000 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9001 (minus:QI (const_int 64) (match_dup 2)))))
9002 (clobber (reg:CC FLAGS_REG))]
9004 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9005 [(set_attr "type" "ishift")
9006 (set_attr "prefix_0f" "1")
9007 (set_attr "mode" "DI")
9008 (set_attr "athlon_decode" "vector")
9009 (set_attr "amdfam10_decode" "vector")
9010 (set_attr "bdver1_decode" "vector")])
9012 (define_insn "x86_shld"
9013 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9014 (ior:SI (ashift:SI (match_dup 0)
9015 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9016 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9017 (minus:QI (const_int 32) (match_dup 2)))))
9018 (clobber (reg:CC FLAGS_REG))]
9020 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9021 [(set_attr "type" "ishift")
9022 (set_attr "prefix_0f" "1")
9023 (set_attr "mode" "SI")
9024 (set_attr "pent_pair" "np")
9025 (set_attr "athlon_decode" "vector")
9026 (set_attr "amdfam10_decode" "vector")
9027 (set_attr "bdver1_decode" "vector")])
9029 (define_expand "x86_shift<mode>_adj_1"
9030 [(set (reg:CCZ FLAGS_REG)
9031 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9034 (set (match_operand:SWI48 0 "register_operand")
9035 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9036 (match_operand:SWI48 1 "register_operand")
9039 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9040 (match_operand:SWI48 3 "register_operand")
9043 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9045 (define_expand "x86_shift<mode>_adj_2"
9046 [(use (match_operand:SWI48 0 "register_operand"))
9047 (use (match_operand:SWI48 1 "register_operand"))
9048 (use (match_operand:QI 2 "register_operand"))]
9051 rtx label = gen_label_rtx ();
9054 emit_insn (gen_testqi_ccz_1 (operands[2],
9055 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9057 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9058 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9059 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9060 gen_rtx_LABEL_REF (VOIDmode, label),
9062 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9063 JUMP_LABEL (tmp) = label;
9065 emit_move_insn (operands[0], operands[1]);
9066 ix86_expand_clear (operands[1]);
9069 LABEL_NUSES (label) = 1;
9074 ;; Avoid useless masking of count operand.
9075 (define_insn "*ashl<mode>3_mask"
9076 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9078 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9081 (match_operand:SI 2 "register_operand" "c")
9082 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9083 (clobber (reg:CC FLAGS_REG))]
9084 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9085 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9086 == GET_MODE_BITSIZE (<MODE>mode)-1"
9088 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9090 [(set_attr "type" "ishift")
9091 (set_attr "mode" "<MODE>")])
9093 (define_insn "*bmi2_ashl<mode>3_1"
9094 [(set (match_operand:SWI48 0 "register_operand" "=r")
9095 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9096 (match_operand:SWI48 2 "register_operand" "r")))]
9098 "shlx\t{%2, %1, %0|%0, %1, %2}"
9099 [(set_attr "type" "ishiftx")
9100 (set_attr "mode" "<MODE>")])
9102 (define_insn "*ashl<mode>3_1"
9103 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9104 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9105 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9106 (clobber (reg:CC FLAGS_REG))]
9107 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9109 switch (get_attr_type (insn))
9116 gcc_assert (operands[2] == const1_rtx);
9117 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9118 return "add{<imodesuffix>}\t%0, %0";
9121 if (operands[2] == const1_rtx
9122 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9123 return "sal{<imodesuffix>}\t%0";
9125 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9128 [(set_attr "isa" "*,*,bmi2")
9130 (cond [(eq_attr "alternative" "1")
9131 (const_string "lea")
9132 (eq_attr "alternative" "2")
9133 (const_string "ishiftx")
9134 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9135 (match_operand 0 "register_operand"))
9136 (match_operand 2 "const1_operand"))
9137 (const_string "alu")
9139 (const_string "ishift")))
9140 (set (attr "length_immediate")
9142 (ior (eq_attr "type" "alu")
9143 (and (eq_attr "type" "ishift")
9144 (and (match_operand 2 "const1_operand")
9145 (ior (match_test "TARGET_SHIFT1")
9146 (match_test "optimize_function_for_size_p (cfun)")))))
9148 (const_string "*")))
9149 (set_attr "mode" "<MODE>")])
9151 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9153 [(set (match_operand:SWI48 0 "register_operand")
9154 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9155 (match_operand:QI 2 "register_operand")))
9156 (clobber (reg:CC FLAGS_REG))]
9157 "TARGET_BMI2 && reload_completed"
9159 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9160 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9162 (define_insn "*bmi2_ashlsi3_1_zext"
9163 [(set (match_operand:DI 0 "register_operand" "=r")
9165 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9166 (match_operand:SI 2 "register_operand" "r"))))]
9167 "TARGET_64BIT && TARGET_BMI2"
9168 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9169 [(set_attr "type" "ishiftx")
9170 (set_attr "mode" "SI")])
9172 (define_insn "*ashlsi3_1_zext"
9173 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9175 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9176 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9177 (clobber (reg:CC FLAGS_REG))]
9178 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9180 switch (get_attr_type (insn))
9187 gcc_assert (operands[2] == const1_rtx);
9188 return "add{l}\t%k0, %k0";
9191 if (operands[2] == const1_rtx
9192 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9193 return "sal{l}\t%k0";
9195 return "sal{l}\t{%2, %k0|%k0, %2}";
9198 [(set_attr "isa" "*,*,bmi2")
9200 (cond [(eq_attr "alternative" "1")
9201 (const_string "lea")
9202 (eq_attr "alternative" "2")
9203 (const_string "ishiftx")
9204 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9205 (match_operand 2 "const1_operand"))
9206 (const_string "alu")
9208 (const_string "ishift")))
9209 (set (attr "length_immediate")
9211 (ior (eq_attr "type" "alu")
9212 (and (eq_attr "type" "ishift")
9213 (and (match_operand 2 "const1_operand")
9214 (ior (match_test "TARGET_SHIFT1")
9215 (match_test "optimize_function_for_size_p (cfun)")))))
9217 (const_string "*")))
9218 (set_attr "mode" "SI")])
9220 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9222 [(set (match_operand:DI 0 "register_operand")
9224 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9225 (match_operand:QI 2 "register_operand"))))
9226 (clobber (reg:CC FLAGS_REG))]
9227 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9229 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9230 "operands[2] = gen_lowpart (SImode, operands[2]);")
9232 (define_insn "*ashlhi3_1"
9233 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9234 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9235 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9236 (clobber (reg:CC FLAGS_REG))]
9237 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9239 switch (get_attr_type (insn))
9245 gcc_assert (operands[2] == const1_rtx);
9246 return "add{w}\t%0, %0";
9249 if (operands[2] == const1_rtx
9250 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9251 return "sal{w}\t%0";
9253 return "sal{w}\t{%2, %0|%0, %2}";
9257 (cond [(eq_attr "alternative" "1")
9258 (const_string "lea")
9259 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9260 (match_operand 0 "register_operand"))
9261 (match_operand 2 "const1_operand"))
9262 (const_string "alu")
9264 (const_string "ishift")))
9265 (set (attr "length_immediate")
9267 (ior (eq_attr "type" "alu")
9268 (and (eq_attr "type" "ishift")
9269 (and (match_operand 2 "const1_operand")
9270 (ior (match_test "TARGET_SHIFT1")
9271 (match_test "optimize_function_for_size_p (cfun)")))))
9273 (const_string "*")))
9274 (set_attr "mode" "HI,SI")])
9276 ;; %%% Potential partial reg stall on alternative 1. What to do?
9277 (define_insn "*ashlqi3_1"
9278 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9279 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9280 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9281 (clobber (reg:CC FLAGS_REG))]
9282 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9284 switch (get_attr_type (insn))
9290 gcc_assert (operands[2] == const1_rtx);
9291 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9292 return "add{l}\t%k0, %k0";
9294 return "add{b}\t%0, %0";
9297 if (operands[2] == const1_rtx
9298 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9300 if (get_attr_mode (insn) == MODE_SI)
9301 return "sal{l}\t%k0";
9303 return "sal{b}\t%0";
9307 if (get_attr_mode (insn) == MODE_SI)
9308 return "sal{l}\t{%2, %k0|%k0, %2}";
9310 return "sal{b}\t{%2, %0|%0, %2}";
9315 (cond [(eq_attr "alternative" "2")
9316 (const_string "lea")
9317 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9318 (match_operand 0 "register_operand"))
9319 (match_operand 2 "const1_operand"))
9320 (const_string "alu")
9322 (const_string "ishift")))
9323 (set (attr "length_immediate")
9325 (ior (eq_attr "type" "alu")
9326 (and (eq_attr "type" "ishift")
9327 (and (match_operand 2 "const1_operand")
9328 (ior (match_test "TARGET_SHIFT1")
9329 (match_test "optimize_function_for_size_p (cfun)")))))
9331 (const_string "*")))
9332 (set_attr "mode" "QI,SI,SI")])
9334 (define_insn "*ashlqi3_1_slp"
9335 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9336 (ashift:QI (match_dup 0)
9337 (match_operand:QI 1 "nonmemory_operand" "cI")))
9338 (clobber (reg:CC FLAGS_REG))]
9339 "(optimize_function_for_size_p (cfun)
9340 || !TARGET_PARTIAL_FLAG_REG_STALL
9341 || (operands[1] == const1_rtx
9343 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9345 switch (get_attr_type (insn))
9348 gcc_assert (operands[1] == const1_rtx);
9349 return "add{b}\t%0, %0";
9352 if (operands[1] == const1_rtx
9353 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9354 return "sal{b}\t%0";
9356 return "sal{b}\t{%1, %0|%0, %1}";
9360 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9361 (match_operand 0 "register_operand"))
9362 (match_operand 1 "const1_operand"))
9363 (const_string "alu")
9365 (const_string "ishift1")))
9366 (set (attr "length_immediate")
9368 (ior (eq_attr "type" "alu")
9369 (and (eq_attr "type" "ishift1")
9370 (and (match_operand 1 "const1_operand")
9371 (ior (match_test "TARGET_SHIFT1")
9372 (match_test "optimize_function_for_size_p (cfun)")))))
9374 (const_string "*")))
9375 (set_attr "mode" "QI")])
9377 ;; Convert ashift to the lea pattern to avoid flags dependency.
9379 [(set (match_operand 0 "register_operand")
9380 (ashift (match_operand 1 "index_register_operand")
9381 (match_operand:QI 2 "const_int_operand")))
9382 (clobber (reg:CC FLAGS_REG))]
9383 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9385 && true_regnum (operands[0]) != true_regnum (operands[1])"
9388 enum machine_mode mode = GET_MODE (operands[0]);
9391 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9394 operands[0] = gen_lowpart (mode, operands[0]);
9395 operands[1] = gen_lowpart (mode, operands[1]);
9398 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9400 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9402 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9406 ;; Convert ashift to the lea pattern to avoid flags dependency.
9408 [(set (match_operand:DI 0 "register_operand")
9410 (ashift:SI (match_operand:SI 1 "index_register_operand")
9411 (match_operand:QI 2 "const_int_operand"))))
9412 (clobber (reg:CC FLAGS_REG))]
9413 "TARGET_64BIT && reload_completed
9414 && true_regnum (operands[0]) != true_regnum (operands[1])"
9416 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9418 operands[1] = gen_lowpart (SImode, operands[1]);
9419 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9422 ;; This pattern can't accept a variable shift count, since shifts by
9423 ;; zero don't affect the flags. We assume that shifts by constant
9424 ;; zero are optimized away.
9425 (define_insn "*ashl<mode>3_cmp"
9426 [(set (reg FLAGS_REG)
9428 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9429 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9431 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9432 (ashift:SWI (match_dup 1) (match_dup 2)))]
9433 "(optimize_function_for_size_p (cfun)
9434 || !TARGET_PARTIAL_FLAG_REG_STALL
9435 || (operands[2] == const1_rtx
9437 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9438 && ix86_match_ccmode (insn, CCGOCmode)
9439 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9441 switch (get_attr_type (insn))
9444 gcc_assert (operands[2] == const1_rtx);
9445 return "add{<imodesuffix>}\t%0, %0";
9448 if (operands[2] == const1_rtx
9449 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9450 return "sal{<imodesuffix>}\t%0";
9452 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9456 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9457 (match_operand 0 "register_operand"))
9458 (match_operand 2 "const1_operand"))
9459 (const_string "alu")
9461 (const_string "ishift")))
9462 (set (attr "length_immediate")
9464 (ior (eq_attr "type" "alu")
9465 (and (eq_attr "type" "ishift")
9466 (and (match_operand 2 "const1_operand")
9467 (ior (match_test "TARGET_SHIFT1")
9468 (match_test "optimize_function_for_size_p (cfun)")))))
9470 (const_string "*")))
9471 (set_attr "mode" "<MODE>")])
9473 (define_insn "*ashlsi3_cmp_zext"
9474 [(set (reg FLAGS_REG)
9476 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9477 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9479 (set (match_operand:DI 0 "register_operand" "=r")
9480 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9482 && (optimize_function_for_size_p (cfun)
9483 || !TARGET_PARTIAL_FLAG_REG_STALL
9484 || (operands[2] == const1_rtx
9486 || TARGET_DOUBLE_WITH_ADD)))
9487 && ix86_match_ccmode (insn, CCGOCmode)
9488 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9490 switch (get_attr_type (insn))
9493 gcc_assert (operands[2] == const1_rtx);
9494 return "add{l}\t%k0, %k0";
9497 if (operands[2] == const1_rtx
9498 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9499 return "sal{l}\t%k0";
9501 return "sal{l}\t{%2, %k0|%k0, %2}";
9505 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9506 (match_operand 2 "const1_operand"))
9507 (const_string "alu")
9509 (const_string "ishift")))
9510 (set (attr "length_immediate")
9512 (ior (eq_attr "type" "alu")
9513 (and (eq_attr "type" "ishift")
9514 (and (match_operand 2 "const1_operand")
9515 (ior (match_test "TARGET_SHIFT1")
9516 (match_test "optimize_function_for_size_p (cfun)")))))
9518 (const_string "*")))
9519 (set_attr "mode" "SI")])
9521 (define_insn "*ashl<mode>3_cconly"
9522 [(set (reg FLAGS_REG)
9524 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9525 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9527 (clobber (match_scratch:SWI 0 "=<r>"))]
9528 "(optimize_function_for_size_p (cfun)
9529 || !TARGET_PARTIAL_FLAG_REG_STALL
9530 || (operands[2] == const1_rtx
9532 || TARGET_DOUBLE_WITH_ADD)))
9533 && ix86_match_ccmode (insn, CCGOCmode)"
9535 switch (get_attr_type (insn))
9538 gcc_assert (operands[2] == const1_rtx);
9539 return "add{<imodesuffix>}\t%0, %0";
9542 if (operands[2] == const1_rtx
9543 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9544 return "sal{<imodesuffix>}\t%0";
9546 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9550 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9551 (match_operand 0 "register_operand"))
9552 (match_operand 2 "const1_operand"))
9553 (const_string "alu")
9555 (const_string "ishift")))
9556 (set (attr "length_immediate")
9558 (ior (eq_attr "type" "alu")
9559 (and (eq_attr "type" "ishift")
9560 (and (match_operand 2 "const1_operand")
9561 (ior (match_test "TARGET_SHIFT1")
9562 (match_test "optimize_function_for_size_p (cfun)")))))
9564 (const_string "*")))
9565 (set_attr "mode" "<MODE>")])
9567 ;; See comment above `ashl<mode>3' about how this works.
9569 (define_expand "<shift_insn><mode>3"
9570 [(set (match_operand:SDWIM 0 "<shift_operand>")
9571 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9572 (match_operand:QI 2 "nonmemory_operand")))]
9574 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9576 ;; Avoid useless masking of count operand.
9577 (define_insn "*<shift_insn><mode>3_mask"
9578 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9580 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9583 (match_operand:SI 2 "register_operand" "c")
9584 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9585 (clobber (reg:CC FLAGS_REG))]
9586 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9587 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9588 == GET_MODE_BITSIZE (<MODE>mode)-1"
9590 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9592 [(set_attr "type" "ishift")
9593 (set_attr "mode" "<MODE>")])
9595 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9596 [(set (match_operand:DWI 0 "register_operand" "=r")
9597 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9598 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9599 (clobber (reg:CC FLAGS_REG))]
9602 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9604 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9605 [(set_attr "type" "multi")])
9607 ;; By default we don't ask for a scratch register, because when DWImode
9608 ;; values are manipulated, registers are already at a premium. But if
9609 ;; we have one handy, we won't turn it away.
9612 [(match_scratch:DWIH 3 "r")
9613 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9615 (match_operand:<DWI> 1 "register_operand")
9616 (match_operand:QI 2 "nonmemory_operand")))
9617 (clobber (reg:CC FLAGS_REG))])
9621 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9623 (define_insn "x86_64_shrd"
9624 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9625 (ior:DI (ashiftrt:DI (match_dup 0)
9626 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9627 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9628 (minus:QI (const_int 64) (match_dup 2)))))
9629 (clobber (reg:CC FLAGS_REG))]
9631 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9632 [(set_attr "type" "ishift")
9633 (set_attr "prefix_0f" "1")
9634 (set_attr "mode" "DI")
9635 (set_attr "athlon_decode" "vector")
9636 (set_attr "amdfam10_decode" "vector")
9637 (set_attr "bdver1_decode" "vector")])
9639 (define_insn "x86_shrd"
9640 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9641 (ior:SI (ashiftrt:SI (match_dup 0)
9642 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9643 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9644 (minus:QI (const_int 32) (match_dup 2)))))
9645 (clobber (reg:CC FLAGS_REG))]
9647 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9648 [(set_attr "type" "ishift")
9649 (set_attr "prefix_0f" "1")
9650 (set_attr "mode" "SI")
9651 (set_attr "pent_pair" "np")
9652 (set_attr "athlon_decode" "vector")
9653 (set_attr "amdfam10_decode" "vector")
9654 (set_attr "bdver1_decode" "vector")])
9656 (define_insn "ashrdi3_cvt"
9657 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9658 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9659 (match_operand:QI 2 "const_int_operand")))
9660 (clobber (reg:CC FLAGS_REG))]
9661 "TARGET_64BIT && INTVAL (operands[2]) == 63
9662 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9663 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9666 sar{q}\t{%2, %0|%0, %2}"
9667 [(set_attr "type" "imovx,ishift")
9668 (set_attr "prefix_0f" "0,*")
9669 (set_attr "length_immediate" "0,*")
9670 (set_attr "modrm" "0,1")
9671 (set_attr "mode" "DI")])
9673 (define_insn "ashrsi3_cvt"
9674 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9675 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9676 (match_operand:QI 2 "const_int_operand")))
9677 (clobber (reg:CC FLAGS_REG))]
9678 "INTVAL (operands[2]) == 31
9679 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9680 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9683 sar{l}\t{%2, %0|%0, %2}"
9684 [(set_attr "type" "imovx,ishift")
9685 (set_attr "prefix_0f" "0,*")
9686 (set_attr "length_immediate" "0,*")
9687 (set_attr "modrm" "0,1")
9688 (set_attr "mode" "SI")])
9690 (define_insn "*ashrsi3_cvt_zext"
9691 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9693 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9694 (match_operand:QI 2 "const_int_operand"))))
9695 (clobber (reg:CC FLAGS_REG))]
9696 "TARGET_64BIT && INTVAL (operands[2]) == 31
9697 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9698 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9701 sar{l}\t{%2, %k0|%k0, %2}"
9702 [(set_attr "type" "imovx,ishift")
9703 (set_attr "prefix_0f" "0,*")
9704 (set_attr "length_immediate" "0,*")
9705 (set_attr "modrm" "0,1")
9706 (set_attr "mode" "SI")])
9708 (define_expand "x86_shift<mode>_adj_3"
9709 [(use (match_operand:SWI48 0 "register_operand"))
9710 (use (match_operand:SWI48 1 "register_operand"))
9711 (use (match_operand:QI 2 "register_operand"))]
9714 rtx label = gen_label_rtx ();
9717 emit_insn (gen_testqi_ccz_1 (operands[2],
9718 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9720 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9721 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9722 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9723 gen_rtx_LABEL_REF (VOIDmode, label),
9725 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9726 JUMP_LABEL (tmp) = label;
9728 emit_move_insn (operands[0], operands[1]);
9729 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9730 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9732 LABEL_NUSES (label) = 1;
9737 (define_insn "*bmi2_<shift_insn><mode>3_1"
9738 [(set (match_operand:SWI48 0 "register_operand" "=r")
9739 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9740 (match_operand:SWI48 2 "register_operand" "r")))]
9742 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9743 [(set_attr "type" "ishiftx")
9744 (set_attr "mode" "<MODE>")])
9746 (define_insn "*<shift_insn><mode>3_1"
9747 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9749 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9750 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9751 (clobber (reg:CC FLAGS_REG))]
9752 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9754 switch (get_attr_type (insn))
9760 if (operands[2] == const1_rtx
9761 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9762 return "<shift>{<imodesuffix>}\t%0";
9764 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9767 [(set_attr "isa" "*,bmi2")
9768 (set_attr "type" "ishift,ishiftx")
9769 (set (attr "length_immediate")
9771 (and (match_operand 2 "const1_operand")
9772 (ior (match_test "TARGET_SHIFT1")
9773 (match_test "optimize_function_for_size_p (cfun)")))
9775 (const_string "*")))
9776 (set_attr "mode" "<MODE>")])
9778 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9780 [(set (match_operand:SWI48 0 "register_operand")
9781 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9782 (match_operand:QI 2 "register_operand")))
9783 (clobber (reg:CC FLAGS_REG))]
9784 "TARGET_BMI2 && reload_completed"
9786 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9787 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9789 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9790 [(set (match_operand:DI 0 "register_operand" "=r")
9792 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9793 (match_operand:SI 2 "register_operand" "r"))))]
9794 "TARGET_64BIT && TARGET_BMI2"
9795 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9796 [(set_attr "type" "ishiftx")
9797 (set_attr "mode" "SI")])
9799 (define_insn "*<shift_insn>si3_1_zext"
9800 [(set (match_operand:DI 0 "register_operand" "=r,r")
9802 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9803 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9804 (clobber (reg:CC FLAGS_REG))]
9805 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9807 switch (get_attr_type (insn))
9813 if (operands[2] == const1_rtx
9814 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9815 return "<shift>{l}\t%k0";
9817 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9820 [(set_attr "isa" "*,bmi2")
9821 (set_attr "type" "ishift,ishiftx")
9822 (set (attr "length_immediate")
9824 (and (match_operand 2 "const1_operand")
9825 (ior (match_test "TARGET_SHIFT1")
9826 (match_test "optimize_function_for_size_p (cfun)")))
9828 (const_string "*")))
9829 (set_attr "mode" "SI")])
9831 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9833 [(set (match_operand:DI 0 "register_operand")
9835 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9836 (match_operand:QI 2 "register_operand"))))
9837 (clobber (reg:CC FLAGS_REG))]
9838 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9840 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9841 "operands[2] = gen_lowpart (SImode, operands[2]);")
9843 (define_insn "*<shift_insn><mode>3_1"
9844 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9846 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9847 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9848 (clobber (reg:CC FLAGS_REG))]
9849 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9851 if (operands[2] == const1_rtx
9852 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9853 return "<shift>{<imodesuffix>}\t%0";
9855 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9857 [(set_attr "type" "ishift")
9858 (set (attr "length_immediate")
9860 (and (match_operand 2 "const1_operand")
9861 (ior (match_test "TARGET_SHIFT1")
9862 (match_test "optimize_function_for_size_p (cfun)")))
9864 (const_string "*")))
9865 (set_attr "mode" "<MODE>")])
9867 (define_insn "*<shift_insn>qi3_1_slp"
9868 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9869 (any_shiftrt:QI (match_dup 0)
9870 (match_operand:QI 1 "nonmemory_operand" "cI")))
9871 (clobber (reg:CC FLAGS_REG))]
9872 "(optimize_function_for_size_p (cfun)
9873 || !TARGET_PARTIAL_REG_STALL
9874 || (operands[1] == const1_rtx
9877 if (operands[1] == const1_rtx
9878 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9879 return "<shift>{b}\t%0";
9881 return "<shift>{b}\t{%1, %0|%0, %1}";
9883 [(set_attr "type" "ishift1")
9884 (set (attr "length_immediate")
9886 (and (match_operand 1 "const1_operand")
9887 (ior (match_test "TARGET_SHIFT1")
9888 (match_test "optimize_function_for_size_p (cfun)")))
9890 (const_string "*")))
9891 (set_attr "mode" "QI")])
9893 ;; This pattern can't accept a variable shift count, since shifts by
9894 ;; zero don't affect the flags. We assume that shifts by constant
9895 ;; zero are optimized away.
9896 (define_insn "*<shift_insn><mode>3_cmp"
9897 [(set (reg FLAGS_REG)
9900 (match_operand:SWI 1 "nonimmediate_operand" "0")
9901 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9903 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9904 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9905 "(optimize_function_for_size_p (cfun)
9906 || !TARGET_PARTIAL_FLAG_REG_STALL
9907 || (operands[2] == const1_rtx
9909 && ix86_match_ccmode (insn, CCGOCmode)
9910 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9912 if (operands[2] == const1_rtx
9913 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9914 return "<shift>{<imodesuffix>}\t%0";
9916 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9918 [(set_attr "type" "ishift")
9919 (set (attr "length_immediate")
9921 (and (match_operand 2 "const1_operand")
9922 (ior (match_test "TARGET_SHIFT1")
9923 (match_test "optimize_function_for_size_p (cfun)")))
9925 (const_string "*")))
9926 (set_attr "mode" "<MODE>")])
9928 (define_insn "*<shift_insn>si3_cmp_zext"
9929 [(set (reg FLAGS_REG)
9931 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9932 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9934 (set (match_operand:DI 0 "register_operand" "=r")
9935 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9937 && (optimize_function_for_size_p (cfun)
9938 || !TARGET_PARTIAL_FLAG_REG_STALL
9939 || (operands[2] == const1_rtx
9941 && ix86_match_ccmode (insn, CCGOCmode)
9942 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9944 if (operands[2] == const1_rtx
9945 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9946 return "<shift>{l}\t%k0";
9948 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9950 [(set_attr "type" "ishift")
9951 (set (attr "length_immediate")
9953 (and (match_operand 2 "const1_operand")
9954 (ior (match_test "TARGET_SHIFT1")
9955 (match_test "optimize_function_for_size_p (cfun)")))
9957 (const_string "*")))
9958 (set_attr "mode" "SI")])
9960 (define_insn "*<shift_insn><mode>3_cconly"
9961 [(set (reg FLAGS_REG)
9964 (match_operand:SWI 1 "register_operand" "0")
9965 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9967 (clobber (match_scratch:SWI 0 "=<r>"))]
9968 "(optimize_function_for_size_p (cfun)
9969 || !TARGET_PARTIAL_FLAG_REG_STALL
9970 || (operands[2] == const1_rtx
9972 && ix86_match_ccmode (insn, CCGOCmode)"
9974 if (operands[2] == const1_rtx
9975 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9976 return "<shift>{<imodesuffix>}\t%0";
9978 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9980 [(set_attr "type" "ishift")
9981 (set (attr "length_immediate")
9983 (and (match_operand 2 "const1_operand")
9984 (ior (match_test "TARGET_SHIFT1")
9985 (match_test "optimize_function_for_size_p (cfun)")))
9987 (const_string "*")))
9988 (set_attr "mode" "<MODE>")])
9990 ;; Rotate instructions
9992 (define_expand "<rotate_insn>ti3"
9993 [(set (match_operand:TI 0 "register_operand")
9994 (any_rotate:TI (match_operand:TI 1 "register_operand")
9995 (match_operand:QI 2 "nonmemory_operand")))]
9998 if (const_1_to_63_operand (operands[2], VOIDmode))
9999 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10000 (operands[0], operands[1], operands[2]));
10007 (define_expand "<rotate_insn>di3"
10008 [(set (match_operand:DI 0 "shiftdi_operand")
10009 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10010 (match_operand:QI 2 "nonmemory_operand")))]
10014 ix86_expand_binary_operator (<CODE>, DImode, operands);
10015 else if (const_1_to_31_operand (operands[2], VOIDmode))
10016 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10017 (operands[0], operands[1], operands[2]));
10024 (define_expand "<rotate_insn><mode>3"
10025 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10026 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10027 (match_operand:QI 2 "nonmemory_operand")))]
10029 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10031 ;; Avoid useless masking of count operand.
10032 (define_insn "*<rotate_insn><mode>3_mask"
10033 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10035 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10038 (match_operand:SI 2 "register_operand" "c")
10039 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10040 (clobber (reg:CC FLAGS_REG))]
10041 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10042 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10043 == GET_MODE_BITSIZE (<MODE>mode)-1"
10045 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10047 [(set_attr "type" "rotate")
10048 (set_attr "mode" "<MODE>")])
10050 ;; Implement rotation using two double-precision
10051 ;; shift instructions and a scratch register.
10053 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10054 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10055 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10056 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10057 (clobber (reg:CC FLAGS_REG))
10058 (clobber (match_scratch:DWIH 3 "=&r"))]
10062 [(set (match_dup 3) (match_dup 4))
10064 [(set (match_dup 4)
10065 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10066 (lshiftrt:DWIH (match_dup 5)
10067 (minus:QI (match_dup 6) (match_dup 2)))))
10068 (clobber (reg:CC FLAGS_REG))])
10070 [(set (match_dup 5)
10071 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10072 (lshiftrt:DWIH (match_dup 3)
10073 (minus:QI (match_dup 6) (match_dup 2)))))
10074 (clobber (reg:CC FLAGS_REG))])]
10076 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10078 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10081 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10082 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10083 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10084 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10085 (clobber (reg:CC FLAGS_REG))
10086 (clobber (match_scratch:DWIH 3 "=&r"))]
10090 [(set (match_dup 3) (match_dup 4))
10092 [(set (match_dup 4)
10093 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10094 (ashift:DWIH (match_dup 5)
10095 (minus:QI (match_dup 6) (match_dup 2)))))
10096 (clobber (reg:CC FLAGS_REG))])
10098 [(set (match_dup 5)
10099 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10100 (ashift:DWIH (match_dup 3)
10101 (minus:QI (match_dup 6) (match_dup 2)))))
10102 (clobber (reg:CC FLAGS_REG))])]
10104 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10106 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10109 (define_insn "*bmi2_rorx<mode>3_1"
10110 [(set (match_operand:SWI48 0 "register_operand" "=r")
10111 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10112 (match_operand:QI 2 "immediate_operand" "<S>")))]
10114 "rorx\t{%2, %1, %0|%0, %1, %2}"
10115 [(set_attr "type" "rotatex")
10116 (set_attr "mode" "<MODE>")])
10118 (define_insn "*<rotate_insn><mode>3_1"
10119 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10121 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10122 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10123 (clobber (reg:CC FLAGS_REG))]
10124 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10126 switch (get_attr_type (insn))
10132 if (operands[2] == const1_rtx
10133 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10134 return "<rotate>{<imodesuffix>}\t%0";
10136 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10139 [(set_attr "isa" "*,bmi2")
10140 (set_attr "type" "rotate,rotatex")
10141 (set (attr "length_immediate")
10143 (and (eq_attr "type" "rotate")
10144 (and (match_operand 2 "const1_operand")
10145 (ior (match_test "TARGET_SHIFT1")
10146 (match_test "optimize_function_for_size_p (cfun)"))))
10148 (const_string "*")))
10149 (set_attr "mode" "<MODE>")])
10151 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10153 [(set (match_operand:SWI48 0 "register_operand")
10154 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10155 (match_operand:QI 2 "immediate_operand")))
10156 (clobber (reg:CC FLAGS_REG))]
10157 "TARGET_BMI2 && reload_completed"
10158 [(set (match_dup 0)
10159 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10162 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10166 [(set (match_operand:SWI48 0 "register_operand")
10167 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10168 (match_operand:QI 2 "immediate_operand")))
10169 (clobber (reg:CC FLAGS_REG))]
10170 "TARGET_BMI2 && reload_completed"
10171 [(set (match_dup 0)
10172 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10174 (define_insn "*bmi2_rorxsi3_1_zext"
10175 [(set (match_operand:DI 0 "register_operand" "=r")
10177 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10178 (match_operand:QI 2 "immediate_operand" "I"))))]
10179 "TARGET_64BIT && TARGET_BMI2"
10180 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10181 [(set_attr "type" "rotatex")
10182 (set_attr "mode" "SI")])
10184 (define_insn "*<rotate_insn>si3_1_zext"
10185 [(set (match_operand:DI 0 "register_operand" "=r,r")
10187 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10188 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10189 (clobber (reg:CC FLAGS_REG))]
10190 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10192 switch (get_attr_type (insn))
10198 if (operands[2] == const1_rtx
10199 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10200 return "<rotate>{l}\t%k0";
10202 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10205 [(set_attr "isa" "*,bmi2")
10206 (set_attr "type" "rotate,rotatex")
10207 (set (attr "length_immediate")
10209 (and (eq_attr "type" "rotate")
10210 (and (match_operand 2 "const1_operand")
10211 (ior (match_test "TARGET_SHIFT1")
10212 (match_test "optimize_function_for_size_p (cfun)"))))
10214 (const_string "*")))
10215 (set_attr "mode" "SI")])
10217 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10219 [(set (match_operand:DI 0 "register_operand")
10221 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10222 (match_operand:QI 2 "immediate_operand"))))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10225 [(set (match_dup 0)
10226 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10229 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10233 [(set (match_operand:DI 0 "register_operand")
10235 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10236 (match_operand:QI 2 "immediate_operand"))))
10237 (clobber (reg:CC FLAGS_REG))]
10238 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10239 [(set (match_dup 0)
10240 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10242 (define_insn "*<rotate_insn><mode>3_1"
10243 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10244 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10245 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10246 (clobber (reg:CC FLAGS_REG))]
10247 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10249 if (operands[2] == const1_rtx
10250 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10251 return "<rotate>{<imodesuffix>}\t%0";
10253 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10255 [(set_attr "type" "rotate")
10256 (set (attr "length_immediate")
10258 (and (match_operand 2 "const1_operand")
10259 (ior (match_test "TARGET_SHIFT1")
10260 (match_test "optimize_function_for_size_p (cfun)")))
10262 (const_string "*")))
10263 (set_attr "mode" "<MODE>")])
10265 (define_insn "*<rotate_insn>qi3_1_slp"
10266 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10267 (any_rotate:QI (match_dup 0)
10268 (match_operand:QI 1 "nonmemory_operand" "cI")))
10269 (clobber (reg:CC FLAGS_REG))]
10270 "(optimize_function_for_size_p (cfun)
10271 || !TARGET_PARTIAL_REG_STALL
10272 || (operands[1] == const1_rtx
10273 && TARGET_SHIFT1))"
10275 if (operands[1] == const1_rtx
10276 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10277 return "<rotate>{b}\t%0";
10279 return "<rotate>{b}\t{%1, %0|%0, %1}";
10281 [(set_attr "type" "rotate1")
10282 (set (attr "length_immediate")
10284 (and (match_operand 1 "const1_operand")
10285 (ior (match_test "TARGET_SHIFT1")
10286 (match_test "optimize_function_for_size_p (cfun)")))
10288 (const_string "*")))
10289 (set_attr "mode" "QI")])
10292 [(set (match_operand:HI 0 "register_operand")
10293 (any_rotate:HI (match_dup 0) (const_int 8)))
10294 (clobber (reg:CC FLAGS_REG))]
10296 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10297 [(parallel [(set (strict_low_part (match_dup 0))
10298 (bswap:HI (match_dup 0)))
10299 (clobber (reg:CC FLAGS_REG))])])
10301 ;; Bit set / bit test instructions
10303 (define_expand "extv"
10304 [(set (match_operand:SI 0 "register_operand")
10305 (sign_extract:SI (match_operand:SI 1 "register_operand")
10306 (match_operand:SI 2 "const8_operand")
10307 (match_operand:SI 3 "const8_operand")))]
10310 /* Handle extractions from %ah et al. */
10311 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10314 /* From mips.md: extract_bit_field doesn't verify that our source
10315 matches the predicate, so check it again here. */
10316 if (! ext_register_operand (operands[1], VOIDmode))
10320 (define_expand "extzv"
10321 [(set (match_operand:SI 0 "register_operand")
10322 (zero_extract:SI (match_operand 1 "ext_register_operand")
10323 (match_operand:SI 2 "const8_operand")
10324 (match_operand:SI 3 "const8_operand")))]
10327 /* Handle extractions from %ah et al. */
10328 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10331 /* From mips.md: extract_bit_field doesn't verify that our source
10332 matches the predicate, so check it again here. */
10333 if (! ext_register_operand (operands[1], VOIDmode))
10337 (define_expand "insv"
10338 [(set (zero_extract (match_operand 0 "register_operand")
10339 (match_operand 1 "const_int_operand")
10340 (match_operand 2 "const_int_operand"))
10341 (match_operand 3 "register_operand"))]
10344 rtx (*gen_mov_insv_1) (rtx, rtx);
10346 if (ix86_expand_pinsr (operands))
10349 /* Handle insertions to %ah et al. */
10350 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10353 /* From mips.md: insert_bit_field doesn't verify that our source
10354 matches the predicate, so check it again here. */
10355 if (! ext_register_operand (operands[0], VOIDmode))
10358 gen_mov_insv_1 = (TARGET_64BIT
10359 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10361 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10365 ;; %%% bts, btr, btc, bt.
10366 ;; In general these instructions are *slow* when applied to memory,
10367 ;; since they enforce atomic operation. When applied to registers,
10368 ;; it depends on the cpu implementation. They're never faster than
10369 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10370 ;; no point. But in 64-bit, we can't hold the relevant immediates
10371 ;; within the instruction itself, so operating on bits in the high
10372 ;; 32-bits of a register becomes easier.
10374 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10375 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10376 ;; negdf respectively, so they can never be disabled entirely.
10378 (define_insn "*btsq"
10379 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10381 (match_operand:DI 1 "const_0_to_63_operand"))
10383 (clobber (reg:CC FLAGS_REG))]
10384 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10385 "bts{q}\t{%1, %0|%0, %1}"
10386 [(set_attr "type" "alu1")
10387 (set_attr "prefix_0f" "1")
10388 (set_attr "mode" "DI")])
10390 (define_insn "*btrq"
10391 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10393 (match_operand:DI 1 "const_0_to_63_operand"))
10395 (clobber (reg:CC FLAGS_REG))]
10396 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10397 "btr{q}\t{%1, %0|%0, %1}"
10398 [(set_attr "type" "alu1")
10399 (set_attr "prefix_0f" "1")
10400 (set_attr "mode" "DI")])
10402 (define_insn "*btcq"
10403 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10405 (match_operand:DI 1 "const_0_to_63_operand"))
10406 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10407 (clobber (reg:CC FLAGS_REG))]
10408 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10409 "btc{q}\t{%1, %0|%0, %1}"
10410 [(set_attr "type" "alu1")
10411 (set_attr "prefix_0f" "1")
10412 (set_attr "mode" "DI")])
10414 ;; Allow Nocona to avoid these instructions if a register is available.
10417 [(match_scratch:DI 2 "r")
10418 (parallel [(set (zero_extract:DI
10419 (match_operand:DI 0 "register_operand")
10421 (match_operand:DI 1 "const_0_to_63_operand"))
10423 (clobber (reg:CC FLAGS_REG))])]
10424 "TARGET_64BIT && !TARGET_USE_BT"
10427 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10430 if (HOST_BITS_PER_WIDE_INT >= 64)
10431 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10432 else if (i < HOST_BITS_PER_WIDE_INT)
10433 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10435 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10437 op1 = immed_double_const (lo, hi, DImode);
10440 emit_move_insn (operands[2], op1);
10444 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10449 [(match_scratch:DI 2 "r")
10450 (parallel [(set (zero_extract:DI
10451 (match_operand:DI 0 "register_operand")
10453 (match_operand:DI 1 "const_0_to_63_operand"))
10455 (clobber (reg:CC FLAGS_REG))])]
10456 "TARGET_64BIT && !TARGET_USE_BT"
10459 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10462 if (HOST_BITS_PER_WIDE_INT >= 64)
10463 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10464 else if (i < HOST_BITS_PER_WIDE_INT)
10465 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10467 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10469 op1 = immed_double_const (~lo, ~hi, DImode);
10472 emit_move_insn (operands[2], op1);
10476 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10481 [(match_scratch:DI 2 "r")
10482 (parallel [(set (zero_extract:DI
10483 (match_operand:DI 0 "register_operand")
10485 (match_operand:DI 1 "const_0_to_63_operand"))
10486 (not:DI (zero_extract:DI
10487 (match_dup 0) (const_int 1) (match_dup 1))))
10488 (clobber (reg:CC FLAGS_REG))])]
10489 "TARGET_64BIT && !TARGET_USE_BT"
10492 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10495 if (HOST_BITS_PER_WIDE_INT >= 64)
10496 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10497 else if (i < HOST_BITS_PER_WIDE_INT)
10498 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10500 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10502 op1 = immed_double_const (lo, hi, DImode);
10505 emit_move_insn (operands[2], op1);
10509 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10513 (define_insn "*bt<mode>"
10514 [(set (reg:CCC FLAGS_REG)
10516 (zero_extract:SWI48
10517 (match_operand:SWI48 0 "register_operand" "r")
10519 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10521 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10522 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10523 [(set_attr "type" "alu1")
10524 (set_attr "prefix_0f" "1")
10525 (set_attr "mode" "<MODE>")])
10527 ;; Store-flag instructions.
10529 ;; For all sCOND expanders, also expand the compare or test insn that
10530 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10532 (define_insn_and_split "*setcc_di_1"
10533 [(set (match_operand:DI 0 "register_operand" "=q")
10534 (match_operator:DI 1 "ix86_comparison_operator"
10535 [(reg FLAGS_REG) (const_int 0)]))]
10536 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10538 "&& reload_completed"
10539 [(set (match_dup 2) (match_dup 1))
10540 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10542 PUT_MODE (operands[1], QImode);
10543 operands[2] = gen_lowpart (QImode, operands[0]);
10546 (define_insn_and_split "*setcc_si_1_and"
10547 [(set (match_operand:SI 0 "register_operand" "=q")
10548 (match_operator:SI 1 "ix86_comparison_operator"
10549 [(reg FLAGS_REG) (const_int 0)]))
10550 (clobber (reg:CC FLAGS_REG))]
10551 "!TARGET_PARTIAL_REG_STALL
10552 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10554 "&& reload_completed"
10555 [(set (match_dup 2) (match_dup 1))
10556 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10557 (clobber (reg:CC FLAGS_REG))])]
10559 PUT_MODE (operands[1], QImode);
10560 operands[2] = gen_lowpart (QImode, operands[0]);
10563 (define_insn_and_split "*setcc_si_1_movzbl"
10564 [(set (match_operand:SI 0 "register_operand" "=q")
10565 (match_operator:SI 1 "ix86_comparison_operator"
10566 [(reg FLAGS_REG) (const_int 0)]))]
10567 "!TARGET_PARTIAL_REG_STALL
10568 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10570 "&& reload_completed"
10571 [(set (match_dup 2) (match_dup 1))
10572 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10574 PUT_MODE (operands[1], QImode);
10575 operands[2] = gen_lowpart (QImode, operands[0]);
10578 (define_insn "*setcc_qi"
10579 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10580 (match_operator:QI 1 "ix86_comparison_operator"
10581 [(reg FLAGS_REG) (const_int 0)]))]
10584 [(set_attr "type" "setcc")
10585 (set_attr "mode" "QI")])
10587 (define_insn "*setcc_qi_slp"
10588 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10589 (match_operator:QI 1 "ix86_comparison_operator"
10590 [(reg FLAGS_REG) (const_int 0)]))]
10593 [(set_attr "type" "setcc")
10594 (set_attr "mode" "QI")])
10596 ;; In general it is not safe to assume too much about CCmode registers,
10597 ;; so simplify-rtx stops when it sees a second one. Under certain
10598 ;; conditions this is safe on x86, so help combine not create
10605 [(set (match_operand:QI 0 "nonimmediate_operand")
10606 (ne:QI (match_operator 1 "ix86_comparison_operator"
10607 [(reg FLAGS_REG) (const_int 0)])
10610 [(set (match_dup 0) (match_dup 1))]
10611 "PUT_MODE (operands[1], QImode);")
10614 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10615 (ne:QI (match_operator 1 "ix86_comparison_operator"
10616 [(reg FLAGS_REG) (const_int 0)])
10619 [(set (match_dup 0) (match_dup 1))]
10620 "PUT_MODE (operands[1], QImode);")
10623 [(set (match_operand:QI 0 "nonimmediate_operand")
10624 (eq:QI (match_operator 1 "ix86_comparison_operator"
10625 [(reg FLAGS_REG) (const_int 0)])
10628 [(set (match_dup 0) (match_dup 1))]
10630 rtx new_op1 = copy_rtx (operands[1]);
10631 operands[1] = new_op1;
10632 PUT_MODE (new_op1, QImode);
10633 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10634 GET_MODE (XEXP (new_op1, 0))));
10636 /* Make sure that (a) the CCmode we have for the flags is strong
10637 enough for the reversed compare or (b) we have a valid FP compare. */
10638 if (! ix86_comparison_operator (new_op1, VOIDmode))
10643 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10644 (eq:QI (match_operator 1 "ix86_comparison_operator"
10645 [(reg FLAGS_REG) (const_int 0)])
10648 [(set (match_dup 0) (match_dup 1))]
10650 rtx new_op1 = copy_rtx (operands[1]);
10651 operands[1] = new_op1;
10652 PUT_MODE (new_op1, QImode);
10653 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10654 GET_MODE (XEXP (new_op1, 0))));
10656 /* Make sure that (a) the CCmode we have for the flags is strong
10657 enough for the reversed compare or (b) we have a valid FP compare. */
10658 if (! ix86_comparison_operator (new_op1, VOIDmode))
10662 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10663 ;; subsequent logical operations are used to imitate conditional moves.
10664 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10667 (define_insn "setcc_<mode>_sse"
10668 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10669 (match_operator:MODEF 3 "sse_comparison_operator"
10670 [(match_operand:MODEF 1 "register_operand" "0,x")
10671 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10672 "SSE_FLOAT_MODE_P (<MODE>mode)"
10674 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10675 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10676 [(set_attr "isa" "noavx,avx")
10677 (set_attr "type" "ssecmp")
10678 (set_attr "length_immediate" "1")
10679 (set_attr "prefix" "orig,vex")
10680 (set_attr "mode" "<MODE>")])
10682 ;; Basic conditional jump instructions.
10683 ;; We ignore the overflow flag for signed branch instructions.
10685 (define_insn "*jcc_1"
10687 (if_then_else (match_operator 1 "ix86_comparison_operator"
10688 [(reg FLAGS_REG) (const_int 0)])
10689 (label_ref (match_operand 0))
10693 [(set_attr "type" "ibr")
10694 (set_attr "modrm" "0")
10695 (set (attr "length")
10696 (if_then_else (and (ge (minus (match_dup 0) (pc))
10698 (lt (minus (match_dup 0) (pc))
10703 (define_insn "*jcc_2"
10705 (if_then_else (match_operator 1 "ix86_comparison_operator"
10706 [(reg FLAGS_REG) (const_int 0)])
10708 (label_ref (match_operand 0))))]
10711 [(set_attr "type" "ibr")
10712 (set_attr "modrm" "0")
10713 (set (attr "length")
10714 (if_then_else (and (ge (minus (match_dup 0) (pc))
10716 (lt (minus (match_dup 0) (pc))
10721 ;; In general it is not safe to assume too much about CCmode registers,
10722 ;; so simplify-rtx stops when it sees a second one. Under certain
10723 ;; conditions this is safe on x86, so help combine not create
10731 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10732 [(reg FLAGS_REG) (const_int 0)])
10734 (label_ref (match_operand 1))
10738 (if_then_else (match_dup 0)
10739 (label_ref (match_dup 1))
10741 "PUT_MODE (operands[0], VOIDmode);")
10745 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10746 [(reg FLAGS_REG) (const_int 0)])
10748 (label_ref (match_operand 1))
10752 (if_then_else (match_dup 0)
10753 (label_ref (match_dup 1))
10756 rtx new_op0 = copy_rtx (operands[0]);
10757 operands[0] = new_op0;
10758 PUT_MODE (new_op0, VOIDmode);
10759 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10760 GET_MODE (XEXP (new_op0, 0))));
10762 /* Make sure that (a) the CCmode we have for the flags is strong
10763 enough for the reversed compare or (b) we have a valid FP compare. */
10764 if (! ix86_comparison_operator (new_op0, VOIDmode))
10768 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10769 ;; pass generates from shift insn with QImode operand. Actually, the mode
10770 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10771 ;; appropriate modulo of the bit offset value.
10773 (define_insn_and_split "*jcc_bt<mode>"
10775 (if_then_else (match_operator 0 "bt_comparison_operator"
10776 [(zero_extract:SWI48
10777 (match_operand:SWI48 1 "register_operand" "r")
10780 (match_operand:QI 2 "register_operand" "r")))
10782 (label_ref (match_operand 3))
10784 (clobber (reg:CC FLAGS_REG))]
10785 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10788 [(set (reg:CCC FLAGS_REG)
10790 (zero_extract:SWI48
10796 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10797 (label_ref (match_dup 3))
10800 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10802 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10805 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10806 ;; zero extended to SImode.
10807 (define_insn_and_split "*jcc_bt<mode>_1"
10809 (if_then_else (match_operator 0 "bt_comparison_operator"
10810 [(zero_extract:SWI48
10811 (match_operand:SWI48 1 "register_operand" "r")
10813 (match_operand:SI 2 "register_operand" "r"))
10815 (label_ref (match_operand 3))
10817 (clobber (reg:CC FLAGS_REG))]
10818 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10821 [(set (reg:CCC FLAGS_REG)
10823 (zero_extract:SWI48
10829 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10830 (label_ref (match_dup 3))
10833 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10835 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10838 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10839 ;; also for DImode, this is what combine produces.
10840 (define_insn_and_split "*jcc_bt<mode>_mask"
10842 (if_then_else (match_operator 0 "bt_comparison_operator"
10843 [(zero_extract:SWI48
10844 (match_operand:SWI48 1 "register_operand" "r")
10847 (match_operand:SI 2 "register_operand" "r")
10848 (match_operand:SI 3 "const_int_operand" "n")))])
10849 (label_ref (match_operand 4))
10851 (clobber (reg:CC FLAGS_REG))]
10852 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10853 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10854 == GET_MODE_BITSIZE (<MODE>mode)-1"
10857 [(set (reg:CCC FLAGS_REG)
10859 (zero_extract:SWI48
10865 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10866 (label_ref (match_dup 4))
10869 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10871 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10874 (define_insn_and_split "*jcc_btsi_1"
10876 (if_then_else (match_operator 0 "bt_comparison_operator"
10879 (match_operand:SI 1 "register_operand" "r")
10880 (match_operand:QI 2 "register_operand" "r"))
10883 (label_ref (match_operand 3))
10885 (clobber (reg:CC FLAGS_REG))]
10886 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10889 [(set (reg:CCC FLAGS_REG)
10897 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10898 (label_ref (match_dup 3))
10901 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10903 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10906 ;; avoid useless masking of bit offset operand
10907 (define_insn_and_split "*jcc_btsi_mask_1"
10910 (match_operator 0 "bt_comparison_operator"
10913 (match_operand:SI 1 "register_operand" "r")
10916 (match_operand:SI 2 "register_operand" "r")
10917 (match_operand:SI 3 "const_int_operand" "n")) 0))
10920 (label_ref (match_operand 4))
10922 (clobber (reg:CC FLAGS_REG))]
10923 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10924 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10927 [(set (reg:CCC FLAGS_REG)
10935 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10936 (label_ref (match_dup 4))
10938 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10940 ;; Define combination compare-and-branch fp compare instructions to help
10943 (define_insn "*jcc<mode>_0_i387"
10945 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10946 [(match_operand:X87MODEF 1 "register_operand" "f")
10947 (match_operand:X87MODEF 2 "const0_operand")])
10948 (label_ref (match_operand 3))
10950 (clobber (reg:CCFP FPSR_REG))
10951 (clobber (reg:CCFP FLAGS_REG))
10952 (clobber (match_scratch:HI 4 "=a"))]
10953 "TARGET_80387 && !TARGET_CMOVE"
10956 (define_insn "*jcc<mode>_0_r_i387"
10958 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10959 [(match_operand:X87MODEF 1 "register_operand" "f")
10960 (match_operand:X87MODEF 2 "const0_operand")])
10962 (label_ref (match_operand 3))))
10963 (clobber (reg:CCFP FPSR_REG))
10964 (clobber (reg:CCFP FLAGS_REG))
10965 (clobber (match_scratch:HI 4 "=a"))]
10966 "TARGET_80387 && !TARGET_CMOVE"
10969 (define_insn "*jccxf_i387"
10971 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10972 [(match_operand:XF 1 "register_operand" "f")
10973 (match_operand:XF 2 "register_operand" "f")])
10974 (label_ref (match_operand 3))
10976 (clobber (reg:CCFP FPSR_REG))
10977 (clobber (reg:CCFP FLAGS_REG))
10978 (clobber (match_scratch:HI 4 "=a"))]
10979 "TARGET_80387 && !TARGET_CMOVE"
10982 (define_insn "*jccxf_r_i387"
10984 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10985 [(match_operand:XF 1 "register_operand" "f")
10986 (match_operand:XF 2 "register_operand" "f")])
10988 (label_ref (match_operand 3))))
10989 (clobber (reg:CCFP FPSR_REG))
10990 (clobber (reg:CCFP FLAGS_REG))
10991 (clobber (match_scratch:HI 4 "=a"))]
10992 "TARGET_80387 && !TARGET_CMOVE"
10995 (define_insn "*jcc<mode>_i387"
10997 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10998 [(match_operand:MODEF 1 "register_operand" "f")
10999 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11000 (label_ref (match_operand 3))
11002 (clobber (reg:CCFP FPSR_REG))
11003 (clobber (reg:CCFP FLAGS_REG))
11004 (clobber (match_scratch:HI 4 "=a"))]
11005 "TARGET_80387 && !TARGET_CMOVE"
11008 (define_insn "*jcc<mode>_r_i387"
11010 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11011 [(match_operand:MODEF 1 "register_operand" "f")
11012 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11014 (label_ref (match_operand 3))))
11015 (clobber (reg:CCFP FPSR_REG))
11016 (clobber (reg:CCFP FLAGS_REG))
11017 (clobber (match_scratch:HI 4 "=a"))]
11018 "TARGET_80387 && !TARGET_CMOVE"
11021 (define_insn "*jccu<mode>_i387"
11023 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11024 [(match_operand:X87MODEF 1 "register_operand" "f")
11025 (match_operand:X87MODEF 2 "register_operand" "f")])
11026 (label_ref (match_operand 3))
11028 (clobber (reg:CCFP FPSR_REG))
11029 (clobber (reg:CCFP FLAGS_REG))
11030 (clobber (match_scratch:HI 4 "=a"))]
11031 "TARGET_80387 && !TARGET_CMOVE"
11034 (define_insn "*jccu<mode>_r_i387"
11036 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11037 [(match_operand:X87MODEF 1 "register_operand" "f")
11038 (match_operand:X87MODEF 2 "register_operand" "f")])
11040 (label_ref (match_operand 3))))
11041 (clobber (reg:CCFP FPSR_REG))
11042 (clobber (reg:CCFP FLAGS_REG))
11043 (clobber (match_scratch:HI 4 "=a"))]
11044 "TARGET_80387 && !TARGET_CMOVE"
11049 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11050 [(match_operand:X87MODEF 1 "register_operand")
11051 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11053 (match_operand 4)))
11054 (clobber (reg:CCFP FPSR_REG))
11055 (clobber (reg:CCFP FLAGS_REG))]
11056 "TARGET_80387 && !TARGET_CMOVE
11057 && reload_completed"
11060 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11061 operands[3], operands[4], NULL_RTX);
11067 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11068 [(match_operand:X87MODEF 1 "register_operand")
11069 (match_operand:X87MODEF 2 "general_operand")])
11071 (match_operand 4)))
11072 (clobber (reg:CCFP FPSR_REG))
11073 (clobber (reg:CCFP FLAGS_REG))
11074 (clobber (match_scratch:HI 5))]
11075 "TARGET_80387 && !TARGET_CMOVE
11076 && reload_completed"
11079 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11080 operands[3], operands[4], operands[5]);
11084 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11085 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11086 ;; with a precedence over other operators and is always put in the first
11087 ;; place. Swap condition and operands to match ficom instruction.
11089 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11092 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11093 [(match_operator:X87MODEF 1 "float_operator"
11094 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11095 (match_operand:X87MODEF 3 "register_operand" "f")])
11096 (label_ref (match_operand 4))
11098 (clobber (reg:CCFP FPSR_REG))
11099 (clobber (reg:CCFP FLAGS_REG))
11100 (clobber (match_scratch:HI 5 "=a"))]
11101 "TARGET_80387 && !TARGET_CMOVE
11102 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11103 || optimize_function_for_size_p (cfun))"
11106 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11109 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11110 [(match_operator:X87MODEF 1 "float_operator"
11111 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11112 (match_operand:X87MODEF 3 "register_operand" "f")])
11114 (label_ref (match_operand 4))))
11115 (clobber (reg:CCFP FPSR_REG))
11116 (clobber (reg:CCFP FLAGS_REG))
11117 (clobber (match_scratch:HI 5 "=a"))]
11118 "TARGET_80387 && !TARGET_CMOVE
11119 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11120 || optimize_function_for_size_p (cfun))"
11126 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11127 [(match_operator:X87MODEF 1 "float_operator"
11128 [(match_operand:SWI24 2 "memory_operand")])
11129 (match_operand:X87MODEF 3 "register_operand")])
11131 (match_operand 5)))
11132 (clobber (reg:CCFP FPSR_REG))
11133 (clobber (reg:CCFP FLAGS_REG))
11134 (clobber (match_scratch:HI 6))]
11135 "TARGET_80387 && !TARGET_CMOVE
11136 && reload_completed"
11139 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11140 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11141 operands[4], operands[5], operands[6]);
11145 ;; Unconditional and other jump instructions
11147 (define_insn "jump"
11149 (label_ref (match_operand 0)))]
11152 [(set_attr "type" "ibr")
11153 (set (attr "length")
11154 (if_then_else (and (ge (minus (match_dup 0) (pc))
11156 (lt (minus (match_dup 0) (pc))
11160 (set_attr "modrm" "0")])
11162 (define_expand "indirect_jump"
11163 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11167 operands[0] = convert_memory_address (word_mode, operands[0]);
11170 (define_insn "*indirect_jump"
11171 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11174 [(set_attr "type" "ibr")
11175 (set_attr "length_immediate" "0")])
11177 (define_expand "tablejump"
11178 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11179 (use (label_ref (match_operand 1)))])]
11182 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11183 relative. Convert the relative address to an absolute address. */
11187 enum rtx_code code;
11189 /* We can't use @GOTOFF for text labels on VxWorks;
11190 see gotoff_operand. */
11191 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11195 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11197 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11201 op1 = pic_offset_table_rtx;
11206 op0 = pic_offset_table_rtx;
11210 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11215 operands[0] = convert_memory_address (word_mode, operands[0]);
11218 (define_insn "*tablejump_1"
11219 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11220 (use (label_ref (match_operand 1)))]
11223 [(set_attr "type" "ibr")
11224 (set_attr "length_immediate" "0")])
11226 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11229 [(set (reg FLAGS_REG) (match_operand 0))
11230 (set (match_operand:QI 1 "register_operand")
11231 (match_operator:QI 2 "ix86_comparison_operator"
11232 [(reg FLAGS_REG) (const_int 0)]))
11233 (set (match_operand 3 "q_regs_operand")
11234 (zero_extend (match_dup 1)))]
11235 "(peep2_reg_dead_p (3, operands[1])
11236 || operands_match_p (operands[1], operands[3]))
11237 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11238 [(set (match_dup 4) (match_dup 0))
11239 (set (strict_low_part (match_dup 5))
11242 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11243 operands[5] = gen_lowpart (QImode, operands[3]);
11244 ix86_expand_clear (operands[3]);
11248 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11249 (match_operand 4)])
11250 (set (match_operand:QI 1 "register_operand")
11251 (match_operator:QI 2 "ix86_comparison_operator"
11252 [(reg FLAGS_REG) (const_int 0)]))
11253 (set (match_operand 3 "q_regs_operand")
11254 (zero_extend (match_dup 1)))]
11255 "(peep2_reg_dead_p (3, operands[1])
11256 || operands_match_p (operands[1], operands[3]))
11257 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11258 [(parallel [(set (match_dup 5) (match_dup 0))
11260 (set (strict_low_part (match_dup 6))
11263 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11264 operands[6] = gen_lowpart (QImode, operands[3]);
11265 ix86_expand_clear (operands[3]);
11268 ;; Similar, but match zero extend with andsi3.
11271 [(set (reg FLAGS_REG) (match_operand 0))
11272 (set (match_operand:QI 1 "register_operand")
11273 (match_operator:QI 2 "ix86_comparison_operator"
11274 [(reg FLAGS_REG) (const_int 0)]))
11275 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11276 (and:SI (match_dup 3) (const_int 255)))
11277 (clobber (reg:CC FLAGS_REG))])]
11278 "REGNO (operands[1]) == REGNO (operands[3])
11279 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11280 [(set (match_dup 4) (match_dup 0))
11281 (set (strict_low_part (match_dup 5))
11284 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11285 operands[5] = gen_lowpart (QImode, operands[3]);
11286 ix86_expand_clear (operands[3]);
11290 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11291 (match_operand 4)])
11292 (set (match_operand:QI 1 "register_operand")
11293 (match_operator:QI 2 "ix86_comparison_operator"
11294 [(reg FLAGS_REG) (const_int 0)]))
11295 (parallel [(set (match_operand 3 "q_regs_operand")
11296 (zero_extend (match_dup 1)))
11297 (clobber (reg:CC FLAGS_REG))])]
11298 "(peep2_reg_dead_p (3, operands[1])
11299 || operands_match_p (operands[1], operands[3]))
11300 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11301 [(parallel [(set (match_dup 5) (match_dup 0))
11303 (set (strict_low_part (match_dup 6))
11306 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11307 operands[6] = gen_lowpart (QImode, operands[3]);
11308 ix86_expand_clear (operands[3]);
11311 ;; Call instructions.
11313 ;; The predicates normally associated with named expanders are not properly
11314 ;; checked for calls. This is a bug in the generic code, but it isn't that
11315 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11317 ;; P6 processors will jump to the address after the decrement when %esp
11318 ;; is used as a call operand, so they will execute return address as a code.
11319 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11321 ;; Register constraint for call instruction.
11322 (define_mode_attr c [(SI "l") (DI "r")])
11324 ;; Call subroutine returning no value.
11326 (define_expand "call"
11327 [(call (match_operand:QI 0)
11329 (use (match_operand 2))]
11332 ix86_expand_call (NULL, operands[0], operands[1],
11333 operands[2], NULL, false);
11337 (define_expand "sibcall"
11338 [(call (match_operand:QI 0)
11340 (use (match_operand 2))]
11343 ix86_expand_call (NULL, operands[0], operands[1],
11344 operands[2], NULL, true);
11348 (define_insn "*call"
11349 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11350 (match_operand 1))]
11351 "!SIBLING_CALL_P (insn)"
11352 "* return ix86_output_call_insn (insn, operands[0]);"
11353 [(set_attr "type" "call")])
11355 (define_insn "*call_rex64_ms_sysv"
11356 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11357 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11359 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11360 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11361 "* return ix86_output_call_insn (insn, operands[0]);"
11362 [(set_attr "type" "call")])
11364 (define_insn "*sibcall"
11365 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11366 (match_operand 1))]
11367 "SIBLING_CALL_P (insn)"
11368 "* return ix86_output_call_insn (insn, operands[0]);"
11369 [(set_attr "type" "call")])
11371 (define_expand "call_pop"
11372 [(parallel [(call (match_operand:QI 0)
11373 (match_operand:SI 1))
11374 (set (reg:SI SP_REG)
11375 (plus:SI (reg:SI SP_REG)
11376 (match_operand:SI 3)))])]
11379 ix86_expand_call (NULL, operands[0], operands[1],
11380 operands[2], operands[3], false);
11384 (define_insn "*call_pop"
11385 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11387 (set (reg:SI SP_REG)
11388 (plus:SI (reg:SI SP_REG)
11389 (match_operand:SI 2 "immediate_operand" "i")))]
11390 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11391 "* return ix86_output_call_insn (insn, operands[0]);"
11392 [(set_attr "type" "call")])
11394 (define_insn "*sibcall_pop"
11395 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11397 (set (reg:SI SP_REG)
11398 (plus:SI (reg:SI SP_REG)
11399 (match_operand:SI 2 "immediate_operand" "i")))]
11400 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11401 "* return ix86_output_call_insn (insn, operands[0]);"
11402 [(set_attr "type" "call")])
11404 ;; Call subroutine, returning value in operand 0
11406 (define_expand "call_value"
11407 [(set (match_operand 0)
11408 (call (match_operand:QI 1)
11409 (match_operand 2)))
11410 (use (match_operand 3))]
11413 ix86_expand_call (operands[0], operands[1], operands[2],
11414 operands[3], NULL, false);
11418 (define_expand "sibcall_value"
11419 [(set (match_operand 0)
11420 (call (match_operand:QI 1)
11421 (match_operand 2)))
11422 (use (match_operand 3))]
11425 ix86_expand_call (operands[0], operands[1], operands[2],
11426 operands[3], NULL, true);
11430 (define_insn "*call_value"
11431 [(set (match_operand 0)
11432 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11433 (match_operand 2)))]
11434 "!SIBLING_CALL_P (insn)"
11435 "* return ix86_output_call_insn (insn, operands[1]);"
11436 [(set_attr "type" "callv")])
11438 (define_insn "*sibcall_value"
11439 [(set (match_operand 0)
11440 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11441 (match_operand 2)))]
11442 "SIBLING_CALL_P (insn)"
11443 "* return ix86_output_call_insn (insn, operands[1]);"
11444 [(set_attr "type" "callv")])
11446 (define_insn "*call_value_rex64_ms_sysv"
11447 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11448 [(set (match_operand 0)
11449 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11450 (match_operand 2)))
11451 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11452 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11453 "* return ix86_output_call_insn (insn, operands[1]);"
11454 [(set_attr "type" "callv")])
11456 (define_expand "call_value_pop"
11457 [(parallel [(set (match_operand 0)
11458 (call (match_operand:QI 1)
11459 (match_operand:SI 2)))
11460 (set (reg:SI SP_REG)
11461 (plus:SI (reg:SI SP_REG)
11462 (match_operand:SI 4)))])]
11465 ix86_expand_call (operands[0], operands[1], operands[2],
11466 operands[3], operands[4], false);
11470 (define_insn "*call_value_pop"
11471 [(set (match_operand 0)
11472 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11473 (match_operand 2)))
11474 (set (reg:SI SP_REG)
11475 (plus:SI (reg:SI SP_REG)
11476 (match_operand:SI 3 "immediate_operand" "i")))]
11477 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11478 "* return ix86_output_call_insn (insn, operands[1]);"
11479 [(set_attr "type" "callv")])
11481 (define_insn "*sibcall_value_pop"
11482 [(set (match_operand 0)
11483 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11484 (match_operand 2)))
11485 (set (reg:SI SP_REG)
11486 (plus:SI (reg:SI SP_REG)
11487 (match_operand:SI 3 "immediate_operand" "i")))]
11488 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11489 "* return ix86_output_call_insn (insn, operands[1]);"
11490 [(set_attr "type" "callv")])
11492 ;; Call subroutine returning any type.
11494 (define_expand "untyped_call"
11495 [(parallel [(call (match_operand 0)
11498 (match_operand 2)])]
11503 /* In order to give reg-stack an easier job in validating two
11504 coprocessor registers as containing a possible return value,
11505 simply pretend the untyped call returns a complex long double
11508 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11509 and should have the default ABI. */
11511 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11512 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11513 operands[0], const0_rtx,
11514 GEN_INT ((TARGET_64BIT
11515 ? (ix86_abi == SYSV_ABI
11516 ? X86_64_SSE_REGPARM_MAX
11517 : X86_64_MS_SSE_REGPARM_MAX)
11518 : X86_32_SSE_REGPARM_MAX)
11522 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11524 rtx set = XVECEXP (operands[2], 0, i);
11525 emit_move_insn (SET_DEST (set), SET_SRC (set));
11528 /* The optimizer does not know that the call sets the function value
11529 registers we stored in the result block. We avoid problems by
11530 claiming that all hard registers are used and clobbered at this
11532 emit_insn (gen_blockage ());
11537 ;; Prologue and epilogue instructions
11539 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11540 ;; all of memory. This blocks insns from being moved across this point.
11542 (define_insn "blockage"
11543 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11546 [(set_attr "length" "0")])
11548 ;; Do not schedule instructions accessing memory across this point.
11550 (define_expand "memory_blockage"
11551 [(set (match_dup 0)
11552 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11555 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11556 MEM_VOLATILE_P (operands[0]) = 1;
11559 (define_insn "*memory_blockage"
11560 [(set (match_operand:BLK 0)
11561 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11564 [(set_attr "length" "0")])
11566 ;; As USE insns aren't meaningful after reload, this is used instead
11567 ;; to prevent deleting instructions setting registers for PIC code
11568 (define_insn "prologue_use"
11569 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11572 [(set_attr "length" "0")])
11574 ;; Insn emitted into the body of a function to return from a function.
11575 ;; This is only done if the function's epilogue is known to be simple.
11576 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11578 (define_expand "return"
11580 "ix86_can_use_return_insn_p ()"
11582 if (crtl->args.pops_args)
11584 rtx popc = GEN_INT (crtl->args.pops_args);
11585 emit_jump_insn (gen_simple_return_pop_internal (popc));
11590 ;; We need to disable this for TARGET_SEH, as otherwise
11591 ;; shrink-wrapped prologue gets enabled too. This might exceed
11592 ;; the maximum size of prologue in unwind information.
11594 (define_expand "simple_return"
11598 if (crtl->args.pops_args)
11600 rtx popc = GEN_INT (crtl->args.pops_args);
11601 emit_jump_insn (gen_simple_return_pop_internal (popc));
11606 (define_insn "simple_return_internal"
11610 if (TARGET_64BIT && patch_functions_for_instrumentation)
11612 /* Emit 10 nop bytes after ret. */
11613 if (ix86_output_function_nops_prologue_epilogue (asm_out_file,
11614 FUNCTION_PATCH_EPILOGUE_SECTION,
11621 [(set_attr "length" "1")
11622 (set_attr "atom_unit" "jeu")
11623 (set_attr "length_immediate" "0")
11624 (set_attr "modrm" "0")])
11626 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11627 ;; instruction Athlon and K8 have.
11629 (define_insn "simple_return_internal_long"
11631 (unspec [(const_int 0)] UNSPEC_REP)]
11634 if (TARGET_64BIT && patch_functions_for_instrumentation)
11636 /* Emit 9 nop bytes after rep;ret. */
11637 if (ix86_output_function_nops_prologue_epilogue (asm_out_file,
11638 FUNCTION_PATCH_EPILOGUE_SECTION,
11645 [(set_attr "length" "2")
11646 (set_attr "atom_unit" "jeu")
11647 (set_attr "length_immediate" "0")
11648 (set_attr "prefix_rep" "1")
11649 (set_attr "modrm" "0")])
11651 (define_insn "simple_return_pop_internal"
11653 (use (match_operand:SI 0 "const_int_operand"))]
11656 [(set_attr "length" "3")
11657 (set_attr "atom_unit" "jeu")
11658 (set_attr "length_immediate" "2")
11659 (set_attr "modrm" "0")])
11661 (define_insn "simple_return_indirect_internal"
11663 (use (match_operand:SI 0 "register_operand" "r"))]
11666 [(set_attr "type" "ibr")
11667 (set_attr "length_immediate" "0")])
11673 [(set_attr "length" "1")
11674 (set_attr "length_immediate" "0")
11675 (set_attr "modrm" "0")])
11677 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11678 (define_insn "nops"
11679 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11683 int num = INTVAL (operands[0]);
11685 gcc_assert (IN_RANGE (num, 1, 8));
11688 fputs ("\tnop\n", asm_out_file);
11692 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11693 (set_attr "length_immediate" "0")
11694 (set_attr "modrm" "0")])
11696 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11697 ;; branch prediction penalty for the third jump in a 16-byte
11701 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11704 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11705 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11707 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11708 The align insn is used to avoid 3 jump instructions in the row to improve
11709 branch prediction and the benefits hardly outweigh the cost of extra 8
11710 nops on the average inserted by full alignment pseudo operation. */
11714 [(set_attr "length" "16")])
11716 (define_expand "prologue"
11719 "ix86_expand_prologue (); DONE;")
11721 (define_insn "set_got"
11722 [(set (match_operand:SI 0 "register_operand" "=r")
11723 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11724 (clobber (reg:CC FLAGS_REG))]
11726 "* return output_set_got (operands[0], NULL_RTX);"
11727 [(set_attr "type" "multi")
11728 (set_attr "length" "12")])
11730 (define_insn "set_got_labelled"
11731 [(set (match_operand:SI 0 "register_operand" "=r")
11732 (unspec:SI [(label_ref (match_operand 1))]
11734 (clobber (reg:CC FLAGS_REG))]
11736 "* return output_set_got (operands[0], operands[1]);"
11737 [(set_attr "type" "multi")
11738 (set_attr "length" "12")])
11740 (define_insn "set_got_rex64"
11741 [(set (match_operand:DI 0 "register_operand" "=r")
11742 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11744 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11745 [(set_attr "type" "lea")
11746 (set_attr "length_address" "4")
11747 (set_attr "mode" "DI")])
11749 (define_insn "set_rip_rex64"
11750 [(set (match_operand:DI 0 "register_operand" "=r")
11751 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11753 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11754 [(set_attr "type" "lea")
11755 (set_attr "length_address" "4")
11756 (set_attr "mode" "DI")])
11758 (define_insn "set_got_offset_rex64"
11759 [(set (match_operand:DI 0 "register_operand" "=r")
11761 [(label_ref (match_operand 1))]
11762 UNSPEC_SET_GOT_OFFSET))]
11764 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11765 [(set_attr "type" "imov")
11766 (set_attr "length_immediate" "0")
11767 (set_attr "length_address" "8")
11768 (set_attr "mode" "DI")])
11770 (define_expand "epilogue"
11773 "ix86_expand_epilogue (1); DONE;")
11775 (define_expand "sibcall_epilogue"
11778 "ix86_expand_epilogue (0); DONE;")
11780 (define_expand "eh_return"
11781 [(use (match_operand 0 "register_operand"))]
11784 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11786 /* Tricky bit: we write the address of the handler to which we will
11787 be returning into someone else's stack frame, one word below the
11788 stack address we wish to restore. */
11789 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11790 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11791 tmp = gen_rtx_MEM (Pmode, tmp);
11792 emit_move_insn (tmp, ra);
11794 emit_jump_insn (gen_eh_return_internal ());
11799 (define_insn_and_split "eh_return_internal"
11803 "epilogue_completed"
11805 "ix86_expand_epilogue (2); DONE;")
11807 (define_insn "leave"
11808 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11809 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11810 (clobber (mem:BLK (scratch)))]
11813 [(set_attr "type" "leave")])
11815 (define_insn "leave_rex64"
11816 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11817 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11818 (clobber (mem:BLK (scratch)))]
11821 [(set_attr "type" "leave")])
11823 ;; Handle -fsplit-stack.
11825 (define_expand "split_stack_prologue"
11829 ix86_expand_split_stack_prologue ();
11833 ;; In order to support the call/return predictor, we use a return
11834 ;; instruction which the middle-end doesn't see.
11835 (define_insn "split_stack_return"
11836 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11837 UNSPECV_SPLIT_STACK_RETURN)]
11840 if (operands[0] == const0_rtx)
11845 [(set_attr "atom_unit" "jeu")
11846 (set_attr "modrm" "0")
11847 (set (attr "length")
11848 (if_then_else (match_operand:SI 0 "const0_operand")
11851 (set (attr "length_immediate")
11852 (if_then_else (match_operand:SI 0 "const0_operand")
11856 ;; If there are operand 0 bytes available on the stack, jump to
11859 (define_expand "split_stack_space_check"
11860 [(set (pc) (if_then_else
11861 (ltu (minus (reg SP_REG)
11862 (match_operand 0 "register_operand"))
11863 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11864 (label_ref (match_operand 1))
11868 rtx reg, size, limit;
11870 reg = gen_reg_rtx (Pmode);
11871 size = force_reg (Pmode, operands[0]);
11872 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11873 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11874 UNSPEC_STACK_CHECK);
11875 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11876 ix86_expand_branch (GEU, reg, limit, operands[1]);
11881 ;; Bit manipulation instructions.
11883 (define_expand "ffs<mode>2"
11884 [(set (match_dup 2) (const_int -1))
11885 (parallel [(set (match_dup 3) (match_dup 4))
11886 (set (match_operand:SWI48 0 "register_operand")
11888 (match_operand:SWI48 1 "nonimmediate_operand")))])
11889 (set (match_dup 0) (if_then_else:SWI48
11890 (eq (match_dup 3) (const_int 0))
11893 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11894 (clobber (reg:CC FLAGS_REG))])]
11897 enum machine_mode flags_mode;
11899 if (<MODE>mode == SImode && !TARGET_CMOVE)
11901 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11905 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11907 operands[2] = gen_reg_rtx (<MODE>mode);
11908 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
11909 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11912 (define_insn_and_split "ffssi2_no_cmove"
11913 [(set (match_operand:SI 0 "register_operand" "=r")
11914 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11915 (clobber (match_scratch:SI 2 "=&q"))
11916 (clobber (reg:CC FLAGS_REG))]
11919 "&& reload_completed"
11920 [(parallel [(set (match_dup 4) (match_dup 5))
11921 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11922 (set (strict_low_part (match_dup 3))
11923 (eq:QI (match_dup 4) (const_int 0)))
11924 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11925 (clobber (reg:CC FLAGS_REG))])
11926 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11927 (clobber (reg:CC FLAGS_REG))])
11928 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11929 (clobber (reg:CC FLAGS_REG))])]
11931 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11933 operands[3] = gen_lowpart (QImode, operands[2]);
11934 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
11935 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11937 ix86_expand_clear (operands[2]);
11940 (define_insn "*tzcnt<mode>_1"
11941 [(set (reg:CCC FLAGS_REG)
11942 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11944 (set (match_operand:SWI48 0 "register_operand" "=r")
11945 (ctz:SWI48 (match_dup 1)))]
11947 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11948 [(set_attr "type" "alu1")
11949 (set_attr "prefix_0f" "1")
11950 (set_attr "prefix_rep" "1")
11951 (set_attr "btver2_decode" "double")
11952 (set_attr "mode" "<MODE>")])
11954 (define_insn "*bsf<mode>_1"
11955 [(set (reg:CCZ FLAGS_REG)
11956 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11958 (set (match_operand:SWI48 0 "register_operand" "=r")
11959 (ctz:SWI48 (match_dup 1)))]
11961 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11962 [(set_attr "type" "alu1")
11963 (set_attr "prefix_0f" "1")
11964 (set_attr "btver2_decode" "double")
11965 (set_attr "mode" "<MODE>")])
11967 (define_insn "ctz<mode>2"
11968 [(set (match_operand:SWI248 0 "register_operand" "=r")
11969 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11970 (clobber (reg:CC FLAGS_REG))]
11974 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11975 else if (optimize_function_for_size_p (cfun))
11977 else if (TARGET_GENERIC)
11978 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
11979 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11981 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11983 [(set_attr "type" "alu1")
11984 (set_attr "prefix_0f" "1")
11985 (set (attr "prefix_rep")
11987 (ior (match_test "TARGET_BMI")
11988 (and (not (match_test "optimize_function_for_size_p (cfun)"))
11989 (match_test "TARGET_GENERIC")))
11991 (const_string "0")))
11992 (set_attr "mode" "<MODE>")])
11994 (define_expand "clz<mode>2"
11996 [(set (match_operand:SWI248 0 "register_operand")
11999 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12000 (clobber (reg:CC FLAGS_REG))])
12002 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12003 (clobber (reg:CC FLAGS_REG))])]
12008 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12011 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12014 (define_insn "clz<mode>2_lzcnt"
12015 [(set (match_operand:SWI248 0 "register_operand" "=r")
12016 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12017 (clobber (reg:CC FLAGS_REG))]
12019 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12020 [(set_attr "prefix_rep" "1")
12021 (set_attr "type" "bitmanip")
12022 (set_attr "mode" "<MODE>")])
12024 ;; BMI instructions.
12025 (define_insn "*bmi_andn_<mode>"
12026 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12029 (match_operand:SWI48 1 "register_operand" "r,r"))
12030 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12031 (clobber (reg:CC FLAGS_REG))]
12033 "andn\t{%2, %1, %0|%0, %1, %2}"
12034 [(set_attr "type" "bitmanip")
12035 (set_attr "btver2_decode" "direct, double")
12036 (set_attr "mode" "<MODE>")])
12038 (define_insn "bmi_bextr_<mode>"
12039 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12040 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12041 (match_operand:SWI48 2 "register_operand" "r,r")]
12043 (clobber (reg:CC FLAGS_REG))]
12045 "bextr\t{%2, %1, %0|%0, %1, %2}"
12046 [(set_attr "type" "bitmanip")
12047 (set_attr "btver2_decode" "direct, double")
12048 (set_attr "mode" "<MODE>")])
12050 (define_insn "*bmi_blsi_<mode>"
12051 [(set (match_operand:SWI48 0 "register_operand" "=r")
12054 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12056 (clobber (reg:CC FLAGS_REG))]
12058 "blsi\t{%1, %0|%0, %1}"
12059 [(set_attr "type" "bitmanip")
12060 (set_attr "btver2_decode" "double")
12061 (set_attr "mode" "<MODE>")])
12063 (define_insn "*bmi_blsmsk_<mode>"
12064 [(set (match_operand:SWI48 0 "register_operand" "=r")
12067 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12070 (clobber (reg:CC FLAGS_REG))]
12072 "blsmsk\t{%1, %0|%0, %1}"
12073 [(set_attr "type" "bitmanip")
12074 (set_attr "btver2_decode" "double")
12075 (set_attr "mode" "<MODE>")])
12077 (define_insn "*bmi_blsr_<mode>"
12078 [(set (match_operand:SWI48 0 "register_operand" "=r")
12081 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12084 (clobber (reg:CC FLAGS_REG))]
12086 "blsr\t{%1, %0|%0, %1}"
12087 [(set_attr "type" "bitmanip")
12088 (set_attr "btver2_decode" "double")
12089 (set_attr "mode" "<MODE>")])
12091 ;; BMI2 instructions.
12092 (define_insn "bmi2_bzhi_<mode>3"
12093 [(set (match_operand:SWI48 0 "register_operand" "=r")
12094 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12095 (match_operand:SWI48 2 "register_operand" "r"))
12096 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12097 (clobber (reg:CC FLAGS_REG))]
12099 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12100 [(set_attr "type" "bitmanip")
12101 (set_attr "prefix" "vex")
12102 (set_attr "mode" "<MODE>")])
12104 (define_insn "bmi2_pdep_<mode>3"
12105 [(set (match_operand:SWI48 0 "register_operand" "=r")
12106 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12107 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12110 "pdep\t{%2, %1, %0|%0, %1, %2}"
12111 [(set_attr "type" "bitmanip")
12112 (set_attr "prefix" "vex")
12113 (set_attr "mode" "<MODE>")])
12115 (define_insn "bmi2_pext_<mode>3"
12116 [(set (match_operand:SWI48 0 "register_operand" "=r")
12117 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12118 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12121 "pext\t{%2, %1, %0|%0, %1, %2}"
12122 [(set_attr "type" "bitmanip")
12123 (set_attr "prefix" "vex")
12124 (set_attr "mode" "<MODE>")])
12126 ;; TBM instructions.
12127 (define_insn "tbm_bextri_<mode>"
12128 [(set (match_operand:SWI48 0 "register_operand" "=r")
12129 (zero_extract:SWI48
12130 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12131 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12132 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12133 (clobber (reg:CC FLAGS_REG))]
12136 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12137 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12139 [(set_attr "type" "bitmanip")
12140 (set_attr "mode" "<MODE>")])
12142 (define_insn "*tbm_blcfill_<mode>"
12143 [(set (match_operand:SWI48 0 "register_operand" "=r")
12146 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12149 (clobber (reg:CC FLAGS_REG))]
12151 "blcfill\t{%1, %0|%0, %1}"
12152 [(set_attr "type" "bitmanip")
12153 (set_attr "mode" "<MODE>")])
12155 (define_insn "*tbm_blci_<mode>"
12156 [(set (match_operand:SWI48 0 "register_operand" "=r")
12160 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12163 (clobber (reg:CC FLAGS_REG))]
12165 "blci\t{%1, %0|%0, %1}"
12166 [(set_attr "type" "bitmanip")
12167 (set_attr "mode" "<MODE>")])
12169 (define_insn "*tbm_blcic_<mode>"
12170 [(set (match_operand:SWI48 0 "register_operand" "=r")
12173 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12177 (clobber (reg:CC FLAGS_REG))]
12179 "blcic\t{%1, %0|%0, %1}"
12180 [(set_attr "type" "bitmanip")
12181 (set_attr "mode" "<MODE>")])
12183 (define_insn "*tbm_blcmsk_<mode>"
12184 [(set (match_operand:SWI48 0 "register_operand" "=r")
12187 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12190 (clobber (reg:CC FLAGS_REG))]
12192 "blcmsk\t{%1, %0|%0, %1}"
12193 [(set_attr "type" "bitmanip")
12194 (set_attr "mode" "<MODE>")])
12196 (define_insn "*tbm_blcs_<mode>"
12197 [(set (match_operand:SWI48 0 "register_operand" "=r")
12200 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12203 (clobber (reg:CC FLAGS_REG))]
12205 "blcs\t{%1, %0|%0, %1}"
12206 [(set_attr "type" "bitmanip")
12207 (set_attr "mode" "<MODE>")])
12209 (define_insn "*tbm_blsfill_<mode>"
12210 [(set (match_operand:SWI48 0 "register_operand" "=r")
12213 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12216 (clobber (reg:CC FLAGS_REG))]
12218 "blsfill\t{%1, %0|%0, %1}"
12219 [(set_attr "type" "bitmanip")
12220 (set_attr "mode" "<MODE>")])
12222 (define_insn "*tbm_blsic_<mode>"
12223 [(set (match_operand:SWI48 0 "register_operand" "=r")
12226 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12230 (clobber (reg:CC FLAGS_REG))]
12232 "blsic\t{%1, %0|%0, %1}"
12233 [(set_attr "type" "bitmanip")
12234 (set_attr "mode" "<MODE>")])
12236 (define_insn "*tbm_t1mskc_<mode>"
12237 [(set (match_operand:SWI48 0 "register_operand" "=r")
12240 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12244 (clobber (reg:CC FLAGS_REG))]
12246 "t1mskc\t{%1, %0|%0, %1}"
12247 [(set_attr "type" "bitmanip")
12248 (set_attr "mode" "<MODE>")])
12250 (define_insn "*tbm_tzmsk_<mode>"
12251 [(set (match_operand:SWI48 0 "register_operand" "=r")
12254 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12258 (clobber (reg:CC FLAGS_REG))]
12260 "tzmsk\t{%1, %0|%0, %1}"
12261 [(set_attr "type" "bitmanip")
12262 (set_attr "mode" "<MODE>")])
12264 (define_insn "bsr_rex64"
12265 [(set (match_operand:DI 0 "register_operand" "=r")
12266 (minus:DI (const_int 63)
12267 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12268 (clobber (reg:CC FLAGS_REG))]
12270 "bsr{q}\t{%1, %0|%0, %1}"
12271 [(set_attr "type" "alu1")
12272 (set_attr "prefix_0f" "1")
12273 (set_attr "mode" "DI")])
12276 [(set (match_operand:SI 0 "register_operand" "=r")
12277 (minus:SI (const_int 31)
12278 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12279 (clobber (reg:CC FLAGS_REG))]
12281 "bsr{l}\t{%1, %0|%0, %1}"
12282 [(set_attr "type" "alu1")
12283 (set_attr "prefix_0f" "1")
12284 (set_attr "mode" "SI")])
12286 (define_insn "*bsrhi"
12287 [(set (match_operand:HI 0 "register_operand" "=r")
12288 (minus:HI (const_int 15)
12289 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12290 (clobber (reg:CC FLAGS_REG))]
12292 "bsr{w}\t{%1, %0|%0, %1}"
12293 [(set_attr "type" "alu1")
12294 (set_attr "prefix_0f" "1")
12295 (set_attr "mode" "HI")])
12297 (define_insn "popcount<mode>2"
12298 [(set (match_operand:SWI248 0 "register_operand" "=r")
12300 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12301 (clobber (reg:CC FLAGS_REG))]
12305 return "popcnt\t{%1, %0|%0, %1}";
12307 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12310 [(set_attr "prefix_rep" "1")
12311 (set_attr "type" "bitmanip")
12312 (set_attr "mode" "<MODE>")])
12314 (define_insn "*popcount<mode>2_cmp"
12315 [(set (reg FLAGS_REG)
12318 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12320 (set (match_operand:SWI248 0 "register_operand" "=r")
12321 (popcount:SWI248 (match_dup 1)))]
12322 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12325 return "popcnt\t{%1, %0|%0, %1}";
12327 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12330 [(set_attr "prefix_rep" "1")
12331 (set_attr "type" "bitmanip")
12332 (set_attr "mode" "<MODE>")])
12334 (define_insn "*popcountsi2_cmp_zext"
12335 [(set (reg FLAGS_REG)
12337 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12339 (set (match_operand:DI 0 "register_operand" "=r")
12340 (zero_extend:DI(popcount:SI (match_dup 1))))]
12341 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12344 return "popcnt\t{%1, %0|%0, %1}";
12346 return "popcnt{l}\t{%1, %0|%0, %1}";
12349 [(set_attr "prefix_rep" "1")
12350 (set_attr "type" "bitmanip")
12351 (set_attr "mode" "SI")])
12353 (define_expand "bswapdi2"
12354 [(set (match_operand:DI 0 "register_operand")
12355 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12359 operands[1] = force_reg (DImode, operands[1]);
12362 (define_expand "bswapsi2"
12363 [(set (match_operand:SI 0 "register_operand")
12364 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12369 else if (TARGET_BSWAP)
12370 operands[1] = force_reg (SImode, operands[1]);
12373 rtx x = operands[0];
12375 emit_move_insn (x, operands[1]);
12376 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12377 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12378 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12383 (define_insn "*bswap<mode>2_movbe"
12384 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12385 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12387 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12390 movbe\t{%1, %0|%0, %1}
12391 movbe\t{%1, %0|%0, %1}"
12392 [(set_attr "type" "bitmanip,imov,imov")
12393 (set_attr "modrm" "0,1,1")
12394 (set_attr "prefix_0f" "*,1,1")
12395 (set_attr "prefix_extra" "*,1,1")
12396 (set_attr "mode" "<MODE>")])
12398 (define_insn "*bswap<mode>2"
12399 [(set (match_operand:SWI48 0 "register_operand" "=r")
12400 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12403 [(set_attr "type" "bitmanip")
12404 (set_attr "modrm" "0")
12405 (set_attr "mode" "<MODE>")])
12407 (define_insn "*bswaphi_lowpart_1"
12408 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12409 (bswap:HI (match_dup 0)))
12410 (clobber (reg:CC FLAGS_REG))]
12411 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12413 xchg{b}\t{%h0, %b0|%b0, %h0}
12414 rol{w}\t{$8, %0|%0, 8}"
12415 [(set_attr "length" "2,4")
12416 (set_attr "mode" "QI,HI")])
12418 (define_insn "bswaphi_lowpart"
12419 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12420 (bswap:HI (match_dup 0)))
12421 (clobber (reg:CC FLAGS_REG))]
12423 "rol{w}\t{$8, %0|%0, 8}"
12424 [(set_attr "length" "4")
12425 (set_attr "mode" "HI")])
12427 (define_expand "paritydi2"
12428 [(set (match_operand:DI 0 "register_operand")
12429 (parity:DI (match_operand:DI 1 "register_operand")))]
12432 rtx scratch = gen_reg_rtx (QImode);
12435 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12436 NULL_RTX, operands[1]));
12438 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12439 gen_rtx_REG (CCmode, FLAGS_REG),
12441 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12444 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12447 rtx tmp = gen_reg_rtx (SImode);
12449 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12450 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12455 (define_expand "paritysi2"
12456 [(set (match_operand:SI 0 "register_operand")
12457 (parity:SI (match_operand:SI 1 "register_operand")))]
12460 rtx scratch = gen_reg_rtx (QImode);
12463 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12465 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12466 gen_rtx_REG (CCmode, FLAGS_REG),
12468 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12470 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12474 (define_insn_and_split "paritydi2_cmp"
12475 [(set (reg:CC FLAGS_REG)
12476 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12478 (clobber (match_scratch:DI 0 "=r"))
12479 (clobber (match_scratch:SI 1 "=&r"))
12480 (clobber (match_scratch:HI 2 "=Q"))]
12483 "&& reload_completed"
12485 [(set (match_dup 1)
12486 (xor:SI (match_dup 1) (match_dup 4)))
12487 (clobber (reg:CC FLAGS_REG))])
12489 [(set (reg:CC FLAGS_REG)
12490 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12491 (clobber (match_dup 1))
12492 (clobber (match_dup 2))])]
12494 operands[4] = gen_lowpart (SImode, operands[3]);
12498 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12499 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12502 operands[1] = gen_highpart (SImode, operands[3]);
12505 (define_insn_and_split "paritysi2_cmp"
12506 [(set (reg:CC FLAGS_REG)
12507 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12509 (clobber (match_scratch:SI 0 "=r"))
12510 (clobber (match_scratch:HI 1 "=&Q"))]
12513 "&& reload_completed"
12515 [(set (match_dup 1)
12516 (xor:HI (match_dup 1) (match_dup 3)))
12517 (clobber (reg:CC FLAGS_REG))])
12519 [(set (reg:CC FLAGS_REG)
12520 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12521 (clobber (match_dup 1))])]
12523 operands[3] = gen_lowpart (HImode, operands[2]);
12525 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12526 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12529 (define_insn "*parityhi2_cmp"
12530 [(set (reg:CC FLAGS_REG)
12531 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12533 (clobber (match_scratch:HI 0 "=Q"))]
12535 "xor{b}\t{%h0, %b0|%b0, %h0}"
12536 [(set_attr "length" "2")
12537 (set_attr "mode" "HI")])
12540 ;; Thread-local storage patterns for ELF.
12542 ;; Note that these code sequences must appear exactly as shown
12543 ;; in order to allow linker relaxation.
12545 (define_insn "*tls_global_dynamic_32_gnu"
12546 [(set (match_operand:SI 0 "register_operand" "=a")
12548 [(match_operand:SI 1 "register_operand" "b")
12549 (match_operand 2 "tls_symbolic_operand")
12550 (match_operand 3 "constant_call_address_operand" "z")]
12552 (clobber (match_scratch:SI 4 "=d"))
12553 (clobber (match_scratch:SI 5 "=c"))
12554 (clobber (reg:CC FLAGS_REG))]
12555 "!TARGET_64BIT && TARGET_GNU_TLS"
12558 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12559 if (TARGET_SUN_TLS)
12560 #ifdef HAVE_AS_IX86_TLSGDPLT
12561 return "call\t%a2@tlsgdplt";
12563 return "call\t%p3@plt";
12565 return "call\t%P3";
12567 [(set_attr "type" "multi")
12568 (set_attr "length" "12")])
12570 (define_expand "tls_global_dynamic_32"
12572 [(set (match_operand:SI 0 "register_operand")
12573 (unspec:SI [(match_operand:SI 2 "register_operand")
12574 (match_operand 1 "tls_symbolic_operand")
12575 (match_operand 3 "constant_call_address_operand")]
12577 (clobber (match_scratch:SI 4))
12578 (clobber (match_scratch:SI 5))
12579 (clobber (reg:CC FLAGS_REG))])])
12581 (define_insn "*tls_global_dynamic_64_<mode>"
12582 [(set (match_operand:P 0 "register_operand" "=a")
12584 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12585 (match_operand 3)))
12586 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12591 fputs (ASM_BYTE "0x66\n", asm_out_file);
12593 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12594 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12595 fputs ("\trex64\n", asm_out_file);
12596 if (TARGET_SUN_TLS)
12597 return "call\t%p2@plt";
12598 return "call\t%P2";
12600 [(set_attr "type" "multi")
12601 (set (attr "length")
12602 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12604 (define_insn "*tls_global_dynamic_64_largepic"
12605 [(set (match_operand:DI 0 "register_operand" "=a")
12607 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12608 (match_operand:DI 3 "immediate_operand" "i")))
12609 (match_operand 4)))
12610 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12612 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12613 && GET_CODE (operands[3]) == CONST
12614 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12615 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12618 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12619 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12620 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12621 return "call\t{*%%rax|rax}";
12623 [(set_attr "type" "multi")
12624 (set_attr "length" "22")])
12626 (define_expand "tls_global_dynamic_64_<mode>"
12628 [(set (match_operand:P 0 "register_operand")
12630 (mem:QI (match_operand 2))
12632 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12636 (define_insn "*tls_local_dynamic_base_32_gnu"
12637 [(set (match_operand:SI 0 "register_operand" "=a")
12639 [(match_operand:SI 1 "register_operand" "b")
12640 (match_operand 2 "constant_call_address_operand" "z")]
12641 UNSPEC_TLS_LD_BASE))
12642 (clobber (match_scratch:SI 3 "=d"))
12643 (clobber (match_scratch:SI 4 "=c"))
12644 (clobber (reg:CC FLAGS_REG))]
12645 "!TARGET_64BIT && TARGET_GNU_TLS"
12648 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12649 if (TARGET_SUN_TLS)
12651 if (HAVE_AS_IX86_TLSLDMPLT)
12652 return "call\t%&@tlsldmplt";
12654 return "call\t%p2@plt";
12656 return "call\t%P2";
12658 [(set_attr "type" "multi")
12659 (set_attr "length" "11")])
12661 (define_expand "tls_local_dynamic_base_32"
12663 [(set (match_operand:SI 0 "register_operand")
12665 [(match_operand:SI 1 "register_operand")
12666 (match_operand 2 "constant_call_address_operand")]
12667 UNSPEC_TLS_LD_BASE))
12668 (clobber (match_scratch:SI 3))
12669 (clobber (match_scratch:SI 4))
12670 (clobber (reg:CC FLAGS_REG))])])
12672 (define_insn "*tls_local_dynamic_base_64_<mode>"
12673 [(set (match_operand:P 0 "register_operand" "=a")
12675 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12676 (match_operand 2)))
12677 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12681 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12682 if (TARGET_SUN_TLS)
12683 return "call\t%p1@plt";
12684 return "call\t%P1";
12686 [(set_attr "type" "multi")
12687 (set_attr "length" "12")])
12689 (define_insn "*tls_local_dynamic_base_64_largepic"
12690 [(set (match_operand:DI 0 "register_operand" "=a")
12692 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12693 (match_operand:DI 2 "immediate_operand" "i")))
12694 (match_operand 3)))
12695 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12696 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12697 && GET_CODE (operands[2]) == CONST
12698 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
12699 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
12702 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12703 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
12704 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
12705 return "call\t{*%%rax|rax}";
12707 [(set_attr "type" "multi")
12708 (set_attr "length" "22")])
12710 (define_expand "tls_local_dynamic_base_64_<mode>"
12712 [(set (match_operand:P 0 "register_operand")
12714 (mem:QI (match_operand 1))
12716 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12719 ;; Local dynamic of a single variable is a lose. Show combine how
12720 ;; to convert that back to global dynamic.
12722 (define_insn_and_split "*tls_local_dynamic_32_once"
12723 [(set (match_operand:SI 0 "register_operand" "=a")
12725 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12726 (match_operand 2 "constant_call_address_operand" "z")]
12727 UNSPEC_TLS_LD_BASE)
12728 (const:SI (unspec:SI
12729 [(match_operand 3 "tls_symbolic_operand")]
12731 (clobber (match_scratch:SI 4 "=d"))
12732 (clobber (match_scratch:SI 5 "=c"))
12733 (clobber (reg:CC FLAGS_REG))]
12738 [(set (match_dup 0)
12739 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12741 (clobber (match_dup 4))
12742 (clobber (match_dup 5))
12743 (clobber (reg:CC FLAGS_REG))])])
12745 ;; Segment register for the thread base ptr load
12746 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12748 ;; Load and add the thread base pointer from %<tp_seg>:0.
12749 (define_insn "*load_tp_x32"
12750 [(set (match_operand:SI 0 "register_operand" "=r")
12751 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12753 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12754 [(set_attr "type" "imov")
12755 (set_attr "modrm" "0")
12756 (set_attr "length" "7")
12757 (set_attr "memory" "load")
12758 (set_attr "imm_disp" "false")])
12760 (define_insn "*load_tp_x32_zext"
12761 [(set (match_operand:DI 0 "register_operand" "=r")
12762 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12764 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12765 [(set_attr "type" "imov")
12766 (set_attr "modrm" "0")
12767 (set_attr "length" "7")
12768 (set_attr "memory" "load")
12769 (set_attr "imm_disp" "false")])
12771 (define_insn "*load_tp_<mode>"
12772 [(set (match_operand:P 0 "register_operand" "=r")
12773 (unspec:P [(const_int 0)] UNSPEC_TP))]
12775 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12776 [(set_attr "type" "imov")
12777 (set_attr "modrm" "0")
12778 (set_attr "length" "7")
12779 (set_attr "memory" "load")
12780 (set_attr "imm_disp" "false")])
12782 (define_insn "*add_tp_x32"
12783 [(set (match_operand:SI 0 "register_operand" "=r")
12784 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12785 (match_operand:SI 1 "register_operand" "0")))
12786 (clobber (reg:CC FLAGS_REG))]
12788 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12789 [(set_attr "type" "alu")
12790 (set_attr "modrm" "0")
12791 (set_attr "length" "7")
12792 (set_attr "memory" "load")
12793 (set_attr "imm_disp" "false")])
12795 (define_insn "*add_tp_x32_zext"
12796 [(set (match_operand:DI 0 "register_operand" "=r")
12798 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12799 (match_operand:SI 1 "register_operand" "0"))))
12800 (clobber (reg:CC FLAGS_REG))]
12802 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12803 [(set_attr "type" "alu")
12804 (set_attr "modrm" "0")
12805 (set_attr "length" "7")
12806 (set_attr "memory" "load")
12807 (set_attr "imm_disp" "false")])
12809 (define_insn "*add_tp_<mode>"
12810 [(set (match_operand:P 0 "register_operand" "=r")
12811 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12812 (match_operand:P 1 "register_operand" "0")))
12813 (clobber (reg:CC FLAGS_REG))]
12815 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12816 [(set_attr "type" "alu")
12817 (set_attr "modrm" "0")
12818 (set_attr "length" "7")
12819 (set_attr "memory" "load")
12820 (set_attr "imm_disp" "false")])
12822 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12823 ;; %rax as destination of the initial executable code sequence.
12824 (define_insn "tls_initial_exec_64_sun"
12825 [(set (match_operand:DI 0 "register_operand" "=a")
12827 [(match_operand 1 "tls_symbolic_operand")]
12828 UNSPEC_TLS_IE_SUN))
12829 (clobber (reg:CC FLAGS_REG))]
12830 "TARGET_64BIT && TARGET_SUN_TLS"
12833 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12834 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12836 [(set_attr "type" "multi")])
12838 ;; GNU2 TLS patterns can be split.
12840 (define_expand "tls_dynamic_gnu2_32"
12841 [(set (match_dup 3)
12842 (plus:SI (match_operand:SI 2 "register_operand")
12844 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12847 [(set (match_operand:SI 0 "register_operand")
12848 (unspec:SI [(match_dup 1) (match_dup 3)
12849 (match_dup 2) (reg:SI SP_REG)]
12851 (clobber (reg:CC FLAGS_REG))])]
12852 "!TARGET_64BIT && TARGET_GNU2_TLS"
12854 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12855 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12858 (define_insn "*tls_dynamic_gnu2_lea_32"
12859 [(set (match_operand:SI 0 "register_operand" "=r")
12860 (plus:SI (match_operand:SI 1 "register_operand" "b")
12862 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12863 UNSPEC_TLSDESC))))]
12864 "!TARGET_64BIT && TARGET_GNU2_TLS"
12865 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12866 [(set_attr "type" "lea")
12867 (set_attr "mode" "SI")
12868 (set_attr "length" "6")
12869 (set_attr "length_address" "4")])
12871 (define_insn "*tls_dynamic_gnu2_call_32"
12872 [(set (match_operand:SI 0 "register_operand" "=a")
12873 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12874 (match_operand:SI 2 "register_operand" "0")
12875 ;; we have to make sure %ebx still points to the GOT
12876 (match_operand:SI 3 "register_operand" "b")
12879 (clobber (reg:CC FLAGS_REG))]
12880 "!TARGET_64BIT && TARGET_GNU2_TLS"
12881 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12882 [(set_attr "type" "call")
12883 (set_attr "length" "2")
12884 (set_attr "length_address" "0")])
12886 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12887 [(set (match_operand:SI 0 "register_operand" "=&a")
12889 (unspec:SI [(match_operand 3 "tls_modbase_operand")
12890 (match_operand:SI 4)
12891 (match_operand:SI 2 "register_operand" "b")
12894 (const:SI (unspec:SI
12895 [(match_operand 1 "tls_symbolic_operand")]
12897 (clobber (reg:CC FLAGS_REG))]
12898 "!TARGET_64BIT && TARGET_GNU2_TLS"
12901 [(set (match_dup 0) (match_dup 5))]
12903 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12904 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12907 (define_expand "tls_dynamic_gnu2_64"
12908 [(set (match_dup 2)
12909 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12912 [(set (match_operand:DI 0 "register_operand")
12913 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12915 (clobber (reg:CC FLAGS_REG))])]
12916 "TARGET_64BIT && TARGET_GNU2_TLS"
12918 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12919 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12922 (define_insn "*tls_dynamic_gnu2_lea_64"
12923 [(set (match_operand:DI 0 "register_operand" "=r")
12924 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12926 "TARGET_64BIT && TARGET_GNU2_TLS"
12927 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12928 [(set_attr "type" "lea")
12929 (set_attr "mode" "DI")
12930 (set_attr "length" "7")
12931 (set_attr "length_address" "4")])
12933 (define_insn "*tls_dynamic_gnu2_call_64"
12934 [(set (match_operand:DI 0 "register_operand" "=a")
12935 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
12936 (match_operand:DI 2 "register_operand" "0")
12939 (clobber (reg:CC FLAGS_REG))]
12940 "TARGET_64BIT && TARGET_GNU2_TLS"
12941 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12942 [(set_attr "type" "call")
12943 (set_attr "length" "2")
12944 (set_attr "length_address" "0")])
12946 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12947 [(set (match_operand:DI 0 "register_operand" "=&a")
12949 (unspec:DI [(match_operand 2 "tls_modbase_operand")
12950 (match_operand:DI 3)
12953 (const:DI (unspec:DI
12954 [(match_operand 1 "tls_symbolic_operand")]
12956 (clobber (reg:CC FLAGS_REG))]
12957 "TARGET_64BIT && TARGET_GNU2_TLS"
12960 [(set (match_dup 0) (match_dup 4))]
12962 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12963 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12966 ;; These patterns match the binary 387 instructions for addM3, subM3,
12967 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12968 ;; SFmode. The first is the normal insn, the second the same insn but
12969 ;; with one operand a conversion, and the third the same insn but with
12970 ;; the other operand a conversion. The conversion may be SFmode or
12971 ;; SImode if the target mode DFmode, but only SImode if the target mode
12974 ;; Gcc is slightly more smart about handling normal two address instructions
12975 ;; so use special patterns for add and mull.
12977 (define_insn "*fop_<mode>_comm_mixed"
12978 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12979 (match_operator:MODEF 3 "binary_fp_operator"
12980 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12981 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12982 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12983 && COMMUTATIVE_ARITH_P (operands[3])
12984 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12985 "* return output_387_binary_op (insn, operands);"
12986 [(set (attr "type")
12987 (if_then_else (eq_attr "alternative" "1,2")
12988 (if_then_else (match_operand:MODEF 3 "mult_operator")
12989 (const_string "ssemul")
12990 (const_string "sseadd"))
12991 (if_then_else (match_operand:MODEF 3 "mult_operator")
12992 (const_string "fmul")
12993 (const_string "fop"))))
12994 (set_attr "isa" "*,noavx,avx")
12995 (set_attr "prefix" "orig,orig,vex")
12996 (set_attr "mode" "<MODE>")])
12998 (define_insn "*fop_<mode>_comm_sse"
12999 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13000 (match_operator:MODEF 3 "binary_fp_operator"
13001 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13002 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13003 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13004 && COMMUTATIVE_ARITH_P (operands[3])
13005 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13006 "* return output_387_binary_op (insn, operands);"
13007 [(set (attr "type")
13008 (if_then_else (match_operand:MODEF 3 "mult_operator")
13009 (const_string "ssemul")
13010 (const_string "sseadd")))
13011 (set_attr "isa" "noavx,avx")
13012 (set_attr "prefix" "orig,vex")
13013 (set_attr "mode" "<MODE>")])
13015 (define_insn "*fop_<mode>_comm_i387"
13016 [(set (match_operand:MODEF 0 "register_operand" "=f")
13017 (match_operator:MODEF 3 "binary_fp_operator"
13018 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13019 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13020 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13021 && COMMUTATIVE_ARITH_P (operands[3])
13022 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13023 "* return output_387_binary_op (insn, operands);"
13024 [(set (attr "type")
13025 (if_then_else (match_operand:MODEF 3 "mult_operator")
13026 (const_string "fmul")
13027 (const_string "fop")))
13028 (set_attr "mode" "<MODE>")])
13030 (define_insn "*fop_<mode>_1_mixed"
13031 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13032 (match_operator:MODEF 3 "binary_fp_operator"
13033 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13034 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13035 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13036 && !COMMUTATIVE_ARITH_P (operands[3])
13037 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13038 "* return output_387_binary_op (insn, operands);"
13039 [(set (attr "type")
13040 (cond [(and (eq_attr "alternative" "2,3")
13041 (match_operand:MODEF 3 "mult_operator"))
13042 (const_string "ssemul")
13043 (and (eq_attr "alternative" "2,3")
13044 (match_operand:MODEF 3 "div_operator"))
13045 (const_string "ssediv")
13046 (eq_attr "alternative" "2,3")
13047 (const_string "sseadd")
13048 (match_operand:MODEF 3 "mult_operator")
13049 (const_string "fmul")
13050 (match_operand:MODEF 3 "div_operator")
13051 (const_string "fdiv")
13053 (const_string "fop")))
13054 (set_attr "isa" "*,*,noavx,avx")
13055 (set_attr "prefix" "orig,orig,orig,vex")
13056 (set_attr "mode" "<MODE>")])
13058 (define_insn "*rcpsf2_sse"
13059 [(set (match_operand:SF 0 "register_operand" "=x")
13060 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13063 "%vrcpss\t{%1, %d0|%d0, %1}"
13064 [(set_attr "type" "sse")
13065 (set_attr "atom_sse_attr" "rcp")
13066 (set_attr "btver2_sse_attr" "rcp")
13067 (set_attr "prefix" "maybe_vex")
13068 (set_attr "mode" "SF")])
13070 (define_insn "*fop_<mode>_1_sse"
13071 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13072 (match_operator:MODEF 3 "binary_fp_operator"
13073 [(match_operand:MODEF 1 "register_operand" "0,x")
13074 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13075 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13076 && !COMMUTATIVE_ARITH_P (operands[3])"
13077 "* return output_387_binary_op (insn, operands);"
13078 [(set (attr "type")
13079 (cond [(match_operand:MODEF 3 "mult_operator")
13080 (const_string "ssemul")
13081 (match_operand:MODEF 3 "div_operator")
13082 (const_string "ssediv")
13084 (const_string "sseadd")))
13085 (set_attr "isa" "noavx,avx")
13086 (set_attr "prefix" "orig,vex")
13087 (set_attr "mode" "<MODE>")])
13089 ;; This pattern is not fully shadowed by the pattern above.
13090 (define_insn "*fop_<mode>_1_i387"
13091 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13092 (match_operator:MODEF 3 "binary_fp_operator"
13093 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13094 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13095 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13096 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13097 && !COMMUTATIVE_ARITH_P (operands[3])
13098 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13099 "* return output_387_binary_op (insn, operands);"
13100 [(set (attr "type")
13101 (cond [(match_operand:MODEF 3 "mult_operator")
13102 (const_string "fmul")
13103 (match_operand:MODEF 3 "div_operator")
13104 (const_string "fdiv")
13106 (const_string "fop")))
13107 (set_attr "mode" "<MODE>")])
13109 ;; ??? Add SSE splitters for these!
13110 (define_insn "*fop_<MODEF:mode>_2_i387"
13111 [(set (match_operand:MODEF 0 "register_operand" "=f")
13112 (match_operator:MODEF 3 "binary_fp_operator"
13114 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13115 (match_operand:MODEF 2 "register_operand" "0")]))]
13116 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13117 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13118 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13119 || optimize_function_for_size_p (cfun))"
13120 { return output_387_binary_op (insn, operands); }
13121 [(set (attr "type")
13122 (cond [(match_operand:MODEF 3 "mult_operator")
13123 (const_string "fmul")
13124 (match_operand:MODEF 3 "div_operator")
13125 (const_string "fdiv")
13127 (const_string "fop")))
13128 (set_attr "fp_int_src" "true")
13129 (set_attr "mode" "<SWI24:MODE>")])
13131 (define_insn "*fop_<MODEF:mode>_3_i387"
13132 [(set (match_operand:MODEF 0 "register_operand" "=f")
13133 (match_operator:MODEF 3 "binary_fp_operator"
13134 [(match_operand:MODEF 1 "register_operand" "0")
13136 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13137 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13138 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13139 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13140 || optimize_function_for_size_p (cfun))"
13141 { return output_387_binary_op (insn, operands); }
13142 [(set (attr "type")
13143 (cond [(match_operand:MODEF 3 "mult_operator")
13144 (const_string "fmul")
13145 (match_operand:MODEF 3 "div_operator")
13146 (const_string "fdiv")
13148 (const_string "fop")))
13149 (set_attr "fp_int_src" "true")
13150 (set_attr "mode" "<MODE>")])
13152 (define_insn "*fop_df_4_i387"
13153 [(set (match_operand:DF 0 "register_operand" "=f,f")
13154 (match_operator:DF 3 "binary_fp_operator"
13156 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13157 (match_operand:DF 2 "register_operand" "0,f")]))]
13158 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13159 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13160 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13161 "* return output_387_binary_op (insn, operands);"
13162 [(set (attr "type")
13163 (cond [(match_operand:DF 3 "mult_operator")
13164 (const_string "fmul")
13165 (match_operand:DF 3 "div_operator")
13166 (const_string "fdiv")
13168 (const_string "fop")))
13169 (set_attr "mode" "SF")])
13171 (define_insn "*fop_df_5_i387"
13172 [(set (match_operand:DF 0 "register_operand" "=f,f")
13173 (match_operator:DF 3 "binary_fp_operator"
13174 [(match_operand:DF 1 "register_operand" "0,f")
13176 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13177 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13178 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13179 "* return output_387_binary_op (insn, operands);"
13180 [(set (attr "type")
13181 (cond [(match_operand:DF 3 "mult_operator")
13182 (const_string "fmul")
13183 (match_operand:DF 3 "div_operator")
13184 (const_string "fdiv")
13186 (const_string "fop")))
13187 (set_attr "mode" "SF")])
13189 (define_insn "*fop_df_6_i387"
13190 [(set (match_operand:DF 0 "register_operand" "=f,f")
13191 (match_operator:DF 3 "binary_fp_operator"
13193 (match_operand:SF 1 "register_operand" "0,f"))
13195 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13196 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13197 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13198 "* return output_387_binary_op (insn, operands);"
13199 [(set (attr "type")
13200 (cond [(match_operand:DF 3 "mult_operator")
13201 (const_string "fmul")
13202 (match_operand:DF 3 "div_operator")
13203 (const_string "fdiv")
13205 (const_string "fop")))
13206 (set_attr "mode" "SF")])
13208 (define_insn "*fop_xf_comm_i387"
13209 [(set (match_operand:XF 0 "register_operand" "=f")
13210 (match_operator:XF 3 "binary_fp_operator"
13211 [(match_operand:XF 1 "register_operand" "%0")
13212 (match_operand:XF 2 "register_operand" "f")]))]
13214 && COMMUTATIVE_ARITH_P (operands[3])"
13215 "* return output_387_binary_op (insn, operands);"
13216 [(set (attr "type")
13217 (if_then_else (match_operand:XF 3 "mult_operator")
13218 (const_string "fmul")
13219 (const_string "fop")))
13220 (set_attr "mode" "XF")])
13222 (define_insn "*fop_xf_1_i387"
13223 [(set (match_operand:XF 0 "register_operand" "=f,f")
13224 (match_operator:XF 3 "binary_fp_operator"
13225 [(match_operand:XF 1 "register_operand" "0,f")
13226 (match_operand:XF 2 "register_operand" "f,0")]))]
13228 && !COMMUTATIVE_ARITH_P (operands[3])"
13229 "* return output_387_binary_op (insn, operands);"
13230 [(set (attr "type")
13231 (cond [(match_operand:XF 3 "mult_operator")
13232 (const_string "fmul")
13233 (match_operand:XF 3 "div_operator")
13234 (const_string "fdiv")
13236 (const_string "fop")))
13237 (set_attr "mode" "XF")])
13239 (define_insn "*fop_xf_2_i387"
13240 [(set (match_operand:XF 0 "register_operand" "=f")
13241 (match_operator:XF 3 "binary_fp_operator"
13243 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13244 (match_operand:XF 2 "register_operand" "0")]))]
13246 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13247 { return output_387_binary_op (insn, operands); }
13248 [(set (attr "type")
13249 (cond [(match_operand:XF 3 "mult_operator")
13250 (const_string "fmul")
13251 (match_operand:XF 3 "div_operator")
13252 (const_string "fdiv")
13254 (const_string "fop")))
13255 (set_attr "fp_int_src" "true")
13256 (set_attr "mode" "<MODE>")])
13258 (define_insn "*fop_xf_3_i387"
13259 [(set (match_operand:XF 0 "register_operand" "=f")
13260 (match_operator:XF 3 "binary_fp_operator"
13261 [(match_operand:XF 1 "register_operand" "0")
13263 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13265 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13266 { return output_387_binary_op (insn, operands); }
13267 [(set (attr "type")
13268 (cond [(match_operand:XF 3 "mult_operator")
13269 (const_string "fmul")
13270 (match_operand:XF 3 "div_operator")
13271 (const_string "fdiv")
13273 (const_string "fop")))
13274 (set_attr "fp_int_src" "true")
13275 (set_attr "mode" "<MODE>")])
13277 (define_insn "*fop_xf_4_i387"
13278 [(set (match_operand:XF 0 "register_operand" "=f,f")
13279 (match_operator:XF 3 "binary_fp_operator"
13281 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13282 (match_operand:XF 2 "register_operand" "0,f")]))]
13284 "* return output_387_binary_op (insn, operands);"
13285 [(set (attr "type")
13286 (cond [(match_operand:XF 3 "mult_operator")
13287 (const_string "fmul")
13288 (match_operand:XF 3 "div_operator")
13289 (const_string "fdiv")
13291 (const_string "fop")))
13292 (set_attr "mode" "<MODE>")])
13294 (define_insn "*fop_xf_5_i387"
13295 [(set (match_operand:XF 0 "register_operand" "=f,f")
13296 (match_operator:XF 3 "binary_fp_operator"
13297 [(match_operand:XF 1 "register_operand" "0,f")
13299 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13301 "* return output_387_binary_op (insn, operands);"
13302 [(set (attr "type")
13303 (cond [(match_operand:XF 3 "mult_operator")
13304 (const_string "fmul")
13305 (match_operand:XF 3 "div_operator")
13306 (const_string "fdiv")
13308 (const_string "fop")))
13309 (set_attr "mode" "<MODE>")])
13311 (define_insn "*fop_xf_6_i387"
13312 [(set (match_operand:XF 0 "register_operand" "=f,f")
13313 (match_operator:XF 3 "binary_fp_operator"
13315 (match_operand:MODEF 1 "register_operand" "0,f"))
13317 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13319 "* return output_387_binary_op (insn, operands);"
13320 [(set (attr "type")
13321 (cond [(match_operand:XF 3 "mult_operator")
13322 (const_string "fmul")
13323 (match_operand:XF 3 "div_operator")
13324 (const_string "fdiv")
13326 (const_string "fop")))
13327 (set_attr "mode" "<MODE>")])
13329 ;; FPU special functions.
13331 ;; This pattern implements a no-op XFmode truncation for
13332 ;; all fancy i386 XFmode math functions.
13334 (define_insn "truncxf<mode>2_i387_noop_unspec"
13335 [(set (match_operand:MODEF 0 "register_operand" "=f")
13336 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13337 UNSPEC_TRUNC_NOOP))]
13338 "TARGET_USE_FANCY_MATH_387"
13339 "* return output_387_reg_move (insn, operands);"
13340 [(set_attr "type" "fmov")
13341 (set_attr "mode" "<MODE>")])
13343 (define_insn "sqrtxf2"
13344 [(set (match_operand:XF 0 "register_operand" "=f")
13345 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13346 "TARGET_USE_FANCY_MATH_387"
13348 [(set_attr "type" "fpspc")
13349 (set_attr "mode" "XF")
13350 (set_attr "athlon_decode" "direct")
13351 (set_attr "amdfam10_decode" "direct")
13352 (set_attr "bdver1_decode" "direct")])
13354 (define_insn "sqrt_extend<mode>xf2_i387"
13355 [(set (match_operand:XF 0 "register_operand" "=f")
13358 (match_operand:MODEF 1 "register_operand" "0"))))]
13359 "TARGET_USE_FANCY_MATH_387"
13361 [(set_attr "type" "fpspc")
13362 (set_attr "mode" "XF")
13363 (set_attr "athlon_decode" "direct")
13364 (set_attr "amdfam10_decode" "direct")
13365 (set_attr "bdver1_decode" "direct")])
13367 (define_insn "*rsqrtsf2_sse"
13368 [(set (match_operand:SF 0 "register_operand" "=x")
13369 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13372 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13373 [(set_attr "type" "sse")
13374 (set_attr "atom_sse_attr" "rcp")
13375 (set_attr "btver2_sse_attr" "rcp")
13376 (set_attr "prefix" "maybe_vex")
13377 (set_attr "mode" "SF")])
13379 (define_expand "rsqrtsf2"
13380 [(set (match_operand:SF 0 "register_operand")
13381 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13385 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13389 (define_insn "*sqrt<mode>2_sse"
13390 [(set (match_operand:MODEF 0 "register_operand" "=x")
13392 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13393 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13394 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13395 [(set_attr "type" "sse")
13396 (set_attr "atom_sse_attr" "sqrt")
13397 (set_attr "btver2_sse_attr" "sqrt")
13398 (set_attr "prefix" "maybe_vex")
13399 (set_attr "mode" "<MODE>")
13400 (set_attr "athlon_decode" "*")
13401 (set_attr "amdfam10_decode" "*")
13402 (set_attr "bdver1_decode" "*")])
13404 (define_expand "sqrt<mode>2"
13405 [(set (match_operand:MODEF 0 "register_operand")
13407 (match_operand:MODEF 1 "nonimmediate_operand")))]
13408 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13409 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13411 if (<MODE>mode == SFmode
13413 && TARGET_RECIP_SQRT
13414 && !optimize_function_for_size_p (cfun)
13415 && flag_finite_math_only && !flag_trapping_math
13416 && flag_unsafe_math_optimizations)
13418 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13422 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13424 rtx op0 = gen_reg_rtx (XFmode);
13425 rtx op1 = force_reg (<MODE>mode, operands[1]);
13427 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13428 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13433 (define_insn "fpremxf4_i387"
13434 [(set (match_operand:XF 0 "register_operand" "=f")
13435 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13436 (match_operand:XF 3 "register_operand" "1")]
13438 (set (match_operand:XF 1 "register_operand" "=u")
13439 (unspec:XF [(match_dup 2) (match_dup 3)]
13441 (set (reg:CCFP FPSR_REG)
13442 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13444 "TARGET_USE_FANCY_MATH_387"
13446 [(set_attr "type" "fpspc")
13447 (set_attr "mode" "XF")])
13449 (define_expand "fmodxf3"
13450 [(use (match_operand:XF 0 "register_operand"))
13451 (use (match_operand:XF 1 "general_operand"))
13452 (use (match_operand:XF 2 "general_operand"))]
13453 "TARGET_USE_FANCY_MATH_387"
13455 rtx label = gen_label_rtx ();
13457 rtx op1 = gen_reg_rtx (XFmode);
13458 rtx op2 = gen_reg_rtx (XFmode);
13460 emit_move_insn (op2, operands[2]);
13461 emit_move_insn (op1, operands[1]);
13463 emit_label (label);
13464 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13465 ix86_emit_fp_unordered_jump (label);
13466 LABEL_NUSES (label) = 1;
13468 emit_move_insn (operands[0], op1);
13472 (define_expand "fmod<mode>3"
13473 [(use (match_operand:MODEF 0 "register_operand"))
13474 (use (match_operand:MODEF 1 "general_operand"))
13475 (use (match_operand:MODEF 2 "general_operand"))]
13476 "TARGET_USE_FANCY_MATH_387"
13478 rtx (*gen_truncxf) (rtx, rtx);
13480 rtx label = gen_label_rtx ();
13482 rtx op1 = gen_reg_rtx (XFmode);
13483 rtx op2 = gen_reg_rtx (XFmode);
13485 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13486 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13488 emit_label (label);
13489 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13490 ix86_emit_fp_unordered_jump (label);
13491 LABEL_NUSES (label) = 1;
13493 /* Truncate the result properly for strict SSE math. */
13494 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13495 && !TARGET_MIX_SSE_I387)
13496 gen_truncxf = gen_truncxf<mode>2;
13498 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13500 emit_insn (gen_truncxf (operands[0], op1));
13504 (define_insn "fprem1xf4_i387"
13505 [(set (match_operand:XF 0 "register_operand" "=f")
13506 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13507 (match_operand:XF 3 "register_operand" "1")]
13509 (set (match_operand:XF 1 "register_operand" "=u")
13510 (unspec:XF [(match_dup 2) (match_dup 3)]
13512 (set (reg:CCFP FPSR_REG)
13513 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13515 "TARGET_USE_FANCY_MATH_387"
13517 [(set_attr "type" "fpspc")
13518 (set_attr "mode" "XF")])
13520 (define_expand "remainderxf3"
13521 [(use (match_operand:XF 0 "register_operand"))
13522 (use (match_operand:XF 1 "general_operand"))
13523 (use (match_operand:XF 2 "general_operand"))]
13524 "TARGET_USE_FANCY_MATH_387"
13526 rtx label = gen_label_rtx ();
13528 rtx op1 = gen_reg_rtx (XFmode);
13529 rtx op2 = gen_reg_rtx (XFmode);
13531 emit_move_insn (op2, operands[2]);
13532 emit_move_insn (op1, operands[1]);
13534 emit_label (label);
13535 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13536 ix86_emit_fp_unordered_jump (label);
13537 LABEL_NUSES (label) = 1;
13539 emit_move_insn (operands[0], op1);
13543 (define_expand "remainder<mode>3"
13544 [(use (match_operand:MODEF 0 "register_operand"))
13545 (use (match_operand:MODEF 1 "general_operand"))
13546 (use (match_operand:MODEF 2 "general_operand"))]
13547 "TARGET_USE_FANCY_MATH_387"
13549 rtx (*gen_truncxf) (rtx, rtx);
13551 rtx label = gen_label_rtx ();
13553 rtx op1 = gen_reg_rtx (XFmode);
13554 rtx op2 = gen_reg_rtx (XFmode);
13556 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13557 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13559 emit_label (label);
13561 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13562 ix86_emit_fp_unordered_jump (label);
13563 LABEL_NUSES (label) = 1;
13565 /* Truncate the result properly for strict SSE math. */
13566 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13567 && !TARGET_MIX_SSE_I387)
13568 gen_truncxf = gen_truncxf<mode>2;
13570 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13572 emit_insn (gen_truncxf (operands[0], op1));
13576 (define_int_iterator SINCOS
13580 (define_int_attr sincos
13581 [(UNSPEC_SIN "sin")
13582 (UNSPEC_COS "cos")])
13584 (define_insn "*<sincos>xf2_i387"
13585 [(set (match_operand:XF 0 "register_operand" "=f")
13586 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13588 "TARGET_USE_FANCY_MATH_387
13589 && flag_unsafe_math_optimizations"
13591 [(set_attr "type" "fpspc")
13592 (set_attr "mode" "XF")])
13594 (define_insn "*<sincos>_extend<mode>xf2_i387"
13595 [(set (match_operand:XF 0 "register_operand" "=f")
13596 (unspec:XF [(float_extend:XF
13597 (match_operand:MODEF 1 "register_operand" "0"))]
13599 "TARGET_USE_FANCY_MATH_387
13600 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13601 || TARGET_MIX_SSE_I387)
13602 && flag_unsafe_math_optimizations"
13604 [(set_attr "type" "fpspc")
13605 (set_attr "mode" "XF")])
13607 ;; When sincos pattern is defined, sin and cos builtin functions will be
13608 ;; expanded to sincos pattern with one of its outputs left unused.
13609 ;; CSE pass will figure out if two sincos patterns can be combined,
13610 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13611 ;; depending on the unused output.
13613 (define_insn "sincosxf3"
13614 [(set (match_operand:XF 0 "register_operand" "=f")
13615 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13616 UNSPEC_SINCOS_COS))
13617 (set (match_operand:XF 1 "register_operand" "=u")
13618 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13619 "TARGET_USE_FANCY_MATH_387
13620 && flag_unsafe_math_optimizations"
13622 [(set_attr "type" "fpspc")
13623 (set_attr "mode" "XF")])
13626 [(set (match_operand:XF 0 "register_operand")
13627 (unspec:XF [(match_operand:XF 2 "register_operand")]
13628 UNSPEC_SINCOS_COS))
13629 (set (match_operand:XF 1 "register_operand")
13630 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13631 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13632 && can_create_pseudo_p ()"
13633 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13636 [(set (match_operand:XF 0 "register_operand")
13637 (unspec:XF [(match_operand:XF 2 "register_operand")]
13638 UNSPEC_SINCOS_COS))
13639 (set (match_operand:XF 1 "register_operand")
13640 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13641 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13642 && can_create_pseudo_p ()"
13643 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13645 (define_insn "sincos_extend<mode>xf3_i387"
13646 [(set (match_operand:XF 0 "register_operand" "=f")
13647 (unspec:XF [(float_extend:XF
13648 (match_operand:MODEF 2 "register_operand" "0"))]
13649 UNSPEC_SINCOS_COS))
13650 (set (match_operand:XF 1 "register_operand" "=u")
13651 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13652 "TARGET_USE_FANCY_MATH_387
13653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13654 || TARGET_MIX_SSE_I387)
13655 && flag_unsafe_math_optimizations"
13657 [(set_attr "type" "fpspc")
13658 (set_attr "mode" "XF")])
13661 [(set (match_operand:XF 0 "register_operand")
13662 (unspec:XF [(float_extend:XF
13663 (match_operand:MODEF 2 "register_operand"))]
13664 UNSPEC_SINCOS_COS))
13665 (set (match_operand:XF 1 "register_operand")
13666 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13667 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13668 && can_create_pseudo_p ()"
13669 [(set (match_dup 1)
13670 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13673 [(set (match_operand:XF 0 "register_operand")
13674 (unspec:XF [(float_extend:XF
13675 (match_operand:MODEF 2 "register_operand"))]
13676 UNSPEC_SINCOS_COS))
13677 (set (match_operand:XF 1 "register_operand")
13678 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13679 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13680 && can_create_pseudo_p ()"
13681 [(set (match_dup 0)
13682 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13684 (define_expand "sincos<mode>3"
13685 [(use (match_operand:MODEF 0 "register_operand"))
13686 (use (match_operand:MODEF 1 "register_operand"))
13687 (use (match_operand:MODEF 2 "register_operand"))]
13688 "TARGET_USE_FANCY_MATH_387
13689 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13690 || TARGET_MIX_SSE_I387)
13691 && flag_unsafe_math_optimizations"
13693 rtx op0 = gen_reg_rtx (XFmode);
13694 rtx op1 = gen_reg_rtx (XFmode);
13696 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13697 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13698 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13702 (define_insn "fptanxf4_i387"
13703 [(set (match_operand:XF 0 "register_operand" "=f")
13704 (match_operand:XF 3 "const_double_operand" "F"))
13705 (set (match_operand:XF 1 "register_operand" "=u")
13706 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13708 "TARGET_USE_FANCY_MATH_387
13709 && flag_unsafe_math_optimizations
13710 && standard_80387_constant_p (operands[3]) == 2"
13712 [(set_attr "type" "fpspc")
13713 (set_attr "mode" "XF")])
13715 (define_insn "fptan_extend<mode>xf4_i387"
13716 [(set (match_operand:MODEF 0 "register_operand" "=f")
13717 (match_operand:MODEF 3 "const_double_operand" "F"))
13718 (set (match_operand:XF 1 "register_operand" "=u")
13719 (unspec:XF [(float_extend:XF
13720 (match_operand:MODEF 2 "register_operand" "0"))]
13722 "TARGET_USE_FANCY_MATH_387
13723 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13724 || TARGET_MIX_SSE_I387)
13725 && flag_unsafe_math_optimizations
13726 && standard_80387_constant_p (operands[3]) == 2"
13728 [(set_attr "type" "fpspc")
13729 (set_attr "mode" "XF")])
13731 (define_expand "tanxf2"
13732 [(use (match_operand:XF 0 "register_operand"))
13733 (use (match_operand:XF 1 "register_operand"))]
13734 "TARGET_USE_FANCY_MATH_387
13735 && flag_unsafe_math_optimizations"
13737 rtx one = gen_reg_rtx (XFmode);
13738 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13740 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13744 (define_expand "tan<mode>2"
13745 [(use (match_operand:MODEF 0 "register_operand"))
13746 (use (match_operand:MODEF 1 "register_operand"))]
13747 "TARGET_USE_FANCY_MATH_387
13748 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13749 || TARGET_MIX_SSE_I387)
13750 && flag_unsafe_math_optimizations"
13752 rtx op0 = gen_reg_rtx (XFmode);
13754 rtx one = gen_reg_rtx (<MODE>mode);
13755 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13757 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13758 operands[1], op2));
13759 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13763 (define_insn "*fpatanxf3_i387"
13764 [(set (match_operand:XF 0 "register_operand" "=f")
13765 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13766 (match_operand:XF 2 "register_operand" "u")]
13768 (clobber (match_scratch:XF 3 "=2"))]
13769 "TARGET_USE_FANCY_MATH_387
13770 && flag_unsafe_math_optimizations"
13772 [(set_attr "type" "fpspc")
13773 (set_attr "mode" "XF")])
13775 (define_insn "fpatan_extend<mode>xf3_i387"
13776 [(set (match_operand:XF 0 "register_operand" "=f")
13777 (unspec:XF [(float_extend:XF
13778 (match_operand:MODEF 1 "register_operand" "0"))
13780 (match_operand:MODEF 2 "register_operand" "u"))]
13782 (clobber (match_scratch:XF 3 "=2"))]
13783 "TARGET_USE_FANCY_MATH_387
13784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13785 || TARGET_MIX_SSE_I387)
13786 && flag_unsafe_math_optimizations"
13788 [(set_attr "type" "fpspc")
13789 (set_attr "mode" "XF")])
13791 (define_expand "atan2xf3"
13792 [(parallel [(set (match_operand:XF 0 "register_operand")
13793 (unspec:XF [(match_operand:XF 2 "register_operand")
13794 (match_operand:XF 1 "register_operand")]
13796 (clobber (match_scratch:XF 3))])]
13797 "TARGET_USE_FANCY_MATH_387
13798 && flag_unsafe_math_optimizations")
13800 (define_expand "atan2<mode>3"
13801 [(use (match_operand:MODEF 0 "register_operand"))
13802 (use (match_operand:MODEF 1 "register_operand"))
13803 (use (match_operand:MODEF 2 "register_operand"))]
13804 "TARGET_USE_FANCY_MATH_387
13805 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13806 || TARGET_MIX_SSE_I387)
13807 && flag_unsafe_math_optimizations"
13809 rtx op0 = gen_reg_rtx (XFmode);
13811 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13812 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13816 (define_expand "atanxf2"
13817 [(parallel [(set (match_operand:XF 0 "register_operand")
13818 (unspec:XF [(match_dup 2)
13819 (match_operand:XF 1 "register_operand")]
13821 (clobber (match_scratch:XF 3))])]
13822 "TARGET_USE_FANCY_MATH_387
13823 && flag_unsafe_math_optimizations"
13825 operands[2] = gen_reg_rtx (XFmode);
13826 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13829 (define_expand "atan<mode>2"
13830 [(use (match_operand:MODEF 0 "register_operand"))
13831 (use (match_operand:MODEF 1 "register_operand"))]
13832 "TARGET_USE_FANCY_MATH_387
13833 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13834 || TARGET_MIX_SSE_I387)
13835 && flag_unsafe_math_optimizations"
13837 rtx op0 = gen_reg_rtx (XFmode);
13839 rtx op2 = gen_reg_rtx (<MODE>mode);
13840 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13842 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13843 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13847 (define_expand "asinxf2"
13848 [(set (match_dup 2)
13849 (mult:XF (match_operand:XF 1 "register_operand")
13851 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13852 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13853 (parallel [(set (match_operand:XF 0 "register_operand")
13854 (unspec:XF [(match_dup 5) (match_dup 1)]
13856 (clobber (match_scratch:XF 6))])]
13857 "TARGET_USE_FANCY_MATH_387
13858 && flag_unsafe_math_optimizations"
13862 if (optimize_insn_for_size_p ())
13865 for (i = 2; i < 6; i++)
13866 operands[i] = gen_reg_rtx (XFmode);
13868 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13871 (define_expand "asin<mode>2"
13872 [(use (match_operand:MODEF 0 "register_operand"))
13873 (use (match_operand:MODEF 1 "general_operand"))]
13874 "TARGET_USE_FANCY_MATH_387
13875 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13876 || TARGET_MIX_SSE_I387)
13877 && flag_unsafe_math_optimizations"
13879 rtx op0 = gen_reg_rtx (XFmode);
13880 rtx op1 = gen_reg_rtx (XFmode);
13882 if (optimize_insn_for_size_p ())
13885 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13886 emit_insn (gen_asinxf2 (op0, op1));
13887 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13891 (define_expand "acosxf2"
13892 [(set (match_dup 2)
13893 (mult:XF (match_operand:XF 1 "register_operand")
13895 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13896 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13897 (parallel [(set (match_operand:XF 0 "register_operand")
13898 (unspec:XF [(match_dup 1) (match_dup 5)]
13900 (clobber (match_scratch:XF 6))])]
13901 "TARGET_USE_FANCY_MATH_387
13902 && flag_unsafe_math_optimizations"
13906 if (optimize_insn_for_size_p ())
13909 for (i = 2; i < 6; i++)
13910 operands[i] = gen_reg_rtx (XFmode);
13912 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13915 (define_expand "acos<mode>2"
13916 [(use (match_operand:MODEF 0 "register_operand"))
13917 (use (match_operand:MODEF 1 "general_operand"))]
13918 "TARGET_USE_FANCY_MATH_387
13919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13920 || TARGET_MIX_SSE_I387)
13921 && flag_unsafe_math_optimizations"
13923 rtx op0 = gen_reg_rtx (XFmode);
13924 rtx op1 = gen_reg_rtx (XFmode);
13926 if (optimize_insn_for_size_p ())
13929 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13930 emit_insn (gen_acosxf2 (op0, op1));
13931 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13935 (define_insn "fyl2xxf3_i387"
13936 [(set (match_operand:XF 0 "register_operand" "=f")
13937 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13938 (match_operand:XF 2 "register_operand" "u")]
13940 (clobber (match_scratch:XF 3 "=2"))]
13941 "TARGET_USE_FANCY_MATH_387
13942 && flag_unsafe_math_optimizations"
13944 [(set_attr "type" "fpspc")
13945 (set_attr "mode" "XF")])
13947 (define_insn "fyl2x_extend<mode>xf3_i387"
13948 [(set (match_operand:XF 0 "register_operand" "=f")
13949 (unspec:XF [(float_extend:XF
13950 (match_operand:MODEF 1 "register_operand" "0"))
13951 (match_operand:XF 2 "register_operand" "u")]
13953 (clobber (match_scratch:XF 3 "=2"))]
13954 "TARGET_USE_FANCY_MATH_387
13955 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13956 || TARGET_MIX_SSE_I387)
13957 && flag_unsafe_math_optimizations"
13959 [(set_attr "type" "fpspc")
13960 (set_attr "mode" "XF")])
13962 (define_expand "logxf2"
13963 [(parallel [(set (match_operand:XF 0 "register_operand")
13964 (unspec:XF [(match_operand:XF 1 "register_operand")
13965 (match_dup 2)] UNSPEC_FYL2X))
13966 (clobber (match_scratch:XF 3))])]
13967 "TARGET_USE_FANCY_MATH_387
13968 && flag_unsafe_math_optimizations"
13970 operands[2] = gen_reg_rtx (XFmode);
13971 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13974 (define_expand "log<mode>2"
13975 [(use (match_operand:MODEF 0 "register_operand"))
13976 (use (match_operand:MODEF 1 "register_operand"))]
13977 "TARGET_USE_FANCY_MATH_387
13978 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13979 || TARGET_MIX_SSE_I387)
13980 && flag_unsafe_math_optimizations"
13982 rtx op0 = gen_reg_rtx (XFmode);
13984 rtx op2 = gen_reg_rtx (XFmode);
13985 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13987 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13988 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13992 (define_expand "log10xf2"
13993 [(parallel [(set (match_operand:XF 0 "register_operand")
13994 (unspec:XF [(match_operand:XF 1 "register_operand")
13995 (match_dup 2)] UNSPEC_FYL2X))
13996 (clobber (match_scratch:XF 3))])]
13997 "TARGET_USE_FANCY_MATH_387
13998 && flag_unsafe_math_optimizations"
14000 operands[2] = gen_reg_rtx (XFmode);
14001 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14004 (define_expand "log10<mode>2"
14005 [(use (match_operand:MODEF 0 "register_operand"))
14006 (use (match_operand:MODEF 1 "register_operand"))]
14007 "TARGET_USE_FANCY_MATH_387
14008 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14009 || TARGET_MIX_SSE_I387)
14010 && flag_unsafe_math_optimizations"
14012 rtx op0 = gen_reg_rtx (XFmode);
14014 rtx op2 = gen_reg_rtx (XFmode);
14015 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14017 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14018 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14022 (define_expand "log2xf2"
14023 [(parallel [(set (match_operand:XF 0 "register_operand")
14024 (unspec:XF [(match_operand:XF 1 "register_operand")
14025 (match_dup 2)] UNSPEC_FYL2X))
14026 (clobber (match_scratch:XF 3))])]
14027 "TARGET_USE_FANCY_MATH_387
14028 && flag_unsafe_math_optimizations"
14030 operands[2] = gen_reg_rtx (XFmode);
14031 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14034 (define_expand "log2<mode>2"
14035 [(use (match_operand:MODEF 0 "register_operand"))
14036 (use (match_operand:MODEF 1 "register_operand"))]
14037 "TARGET_USE_FANCY_MATH_387
14038 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14039 || TARGET_MIX_SSE_I387)
14040 && flag_unsafe_math_optimizations"
14042 rtx op0 = gen_reg_rtx (XFmode);
14044 rtx op2 = gen_reg_rtx (XFmode);
14045 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14047 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14048 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14052 (define_insn "fyl2xp1xf3_i387"
14053 [(set (match_operand:XF 0 "register_operand" "=f")
14054 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14055 (match_operand:XF 2 "register_operand" "u")]
14057 (clobber (match_scratch:XF 3 "=2"))]
14058 "TARGET_USE_FANCY_MATH_387
14059 && flag_unsafe_math_optimizations"
14061 [(set_attr "type" "fpspc")
14062 (set_attr "mode" "XF")])
14064 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14065 [(set (match_operand:XF 0 "register_operand" "=f")
14066 (unspec:XF [(float_extend:XF
14067 (match_operand:MODEF 1 "register_operand" "0"))
14068 (match_operand:XF 2 "register_operand" "u")]
14070 (clobber (match_scratch:XF 3 "=2"))]
14071 "TARGET_USE_FANCY_MATH_387
14072 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14073 || TARGET_MIX_SSE_I387)
14074 && flag_unsafe_math_optimizations"
14076 [(set_attr "type" "fpspc")
14077 (set_attr "mode" "XF")])
14079 (define_expand "log1pxf2"
14080 [(use (match_operand:XF 0 "register_operand"))
14081 (use (match_operand:XF 1 "register_operand"))]
14082 "TARGET_USE_FANCY_MATH_387
14083 && flag_unsafe_math_optimizations"
14085 if (optimize_insn_for_size_p ())
14088 ix86_emit_i387_log1p (operands[0], operands[1]);
14092 (define_expand "log1p<mode>2"
14093 [(use (match_operand:MODEF 0 "register_operand"))
14094 (use (match_operand:MODEF 1 "register_operand"))]
14095 "TARGET_USE_FANCY_MATH_387
14096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14097 || TARGET_MIX_SSE_I387)
14098 && flag_unsafe_math_optimizations"
14102 if (optimize_insn_for_size_p ())
14105 op0 = gen_reg_rtx (XFmode);
14107 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14109 ix86_emit_i387_log1p (op0, operands[1]);
14110 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14114 (define_insn "fxtractxf3_i387"
14115 [(set (match_operand:XF 0 "register_operand" "=f")
14116 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14117 UNSPEC_XTRACT_FRACT))
14118 (set (match_operand:XF 1 "register_operand" "=u")
14119 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14120 "TARGET_USE_FANCY_MATH_387
14121 && flag_unsafe_math_optimizations"
14123 [(set_attr "type" "fpspc")
14124 (set_attr "mode" "XF")])
14126 (define_insn "fxtract_extend<mode>xf3_i387"
14127 [(set (match_operand:XF 0 "register_operand" "=f")
14128 (unspec:XF [(float_extend:XF
14129 (match_operand:MODEF 2 "register_operand" "0"))]
14130 UNSPEC_XTRACT_FRACT))
14131 (set (match_operand:XF 1 "register_operand" "=u")
14132 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14133 "TARGET_USE_FANCY_MATH_387
14134 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14135 || TARGET_MIX_SSE_I387)
14136 && flag_unsafe_math_optimizations"
14138 [(set_attr "type" "fpspc")
14139 (set_attr "mode" "XF")])
14141 (define_expand "logbxf2"
14142 [(parallel [(set (match_dup 2)
14143 (unspec:XF [(match_operand:XF 1 "register_operand")]
14144 UNSPEC_XTRACT_FRACT))
14145 (set (match_operand:XF 0 "register_operand")
14146 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14147 "TARGET_USE_FANCY_MATH_387
14148 && flag_unsafe_math_optimizations"
14149 "operands[2] = gen_reg_rtx (XFmode);")
14151 (define_expand "logb<mode>2"
14152 [(use (match_operand:MODEF 0 "register_operand"))
14153 (use (match_operand:MODEF 1 "register_operand"))]
14154 "TARGET_USE_FANCY_MATH_387
14155 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14156 || TARGET_MIX_SSE_I387)
14157 && flag_unsafe_math_optimizations"
14159 rtx op0 = gen_reg_rtx (XFmode);
14160 rtx op1 = gen_reg_rtx (XFmode);
14162 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14163 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14167 (define_expand "ilogbxf2"
14168 [(use (match_operand:SI 0 "register_operand"))
14169 (use (match_operand:XF 1 "register_operand"))]
14170 "TARGET_USE_FANCY_MATH_387
14171 && flag_unsafe_math_optimizations"
14175 if (optimize_insn_for_size_p ())
14178 op0 = gen_reg_rtx (XFmode);
14179 op1 = gen_reg_rtx (XFmode);
14181 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14182 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14186 (define_expand "ilogb<mode>2"
14187 [(use (match_operand:SI 0 "register_operand"))
14188 (use (match_operand:MODEF 1 "register_operand"))]
14189 "TARGET_USE_FANCY_MATH_387
14190 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14191 || TARGET_MIX_SSE_I387)
14192 && flag_unsafe_math_optimizations"
14196 if (optimize_insn_for_size_p ())
14199 op0 = gen_reg_rtx (XFmode);
14200 op1 = gen_reg_rtx (XFmode);
14202 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14203 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14207 (define_insn "*f2xm1xf2_i387"
14208 [(set (match_operand:XF 0 "register_operand" "=f")
14209 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14211 "TARGET_USE_FANCY_MATH_387
14212 && flag_unsafe_math_optimizations"
14214 [(set_attr "type" "fpspc")
14215 (set_attr "mode" "XF")])
14217 (define_insn "fscalexf4_i387"
14218 [(set (match_operand:XF 0 "register_operand" "=f")
14219 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14220 (match_operand:XF 3 "register_operand" "1")]
14221 UNSPEC_FSCALE_FRACT))
14222 (set (match_operand:XF 1 "register_operand" "=u")
14223 (unspec:XF [(match_dup 2) (match_dup 3)]
14224 UNSPEC_FSCALE_EXP))]
14225 "TARGET_USE_FANCY_MATH_387
14226 && flag_unsafe_math_optimizations"
14228 [(set_attr "type" "fpspc")
14229 (set_attr "mode" "XF")])
14231 (define_expand "expNcorexf3"
14232 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14233 (match_operand:XF 2 "register_operand")))
14234 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14235 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14236 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14237 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14238 (parallel [(set (match_operand:XF 0 "register_operand")
14239 (unspec:XF [(match_dup 8) (match_dup 4)]
14240 UNSPEC_FSCALE_FRACT))
14242 (unspec:XF [(match_dup 8) (match_dup 4)]
14243 UNSPEC_FSCALE_EXP))])]
14244 "TARGET_USE_FANCY_MATH_387
14245 && flag_unsafe_math_optimizations"
14249 if (optimize_insn_for_size_p ())
14252 for (i = 3; i < 10; i++)
14253 operands[i] = gen_reg_rtx (XFmode);
14255 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14258 (define_expand "expxf2"
14259 [(use (match_operand:XF 0 "register_operand"))
14260 (use (match_operand:XF 1 "register_operand"))]
14261 "TARGET_USE_FANCY_MATH_387
14262 && flag_unsafe_math_optimizations"
14266 if (optimize_insn_for_size_p ())
14269 op2 = gen_reg_rtx (XFmode);
14270 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14272 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14276 (define_expand "exp<mode>2"
14277 [(use (match_operand:MODEF 0 "register_operand"))
14278 (use (match_operand:MODEF 1 "general_operand"))]
14279 "TARGET_USE_FANCY_MATH_387
14280 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14281 || TARGET_MIX_SSE_I387)
14282 && flag_unsafe_math_optimizations"
14286 if (optimize_insn_for_size_p ())
14289 op0 = gen_reg_rtx (XFmode);
14290 op1 = gen_reg_rtx (XFmode);
14292 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14293 emit_insn (gen_expxf2 (op0, op1));
14294 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14298 (define_expand "exp10xf2"
14299 [(use (match_operand:XF 0 "register_operand"))
14300 (use (match_operand:XF 1 "register_operand"))]
14301 "TARGET_USE_FANCY_MATH_387
14302 && flag_unsafe_math_optimizations"
14306 if (optimize_insn_for_size_p ())
14309 op2 = gen_reg_rtx (XFmode);
14310 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14312 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14316 (define_expand "exp10<mode>2"
14317 [(use (match_operand:MODEF 0 "register_operand"))
14318 (use (match_operand:MODEF 1 "general_operand"))]
14319 "TARGET_USE_FANCY_MATH_387
14320 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14321 || TARGET_MIX_SSE_I387)
14322 && flag_unsafe_math_optimizations"
14326 if (optimize_insn_for_size_p ())
14329 op0 = gen_reg_rtx (XFmode);
14330 op1 = gen_reg_rtx (XFmode);
14332 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14333 emit_insn (gen_exp10xf2 (op0, op1));
14334 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14338 (define_expand "exp2xf2"
14339 [(use (match_operand:XF 0 "register_operand"))
14340 (use (match_operand:XF 1 "register_operand"))]
14341 "TARGET_USE_FANCY_MATH_387
14342 && flag_unsafe_math_optimizations"
14346 if (optimize_insn_for_size_p ())
14349 op2 = gen_reg_rtx (XFmode);
14350 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14352 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14356 (define_expand "exp2<mode>2"
14357 [(use (match_operand:MODEF 0 "register_operand"))
14358 (use (match_operand:MODEF 1 "general_operand"))]
14359 "TARGET_USE_FANCY_MATH_387
14360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14361 || TARGET_MIX_SSE_I387)
14362 && flag_unsafe_math_optimizations"
14366 if (optimize_insn_for_size_p ())
14369 op0 = gen_reg_rtx (XFmode);
14370 op1 = gen_reg_rtx (XFmode);
14372 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14373 emit_insn (gen_exp2xf2 (op0, op1));
14374 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14378 (define_expand "expm1xf2"
14379 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14381 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14382 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14383 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14384 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14385 (parallel [(set (match_dup 7)
14386 (unspec:XF [(match_dup 6) (match_dup 4)]
14387 UNSPEC_FSCALE_FRACT))
14389 (unspec:XF [(match_dup 6) (match_dup 4)]
14390 UNSPEC_FSCALE_EXP))])
14391 (parallel [(set (match_dup 10)
14392 (unspec:XF [(match_dup 9) (match_dup 8)]
14393 UNSPEC_FSCALE_FRACT))
14394 (set (match_dup 11)
14395 (unspec:XF [(match_dup 9) (match_dup 8)]
14396 UNSPEC_FSCALE_EXP))])
14397 (set (match_dup 12) (minus:XF (match_dup 10)
14398 (float_extend:XF (match_dup 13))))
14399 (set (match_operand:XF 0 "register_operand")
14400 (plus:XF (match_dup 12) (match_dup 7)))]
14401 "TARGET_USE_FANCY_MATH_387
14402 && flag_unsafe_math_optimizations"
14406 if (optimize_insn_for_size_p ())
14409 for (i = 2; i < 13; i++)
14410 operands[i] = gen_reg_rtx (XFmode);
14413 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14415 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14418 (define_expand "expm1<mode>2"
14419 [(use (match_operand:MODEF 0 "register_operand"))
14420 (use (match_operand:MODEF 1 "general_operand"))]
14421 "TARGET_USE_FANCY_MATH_387
14422 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14423 || TARGET_MIX_SSE_I387)
14424 && flag_unsafe_math_optimizations"
14428 if (optimize_insn_for_size_p ())
14431 op0 = gen_reg_rtx (XFmode);
14432 op1 = gen_reg_rtx (XFmode);
14434 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14435 emit_insn (gen_expm1xf2 (op0, op1));
14436 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14440 (define_expand "ldexpxf3"
14441 [(match_operand:XF 0 "register_operand")
14442 (match_operand:XF 1 "register_operand")
14443 (match_operand:SI 2 "register_operand")]
14444 "TARGET_USE_FANCY_MATH_387
14445 && flag_unsafe_math_optimizations"
14447 if (optimize_insn_for_size_p ())
14450 operands[3] = gen_reg_rtx (XFmode);
14451 operands[4] = gen_reg_rtx (XFmode);
14453 emit_insn (gen_floatsixf2 (operands[3], operands[2]));
14454 emit_insn (gen_fscalexf4_i387 (operands[0], operands[4],
14455 operands[1], operands[3]));
14459 (define_expand "ldexp<mode>3"
14460 [(use (match_operand:MODEF 0 "register_operand"))
14461 (use (match_operand:MODEF 1 "general_operand"))
14462 (use (match_operand:SI 2 "register_operand"))]
14463 "TARGET_USE_FANCY_MATH_387
14464 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14465 || TARGET_MIX_SSE_I387)
14466 && flag_unsafe_math_optimizations"
14470 if (optimize_insn_for_size_p ())
14473 op0 = gen_reg_rtx (XFmode);
14474 op1 = gen_reg_rtx (XFmode);
14476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14477 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14478 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14482 (define_expand "scalbxf3"
14483 [(parallel [(set (match_operand:XF 0 " register_operand")
14484 (unspec:XF [(match_operand:XF 1 "register_operand")
14485 (match_operand:XF 2 "register_operand")]
14486 UNSPEC_FSCALE_FRACT))
14488 (unspec:XF [(match_dup 1) (match_dup 2)]
14489 UNSPEC_FSCALE_EXP))])]
14490 "TARGET_USE_FANCY_MATH_387
14491 && flag_unsafe_math_optimizations"
14493 if (optimize_insn_for_size_p ())
14496 operands[3] = gen_reg_rtx (XFmode);
14499 (define_expand "scalb<mode>3"
14500 [(use (match_operand:MODEF 0 "register_operand"))
14501 (use (match_operand:MODEF 1 "general_operand"))
14502 (use (match_operand:MODEF 2 "general_operand"))]
14503 "TARGET_USE_FANCY_MATH_387
14504 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14505 || TARGET_MIX_SSE_I387)
14506 && flag_unsafe_math_optimizations"
14510 if (optimize_insn_for_size_p ())
14513 op0 = gen_reg_rtx (XFmode);
14514 op1 = gen_reg_rtx (XFmode);
14515 op2 = gen_reg_rtx (XFmode);
14517 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14518 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14519 emit_insn (gen_scalbxf3 (op0, op1, op2));
14520 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14524 (define_expand "significandxf2"
14525 [(parallel [(set (match_operand:XF 0 "register_operand")
14526 (unspec:XF [(match_operand:XF 1 "register_operand")]
14527 UNSPEC_XTRACT_FRACT))
14529 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14530 "TARGET_USE_FANCY_MATH_387
14531 && flag_unsafe_math_optimizations"
14532 "operands[2] = gen_reg_rtx (XFmode);")
14534 (define_expand "significand<mode>2"
14535 [(use (match_operand:MODEF 0 "register_operand"))
14536 (use (match_operand:MODEF 1 "register_operand"))]
14537 "TARGET_USE_FANCY_MATH_387
14538 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14539 || TARGET_MIX_SSE_I387)
14540 && flag_unsafe_math_optimizations"
14542 rtx op0 = gen_reg_rtx (XFmode);
14543 rtx op1 = gen_reg_rtx (XFmode);
14545 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14546 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14551 (define_insn "sse4_1_round<mode>2"
14552 [(set (match_operand:MODEF 0 "register_operand" "=x")
14553 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14554 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14557 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14558 [(set_attr "type" "ssecvt")
14559 (set_attr "prefix_extra" "1")
14560 (set_attr "prefix" "maybe_vex")
14561 (set_attr "mode" "<MODE>")])
14563 (define_insn "rintxf2"
14564 [(set (match_operand:XF 0 "register_operand" "=f")
14565 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14567 "TARGET_USE_FANCY_MATH_387
14568 && flag_unsafe_math_optimizations"
14570 [(set_attr "type" "fpspc")
14571 (set_attr "mode" "XF")])
14573 (define_expand "rint<mode>2"
14574 [(use (match_operand:MODEF 0 "register_operand"))
14575 (use (match_operand:MODEF 1 "register_operand"))]
14576 "(TARGET_USE_FANCY_MATH_387
14577 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14578 || TARGET_MIX_SSE_I387)
14579 && flag_unsafe_math_optimizations)
14580 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14581 && !flag_trapping_math)"
14583 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14584 && !flag_trapping_math)
14587 emit_insn (gen_sse4_1_round<mode>2
14588 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14589 else if (optimize_insn_for_size_p ())
14592 ix86_expand_rint (operands[0], operands[1]);
14596 rtx op0 = gen_reg_rtx (XFmode);
14597 rtx op1 = gen_reg_rtx (XFmode);
14599 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14600 emit_insn (gen_rintxf2 (op0, op1));
14602 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14607 (define_expand "round<mode>2"
14608 [(match_operand:X87MODEF 0 "register_operand")
14609 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14610 "(TARGET_USE_FANCY_MATH_387
14611 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14612 || TARGET_MIX_SSE_I387)
14613 && flag_unsafe_math_optimizations)
14614 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14615 && !flag_trapping_math && !flag_rounding_math)"
14617 if (optimize_insn_for_size_p ())
14620 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14621 && !flag_trapping_math && !flag_rounding_math)
14625 operands[1] = force_reg (<MODE>mode, operands[1]);
14626 ix86_expand_round_sse4 (operands[0], operands[1]);
14628 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14629 ix86_expand_round (operands[0], operands[1]);
14631 ix86_expand_rounddf_32 (operands[0], operands[1]);
14635 operands[1] = force_reg (<MODE>mode, operands[1]);
14636 ix86_emit_i387_round (operands[0], operands[1]);
14641 (define_insn_and_split "*fistdi2_1"
14642 [(set (match_operand:DI 0 "nonimmediate_operand")
14643 (unspec:DI [(match_operand:XF 1 "register_operand")]
14645 "TARGET_USE_FANCY_MATH_387
14646 && can_create_pseudo_p ()"
14651 if (memory_operand (operands[0], VOIDmode))
14652 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14655 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14656 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14661 [(set_attr "type" "fpspc")
14662 (set_attr "mode" "DI")])
14664 (define_insn "fistdi2"
14665 [(set (match_operand:DI 0 "memory_operand" "=m")
14666 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14668 (clobber (match_scratch:XF 2 "=&1f"))]
14669 "TARGET_USE_FANCY_MATH_387"
14670 "* return output_fix_trunc (insn, operands, false);"
14671 [(set_attr "type" "fpspc")
14672 (set_attr "mode" "DI")])
14674 (define_insn "fistdi2_with_temp"
14675 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14676 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14678 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14679 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14680 "TARGET_USE_FANCY_MATH_387"
14682 [(set_attr "type" "fpspc")
14683 (set_attr "mode" "DI")])
14686 [(set (match_operand:DI 0 "register_operand")
14687 (unspec:DI [(match_operand:XF 1 "register_operand")]
14689 (clobber (match_operand:DI 2 "memory_operand"))
14690 (clobber (match_scratch 3))]
14692 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14693 (clobber (match_dup 3))])
14694 (set (match_dup 0) (match_dup 2))])
14697 [(set (match_operand:DI 0 "memory_operand")
14698 (unspec:DI [(match_operand:XF 1 "register_operand")]
14700 (clobber (match_operand:DI 2 "memory_operand"))
14701 (clobber (match_scratch 3))]
14703 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14704 (clobber (match_dup 3))])])
14706 (define_insn_and_split "*fist<mode>2_1"
14707 [(set (match_operand:SWI24 0 "register_operand")
14708 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14710 "TARGET_USE_FANCY_MATH_387
14711 && can_create_pseudo_p ()"
14716 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14717 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14721 [(set_attr "type" "fpspc")
14722 (set_attr "mode" "<MODE>")])
14724 (define_insn "fist<mode>2"
14725 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14726 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14728 "TARGET_USE_FANCY_MATH_387"
14729 "* return output_fix_trunc (insn, operands, false);"
14730 [(set_attr "type" "fpspc")
14731 (set_attr "mode" "<MODE>")])
14733 (define_insn "fist<mode>2_with_temp"
14734 [(set (match_operand:SWI24 0 "register_operand" "=r")
14735 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14737 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14738 "TARGET_USE_FANCY_MATH_387"
14740 [(set_attr "type" "fpspc")
14741 (set_attr "mode" "<MODE>")])
14744 [(set (match_operand:SWI24 0 "register_operand")
14745 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14747 (clobber (match_operand:SWI24 2 "memory_operand"))]
14749 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14750 (set (match_dup 0) (match_dup 2))])
14753 [(set (match_operand:SWI24 0 "memory_operand")
14754 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14756 (clobber (match_operand:SWI24 2 "memory_operand"))]
14758 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14760 (define_expand "lrintxf<mode>2"
14761 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14762 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14764 "TARGET_USE_FANCY_MATH_387")
14766 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14767 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14768 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14769 UNSPEC_FIX_NOTRUNC))]
14770 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14772 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14773 [(match_operand:SWI248x 0 "nonimmediate_operand")
14774 (match_operand:X87MODEF 1 "register_operand")]
14775 "(TARGET_USE_FANCY_MATH_387
14776 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14777 || TARGET_MIX_SSE_I387)
14778 && flag_unsafe_math_optimizations)
14779 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14780 && <SWI248x:MODE>mode != HImode
14781 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14782 && !flag_trapping_math && !flag_rounding_math)"
14784 if (optimize_insn_for_size_p ())
14787 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14788 && <SWI248x:MODE>mode != HImode
14789 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14790 && !flag_trapping_math && !flag_rounding_math)
14791 ix86_expand_lround (operands[0], operands[1]);
14793 ix86_emit_i387_round (operands[0], operands[1]);
14797 (define_int_iterator FRNDINT_ROUNDING
14798 [UNSPEC_FRNDINT_FLOOR
14799 UNSPEC_FRNDINT_CEIL
14800 UNSPEC_FRNDINT_TRUNC])
14802 (define_int_iterator FIST_ROUNDING
14806 ;; Base name for define_insn
14807 (define_int_attr rounding_insn
14808 [(UNSPEC_FRNDINT_FLOOR "floor")
14809 (UNSPEC_FRNDINT_CEIL "ceil")
14810 (UNSPEC_FRNDINT_TRUNC "btrunc")
14811 (UNSPEC_FIST_FLOOR "floor")
14812 (UNSPEC_FIST_CEIL "ceil")])
14814 (define_int_attr rounding
14815 [(UNSPEC_FRNDINT_FLOOR "floor")
14816 (UNSPEC_FRNDINT_CEIL "ceil")
14817 (UNSPEC_FRNDINT_TRUNC "trunc")
14818 (UNSPEC_FIST_FLOOR "floor")
14819 (UNSPEC_FIST_CEIL "ceil")])
14821 (define_int_attr ROUNDING
14822 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14823 (UNSPEC_FRNDINT_CEIL "CEIL")
14824 (UNSPEC_FRNDINT_TRUNC "TRUNC")
14825 (UNSPEC_FIST_FLOOR "FLOOR")
14826 (UNSPEC_FIST_CEIL "CEIL")])
14828 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14829 (define_insn_and_split "frndintxf2_<rounding>"
14830 [(set (match_operand:XF 0 "register_operand")
14831 (unspec:XF [(match_operand:XF 1 "register_operand")]
14833 (clobber (reg:CC FLAGS_REG))]
14834 "TARGET_USE_FANCY_MATH_387
14835 && flag_unsafe_math_optimizations
14836 && can_create_pseudo_p ()"
14841 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14843 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14844 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14846 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14847 operands[2], operands[3]));
14850 [(set_attr "type" "frndint")
14851 (set_attr "i387_cw" "<rounding>")
14852 (set_attr "mode" "XF")])
14854 (define_insn "frndintxf2_<rounding>_i387"
14855 [(set (match_operand:XF 0 "register_operand" "=f")
14856 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14858 (use (match_operand:HI 2 "memory_operand" "m"))
14859 (use (match_operand:HI 3 "memory_operand" "m"))]
14860 "TARGET_USE_FANCY_MATH_387
14861 && flag_unsafe_math_optimizations"
14862 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14863 [(set_attr "type" "frndint")
14864 (set_attr "i387_cw" "<rounding>")
14865 (set_attr "mode" "XF")])
14867 (define_expand "<rounding_insn>xf2"
14868 [(parallel [(set (match_operand:XF 0 "register_operand")
14869 (unspec:XF [(match_operand:XF 1 "register_operand")]
14871 (clobber (reg:CC FLAGS_REG))])]
14872 "TARGET_USE_FANCY_MATH_387
14873 && flag_unsafe_math_optimizations
14874 && !optimize_insn_for_size_p ()")
14876 (define_expand "<rounding_insn><mode>2"
14877 [(parallel [(set (match_operand:MODEF 0 "register_operand")
14878 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
14880 (clobber (reg:CC FLAGS_REG))])]
14881 "(TARGET_USE_FANCY_MATH_387
14882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14883 || TARGET_MIX_SSE_I387)
14884 && flag_unsafe_math_optimizations)
14885 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14886 && !flag_trapping_math)"
14888 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14889 && !flag_trapping_math)
14892 emit_insn (gen_sse4_1_round<mode>2
14893 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
14894 else if (optimize_insn_for_size_p ())
14896 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14898 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14899 ix86_expand_floorceil (operands[0], operands[1], true);
14900 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14901 ix86_expand_floorceil (operands[0], operands[1], false);
14902 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14903 ix86_expand_trunc (operands[0], operands[1]);
14905 gcc_unreachable ();
14909 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14910 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14911 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14912 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
14913 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14914 ix86_expand_truncdf_32 (operands[0], operands[1]);
14916 gcc_unreachable ();
14923 if (optimize_insn_for_size_p ())
14926 op0 = gen_reg_rtx (XFmode);
14927 op1 = gen_reg_rtx (XFmode);
14928 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14929 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
14931 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14936 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14937 (define_insn_and_split "frndintxf2_mask_pm"
14938 [(set (match_operand:XF 0 "register_operand")
14939 (unspec:XF [(match_operand:XF 1 "register_operand")]
14940 UNSPEC_FRNDINT_MASK_PM))
14941 (clobber (reg:CC FLAGS_REG))]
14942 "TARGET_USE_FANCY_MATH_387
14943 && flag_unsafe_math_optimizations
14944 && can_create_pseudo_p ()"
14949 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14951 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14952 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14954 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14955 operands[2], operands[3]));
14958 [(set_attr "type" "frndint")
14959 (set_attr "i387_cw" "mask_pm")
14960 (set_attr "mode" "XF")])
14962 (define_insn "frndintxf2_mask_pm_i387"
14963 [(set (match_operand:XF 0 "register_operand" "=f")
14964 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14965 UNSPEC_FRNDINT_MASK_PM))
14966 (use (match_operand:HI 2 "memory_operand" "m"))
14967 (use (match_operand:HI 3 "memory_operand" "m"))]
14968 "TARGET_USE_FANCY_MATH_387
14969 && flag_unsafe_math_optimizations"
14970 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14971 [(set_attr "type" "frndint")
14972 (set_attr "i387_cw" "mask_pm")
14973 (set_attr "mode" "XF")])
14975 (define_expand "nearbyintxf2"
14976 [(parallel [(set (match_operand:XF 0 "register_operand")
14977 (unspec:XF [(match_operand:XF 1 "register_operand")]
14978 UNSPEC_FRNDINT_MASK_PM))
14979 (clobber (reg:CC FLAGS_REG))])]
14980 "TARGET_USE_FANCY_MATH_387
14981 && flag_unsafe_math_optimizations")
14983 (define_expand "nearbyint<mode>2"
14984 [(use (match_operand:MODEF 0 "register_operand"))
14985 (use (match_operand:MODEF 1 "register_operand"))]
14986 "TARGET_USE_FANCY_MATH_387
14987 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14988 || TARGET_MIX_SSE_I387)
14989 && flag_unsafe_math_optimizations"
14991 rtx op0 = gen_reg_rtx (XFmode);
14992 rtx op1 = gen_reg_rtx (XFmode);
14994 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14995 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14997 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15001 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15002 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15003 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15004 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15006 (clobber (reg:CC FLAGS_REG))]
15007 "TARGET_USE_FANCY_MATH_387
15008 && flag_unsafe_math_optimizations
15009 && can_create_pseudo_p ()"
15014 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15016 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15017 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15018 if (memory_operand (operands[0], VOIDmode))
15019 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15020 operands[2], operands[3]));
15023 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15024 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15025 (operands[0], operands[1], operands[2],
15026 operands[3], operands[4]));
15030 [(set_attr "type" "fistp")
15031 (set_attr "i387_cw" "<rounding>")
15032 (set_attr "mode" "<MODE>")])
15034 (define_insn "fistdi2_<rounding>"
15035 [(set (match_operand:DI 0 "memory_operand" "=m")
15036 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15038 (use (match_operand:HI 2 "memory_operand" "m"))
15039 (use (match_operand:HI 3 "memory_operand" "m"))
15040 (clobber (match_scratch:XF 4 "=&1f"))]
15041 "TARGET_USE_FANCY_MATH_387
15042 && flag_unsafe_math_optimizations"
15043 "* return output_fix_trunc (insn, operands, false);"
15044 [(set_attr "type" "fistp")
15045 (set_attr "i387_cw" "<rounding>")
15046 (set_attr "mode" "DI")])
15048 (define_insn "fistdi2_<rounding>_with_temp"
15049 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15050 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15052 (use (match_operand:HI 2 "memory_operand" "m,m"))
15053 (use (match_operand:HI 3 "memory_operand" "m,m"))
15054 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15055 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15056 "TARGET_USE_FANCY_MATH_387
15057 && flag_unsafe_math_optimizations"
15059 [(set_attr "type" "fistp")
15060 (set_attr "i387_cw" "<rounding>")
15061 (set_attr "mode" "DI")])
15064 [(set (match_operand:DI 0 "register_operand")
15065 (unspec:DI [(match_operand:XF 1 "register_operand")]
15067 (use (match_operand:HI 2 "memory_operand"))
15068 (use (match_operand:HI 3 "memory_operand"))
15069 (clobber (match_operand:DI 4 "memory_operand"))
15070 (clobber (match_scratch 5))]
15072 [(parallel [(set (match_dup 4)
15073 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15074 (use (match_dup 2))
15075 (use (match_dup 3))
15076 (clobber (match_dup 5))])
15077 (set (match_dup 0) (match_dup 4))])
15080 [(set (match_operand:DI 0 "memory_operand")
15081 (unspec:DI [(match_operand:XF 1 "register_operand")]
15083 (use (match_operand:HI 2 "memory_operand"))
15084 (use (match_operand:HI 3 "memory_operand"))
15085 (clobber (match_operand:DI 4 "memory_operand"))
15086 (clobber (match_scratch 5))]
15088 [(parallel [(set (match_dup 0)
15089 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15090 (use (match_dup 2))
15091 (use (match_dup 3))
15092 (clobber (match_dup 5))])])
15094 (define_insn "fist<mode>2_<rounding>"
15095 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15096 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15098 (use (match_operand:HI 2 "memory_operand" "m"))
15099 (use (match_operand:HI 3 "memory_operand" "m"))]
15100 "TARGET_USE_FANCY_MATH_387
15101 && flag_unsafe_math_optimizations"
15102 "* return output_fix_trunc (insn, operands, false);"
15103 [(set_attr "type" "fistp")
15104 (set_attr "i387_cw" "<rounding>")
15105 (set_attr "mode" "<MODE>")])
15107 (define_insn "fist<mode>2_<rounding>_with_temp"
15108 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15109 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15111 (use (match_operand:HI 2 "memory_operand" "m,m"))
15112 (use (match_operand:HI 3 "memory_operand" "m,m"))
15113 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15114 "TARGET_USE_FANCY_MATH_387
15115 && flag_unsafe_math_optimizations"
15117 [(set_attr "type" "fistp")
15118 (set_attr "i387_cw" "<rounding>")
15119 (set_attr "mode" "<MODE>")])
15122 [(set (match_operand:SWI24 0 "register_operand")
15123 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15125 (use (match_operand:HI 2 "memory_operand"))
15126 (use (match_operand:HI 3 "memory_operand"))
15127 (clobber (match_operand:SWI24 4 "memory_operand"))]
15129 [(parallel [(set (match_dup 4)
15130 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15131 (use (match_dup 2))
15132 (use (match_dup 3))])
15133 (set (match_dup 0) (match_dup 4))])
15136 [(set (match_operand:SWI24 0 "memory_operand")
15137 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15139 (use (match_operand:HI 2 "memory_operand"))
15140 (use (match_operand:HI 3 "memory_operand"))
15141 (clobber (match_operand:SWI24 4 "memory_operand"))]
15143 [(parallel [(set (match_dup 0)
15144 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15145 (use (match_dup 2))
15146 (use (match_dup 3))])])
15148 (define_expand "l<rounding_insn>xf<mode>2"
15149 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15150 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15152 (clobber (reg:CC FLAGS_REG))])]
15153 "TARGET_USE_FANCY_MATH_387
15154 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15155 && flag_unsafe_math_optimizations")
15157 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15158 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15159 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15161 (clobber (reg:CC FLAGS_REG))])]
15162 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15163 && !flag_trapping_math"
15165 if (TARGET_64BIT && optimize_insn_for_size_p ())
15168 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15169 ix86_expand_lfloorceil (operands[0], operands[1], true);
15170 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15171 ix86_expand_lfloorceil (operands[0], operands[1], false);
15173 gcc_unreachable ();
15178 (define_insn "fxam<mode>2_i387"
15179 [(set (match_operand:HI 0 "register_operand" "=a")
15181 [(match_operand:X87MODEF 1 "register_operand" "f")]
15183 "TARGET_USE_FANCY_MATH_387"
15184 "fxam\n\tfnstsw\t%0"
15185 [(set_attr "type" "multi")
15186 (set_attr "length" "4")
15187 (set_attr "unit" "i387")
15188 (set_attr "mode" "<MODE>")])
15190 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15191 [(set (match_operand:HI 0 "register_operand")
15193 [(match_operand:MODEF 1 "memory_operand")]
15195 "TARGET_USE_FANCY_MATH_387
15196 && can_create_pseudo_p ()"
15199 [(set (match_dup 2)(match_dup 1))
15201 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15203 operands[2] = gen_reg_rtx (<MODE>mode);
15205 MEM_VOLATILE_P (operands[1]) = 1;
15207 [(set_attr "type" "multi")
15208 (set_attr "unit" "i387")
15209 (set_attr "mode" "<MODE>")])
15211 (define_expand "isinfxf2"
15212 [(use (match_operand:SI 0 "register_operand"))
15213 (use (match_operand:XF 1 "register_operand"))]
15214 "TARGET_USE_FANCY_MATH_387
15215 && ix86_libc_has_function (function_c99_misc)"
15217 rtx mask = GEN_INT (0x45);
15218 rtx val = GEN_INT (0x05);
15222 rtx scratch = gen_reg_rtx (HImode);
15223 rtx res = gen_reg_rtx (QImode);
15225 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15227 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15228 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15229 cond = gen_rtx_fmt_ee (EQ, QImode,
15230 gen_rtx_REG (CCmode, FLAGS_REG),
15232 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15233 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15237 (define_expand "isinf<mode>2"
15238 [(use (match_operand:SI 0 "register_operand"))
15239 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15240 "TARGET_USE_FANCY_MATH_387
15241 && ix86_libc_has_function (function_c99_misc)
15242 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15244 rtx mask = GEN_INT (0x45);
15245 rtx val = GEN_INT (0x05);
15249 rtx scratch = gen_reg_rtx (HImode);
15250 rtx res = gen_reg_rtx (QImode);
15252 /* Remove excess precision by forcing value through memory. */
15253 if (memory_operand (operands[1], VOIDmode))
15254 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15257 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15259 emit_move_insn (temp, operands[1]);
15260 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15263 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15264 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15265 cond = gen_rtx_fmt_ee (EQ, QImode,
15266 gen_rtx_REG (CCmode, FLAGS_REG),
15268 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15269 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15273 (define_expand "signbitxf2"
15274 [(use (match_operand:SI 0 "register_operand"))
15275 (use (match_operand:XF 1 "register_operand"))]
15276 "TARGET_USE_FANCY_MATH_387"
15278 rtx scratch = gen_reg_rtx (HImode);
15280 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15281 emit_insn (gen_andsi3 (operands[0],
15282 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15286 (define_insn "movmsk_df"
15287 [(set (match_operand:SI 0 "register_operand" "=r")
15289 [(match_operand:DF 1 "register_operand" "x")]
15291 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15292 "%vmovmskpd\t{%1, %0|%0, %1}"
15293 [(set_attr "type" "ssemov")
15294 (set_attr "prefix" "maybe_vex")
15295 (set_attr "mode" "DF")])
15297 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15298 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15299 (define_expand "signbitdf2"
15300 [(use (match_operand:SI 0 "register_operand"))
15301 (use (match_operand:DF 1 "register_operand"))]
15302 "TARGET_USE_FANCY_MATH_387
15303 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15305 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15307 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15308 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15312 rtx scratch = gen_reg_rtx (HImode);
15314 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15315 emit_insn (gen_andsi3 (operands[0],
15316 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15321 (define_expand "signbitsf2"
15322 [(use (match_operand:SI 0 "register_operand"))
15323 (use (match_operand:SF 1 "register_operand"))]
15324 "TARGET_USE_FANCY_MATH_387
15325 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15327 rtx scratch = gen_reg_rtx (HImode);
15329 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15330 emit_insn (gen_andsi3 (operands[0],
15331 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15335 ;; Block operation instructions
15338 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15341 [(set_attr "length" "1")
15342 (set_attr "length_immediate" "0")
15343 (set_attr "modrm" "0")])
15345 (define_expand "movmem<mode>"
15346 [(use (match_operand:BLK 0 "memory_operand"))
15347 (use (match_operand:BLK 1 "memory_operand"))
15348 (use (match_operand:SWI48 2 "nonmemory_operand"))
15349 (use (match_operand:SWI48 3 "const_int_operand"))
15350 (use (match_operand:SI 4 "const_int_operand"))
15351 (use (match_operand:SI 5 "const_int_operand"))
15352 (use (match_operand:SI 6 ""))
15353 (use (match_operand:SI 7 ""))
15354 (use (match_operand:SI 8 ""))]
15357 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15358 operands[2], NULL, operands[3],
15359 operands[4], operands[5],
15360 operands[6], operands[7],
15361 operands[8], false))
15367 ;; Most CPUs don't like single string operations
15368 ;; Handle this case here to simplify previous expander.
15370 (define_expand "strmov"
15371 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15372 (set (match_operand 1 "memory_operand") (match_dup 4))
15373 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15374 (clobber (reg:CC FLAGS_REG))])
15375 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15376 (clobber (reg:CC FLAGS_REG))])]
15379 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15381 /* If .md ever supports :P for Pmode, these can be directly
15382 in the pattern above. */
15383 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15384 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15386 /* Can't use this if the user has appropriated esi or edi. */
15387 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15388 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15390 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15391 operands[2], operands[3],
15392 operands[5], operands[6]));
15396 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15399 (define_expand "strmov_singleop"
15400 [(parallel [(set (match_operand 1 "memory_operand")
15401 (match_operand 3 "memory_operand"))
15402 (set (match_operand 0 "register_operand")
15404 (set (match_operand 2 "register_operand")
15405 (match_operand 5))])]
15407 "ix86_current_function_needs_cld = 1;")
15409 (define_insn "*strmovdi_rex_1"
15410 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15411 (mem:DI (match_operand:P 3 "register_operand" "1")))
15412 (set (match_operand:P 0 "register_operand" "=D")
15413 (plus:P (match_dup 2)
15415 (set (match_operand:P 1 "register_operand" "=S")
15416 (plus:P (match_dup 3)
15419 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15421 [(set_attr "type" "str")
15422 (set_attr "memory" "both")
15423 (set_attr "mode" "DI")])
15425 (define_insn "*strmovsi_1"
15426 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15427 (mem:SI (match_operand:P 3 "register_operand" "1")))
15428 (set (match_operand:P 0 "register_operand" "=D")
15429 (plus:P (match_dup 2)
15431 (set (match_operand:P 1 "register_operand" "=S")
15432 (plus:P (match_dup 3)
15434 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15436 [(set_attr "type" "str")
15437 (set_attr "memory" "both")
15438 (set_attr "mode" "SI")])
15440 (define_insn "*strmovhi_1"
15441 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15442 (mem:HI (match_operand:P 3 "register_operand" "1")))
15443 (set (match_operand:P 0 "register_operand" "=D")
15444 (plus:P (match_dup 2)
15446 (set (match_operand:P 1 "register_operand" "=S")
15447 (plus:P (match_dup 3)
15449 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15451 [(set_attr "type" "str")
15452 (set_attr "memory" "both")
15453 (set_attr "mode" "HI")])
15455 (define_insn "*strmovqi_1"
15456 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15457 (mem:QI (match_operand:P 3 "register_operand" "1")))
15458 (set (match_operand:P 0 "register_operand" "=D")
15459 (plus:P (match_dup 2)
15461 (set (match_operand:P 1 "register_operand" "=S")
15462 (plus:P (match_dup 3)
15464 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15466 [(set_attr "type" "str")
15467 (set_attr "memory" "both")
15468 (set (attr "prefix_rex")
15470 (match_test "<P:MODE>mode == DImode")
15472 (const_string "*")))
15473 (set_attr "mode" "QI")])
15475 (define_expand "rep_mov"
15476 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15477 (set (match_operand 0 "register_operand")
15479 (set (match_operand 2 "register_operand")
15481 (set (match_operand 1 "memory_operand")
15482 (match_operand 3 "memory_operand"))
15483 (use (match_dup 4))])]
15485 "ix86_current_function_needs_cld = 1;")
15487 (define_insn "*rep_movdi_rex64"
15488 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15489 (set (match_operand:P 0 "register_operand" "=D")
15490 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15492 (match_operand:P 3 "register_operand" "0")))
15493 (set (match_operand:P 1 "register_operand" "=S")
15494 (plus:P (ashift:P (match_dup 5) (const_int 3))
15495 (match_operand:P 4 "register_operand" "1")))
15496 (set (mem:BLK (match_dup 3))
15497 (mem:BLK (match_dup 4)))
15498 (use (match_dup 5))]
15500 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15502 [(set_attr "type" "str")
15503 (set_attr "prefix_rep" "1")
15504 (set_attr "memory" "both")
15505 (set_attr "mode" "DI")])
15507 (define_insn "*rep_movsi"
15508 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15509 (set (match_operand:P 0 "register_operand" "=D")
15510 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15512 (match_operand:P 3 "register_operand" "0")))
15513 (set (match_operand:P 1 "register_operand" "=S")
15514 (plus:P (ashift:P (match_dup 5) (const_int 2))
15515 (match_operand:P 4 "register_operand" "1")))
15516 (set (mem:BLK (match_dup 3))
15517 (mem:BLK (match_dup 4)))
15518 (use (match_dup 5))]
15519 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15520 "%^rep{%;} movs{l|d}"
15521 [(set_attr "type" "str")
15522 (set_attr "prefix_rep" "1")
15523 (set_attr "memory" "both")
15524 (set_attr "mode" "SI")])
15526 (define_insn "*rep_movqi"
15527 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15528 (set (match_operand:P 0 "register_operand" "=D")
15529 (plus:P (match_operand:P 3 "register_operand" "0")
15530 (match_operand:P 5 "register_operand" "2")))
15531 (set (match_operand:P 1 "register_operand" "=S")
15532 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15533 (set (mem:BLK (match_dup 3))
15534 (mem:BLK (match_dup 4)))
15535 (use (match_dup 5))]
15536 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15538 [(set_attr "type" "str")
15539 (set_attr "prefix_rep" "1")
15540 (set_attr "memory" "both")
15541 (set_attr "mode" "QI")])
15543 (define_expand "setmem<mode>"
15544 [(use (match_operand:BLK 0 "memory_operand"))
15545 (use (match_operand:SWI48 1 "nonmemory_operand"))
15546 (use (match_operand:QI 2 "nonmemory_operand"))
15547 (use (match_operand 3 "const_int_operand"))
15548 (use (match_operand:SI 4 "const_int_operand"))
15549 (use (match_operand:SI 5 "const_int_operand"))
15550 (use (match_operand:SI 6 ""))
15551 (use (match_operand:SI 7 ""))
15552 (use (match_operand:SI 8 ""))]
15555 if (ix86_expand_set_or_movmem (operands[0], NULL,
15556 operands[1], operands[2],
15557 operands[3], operands[4],
15558 operands[5], operands[6],
15559 operands[7], operands[8], true))
15565 ;; Most CPUs don't like single string operations
15566 ;; Handle this case here to simplify previous expander.
15568 (define_expand "strset"
15569 [(set (match_operand 1 "memory_operand")
15570 (match_operand 2 "register_operand"))
15571 (parallel [(set (match_operand 0 "register_operand")
15573 (clobber (reg:CC FLAGS_REG))])]
15576 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15577 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15579 /* If .md ever supports :P for Pmode, this can be directly
15580 in the pattern above. */
15581 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15582 GEN_INT (GET_MODE_SIZE (GET_MODE
15584 /* Can't use this if the user has appropriated eax or edi. */
15585 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15586 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15588 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15594 (define_expand "strset_singleop"
15595 [(parallel [(set (match_operand 1 "memory_operand")
15596 (match_operand 2 "register_operand"))
15597 (set (match_operand 0 "register_operand")
15599 (unspec [(const_int 0)] UNSPEC_STOS)])]
15601 "ix86_current_function_needs_cld = 1;")
15603 (define_insn "*strsetdi_rex_1"
15604 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15605 (match_operand:DI 2 "register_operand" "a"))
15606 (set (match_operand:P 0 "register_operand" "=D")
15607 (plus:P (match_dup 1)
15609 (unspec [(const_int 0)] UNSPEC_STOS)]
15611 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15613 [(set_attr "type" "str")
15614 (set_attr "memory" "store")
15615 (set_attr "mode" "DI")])
15617 (define_insn "*strsetsi_1"
15618 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15619 (match_operand:SI 2 "register_operand" "a"))
15620 (set (match_operand:P 0 "register_operand" "=D")
15621 (plus:P (match_dup 1)
15623 (unspec [(const_int 0)] UNSPEC_STOS)]
15624 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15626 [(set_attr "type" "str")
15627 (set_attr "memory" "store")
15628 (set_attr "mode" "SI")])
15630 (define_insn "*strsethi_1"
15631 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15632 (match_operand:HI 2 "register_operand" "a"))
15633 (set (match_operand:P 0 "register_operand" "=D")
15634 (plus:P (match_dup 1)
15636 (unspec [(const_int 0)] UNSPEC_STOS)]
15637 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15639 [(set_attr "type" "str")
15640 (set_attr "memory" "store")
15641 (set_attr "mode" "HI")])
15643 (define_insn "*strsetqi_1"
15644 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15645 (match_operand:QI 2 "register_operand" "a"))
15646 (set (match_operand:P 0 "register_operand" "=D")
15647 (plus:P (match_dup 1)
15649 (unspec [(const_int 0)] UNSPEC_STOS)]
15650 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15652 [(set_attr "type" "str")
15653 (set_attr "memory" "store")
15654 (set (attr "prefix_rex")
15656 (match_test "<P:MODE>mode == DImode")
15658 (const_string "*")))
15659 (set_attr "mode" "QI")])
15661 (define_expand "rep_stos"
15662 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15663 (set (match_operand 0 "register_operand")
15665 (set (match_operand 2 "memory_operand") (const_int 0))
15666 (use (match_operand 3 "register_operand"))
15667 (use (match_dup 1))])]
15669 "ix86_current_function_needs_cld = 1;")
15671 (define_insn "*rep_stosdi_rex64"
15672 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15673 (set (match_operand:P 0 "register_operand" "=D")
15674 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15676 (match_operand:P 3 "register_operand" "0")))
15677 (set (mem:BLK (match_dup 3))
15679 (use (match_operand:DI 2 "register_operand" "a"))
15680 (use (match_dup 4))]
15682 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15684 [(set_attr "type" "str")
15685 (set_attr "prefix_rep" "1")
15686 (set_attr "memory" "store")
15687 (set_attr "mode" "DI")])
15689 (define_insn "*rep_stossi"
15690 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15691 (set (match_operand:P 0 "register_operand" "=D")
15692 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15694 (match_operand:P 3 "register_operand" "0")))
15695 (set (mem:BLK (match_dup 3))
15697 (use (match_operand:SI 2 "register_operand" "a"))
15698 (use (match_dup 4))]
15699 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15700 "%^rep{%;} stos{l|d}"
15701 [(set_attr "type" "str")
15702 (set_attr "prefix_rep" "1")
15703 (set_attr "memory" "store")
15704 (set_attr "mode" "SI")])
15706 (define_insn "*rep_stosqi"
15707 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15708 (set (match_operand:P 0 "register_operand" "=D")
15709 (plus:P (match_operand:P 3 "register_operand" "0")
15710 (match_operand:P 4 "register_operand" "1")))
15711 (set (mem:BLK (match_dup 3))
15713 (use (match_operand:QI 2 "register_operand" "a"))
15714 (use (match_dup 4))]
15715 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15717 [(set_attr "type" "str")
15718 (set_attr "prefix_rep" "1")
15719 (set_attr "memory" "store")
15720 (set (attr "prefix_rex")
15722 (match_test "<P:MODE>mode == DImode")
15724 (const_string "*")))
15725 (set_attr "mode" "QI")])
15727 (define_expand "cmpstrnsi"
15728 [(set (match_operand:SI 0 "register_operand")
15729 (compare:SI (match_operand:BLK 1 "general_operand")
15730 (match_operand:BLK 2 "general_operand")))
15731 (use (match_operand 3 "general_operand"))
15732 (use (match_operand 4 "immediate_operand"))]
15735 rtx addr1, addr2, out, outlow, count, countreg, align;
15737 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15740 /* Can't use this if the user has appropriated ecx, esi or edi. */
15741 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15746 out = gen_reg_rtx (SImode);
15748 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15749 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15750 if (addr1 != XEXP (operands[1], 0))
15751 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15752 if (addr2 != XEXP (operands[2], 0))
15753 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15755 count = operands[3];
15756 countreg = ix86_zero_extend_to_Pmode (count);
15758 /* %%% Iff we are testing strict equality, we can use known alignment
15759 to good advantage. This may be possible with combine, particularly
15760 once cc0 is dead. */
15761 align = operands[4];
15763 if (CONST_INT_P (count))
15765 if (INTVAL (count) == 0)
15767 emit_move_insn (operands[0], const0_rtx);
15770 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15771 operands[1], operands[2]));
15775 rtx (*gen_cmp) (rtx, rtx);
15777 gen_cmp = (TARGET_64BIT
15778 ? gen_cmpdi_1 : gen_cmpsi_1);
15780 emit_insn (gen_cmp (countreg, countreg));
15781 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15782 operands[1], operands[2]));
15785 outlow = gen_lowpart (QImode, out);
15786 emit_insn (gen_cmpintqi (outlow));
15787 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15789 if (operands[0] != out)
15790 emit_move_insn (operands[0], out);
15795 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15797 (define_expand "cmpintqi"
15798 [(set (match_dup 1)
15799 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15801 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15802 (parallel [(set (match_operand:QI 0 "register_operand")
15803 (minus:QI (match_dup 1)
15805 (clobber (reg:CC FLAGS_REG))])]
15808 operands[1] = gen_reg_rtx (QImode);
15809 operands[2] = gen_reg_rtx (QImode);
15812 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15813 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15815 (define_expand "cmpstrnqi_nz_1"
15816 [(parallel [(set (reg:CC FLAGS_REG)
15817 (compare:CC (match_operand 4 "memory_operand")
15818 (match_operand 5 "memory_operand")))
15819 (use (match_operand 2 "register_operand"))
15820 (use (match_operand:SI 3 "immediate_operand"))
15821 (clobber (match_operand 0 "register_operand"))
15822 (clobber (match_operand 1 "register_operand"))
15823 (clobber (match_dup 2))])]
15825 "ix86_current_function_needs_cld = 1;")
15827 (define_insn "*cmpstrnqi_nz_1"
15828 [(set (reg:CC FLAGS_REG)
15829 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15830 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15831 (use (match_operand:P 6 "register_operand" "2"))
15832 (use (match_operand:SI 3 "immediate_operand" "i"))
15833 (clobber (match_operand:P 0 "register_operand" "=S"))
15834 (clobber (match_operand:P 1 "register_operand" "=D"))
15835 (clobber (match_operand:P 2 "register_operand" "=c"))]
15836 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15838 [(set_attr "type" "str")
15839 (set_attr "mode" "QI")
15840 (set (attr "prefix_rex")
15842 (match_test "<P:MODE>mode == DImode")
15844 (const_string "*")))
15845 (set_attr "prefix_rep" "1")])
15847 ;; The same, but the count is not known to not be zero.
15849 (define_expand "cmpstrnqi_1"
15850 [(parallel [(set (reg:CC FLAGS_REG)
15851 (if_then_else:CC (ne (match_operand 2 "register_operand")
15853 (compare:CC (match_operand 4 "memory_operand")
15854 (match_operand 5 "memory_operand"))
15856 (use (match_operand:SI 3 "immediate_operand"))
15857 (use (reg:CC FLAGS_REG))
15858 (clobber (match_operand 0 "register_operand"))
15859 (clobber (match_operand 1 "register_operand"))
15860 (clobber (match_dup 2))])]
15862 "ix86_current_function_needs_cld = 1;")
15864 (define_insn "*cmpstrnqi_1"
15865 [(set (reg:CC FLAGS_REG)
15866 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15868 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15869 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15871 (use (match_operand:SI 3 "immediate_operand" "i"))
15872 (use (reg:CC FLAGS_REG))
15873 (clobber (match_operand:P 0 "register_operand" "=S"))
15874 (clobber (match_operand:P 1 "register_operand" "=D"))
15875 (clobber (match_operand:P 2 "register_operand" "=c"))]
15876 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15878 [(set_attr "type" "str")
15879 (set_attr "mode" "QI")
15880 (set (attr "prefix_rex")
15882 (match_test "<P:MODE>mode == DImode")
15884 (const_string "*")))
15885 (set_attr "prefix_rep" "1")])
15887 (define_expand "strlen<mode>"
15888 [(set (match_operand:P 0 "register_operand")
15889 (unspec:P [(match_operand:BLK 1 "general_operand")
15890 (match_operand:QI 2 "immediate_operand")
15891 (match_operand 3 "immediate_operand")]
15895 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15901 (define_expand "strlenqi_1"
15902 [(parallel [(set (match_operand 0 "register_operand")
15904 (clobber (match_operand 1 "register_operand"))
15905 (clobber (reg:CC FLAGS_REG))])]
15907 "ix86_current_function_needs_cld = 1;")
15909 (define_insn "*strlenqi_1"
15910 [(set (match_operand:P 0 "register_operand" "=&c")
15911 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15912 (match_operand:QI 2 "register_operand" "a")
15913 (match_operand:P 3 "immediate_operand" "i")
15914 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15915 (clobber (match_operand:P 1 "register_operand" "=D"))
15916 (clobber (reg:CC FLAGS_REG))]
15917 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15918 "%^repnz{%;} scasb"
15919 [(set_attr "type" "str")
15920 (set_attr "mode" "QI")
15921 (set (attr "prefix_rex")
15923 (match_test "<P:MODE>mode == DImode")
15925 (const_string "*")))
15926 (set_attr "prefix_rep" "1")])
15928 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15929 ;; handled in combine, but it is not currently up to the task.
15930 ;; When used for their truth value, the cmpstrn* expanders generate
15939 ;; The intermediate three instructions are unnecessary.
15941 ;; This one handles cmpstrn*_nz_1...
15944 (set (reg:CC FLAGS_REG)
15945 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15946 (mem:BLK (match_operand 5 "register_operand"))))
15947 (use (match_operand 6 "register_operand"))
15948 (use (match_operand:SI 3 "immediate_operand"))
15949 (clobber (match_operand 0 "register_operand"))
15950 (clobber (match_operand 1 "register_operand"))
15951 (clobber (match_operand 2 "register_operand"))])
15952 (set (match_operand:QI 7 "register_operand")
15953 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15954 (set (match_operand:QI 8 "register_operand")
15955 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15956 (set (reg FLAGS_REG)
15957 (compare (match_dup 7) (match_dup 8)))
15959 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15961 (set (reg:CC FLAGS_REG)
15962 (compare:CC (mem:BLK (match_dup 4))
15963 (mem:BLK (match_dup 5))))
15964 (use (match_dup 6))
15965 (use (match_dup 3))
15966 (clobber (match_dup 0))
15967 (clobber (match_dup 1))
15968 (clobber (match_dup 2))])])
15970 ;; ...and this one handles cmpstrn*_1.
15973 (set (reg:CC FLAGS_REG)
15974 (if_then_else:CC (ne (match_operand 6 "register_operand")
15976 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15977 (mem:BLK (match_operand 5 "register_operand")))
15979 (use (match_operand:SI 3 "immediate_operand"))
15980 (use (reg:CC FLAGS_REG))
15981 (clobber (match_operand 0 "register_operand"))
15982 (clobber (match_operand 1 "register_operand"))
15983 (clobber (match_operand 2 "register_operand"))])
15984 (set (match_operand:QI 7 "register_operand")
15985 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15986 (set (match_operand:QI 8 "register_operand")
15987 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15988 (set (reg FLAGS_REG)
15989 (compare (match_dup 7) (match_dup 8)))
15991 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15993 (set (reg:CC FLAGS_REG)
15994 (if_then_else:CC (ne (match_dup 6)
15996 (compare:CC (mem:BLK (match_dup 4))
15997 (mem:BLK (match_dup 5)))
15999 (use (match_dup 3))
16000 (use (reg:CC FLAGS_REG))
16001 (clobber (match_dup 0))
16002 (clobber (match_dup 1))
16003 (clobber (match_dup 2))])])
16005 ;; Conditional move instructions.
16007 (define_expand "mov<mode>cc"
16008 [(set (match_operand:SWIM 0 "register_operand")
16009 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16010 (match_operand:SWIM 2 "<general_operand>")
16011 (match_operand:SWIM 3 "<general_operand>")))]
16013 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16015 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16016 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16017 ;; So just document what we're doing explicitly.
16019 (define_expand "x86_mov<mode>cc_0_m1"
16021 [(set (match_operand:SWI48 0 "register_operand")
16022 (if_then_else:SWI48
16023 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16024 [(match_operand 1 "flags_reg_operand")
16028 (clobber (reg:CC FLAGS_REG))])])
16030 (define_insn "*x86_mov<mode>cc_0_m1"
16031 [(set (match_operand:SWI48 0 "register_operand" "=r")
16032 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16033 [(reg FLAGS_REG) (const_int 0)])
16036 (clobber (reg:CC FLAGS_REG))]
16038 "sbb{<imodesuffix>}\t%0, %0"
16039 ; Since we don't have the proper number of operands for an alu insn,
16040 ; fill in all the blanks.
16041 [(set_attr "type" "alu")
16042 (set_attr "use_carry" "1")
16043 (set_attr "pent_pair" "pu")
16044 (set_attr "memory" "none")
16045 (set_attr "imm_disp" "false")
16046 (set_attr "mode" "<MODE>")
16047 (set_attr "length_immediate" "0")])
16049 (define_insn "*x86_mov<mode>cc_0_m1_se"
16050 [(set (match_operand:SWI48 0 "register_operand" "=r")
16051 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16052 [(reg FLAGS_REG) (const_int 0)])
16055 (clobber (reg:CC FLAGS_REG))]
16057 "sbb{<imodesuffix>}\t%0, %0"
16058 [(set_attr "type" "alu")
16059 (set_attr "use_carry" "1")
16060 (set_attr "pent_pair" "pu")
16061 (set_attr "memory" "none")
16062 (set_attr "imm_disp" "false")
16063 (set_attr "mode" "<MODE>")
16064 (set_attr "length_immediate" "0")])
16066 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16067 [(set (match_operand:SWI48 0 "register_operand" "=r")
16068 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16069 [(reg FLAGS_REG) (const_int 0)])))
16070 (clobber (reg:CC FLAGS_REG))]
16072 "sbb{<imodesuffix>}\t%0, %0"
16073 [(set_attr "type" "alu")
16074 (set_attr "use_carry" "1")
16075 (set_attr "pent_pair" "pu")
16076 (set_attr "memory" "none")
16077 (set_attr "imm_disp" "false")
16078 (set_attr "mode" "<MODE>")
16079 (set_attr "length_immediate" "0")])
16081 (define_insn "*mov<mode>cc_noc"
16082 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16083 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16084 [(reg FLAGS_REG) (const_int 0)])
16085 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16086 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16087 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16089 cmov%O2%C1\t{%2, %0|%0, %2}
16090 cmov%O2%c1\t{%3, %0|%0, %3}"
16091 [(set_attr "type" "icmov")
16092 (set_attr "mode" "<MODE>")])
16094 ;; Don't do conditional moves with memory inputs. This splitter helps
16095 ;; register starved x86_32 by forcing inputs into registers before reload.
16097 [(set (match_operand:SWI248 0 "register_operand")
16098 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16099 [(reg FLAGS_REG) (const_int 0)])
16100 (match_operand:SWI248 2 "nonimmediate_operand")
16101 (match_operand:SWI248 3 "nonimmediate_operand")))]
16102 "!TARGET_64BIT && TARGET_CMOVE
16103 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16104 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16105 && can_create_pseudo_p ()
16106 && optimize_insn_for_speed_p ()"
16107 [(set (match_dup 0)
16108 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16110 if (MEM_P (operands[2]))
16111 operands[2] = force_reg (<MODE>mode, operands[2]);
16112 if (MEM_P (operands[3]))
16113 operands[3] = force_reg (<MODE>mode, operands[3]);
16116 (define_insn "*movqicc_noc"
16117 [(set (match_operand:QI 0 "register_operand" "=r,r")
16118 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16119 [(reg FLAGS_REG) (const_int 0)])
16120 (match_operand:QI 2 "register_operand" "r,0")
16121 (match_operand:QI 3 "register_operand" "0,r")))]
16122 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16124 [(set_attr "type" "icmov")
16125 (set_attr "mode" "QI")])
16128 [(set (match_operand:SWI12 0 "register_operand")
16129 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16130 [(reg FLAGS_REG) (const_int 0)])
16131 (match_operand:SWI12 2 "register_operand")
16132 (match_operand:SWI12 3 "register_operand")))]
16133 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16134 && reload_completed"
16135 [(set (match_dup 0)
16136 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16138 operands[0] = gen_lowpart (SImode, operands[0]);
16139 operands[2] = gen_lowpart (SImode, operands[2]);
16140 operands[3] = gen_lowpart (SImode, operands[3]);
16143 ;; Don't do conditional moves with memory inputs
16145 [(match_scratch:SWI248 2 "r")
16146 (set (match_operand:SWI248 0 "register_operand")
16147 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16148 [(reg FLAGS_REG) (const_int 0)])
16150 (match_operand:SWI248 3 "memory_operand")))]
16151 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16152 && optimize_insn_for_speed_p ()"
16153 [(set (match_dup 2) (match_dup 3))
16155 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16158 [(match_scratch:SWI248 2 "r")
16159 (set (match_operand:SWI248 0 "register_operand")
16160 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16161 [(reg FLAGS_REG) (const_int 0)])
16162 (match_operand:SWI248 3 "memory_operand")
16164 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16165 && optimize_insn_for_speed_p ()"
16166 [(set (match_dup 2) (match_dup 3))
16168 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16170 (define_expand "mov<mode>cc"
16171 [(set (match_operand:X87MODEF 0 "register_operand")
16172 (if_then_else:X87MODEF
16173 (match_operand 1 "comparison_operator")
16174 (match_operand:X87MODEF 2 "register_operand")
16175 (match_operand:X87MODEF 3 "register_operand")))]
16176 "(TARGET_80387 && TARGET_CMOVE)
16177 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16178 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16180 (define_insn "*movxfcc_1"
16181 [(set (match_operand:XF 0 "register_operand" "=f,f")
16182 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16183 [(reg FLAGS_REG) (const_int 0)])
16184 (match_operand:XF 2 "register_operand" "f,0")
16185 (match_operand:XF 3 "register_operand" "0,f")))]
16186 "TARGET_80387 && TARGET_CMOVE"
16188 fcmov%F1\t{%2, %0|%0, %2}
16189 fcmov%f1\t{%3, %0|%0, %3}"
16190 [(set_attr "type" "fcmov")
16191 (set_attr "mode" "XF")])
16193 (define_insn "*movdfcc_1"
16194 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16195 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16196 [(reg FLAGS_REG) (const_int 0)])
16197 (match_operand:DF 2 "nonimmediate_operand"
16199 (match_operand:DF 3 "nonimmediate_operand"
16200 "0 ,f,0 ,rm,0, rm")))]
16201 "TARGET_80387 && TARGET_CMOVE
16202 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16204 fcmov%F1\t{%2, %0|%0, %2}
16205 fcmov%f1\t{%3, %0|%0, %3}
16208 cmov%O2%C1\t{%2, %0|%0, %2}
16209 cmov%O2%c1\t{%3, %0|%0, %3}"
16210 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16211 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16212 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16215 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16216 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16217 [(reg FLAGS_REG) (const_int 0)])
16218 (match_operand:DF 2 "nonimmediate_operand")
16219 (match_operand:DF 3 "nonimmediate_operand")))]
16220 "!TARGET_64BIT && reload_completed"
16221 [(set (match_dup 2)
16222 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16224 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16226 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16227 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16230 (define_insn "*movsfcc_1_387"
16231 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16232 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16233 [(reg FLAGS_REG) (const_int 0)])
16234 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16235 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16236 "TARGET_80387 && TARGET_CMOVE
16237 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16239 fcmov%F1\t{%2, %0|%0, %2}
16240 fcmov%f1\t{%3, %0|%0, %3}
16241 cmov%O2%C1\t{%2, %0|%0, %2}
16242 cmov%O2%c1\t{%3, %0|%0, %3}"
16243 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16244 (set_attr "mode" "SF,SF,SI,SI")])
16246 ;; Don't do conditional moves with memory inputs. This splitter helps
16247 ;; register starved x86_32 by forcing inputs into registers before reload.
16249 [(set (match_operand:MODEF 0 "register_operand")
16250 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16251 [(reg FLAGS_REG) (const_int 0)])
16252 (match_operand:MODEF 2 "nonimmediate_operand")
16253 (match_operand:MODEF 3 "nonimmediate_operand")))]
16254 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16255 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16256 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16257 && can_create_pseudo_p ()
16258 && optimize_insn_for_speed_p ()"
16259 [(set (match_dup 0)
16260 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16262 if (MEM_P (operands[2]))
16263 operands[2] = force_reg (<MODE>mode, operands[2]);
16264 if (MEM_P (operands[3]))
16265 operands[3] = force_reg (<MODE>mode, operands[3]);
16268 ;; Don't do conditional moves with memory inputs
16270 [(match_scratch:MODEF 2 "r")
16271 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16272 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16273 [(reg FLAGS_REG) (const_int 0)])
16275 (match_operand:MODEF 3 "memory_operand")))]
16276 "(<MODE>mode != DFmode || TARGET_64BIT)
16277 && TARGET_80387 && TARGET_CMOVE
16278 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16279 && optimize_insn_for_speed_p ()"
16280 [(set (match_dup 2) (match_dup 3))
16282 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16285 [(match_scratch:MODEF 2 "r")
16286 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16287 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16288 [(reg FLAGS_REG) (const_int 0)])
16289 (match_operand:MODEF 3 "memory_operand")
16291 "(<MODE>mode != DFmode || TARGET_64BIT)
16292 && TARGET_80387 && TARGET_CMOVE
16293 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16294 && optimize_insn_for_speed_p ()"
16295 [(set (match_dup 2) (match_dup 3))
16297 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16299 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16300 ;; the scalar versions to have only XMM registers as operands.
16302 ;; XOP conditional move
16303 (define_insn "*xop_pcmov_<mode>"
16304 [(set (match_operand:MODEF 0 "register_operand" "=x")
16305 (if_then_else:MODEF
16306 (match_operand:MODEF 1 "register_operand" "x")
16307 (match_operand:MODEF 2 "register_operand" "x")
16308 (match_operand:MODEF 3 "register_operand" "x")))]
16310 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16311 [(set_attr "type" "sse4arg")])
16313 ;; These versions of the min/max patterns are intentionally ignorant of
16314 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16315 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16316 ;; are undefined in this condition, we're certain this is correct.
16318 (define_insn "<code><mode>3"
16319 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16321 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16322 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16323 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16325 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16326 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16327 [(set_attr "isa" "noavx,avx")
16328 (set_attr "prefix" "orig,vex")
16329 (set_attr "type" "sseadd")
16330 (set_attr "mode" "<MODE>")])
16332 ;; These versions of the min/max patterns implement exactly the operations
16333 ;; min = (op1 < op2 ? op1 : op2)
16334 ;; max = (!(op1 < op2) ? op1 : op2)
16335 ;; Their operands are not commutative, and thus they may be used in the
16336 ;; presence of -0.0 and NaN.
16338 (define_int_iterator IEEE_MAXMIN
16342 (define_int_attr ieee_maxmin
16343 [(UNSPEC_IEEE_MAX "max")
16344 (UNSPEC_IEEE_MIN "min")])
16346 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16347 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16349 [(match_operand:MODEF 1 "register_operand" "0,x")
16350 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16352 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16354 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16355 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16356 [(set_attr "isa" "noavx,avx")
16357 (set_attr "prefix" "orig,vex")
16358 (set_attr "type" "sseadd")
16359 (set_attr "mode" "<MODE>")])
16361 ;; Make two stack loads independent:
16363 ;; fld %st(0) -> fld bb
16364 ;; fmul bb fmul %st(1), %st
16366 ;; Actually we only match the last two instructions for simplicity.
16368 [(set (match_operand 0 "fp_register_operand")
16369 (match_operand 1 "fp_register_operand"))
16371 (match_operator 2 "binary_fp_operator"
16373 (match_operand 3 "memory_operand")]))]
16374 "REGNO (operands[0]) != REGNO (operands[1])"
16375 [(set (match_dup 0) (match_dup 3))
16376 (set (match_dup 0) (match_dup 4))]
16378 ;; The % modifier is not operational anymore in peephole2's, so we have to
16379 ;; swap the operands manually in the case of addition and multiplication.
16383 if (COMMUTATIVE_ARITH_P (operands[2]))
16384 op0 = operands[0], op1 = operands[1];
16386 op0 = operands[1], op1 = operands[0];
16388 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16389 GET_MODE (operands[2]),
16393 ;; Conditional addition patterns
16394 (define_expand "add<mode>cc"
16395 [(match_operand:SWI 0 "register_operand")
16396 (match_operand 1 "ordered_comparison_operator")
16397 (match_operand:SWI 2 "register_operand")
16398 (match_operand:SWI 3 "const_int_operand")]
16400 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16402 ;; Misc patterns (?)
16404 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16405 ;; Otherwise there will be nothing to keep
16407 ;; [(set (reg ebp) (reg esp))]
16408 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16409 ;; (clobber (eflags)]
16410 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16412 ;; in proper program order.
16414 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16415 [(set (match_operand:P 0 "register_operand" "=r,r")
16416 (plus:P (match_operand:P 1 "register_operand" "0,r")
16417 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16418 (clobber (reg:CC FLAGS_REG))
16419 (clobber (mem:BLK (scratch)))]
16422 switch (get_attr_type (insn))
16425 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16428 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16429 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16430 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16432 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16435 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16436 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16439 [(set (attr "type")
16440 (cond [(and (eq_attr "alternative" "0")
16441 (not (match_test "TARGET_OPT_AGU")))
16442 (const_string "alu")
16443 (match_operand:<MODE> 2 "const0_operand")
16444 (const_string "imov")
16446 (const_string "lea")))
16447 (set (attr "length_immediate")
16448 (cond [(eq_attr "type" "imov")
16450 (and (eq_attr "type" "alu")
16451 (match_operand 2 "const128_operand"))
16454 (const_string "*")))
16455 (set_attr "mode" "<MODE>")])
16457 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16458 [(set (match_operand:P 0 "register_operand" "=r")
16459 (minus:P (match_operand:P 1 "register_operand" "0")
16460 (match_operand:P 2 "register_operand" "r")))
16461 (clobber (reg:CC FLAGS_REG))
16462 (clobber (mem:BLK (scratch)))]
16464 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16465 [(set_attr "type" "alu")
16466 (set_attr "mode" "<MODE>")])
16468 (define_insn "allocate_stack_worker_probe_<mode>"
16469 [(set (match_operand:P 0 "register_operand" "=a")
16470 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16471 UNSPECV_STACK_PROBE))
16472 (clobber (reg:CC FLAGS_REG))]
16473 "ix86_target_stack_probe ()"
16474 "call\t___chkstk_ms"
16475 [(set_attr "type" "multi")
16476 (set_attr "length" "5")])
16478 (define_expand "allocate_stack"
16479 [(match_operand 0 "register_operand")
16480 (match_operand 1 "general_operand")]
16481 "ix86_target_stack_probe ()"
16485 #ifndef CHECK_STACK_LIMIT
16486 #define CHECK_STACK_LIMIT 0
16489 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16490 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16494 rtx (*insn) (rtx, rtx);
16496 x = copy_to_mode_reg (Pmode, operands[1]);
16498 insn = (TARGET_64BIT
16499 ? gen_allocate_stack_worker_probe_di
16500 : gen_allocate_stack_worker_probe_si);
16502 emit_insn (insn (x, x));
16505 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16506 stack_pointer_rtx, 0, OPTAB_DIRECT);
16508 if (x != stack_pointer_rtx)
16509 emit_move_insn (stack_pointer_rtx, x);
16511 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16515 ;; Use IOR for stack probes, this is shorter.
16516 (define_expand "probe_stack"
16517 [(match_operand 0 "memory_operand")]
16520 rtx (*gen_ior3) (rtx, rtx, rtx);
16522 gen_ior3 = (GET_MODE (operands[0]) == DImode
16523 ? gen_iordi3 : gen_iorsi3);
16525 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16529 (define_insn "adjust_stack_and_probe<mode>"
16530 [(set (match_operand:P 0 "register_operand" "=r")
16531 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16532 UNSPECV_PROBE_STACK_RANGE))
16533 (set (reg:P SP_REG)
16534 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16535 (clobber (reg:CC FLAGS_REG))
16536 (clobber (mem:BLK (scratch)))]
16538 "* return output_adjust_stack_and_probe (operands[0]);"
16539 [(set_attr "type" "multi")])
16541 (define_insn "probe_stack_range<mode>"
16542 [(set (match_operand:P 0 "register_operand" "=r")
16543 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16544 (match_operand:P 2 "const_int_operand" "n")]
16545 UNSPECV_PROBE_STACK_RANGE))
16546 (clobber (reg:CC FLAGS_REG))]
16548 "* return output_probe_stack_range (operands[0], operands[2]);"
16549 [(set_attr "type" "multi")])
16551 (define_expand "builtin_setjmp_receiver"
16552 [(label_ref (match_operand 0))]
16553 "!TARGET_64BIT && flag_pic"
16559 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16560 rtx label_rtx = gen_label_rtx ();
16561 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16562 xops[0] = xops[1] = picreg;
16563 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16564 ix86_expand_binary_operator (MINUS, SImode, xops);
16568 emit_insn (gen_set_got (pic_offset_table_rtx));
16572 (define_insn_and_split "nonlocal_goto_receiver"
16573 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16574 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16576 "&& reload_completed"
16579 if (crtl->uses_pic_offset_table)
16582 rtx label_rtx = gen_label_rtx ();
16585 /* Get a new pic base. */
16586 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16587 /* Correct this with the offset from the new to the old. */
16588 xops[0] = xops[1] = pic_offset_table_rtx;
16589 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16590 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16591 UNSPEC_MACHOPIC_OFFSET);
16592 xops[2] = gen_rtx_CONST (Pmode, tmp);
16593 ix86_expand_binary_operator (MINUS, SImode, xops);
16596 /* No pic reg restore needed. */
16597 emit_note (NOTE_INSN_DELETED);
16602 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16603 ;; Do not split instructions with mask registers.
16605 [(set (match_operand 0 "general_reg_operand")
16606 (match_operator 3 "promotable_binary_operator"
16607 [(match_operand 1 "general_reg_operand")
16608 (match_operand 2 "aligned_operand")]))
16609 (clobber (reg:CC FLAGS_REG))]
16610 "! TARGET_PARTIAL_REG_STALL && reload_completed
16611 && ((GET_MODE (operands[0]) == HImode
16612 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16613 /* ??? next two lines just !satisfies_constraint_K (...) */
16614 || !CONST_INT_P (operands[2])
16615 || satisfies_constraint_K (operands[2])))
16616 || (GET_MODE (operands[0]) == QImode
16617 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16618 [(parallel [(set (match_dup 0)
16619 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16620 (clobber (reg:CC FLAGS_REG))])]
16622 operands[0] = gen_lowpart (SImode, operands[0]);
16623 operands[1] = gen_lowpart (SImode, operands[1]);
16624 if (GET_CODE (operands[3]) != ASHIFT)
16625 operands[2] = gen_lowpart (SImode, operands[2]);
16626 PUT_MODE (operands[3], SImode);
16629 ; Promote the QImode tests, as i386 has encoding of the AND
16630 ; instruction with 32-bit sign-extended immediate and thus the
16631 ; instruction size is unchanged, except in the %eax case for
16632 ; which it is increased by one byte, hence the ! optimize_size.
16634 [(set (match_operand 0 "flags_reg_operand")
16635 (match_operator 2 "compare_operator"
16636 [(and (match_operand 3 "aligned_operand")
16637 (match_operand 4 "const_int_operand"))
16639 (set (match_operand 1 "register_operand")
16640 (and (match_dup 3) (match_dup 4)))]
16641 "! TARGET_PARTIAL_REG_STALL && reload_completed
16642 && optimize_insn_for_speed_p ()
16643 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16644 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16645 /* Ensure that the operand will remain sign-extended immediate. */
16646 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16647 [(parallel [(set (match_dup 0)
16648 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16651 (and:SI (match_dup 3) (match_dup 4)))])]
16654 = gen_int_mode (INTVAL (operands[4])
16655 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16656 operands[1] = gen_lowpart (SImode, operands[1]);
16657 operands[3] = gen_lowpart (SImode, operands[3]);
16660 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16661 ; the TEST instruction with 32-bit sign-extended immediate and thus
16662 ; the instruction size would at least double, which is not what we
16663 ; want even with ! optimize_size.
16665 [(set (match_operand 0 "flags_reg_operand")
16666 (match_operator 1 "compare_operator"
16667 [(and (match_operand:HI 2 "aligned_operand")
16668 (match_operand:HI 3 "const_int_operand"))
16670 "! TARGET_PARTIAL_REG_STALL && reload_completed
16671 && ! TARGET_FAST_PREFIX
16672 && optimize_insn_for_speed_p ()
16673 /* Ensure that the operand will remain sign-extended immediate. */
16674 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16675 [(set (match_dup 0)
16676 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16680 = gen_int_mode (INTVAL (operands[3])
16681 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16682 operands[2] = gen_lowpart (SImode, operands[2]);
16686 [(set (match_operand 0 "register_operand")
16687 (neg (match_operand 1 "register_operand")))
16688 (clobber (reg:CC FLAGS_REG))]
16689 "! TARGET_PARTIAL_REG_STALL && reload_completed
16690 && (GET_MODE (operands[0]) == HImode
16691 || (GET_MODE (operands[0]) == QImode
16692 && (TARGET_PROMOTE_QImode
16693 || optimize_insn_for_size_p ())))"
16694 [(parallel [(set (match_dup 0)
16695 (neg:SI (match_dup 1)))
16696 (clobber (reg:CC FLAGS_REG))])]
16698 operands[0] = gen_lowpart (SImode, operands[0]);
16699 operands[1] = gen_lowpart (SImode, operands[1]);
16702 ;; Do not split instructions with mask regs.
16704 [(set (match_operand 0 "general_reg_operand")
16705 (not (match_operand 1 "general_reg_operand")))]
16706 "! TARGET_PARTIAL_REG_STALL && reload_completed
16707 && (GET_MODE (operands[0]) == HImode
16708 || (GET_MODE (operands[0]) == QImode
16709 && (TARGET_PROMOTE_QImode
16710 || optimize_insn_for_size_p ())))"
16711 [(set (match_dup 0)
16712 (not:SI (match_dup 1)))]
16714 operands[0] = gen_lowpart (SImode, operands[0]);
16715 operands[1] = gen_lowpart (SImode, operands[1]);
16718 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16719 ;; transform a complex memory operation into two memory to register operations.
16721 ;; Don't push memory operands
16723 [(set (match_operand:SWI 0 "push_operand")
16724 (match_operand:SWI 1 "memory_operand"))
16725 (match_scratch:SWI 2 "<r>")]
16726 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16727 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16728 [(set (match_dup 2) (match_dup 1))
16729 (set (match_dup 0) (match_dup 2))])
16731 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16734 [(set (match_operand:SF 0 "push_operand")
16735 (match_operand:SF 1 "memory_operand"))
16736 (match_scratch:SF 2 "r")]
16737 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16738 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16739 [(set (match_dup 2) (match_dup 1))
16740 (set (match_dup 0) (match_dup 2))])
16742 ;; Don't move an immediate directly to memory when the instruction
16743 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16745 [(match_scratch:SWI124 1 "<r>")
16746 (set (match_operand:SWI124 0 "memory_operand")
16748 "optimize_insn_for_speed_p ()
16749 && ((<MODE>mode == HImode
16750 && TARGET_LCP_STALL)
16751 || (!TARGET_USE_MOV0
16752 && TARGET_SPLIT_LONG_MOVES
16753 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16754 && peep2_regno_dead_p (0, FLAGS_REG)"
16755 [(parallel [(set (match_dup 2) (const_int 0))
16756 (clobber (reg:CC FLAGS_REG))])
16757 (set (match_dup 0) (match_dup 1))]
16758 "operands[2] = gen_lowpart (SImode, operands[1]);")
16761 [(match_scratch:SWI124 2 "<r>")
16762 (set (match_operand:SWI124 0 "memory_operand")
16763 (match_operand:SWI124 1 "immediate_operand"))]
16764 "optimize_insn_for_speed_p ()
16765 && ((<MODE>mode == HImode
16766 && TARGET_LCP_STALL)
16767 || (TARGET_SPLIT_LONG_MOVES
16768 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16769 [(set (match_dup 2) (match_dup 1))
16770 (set (match_dup 0) (match_dup 2))])
16772 ;; Don't compare memory with zero, load and use a test instead.
16774 [(set (match_operand 0 "flags_reg_operand")
16775 (match_operator 1 "compare_operator"
16776 [(match_operand:SI 2 "memory_operand")
16778 (match_scratch:SI 3 "r")]
16779 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16780 [(set (match_dup 3) (match_dup 2))
16781 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16783 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16784 ;; Don't split NOTs with a displacement operand, because resulting XOR
16785 ;; will not be pairable anyway.
16787 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16788 ;; represented using a modRM byte. The XOR replacement is long decoded,
16789 ;; so this split helps here as well.
16791 ;; Note: Can't do this as a regular split because we can't get proper
16792 ;; lifetime information then.
16795 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16796 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16797 "optimize_insn_for_speed_p ()
16798 && ((TARGET_NOT_UNPAIRABLE
16799 && (!MEM_P (operands[0])
16800 || !memory_displacement_operand (operands[0], <MODE>mode)))
16801 || (TARGET_NOT_VECTORMODE
16802 && long_memory_operand (operands[0], <MODE>mode)))
16803 && peep2_regno_dead_p (0, FLAGS_REG)"
16804 [(parallel [(set (match_dup 0)
16805 (xor:SWI124 (match_dup 1) (const_int -1)))
16806 (clobber (reg:CC FLAGS_REG))])])
16808 ;; Non pairable "test imm, reg" instructions can be translated to
16809 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16810 ;; byte opcode instead of two, have a short form for byte operands),
16811 ;; so do it for other CPUs as well. Given that the value was dead,
16812 ;; this should not create any new dependencies. Pass on the sub-word
16813 ;; versions if we're concerned about partial register stalls.
16816 [(set (match_operand 0 "flags_reg_operand")
16817 (match_operator 1 "compare_operator"
16818 [(and:SI (match_operand:SI 2 "register_operand")
16819 (match_operand:SI 3 "immediate_operand"))
16821 "ix86_match_ccmode (insn, CCNOmode)
16822 && (true_regnum (operands[2]) != AX_REG
16823 || satisfies_constraint_K (operands[3]))
16824 && peep2_reg_dead_p (1, operands[2])"
16826 [(set (match_dup 0)
16827 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16830 (and:SI (match_dup 2) (match_dup 3)))])])
16832 ;; We don't need to handle HImode case, because it will be promoted to SImode
16833 ;; on ! TARGET_PARTIAL_REG_STALL
16836 [(set (match_operand 0 "flags_reg_operand")
16837 (match_operator 1 "compare_operator"
16838 [(and:QI (match_operand:QI 2 "register_operand")
16839 (match_operand:QI 3 "immediate_operand"))
16841 "! TARGET_PARTIAL_REG_STALL
16842 && ix86_match_ccmode (insn, CCNOmode)
16843 && true_regnum (operands[2]) != AX_REG
16844 && peep2_reg_dead_p (1, operands[2])"
16846 [(set (match_dup 0)
16847 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16850 (and:QI (match_dup 2) (match_dup 3)))])])
16853 [(set (match_operand 0 "flags_reg_operand")
16854 (match_operator 1 "compare_operator"
16857 (match_operand 2 "ext_register_operand")
16860 (match_operand 3 "const_int_operand"))
16862 "! TARGET_PARTIAL_REG_STALL
16863 && ix86_match_ccmode (insn, CCNOmode)
16864 && true_regnum (operands[2]) != AX_REG
16865 && peep2_reg_dead_p (1, operands[2])"
16866 [(parallel [(set (match_dup 0)
16875 (set (zero_extract:SI (match_dup 2)
16883 (match_dup 3)))])])
16885 ;; Don't do logical operations with memory inputs.
16887 [(match_scratch:SI 2 "r")
16888 (parallel [(set (match_operand:SI 0 "register_operand")
16889 (match_operator:SI 3 "arith_or_logical_operator"
16891 (match_operand:SI 1 "memory_operand")]))
16892 (clobber (reg:CC FLAGS_REG))])]
16893 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16894 [(set (match_dup 2) (match_dup 1))
16895 (parallel [(set (match_dup 0)
16896 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16897 (clobber (reg:CC FLAGS_REG))])])
16900 [(match_scratch:SI 2 "r")
16901 (parallel [(set (match_operand:SI 0 "register_operand")
16902 (match_operator:SI 3 "arith_or_logical_operator"
16903 [(match_operand:SI 1 "memory_operand")
16905 (clobber (reg:CC FLAGS_REG))])]
16906 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16907 [(set (match_dup 2) (match_dup 1))
16908 (parallel [(set (match_dup 0)
16909 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16910 (clobber (reg:CC FLAGS_REG))])])
16912 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16913 ;; refers to the destination of the load!
16916 [(set (match_operand:SI 0 "register_operand")
16917 (match_operand:SI 1 "register_operand"))
16918 (parallel [(set (match_dup 0)
16919 (match_operator:SI 3 "commutative_operator"
16921 (match_operand:SI 2 "memory_operand")]))
16922 (clobber (reg:CC FLAGS_REG))])]
16923 "REGNO (operands[0]) != REGNO (operands[1])
16924 && GENERAL_REGNO_P (REGNO (operands[0]))
16925 && GENERAL_REGNO_P (REGNO (operands[1]))"
16926 [(set (match_dup 0) (match_dup 4))
16927 (parallel [(set (match_dup 0)
16928 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16929 (clobber (reg:CC FLAGS_REG))])]
16930 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16933 [(set (match_operand 0 "register_operand")
16934 (match_operand 1 "register_operand"))
16936 (match_operator 3 "commutative_operator"
16938 (match_operand 2 "memory_operand")]))]
16939 "REGNO (operands[0]) != REGNO (operands[1])
16940 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16941 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16942 [(set (match_dup 0) (match_dup 2))
16944 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16946 ; Don't do logical operations with memory outputs
16948 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16949 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16950 ; the same decoder scheduling characteristics as the original.
16953 [(match_scratch:SI 2 "r")
16954 (parallel [(set (match_operand:SI 0 "memory_operand")
16955 (match_operator:SI 3 "arith_or_logical_operator"
16957 (match_operand:SI 1 "nonmemory_operand")]))
16958 (clobber (reg:CC FLAGS_REG))])]
16959 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16960 /* Do not split stack checking probes. */
16961 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16962 [(set (match_dup 2) (match_dup 0))
16963 (parallel [(set (match_dup 2)
16964 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16965 (clobber (reg:CC FLAGS_REG))])
16966 (set (match_dup 0) (match_dup 2))])
16969 [(match_scratch:SI 2 "r")
16970 (parallel [(set (match_operand:SI 0 "memory_operand")
16971 (match_operator:SI 3 "arith_or_logical_operator"
16972 [(match_operand:SI 1 "nonmemory_operand")
16974 (clobber (reg:CC FLAGS_REG))])]
16975 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16976 /* Do not split stack checking probes. */
16977 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16978 [(set (match_dup 2) (match_dup 0))
16979 (parallel [(set (match_dup 2)
16980 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16981 (clobber (reg:CC FLAGS_REG))])
16982 (set (match_dup 0) (match_dup 2))])
16984 ;; Attempt to use arith or logical operations with memory outputs with
16985 ;; setting of flags.
16987 [(set (match_operand:SWI 0 "register_operand")
16988 (match_operand:SWI 1 "memory_operand"))
16989 (parallel [(set (match_dup 0)
16990 (match_operator:SWI 3 "plusminuslogic_operator"
16992 (match_operand:SWI 2 "<nonmemory_operand>")]))
16993 (clobber (reg:CC FLAGS_REG))])
16994 (set (match_dup 1) (match_dup 0))
16995 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16996 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16997 && peep2_reg_dead_p (4, operands[0])
16998 && !reg_overlap_mentioned_p (operands[0], operands[1])
16999 && !reg_overlap_mentioned_p (operands[0], operands[2])
17000 && (<MODE>mode != QImode
17001 || immediate_operand (operands[2], QImode)
17002 || q_regs_operand (operands[2], QImode))
17003 && ix86_match_ccmode (peep2_next_insn (3),
17004 (GET_CODE (operands[3]) == PLUS
17005 || GET_CODE (operands[3]) == MINUS)
17006 ? CCGOCmode : CCNOmode)"
17007 [(parallel [(set (match_dup 4) (match_dup 5))
17008 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17009 (match_dup 2)]))])]
17011 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17012 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17013 copy_rtx (operands[1]),
17014 copy_rtx (operands[2]));
17015 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17016 operands[5], const0_rtx);
17020 [(parallel [(set (match_operand:SWI 0 "register_operand")
17021 (match_operator:SWI 2 "plusminuslogic_operator"
17023 (match_operand:SWI 1 "memory_operand")]))
17024 (clobber (reg:CC FLAGS_REG))])
17025 (set (match_dup 1) (match_dup 0))
17026 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17027 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17028 && GET_CODE (operands[2]) != MINUS
17029 && peep2_reg_dead_p (3, operands[0])
17030 && !reg_overlap_mentioned_p (operands[0], operands[1])
17031 && ix86_match_ccmode (peep2_next_insn (2),
17032 GET_CODE (operands[2]) == PLUS
17033 ? CCGOCmode : CCNOmode)"
17034 [(parallel [(set (match_dup 3) (match_dup 4))
17035 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17036 (match_dup 0)]))])]
17038 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17039 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17040 copy_rtx (operands[1]),
17041 copy_rtx (operands[0]));
17042 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17043 operands[4], const0_rtx);
17047 [(set (match_operand:SWI12 0 "register_operand")
17048 (match_operand:SWI12 1 "memory_operand"))
17049 (parallel [(set (match_operand:SI 4 "register_operand")
17050 (match_operator:SI 3 "plusminuslogic_operator"
17052 (match_operand:SI 2 "nonmemory_operand")]))
17053 (clobber (reg:CC FLAGS_REG))])
17054 (set (match_dup 1) (match_dup 0))
17055 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17056 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17057 && REG_P (operands[0]) && REG_P (operands[4])
17058 && REGNO (operands[0]) == REGNO (operands[4])
17059 && peep2_reg_dead_p (4, operands[0])
17060 && (<MODE>mode != QImode
17061 || immediate_operand (operands[2], SImode)
17062 || q_regs_operand (operands[2], SImode))
17063 && !reg_overlap_mentioned_p (operands[0], operands[1])
17064 && !reg_overlap_mentioned_p (operands[0], operands[2])
17065 && ix86_match_ccmode (peep2_next_insn (3),
17066 (GET_CODE (operands[3]) == PLUS
17067 || GET_CODE (operands[3]) == MINUS)
17068 ? CCGOCmode : CCNOmode)"
17069 [(parallel [(set (match_dup 4) (match_dup 5))
17070 (set (match_dup 1) (match_dup 6))])]
17072 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17073 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17074 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17075 copy_rtx (operands[1]), operands[2]);
17076 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17077 operands[5], const0_rtx);
17078 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17079 copy_rtx (operands[1]),
17080 copy_rtx (operands[2]));
17083 ;; Attempt to always use XOR for zeroing registers.
17085 [(set (match_operand 0 "register_operand")
17086 (match_operand 1 "const0_operand"))]
17087 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17088 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17089 && GENERAL_REG_P (operands[0])
17090 && peep2_regno_dead_p (0, FLAGS_REG)"
17091 [(parallel [(set (match_dup 0) (const_int 0))
17092 (clobber (reg:CC FLAGS_REG))])]
17093 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17096 [(set (strict_low_part (match_operand 0 "register_operand"))
17098 "(GET_MODE (operands[0]) == QImode
17099 || GET_MODE (operands[0]) == HImode)
17100 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17101 && peep2_regno_dead_p (0, FLAGS_REG)"
17102 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17103 (clobber (reg:CC FLAGS_REG))])])
17105 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17107 [(set (match_operand:SWI248 0 "register_operand")
17109 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17110 && peep2_regno_dead_p (0, FLAGS_REG)"
17111 [(parallel [(set (match_dup 0) (const_int -1))
17112 (clobber (reg:CC FLAGS_REG))])]
17114 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17115 operands[0] = gen_lowpart (SImode, operands[0]);
17118 ;; Attempt to convert simple lea to add/shift.
17119 ;; These can be created by move expanders.
17120 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17121 ;; relevant lea instructions were already split.
17124 [(set (match_operand:SWI48 0 "register_operand")
17125 (plus:SWI48 (match_dup 0)
17126 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17128 && peep2_regno_dead_p (0, FLAGS_REG)"
17129 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17130 (clobber (reg:CC FLAGS_REG))])])
17133 [(set (match_operand:SWI48 0 "register_operand")
17134 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17137 && peep2_regno_dead_p (0, FLAGS_REG)"
17138 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17139 (clobber (reg:CC FLAGS_REG))])])
17142 [(set (match_operand:DI 0 "register_operand")
17144 (plus:SI (match_operand:SI 1 "register_operand")
17145 (match_operand:SI 2 "nonmemory_operand"))))]
17146 "TARGET_64BIT && !TARGET_OPT_AGU
17147 && REGNO (operands[0]) == REGNO (operands[1])
17148 && peep2_regno_dead_p (0, FLAGS_REG)"
17149 [(parallel [(set (match_dup 0)
17150 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17151 (clobber (reg:CC FLAGS_REG))])])
17154 [(set (match_operand:DI 0 "register_operand")
17156 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17157 (match_operand:SI 2 "register_operand"))))]
17158 "TARGET_64BIT && !TARGET_OPT_AGU
17159 && REGNO (operands[0]) == REGNO (operands[2])
17160 && peep2_regno_dead_p (0, FLAGS_REG)"
17161 [(parallel [(set (match_dup 0)
17162 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17163 (clobber (reg:CC FLAGS_REG))])])
17166 [(set (match_operand:SWI48 0 "register_operand")
17167 (mult:SWI48 (match_dup 0)
17168 (match_operand:SWI48 1 "const_int_operand")))]
17169 "exact_log2 (INTVAL (operands[1])) >= 0
17170 && peep2_regno_dead_p (0, FLAGS_REG)"
17171 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17172 (clobber (reg:CC FLAGS_REG))])]
17173 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17176 [(set (match_operand:DI 0 "register_operand")
17178 (mult:SI (match_operand:SI 1 "register_operand")
17179 (match_operand:SI 2 "const_int_operand"))))]
17181 && exact_log2 (INTVAL (operands[2])) >= 0
17182 && REGNO (operands[0]) == REGNO (operands[1])
17183 && peep2_regno_dead_p (0, FLAGS_REG)"
17184 [(parallel [(set (match_dup 0)
17185 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17186 (clobber (reg:CC FLAGS_REG))])]
17187 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17189 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17190 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17191 ;; On many CPUs it is also faster, since special hardware to avoid esp
17192 ;; dependencies is present.
17194 ;; While some of these conversions may be done using splitters, we use
17195 ;; peepholes in order to allow combine_stack_adjustments pass to see
17196 ;; nonobfuscated RTL.
17198 ;; Convert prologue esp subtractions to push.
17199 ;; We need register to push. In order to keep verify_flow_info happy we have
17201 ;; - use scratch and clobber it in order to avoid dependencies
17202 ;; - use already live register
17203 ;; We can't use the second way right now, since there is no reliable way how to
17204 ;; verify that given register is live. First choice will also most likely in
17205 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17206 ;; call clobbered registers are dead. We may want to use base pointer as an
17207 ;; alternative when no register is available later.
17210 [(match_scratch:W 1 "r")
17211 (parallel [(set (reg:P SP_REG)
17212 (plus:P (reg:P SP_REG)
17213 (match_operand:P 0 "const_int_operand")))
17214 (clobber (reg:CC FLAGS_REG))
17215 (clobber (mem:BLK (scratch)))])]
17216 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17217 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17218 [(clobber (match_dup 1))
17219 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17220 (clobber (mem:BLK (scratch)))])])
17223 [(match_scratch:W 1 "r")
17224 (parallel [(set (reg:P SP_REG)
17225 (plus:P (reg:P SP_REG)
17226 (match_operand:P 0 "const_int_operand")))
17227 (clobber (reg:CC FLAGS_REG))
17228 (clobber (mem:BLK (scratch)))])]
17229 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17230 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17231 [(clobber (match_dup 1))
17232 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17233 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17234 (clobber (mem:BLK (scratch)))])])
17236 ;; Convert esp subtractions to push.
17238 [(match_scratch:W 1 "r")
17239 (parallel [(set (reg:P SP_REG)
17240 (plus:P (reg:P SP_REG)
17241 (match_operand:P 0 "const_int_operand")))
17242 (clobber (reg:CC FLAGS_REG))])]
17243 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17244 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17245 [(clobber (match_dup 1))
17246 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17249 [(match_scratch:W 1 "r")
17250 (parallel [(set (reg:P SP_REG)
17251 (plus:P (reg:P SP_REG)
17252 (match_operand:P 0 "const_int_operand")))
17253 (clobber (reg:CC FLAGS_REG))])]
17254 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17255 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17256 [(clobber (match_dup 1))
17257 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17258 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17260 ;; Convert epilogue deallocator to pop.
17262 [(match_scratch:W 1 "r")
17263 (parallel [(set (reg:P SP_REG)
17264 (plus:P (reg:P SP_REG)
17265 (match_operand:P 0 "const_int_operand")))
17266 (clobber (reg:CC FLAGS_REG))
17267 (clobber (mem:BLK (scratch)))])]
17268 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17269 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17270 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17271 (clobber (mem:BLK (scratch)))])])
17273 ;; Two pops case is tricky, since pop causes dependency
17274 ;; on destination register. We use two registers if available.
17276 [(match_scratch:W 1 "r")
17277 (match_scratch:W 2 "r")
17278 (parallel [(set (reg:P SP_REG)
17279 (plus:P (reg:P SP_REG)
17280 (match_operand:P 0 "const_int_operand")))
17281 (clobber (reg:CC FLAGS_REG))
17282 (clobber (mem:BLK (scratch)))])]
17283 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17284 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17285 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17286 (clobber (mem:BLK (scratch)))])
17287 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17290 [(match_scratch:W 1 "r")
17291 (parallel [(set (reg:P SP_REG)
17292 (plus:P (reg:P SP_REG)
17293 (match_operand:P 0 "const_int_operand")))
17294 (clobber (reg:CC FLAGS_REG))
17295 (clobber (mem:BLK (scratch)))])]
17296 "optimize_insn_for_size_p ()
17297 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17298 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17299 (clobber (mem:BLK (scratch)))])
17300 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17302 ;; Convert esp additions to pop.
17304 [(match_scratch:W 1 "r")
17305 (parallel [(set (reg:P SP_REG)
17306 (plus:P (reg:P SP_REG)
17307 (match_operand:P 0 "const_int_operand")))
17308 (clobber (reg:CC FLAGS_REG))])]
17309 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17310 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17312 ;; Two pops case is tricky, since pop causes dependency
17313 ;; on destination register. We use two registers if available.
17315 [(match_scratch:W 1 "r")
17316 (match_scratch:W 2 "r")
17317 (parallel [(set (reg:P SP_REG)
17318 (plus:P (reg:P SP_REG)
17319 (match_operand:P 0 "const_int_operand")))
17320 (clobber (reg:CC FLAGS_REG))])]
17321 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17322 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17323 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17326 [(match_scratch:W 1 "r")
17327 (parallel [(set (reg:P SP_REG)
17328 (plus:P (reg:P SP_REG)
17329 (match_operand:P 0 "const_int_operand")))
17330 (clobber (reg:CC FLAGS_REG))])]
17331 "optimize_insn_for_size_p ()
17332 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17333 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17334 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17336 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17337 ;; required and register dies. Similarly for 128 to -128.
17339 [(set (match_operand 0 "flags_reg_operand")
17340 (match_operator 1 "compare_operator"
17341 [(match_operand 2 "register_operand")
17342 (match_operand 3 "const_int_operand")]))]
17343 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17344 && incdec_operand (operands[3], GET_MODE (operands[3])))
17345 || (!TARGET_FUSE_CMP_AND_BRANCH
17346 && INTVAL (operands[3]) == 128))
17347 && ix86_match_ccmode (insn, CCGCmode)
17348 && peep2_reg_dead_p (1, operands[2])"
17349 [(parallel [(set (match_dup 0)
17350 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17351 (clobber (match_dup 2))])])
17353 ;; Convert imul by three, five and nine into lea
17356 [(set (match_operand:SWI48 0 "register_operand")
17357 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17358 (match_operand:SWI48 2 "const359_operand")))
17359 (clobber (reg:CC FLAGS_REG))])]
17360 "!TARGET_PARTIAL_REG_STALL
17361 || <MODE>mode == SImode
17362 || optimize_function_for_size_p (cfun)"
17363 [(set (match_dup 0)
17364 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17366 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17370 [(set (match_operand:SWI48 0 "register_operand")
17371 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17372 (match_operand:SWI48 2 "const359_operand")))
17373 (clobber (reg:CC FLAGS_REG))])]
17374 "optimize_insn_for_speed_p ()
17375 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17376 [(set (match_dup 0) (match_dup 1))
17378 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17380 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17382 ;; imul $32bit_imm, mem, reg is vector decoded, while
17383 ;; imul $32bit_imm, reg, reg is direct decoded.
17385 [(match_scratch:SWI48 3 "r")
17386 (parallel [(set (match_operand:SWI48 0 "register_operand")
17387 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17388 (match_operand:SWI48 2 "immediate_operand")))
17389 (clobber (reg:CC FLAGS_REG))])]
17390 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17391 && !satisfies_constraint_K (operands[2])"
17392 [(set (match_dup 3) (match_dup 1))
17393 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17394 (clobber (reg:CC FLAGS_REG))])])
17397 [(match_scratch:SI 3 "r")
17398 (parallel [(set (match_operand:DI 0 "register_operand")
17400 (mult:SI (match_operand:SI 1 "memory_operand")
17401 (match_operand:SI 2 "immediate_operand"))))
17402 (clobber (reg:CC FLAGS_REG))])]
17404 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17405 && !satisfies_constraint_K (operands[2])"
17406 [(set (match_dup 3) (match_dup 1))
17407 (parallel [(set (match_dup 0)
17408 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17409 (clobber (reg:CC FLAGS_REG))])])
17411 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17412 ;; Convert it into imul reg, reg
17413 ;; It would be better to force assembler to encode instruction using long
17414 ;; immediate, but there is apparently no way to do so.
17416 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17418 (match_operand:SWI248 1 "nonimmediate_operand")
17419 (match_operand:SWI248 2 "const_int_operand")))
17420 (clobber (reg:CC FLAGS_REG))])
17421 (match_scratch:SWI248 3 "r")]
17422 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17423 && satisfies_constraint_K (operands[2])"
17424 [(set (match_dup 3) (match_dup 2))
17425 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17426 (clobber (reg:CC FLAGS_REG))])]
17428 if (!rtx_equal_p (operands[0], operands[1]))
17429 emit_move_insn (operands[0], operands[1]);
17432 ;; After splitting up read-modify operations, array accesses with memory
17433 ;; operands might end up in form:
17435 ;; movl 4(%esp), %edx
17437 ;; instead of pre-splitting:
17439 ;; addl 4(%esp), %eax
17441 ;; movl 4(%esp), %edx
17442 ;; leal (%edx,%eax,4), %eax
17445 [(match_scratch:W 5 "r")
17446 (parallel [(set (match_operand 0 "register_operand")
17447 (ashift (match_operand 1 "register_operand")
17448 (match_operand 2 "const_int_operand")))
17449 (clobber (reg:CC FLAGS_REG))])
17450 (parallel [(set (match_operand 3 "register_operand")
17451 (plus (match_dup 0)
17452 (match_operand 4 "x86_64_general_operand")))
17453 (clobber (reg:CC FLAGS_REG))])]
17454 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17455 /* Validate MODE for lea. */
17456 && ((!TARGET_PARTIAL_REG_STALL
17457 && (GET_MODE (operands[0]) == QImode
17458 || GET_MODE (operands[0]) == HImode))
17459 || GET_MODE (operands[0]) == SImode
17460 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17461 && (rtx_equal_p (operands[0], operands[3])
17462 || peep2_reg_dead_p (2, operands[0]))
17463 /* We reorder load and the shift. */
17464 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17465 [(set (match_dup 5) (match_dup 4))
17466 (set (match_dup 0) (match_dup 1))]
17468 enum machine_mode op1mode = GET_MODE (operands[1]);
17469 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17470 int scale = 1 << INTVAL (operands[2]);
17471 rtx index = gen_lowpart (word_mode, operands[1]);
17472 rtx base = gen_lowpart (word_mode, operands[5]);
17473 rtx dest = gen_lowpart (mode, operands[3]);
17475 operands[1] = gen_rtx_PLUS (word_mode, base,
17476 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17477 operands[5] = base;
17478 if (mode != word_mode)
17479 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17480 if (op1mode != word_mode)
17481 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17482 operands[0] = dest;
17485 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17486 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17487 ;; caught for use by garbage collectors and the like. Using an insn that
17488 ;; maps to SIGILL makes it more likely the program will rightfully die.
17489 ;; Keeping with tradition, "6" is in honor of #UD.
17490 (define_insn "trap"
17491 [(trap_if (const_int 1) (const_int 6))]
17494 #ifdef HAVE_AS_IX86_UD2
17497 return ASM_SHORT "0x0b0f";
17500 [(set_attr "length" "2")])
17502 (define_expand "prefetch"
17503 [(prefetch (match_operand 0 "address_operand")
17504 (match_operand:SI 1 "const_int_operand")
17505 (match_operand:SI 2 "const_int_operand"))]
17506 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17508 bool write = INTVAL (operands[1]) != 0;
17509 int locality = INTVAL (operands[2]);
17511 gcc_assert (IN_RANGE (locality, 0, 3));
17513 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17514 supported by SSE counterpart or the SSE prefetch is not available
17515 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17517 if (TARGET_PREFETCHWT1 && write && locality <= 2)
17518 operands[2] = const2_rtx;
17519 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17520 operands[2] = GEN_INT (3);
17522 operands[1] = const0_rtx;
17525 (define_insn "*prefetch_sse"
17526 [(prefetch (match_operand 0 "address_operand" "p")
17528 (match_operand:SI 1 "const_int_operand"))]
17529 "TARGET_PREFETCH_SSE"
17531 static const char * const patterns[4] = {
17532 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17535 int locality = INTVAL (operands[1]);
17536 gcc_assert (IN_RANGE (locality, 0, 3));
17538 return patterns[locality];
17540 [(set_attr "type" "sse")
17541 (set_attr "atom_sse_attr" "prefetch")
17542 (set (attr "length_address")
17543 (symbol_ref "memory_address_length (operands[0], false)"))
17544 (set_attr "memory" "none")])
17546 (define_insn "*prefetch_3dnow"
17547 [(prefetch (match_operand 0 "address_operand" "p")
17548 (match_operand:SI 1 "const_int_operand" "n")
17552 if (INTVAL (operands[1]) == 0)
17553 return "prefetch\t%a0";
17555 return "prefetchw\t%a0";
17557 [(set_attr "type" "mmx")
17558 (set (attr "length_address")
17559 (symbol_ref "memory_address_length (operands[0], false)"))
17560 (set_attr "memory" "none")])
17562 (define_insn "*prefetch_prefetchwt1_<mode>"
17563 [(prefetch (match_operand:P 0 "address_operand" "p")
17566 "TARGET_PREFETCHWT1"
17567 "prefetchwt1\t%a0";
17568 [(set_attr "type" "sse")
17569 (set (attr "length_address")
17570 (symbol_ref "memory_address_length (operands[0], false)"))
17571 (set_attr "memory" "none")])
17573 (define_expand "stack_protect_set"
17574 [(match_operand 0 "memory_operand")
17575 (match_operand 1 "memory_operand")]
17576 "TARGET_SSP_TLS_GUARD"
17578 rtx (*insn)(rtx, rtx);
17580 #ifdef TARGET_THREAD_SSP_OFFSET
17581 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17582 insn = (TARGET_LP64
17583 ? gen_stack_tls_protect_set_di
17584 : gen_stack_tls_protect_set_si);
17586 insn = (TARGET_LP64
17587 ? gen_stack_protect_set_di
17588 : gen_stack_protect_set_si);
17591 emit_insn (insn (operands[0], operands[1]));
17595 (define_insn "stack_protect_set_<mode>"
17596 [(set (match_operand:PTR 0 "memory_operand" "=m")
17597 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17599 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17600 (clobber (reg:CC FLAGS_REG))]
17601 "TARGET_SSP_TLS_GUARD"
17602 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17603 [(set_attr "type" "multi")])
17605 (define_insn "stack_tls_protect_set_<mode>"
17606 [(set (match_operand:PTR 0 "memory_operand" "=m")
17607 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17608 UNSPEC_SP_TLS_SET))
17609 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17610 (clobber (reg:CC FLAGS_REG))]
17612 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17613 [(set_attr "type" "multi")])
17615 (define_expand "stack_protect_test"
17616 [(match_operand 0 "memory_operand")
17617 (match_operand 1 "memory_operand")
17619 "TARGET_SSP_TLS_GUARD"
17621 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17623 rtx (*insn)(rtx, rtx, rtx);
17625 #ifdef TARGET_THREAD_SSP_OFFSET
17626 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17627 insn = (TARGET_LP64
17628 ? gen_stack_tls_protect_test_di
17629 : gen_stack_tls_protect_test_si);
17631 insn = (TARGET_LP64
17632 ? gen_stack_protect_test_di
17633 : gen_stack_protect_test_si);
17636 emit_insn (insn (flags, operands[0], operands[1]));
17638 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17639 flags, const0_rtx, operands[2]));
17643 (define_insn "stack_protect_test_<mode>"
17644 [(set (match_operand:CCZ 0 "flags_reg_operand")
17645 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17646 (match_operand:PTR 2 "memory_operand" "m")]
17648 (clobber (match_scratch:PTR 3 "=&r"))]
17649 "TARGET_SSP_TLS_GUARD"
17650 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17651 [(set_attr "type" "multi")])
17653 (define_insn "stack_tls_protect_test_<mode>"
17654 [(set (match_operand:CCZ 0 "flags_reg_operand")
17655 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17656 (match_operand:PTR 2 "const_int_operand" "i")]
17657 UNSPEC_SP_TLS_TEST))
17658 (clobber (match_scratch:PTR 3 "=r"))]
17660 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17661 [(set_attr "type" "multi")])
17663 (define_insn "sse4_2_crc32<mode>"
17664 [(set (match_operand:SI 0 "register_operand" "=r")
17666 [(match_operand:SI 1 "register_operand" "0")
17667 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17669 "TARGET_SSE4_2 || TARGET_CRC32"
17670 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17671 [(set_attr "type" "sselog1")
17672 (set_attr "prefix_rep" "1")
17673 (set_attr "prefix_extra" "1")
17674 (set (attr "prefix_data16")
17675 (if_then_else (match_operand:HI 2)
17677 (const_string "*")))
17678 (set (attr "prefix_rex")
17679 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17681 (const_string "*")))
17682 (set_attr "mode" "SI")])
17684 (define_insn "sse4_2_crc32di"
17685 [(set (match_operand:DI 0 "register_operand" "=r")
17687 [(match_operand:DI 1 "register_operand" "0")
17688 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17690 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17691 "crc32{q}\t{%2, %0|%0, %2}"
17692 [(set_attr "type" "sselog1")
17693 (set_attr "prefix_rep" "1")
17694 (set_attr "prefix_extra" "1")
17695 (set_attr "mode" "DI")])
17697 (define_insn "rdpmc"
17698 [(set (match_operand:DI 0 "register_operand" "=A")
17699 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17703 [(set_attr "type" "other")
17704 (set_attr "length" "2")])
17706 (define_insn "rdpmc_rex64"
17707 [(set (match_operand:DI 0 "register_operand" "=a")
17708 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17710 (set (match_operand:DI 1 "register_operand" "=d")
17711 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17714 [(set_attr "type" "other")
17715 (set_attr "length" "2")])
17717 (define_insn "rdtsc"
17718 [(set (match_operand:DI 0 "register_operand" "=A")
17719 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17722 [(set_attr "type" "other")
17723 (set_attr "length" "2")])
17725 (define_insn "rdtsc_rex64"
17726 [(set (match_operand:DI 0 "register_operand" "=a")
17727 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17728 (set (match_operand:DI 1 "register_operand" "=d")
17729 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17732 [(set_attr "type" "other")
17733 (set_attr "length" "2")])
17735 (define_insn "rdtscp"
17736 [(set (match_operand:DI 0 "register_operand" "=A")
17737 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17738 (set (match_operand:SI 1 "register_operand" "=c")
17739 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17742 [(set_attr "type" "other")
17743 (set_attr "length" "3")])
17745 (define_insn "rdtscp_rex64"
17746 [(set (match_operand:DI 0 "register_operand" "=a")
17747 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17748 (set (match_operand:DI 1 "register_operand" "=d")
17749 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17750 (set (match_operand:SI 2 "register_operand" "=c")
17751 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17754 [(set_attr "type" "other")
17755 (set_attr "length" "3")])
17757 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17759 ;; FXSR, XSAVE and XSAVEOPT instructions
17761 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17763 (define_insn "fxsave"
17764 [(set (match_operand:BLK 0 "memory_operand" "=m")
17765 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17768 [(set_attr "type" "other")
17769 (set_attr "memory" "store")
17770 (set (attr "length")
17771 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17773 (define_insn "fxsave64"
17774 [(set (match_operand:BLK 0 "memory_operand" "=m")
17775 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17776 "TARGET_64BIT && TARGET_FXSR"
17778 [(set_attr "type" "other")
17779 (set_attr "memory" "store")
17780 (set (attr "length")
17781 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17783 (define_insn "fxrstor"
17784 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17788 [(set_attr "type" "other")
17789 (set_attr "memory" "load")
17790 (set (attr "length")
17791 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17793 (define_insn "fxrstor64"
17794 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17795 UNSPECV_FXRSTOR64)]
17796 "TARGET_64BIT && TARGET_FXSR"
17798 [(set_attr "type" "other")
17799 (set_attr "memory" "load")
17800 (set (attr "length")
17801 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17803 (define_int_iterator ANY_XSAVE
17805 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17807 (define_int_iterator ANY_XSAVE64
17809 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17811 (define_int_attr xsave
17812 [(UNSPECV_XSAVE "xsave")
17813 (UNSPECV_XSAVE64 "xsave64")
17814 (UNSPECV_XSAVEOPT "xsaveopt")
17815 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17817 (define_insn "<xsave>"
17818 [(set (match_operand:BLK 0 "memory_operand" "=m")
17819 (unspec_volatile:BLK
17820 [(match_operand:DI 1 "register_operand" "A")]
17822 "!TARGET_64BIT && TARGET_XSAVE"
17824 [(set_attr "type" "other")
17825 (set_attr "memory" "store")
17826 (set (attr "length")
17827 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17829 (define_insn "<xsave>_rex64"
17830 [(set (match_operand:BLK 0 "memory_operand" "=m")
17831 (unspec_volatile:BLK
17832 [(match_operand:SI 1 "register_operand" "a")
17833 (match_operand:SI 2 "register_operand" "d")]
17835 "TARGET_64BIT && TARGET_XSAVE"
17837 [(set_attr "type" "other")
17838 (set_attr "memory" "store")
17839 (set (attr "length")
17840 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17842 (define_insn "<xsave>"
17843 [(set (match_operand:BLK 0 "memory_operand" "=m")
17844 (unspec_volatile:BLK
17845 [(match_operand:SI 1 "register_operand" "a")
17846 (match_operand:SI 2 "register_operand" "d")]
17848 "TARGET_64BIT && TARGET_XSAVE"
17850 [(set_attr "type" "other")
17851 (set_attr "memory" "store")
17852 (set (attr "length")
17853 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17855 (define_insn "xrstor"
17856 [(unspec_volatile:BLK
17857 [(match_operand:BLK 0 "memory_operand" "m")
17858 (match_operand:DI 1 "register_operand" "A")]
17860 "!TARGET_64BIT && TARGET_XSAVE"
17862 [(set_attr "type" "other")
17863 (set_attr "memory" "load")
17864 (set (attr "length")
17865 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17867 (define_insn "xrstor_rex64"
17868 [(unspec_volatile:BLK
17869 [(match_operand:BLK 0 "memory_operand" "m")
17870 (match_operand:SI 1 "register_operand" "a")
17871 (match_operand:SI 2 "register_operand" "d")]
17873 "TARGET_64BIT && TARGET_XSAVE"
17875 [(set_attr "type" "other")
17876 (set_attr "memory" "load")
17877 (set (attr "length")
17878 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17880 (define_insn "xrstor64"
17881 [(unspec_volatile:BLK
17882 [(match_operand:BLK 0 "memory_operand" "m")
17883 (match_operand:SI 1 "register_operand" "a")
17884 (match_operand:SI 2 "register_operand" "d")]
17886 "TARGET_64BIT && TARGET_XSAVE"
17888 [(set_attr "type" "other")
17889 (set_attr "memory" "load")
17890 (set (attr "length")
17891 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17893 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17895 ;; Floating-point instructions for atomic compound assignments
17897 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17899 ; Clobber all floating-point registers on environment save and restore
17900 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
17901 (define_insn "fnstenv"
17902 [(set (match_operand:BLK 0 "memory_operand" "=m")
17903 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
17904 (clobber (reg:HI FPCR_REG))
17905 (clobber (reg:XF ST0_REG))
17906 (clobber (reg:XF ST1_REG))
17907 (clobber (reg:XF ST2_REG))
17908 (clobber (reg:XF ST3_REG))
17909 (clobber (reg:XF ST4_REG))
17910 (clobber (reg:XF ST5_REG))
17911 (clobber (reg:XF ST6_REG))
17912 (clobber (reg:XF ST7_REG))]
17915 [(set_attr "type" "other")
17916 (set_attr "memory" "store")
17917 (set (attr "length")
17918 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
17920 (define_insn "fldenv"
17921 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17923 (clobber (reg:CCFP FPSR_REG))
17924 (clobber (reg:HI FPCR_REG))
17925 (clobber (reg:XF ST0_REG))
17926 (clobber (reg:XF ST1_REG))
17927 (clobber (reg:XF ST2_REG))
17928 (clobber (reg:XF ST3_REG))
17929 (clobber (reg:XF ST4_REG))
17930 (clobber (reg:XF ST5_REG))
17931 (clobber (reg:XF ST6_REG))
17932 (clobber (reg:XF ST7_REG))]
17935 [(set_attr "type" "other")
17936 (set_attr "memory" "load")
17937 (set (attr "length")
17938 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
17940 (define_insn "fnstsw"
17941 [(set (match_operand:HI 0 "memory_operand" "=m")
17942 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
17945 [(set_attr "type" "other")
17946 (set_attr "memory" "store")
17947 (set (attr "length")
17948 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
17950 (define_insn "fnclex"
17951 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
17954 [(set_attr "type" "other")
17955 (set_attr "memory" "none")
17956 (set_attr "length" "2")])
17958 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17960 ;; LWP instructions
17962 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17964 (define_expand "lwp_llwpcb"
17965 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17966 UNSPECV_LLWP_INTRINSIC)]
17969 (define_insn "*lwp_llwpcb<mode>1"
17970 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17971 UNSPECV_LLWP_INTRINSIC)]
17974 [(set_attr "type" "lwp")
17975 (set_attr "mode" "<MODE>")
17976 (set_attr "length" "5")])
17978 (define_expand "lwp_slwpcb"
17979 [(set (match_operand 0 "register_operand" "=r")
17980 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17985 insn = (Pmode == DImode
17987 : gen_lwp_slwpcbsi);
17989 emit_insn (insn (operands[0]));
17993 (define_insn "lwp_slwpcb<mode>"
17994 [(set (match_operand:P 0 "register_operand" "=r")
17995 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17998 [(set_attr "type" "lwp")
17999 (set_attr "mode" "<MODE>")
18000 (set_attr "length" "5")])
18002 (define_expand "lwp_lwpval<mode>3"
18003 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18004 (match_operand:SI 2 "nonimmediate_operand" "rm")
18005 (match_operand:SI 3 "const_int_operand" "i")]
18006 UNSPECV_LWPVAL_INTRINSIC)]
18008 ;; Avoid unused variable warning.
18009 "(void) operands[0];")
18011 (define_insn "*lwp_lwpval<mode>3_1"
18012 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18013 (match_operand:SI 1 "nonimmediate_operand" "rm")
18014 (match_operand:SI 2 "const_int_operand" "i")]
18015 UNSPECV_LWPVAL_INTRINSIC)]
18017 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18018 [(set_attr "type" "lwp")
18019 (set_attr "mode" "<MODE>")
18020 (set (attr "length")
18021 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18023 (define_expand "lwp_lwpins<mode>3"
18024 [(set (reg:CCC FLAGS_REG)
18025 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18026 (match_operand:SI 2 "nonimmediate_operand" "rm")
18027 (match_operand:SI 3 "const_int_operand" "i")]
18028 UNSPECV_LWPINS_INTRINSIC))
18029 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18030 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18033 (define_insn "*lwp_lwpins<mode>3_1"
18034 [(set (reg:CCC FLAGS_REG)
18035 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18036 (match_operand:SI 1 "nonimmediate_operand" "rm")
18037 (match_operand:SI 2 "const_int_operand" "i")]
18038 UNSPECV_LWPINS_INTRINSIC))]
18040 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18041 [(set_attr "type" "lwp")
18042 (set_attr "mode" "<MODE>")
18043 (set (attr "length")
18044 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18046 (define_int_iterator RDFSGSBASE
18050 (define_int_iterator WRFSGSBASE
18054 (define_int_attr fsgs
18055 [(UNSPECV_RDFSBASE "fs")
18056 (UNSPECV_RDGSBASE "gs")
18057 (UNSPECV_WRFSBASE "fs")
18058 (UNSPECV_WRGSBASE "gs")])
18060 (define_insn "rd<fsgs>base<mode>"
18061 [(set (match_operand:SWI48 0 "register_operand" "=r")
18062 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18063 "TARGET_64BIT && TARGET_FSGSBASE"
18065 [(set_attr "type" "other")
18066 (set_attr "prefix_extra" "2")])
18068 (define_insn "wr<fsgs>base<mode>"
18069 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18071 "TARGET_64BIT && TARGET_FSGSBASE"
18073 [(set_attr "type" "other")
18074 (set_attr "prefix_extra" "2")])
18076 (define_insn "rdrand<mode>_1"
18077 [(set (match_operand:SWI248 0 "register_operand" "=r")
18078 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18079 (set (reg:CCC FLAGS_REG)
18080 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18083 [(set_attr "type" "other")
18084 (set_attr "prefix_extra" "1")])
18086 (define_insn "rdseed<mode>_1"
18087 [(set (match_operand:SWI248 0 "register_operand" "=r")
18088 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18089 (set (reg:CCC FLAGS_REG)
18090 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18093 [(set_attr "type" "other")
18094 (set_attr "prefix_extra" "1")])
18096 (define_expand "pause"
18097 [(set (match_dup 0)
18098 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18101 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18102 MEM_VOLATILE_P (operands[0]) = 1;
18105 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18106 ;; They have the same encoding.
18107 (define_insn "*pause"
18108 [(set (match_operand:BLK 0)
18109 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18112 [(set_attr "length" "2")
18113 (set_attr "memory" "unknown")])
18115 (define_expand "xbegin"
18116 [(set (match_operand:SI 0 "register_operand")
18117 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18120 rtx label = gen_label_rtx ();
18122 /* xbegin is emitted as jump_insn, so reload won't be able
18123 to reload its operand. Force the value into AX hard register. */
18124 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18125 emit_move_insn (ax_reg, constm1_rtx);
18127 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18129 emit_label (label);
18130 LABEL_NUSES (label) = 1;
18132 emit_move_insn (operands[0], ax_reg);
18137 (define_insn "xbegin_1"
18139 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18141 (label_ref (match_operand 1))
18143 (set (match_operand:SI 0 "register_operand" "+a")
18144 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18147 [(set_attr "type" "other")
18148 (set_attr "length" "6")])
18150 (define_insn "xend"
18151 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18154 [(set_attr "type" "other")
18155 (set_attr "length" "3")])
18157 (define_insn "xabort"
18158 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18162 [(set_attr "type" "other")
18163 (set_attr "length" "3")])
18165 (define_expand "xtest"
18166 [(set (match_operand:QI 0 "register_operand")
18167 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18170 emit_insn (gen_xtest_1 ());
18172 ix86_expand_setcc (operands[0], NE,
18173 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18177 (define_insn "xtest_1"
18178 [(set (reg:CCZ FLAGS_REG)
18179 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18182 [(set_attr "type" "other")
18183 (set_attr "length" "3")])
18187 (include "sync.md")