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
116 ;; For SSE/MMX support:
124 ;; Generic math support
126 UNSPEC_IEEE_MIN ; not commutative
127 UNSPEC_IEEE_MAX ; not commutative
129 ;; x87 Floating point
145 UNSPEC_FRNDINT_MASK_PM
149 ;; x87 Double output FP
183 ;; For AVX512F support
187 (define_c_enum "unspecv" [
190 UNSPECV_PROBE_STACK_RANGE
193 UNSPECV_SPLIT_STACK_RETURN
199 UNSPECV_LLWP_INTRINSIC
200 UNSPECV_SLWP_INTRINSIC
201 UNSPECV_LWPVAL_INTRINSIC
202 UNSPECV_LWPINS_INTRINSIC
224 ;; For atomic compound assignments.
230 ;; For RDRAND support
233 ;; For RDSEED support
244 ;; For CLFLUSHOPT support
248 ;; Constants to represent rounding modes in the ROUND instruction
257 ;; Constants to represent AVX512F embeded rounding
259 [(ROUND_NEAREST_INT 0)
267 ;; Constants to represent pcomtrue/pcomfalse variants
277 ;; Constants used in the XOP pperm instruction
279 [(PPERM_SRC 0x00) /* copy source */
280 (PPERM_INVERT 0x20) /* invert source */
281 (PPERM_REVERSE 0x40) /* bit reverse source */
282 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
283 (PPERM_ZERO 0x80) /* all 0's */
284 (PPERM_ONES 0xa0) /* all 1's */
285 (PPERM_SIGN 0xc0) /* propagate sign bit */
286 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
287 (PPERM_SRC1 0x00) /* use first source byte */
288 (PPERM_SRC2 0x10) /* use second source byte */
291 ;; Registers by name.
370 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
373 ;; In C guard expressions, put expressions which may be compile-time
374 ;; constants first. This allows for better optimization. For
375 ;; example, write "TARGET_64BIT && reload_completed", not
376 ;; "reload_completed && TARGET_64BIT".
380 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
381 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
383 (const (symbol_ref "ix86_schedule")))
385 ;; A basic instruction type. Refinements due to arguments to be
386 ;; provided in other attributes.
389 alu,alu1,negnot,imov,imovx,lea,
390 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
391 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
392 push,pop,call,callv,leave,
394 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
395 fxch,fistp,fisttp,frndint,
396 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
397 ssemul,sseimul,ssediv,sselog,sselog1,
398 sseishft,sseishft1,ssecmp,ssecomi,
399 ssecvt,ssecvt1,sseicvt,sseins,
400 sseshuf,sseshuf1,ssemuladd,sse4arg,
402 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
403 (const_string "other"))
405 ;; Main data type used by the insn
407 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
409 (const_string "unknown"))
411 ;; The CPU unit operations uses.
412 (define_attr "unit" "integer,i387,sse,mmx,unknown"
413 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
414 fxch,fistp,fisttp,frndint")
415 (const_string "i387")
416 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
417 ssemul,sseimul,ssediv,sselog,sselog1,
418 sseishft,sseishft1,ssecmp,ssecomi,
419 ssecvt,ssecvt1,sseicvt,sseins,
420 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
422 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
424 (eq_attr "type" "other")
425 (const_string "unknown")]
426 (const_string "integer")))
428 ;; The minimum required alignment of vector mode memory operands of the SSE
429 ;; (non-VEX/EVEX) instruction in bits, if it is different from
430 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
431 ;; multiple alternatives, this should be conservative maximum of those minimum
432 ;; required alignments.
433 (define_attr "ssememalign" "" (const_int 0))
435 ;; The (bounding maximum) length of an instruction immediate.
436 (define_attr "length_immediate" ""
437 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
438 bitmanip,imulx,msklog,mskmov")
440 (eq_attr "unit" "i387,sse,mmx")
442 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
443 rotate,rotatex,rotate1,imul,icmp,push,pop")
444 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
445 (eq_attr "type" "imov,test")
446 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
447 (eq_attr "type" "call")
448 (if_then_else (match_operand 0 "constant_call_address_operand")
451 (eq_attr "type" "callv")
452 (if_then_else (match_operand 1 "constant_call_address_operand")
455 ;; We don't know the size before shorten_branches. Expect
456 ;; the instruction to fit for better scheduling.
457 (eq_attr "type" "ibr")
460 (symbol_ref "/* Update immediate_length and other attributes! */
461 gcc_unreachable (),1")))
463 ;; The (bounding maximum) length of an instruction address.
464 (define_attr "length_address" ""
465 (cond [(eq_attr "type" "str,other,multi,fxch")
467 (and (eq_attr "type" "call")
468 (match_operand 0 "constant_call_address_operand"))
470 (and (eq_attr "type" "callv")
471 (match_operand 1 "constant_call_address_operand"))
474 (symbol_ref "ix86_attr_length_address_default (insn)")))
476 ;; Set when length prefix is used.
477 (define_attr "prefix_data16" ""
478 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
480 (eq_attr "mode" "HI")
482 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
487 ;; Set when string REP prefix is used.
488 (define_attr "prefix_rep" ""
489 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
491 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
496 ;; Set when 0f opcode prefix is used.
497 (define_attr "prefix_0f" ""
499 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
500 (eq_attr "unit" "sse,mmx"))
504 ;; Set when REX opcode prefix is used.
505 (define_attr "prefix_rex" ""
506 (cond [(not (match_test "TARGET_64BIT"))
508 (and (eq_attr "mode" "DI")
509 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
510 (eq_attr "unit" "!mmx")))
512 (and (eq_attr "mode" "QI")
513 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
515 (match_test "x86_extended_reg_mentioned_p (insn)")
517 (and (eq_attr "type" "imovx")
518 (match_operand:QI 1 "ext_QIreg_operand"))
523 ;; There are also additional prefixes in 3DNOW, SSSE3.
524 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
525 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
526 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
527 (define_attr "prefix_extra" ""
528 (cond [(eq_attr "type" "ssemuladd,sse4arg")
530 (eq_attr "type" "sseiadd1,ssecvt1")
535 ;; Prefix used: original, VEX or maybe VEX.
536 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
537 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
539 (eq_attr "mode" "XI,V16SF,V8DF")
540 (const_string "evex")
542 (const_string "orig")))
544 ;; VEX W bit is used.
545 (define_attr "prefix_vex_w" "" (const_int 0))
547 ;; The length of VEX prefix
548 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
549 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
550 ;; still prefix_0f 1, with prefix_extra 1.
551 (define_attr "length_vex" ""
552 (if_then_else (and (eq_attr "prefix_0f" "1")
553 (eq_attr "prefix_extra" "0"))
554 (if_then_else (eq_attr "prefix_vex_w" "1")
555 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
556 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
557 (if_then_else (eq_attr "prefix_vex_w" "1")
558 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
559 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
561 ;; 4-bytes evex prefix and 1 byte opcode.
562 (define_attr "length_evex" "" (const_int 5))
564 ;; Set when modrm byte is used.
565 (define_attr "modrm" ""
566 (cond [(eq_attr "type" "str,leave")
568 (eq_attr "unit" "i387")
570 (and (eq_attr "type" "incdec")
571 (and (not (match_test "TARGET_64BIT"))
572 (ior (match_operand:SI 1 "register_operand")
573 (match_operand:HI 1 "register_operand"))))
575 (and (eq_attr "type" "push")
576 (not (match_operand 1 "memory_operand")))
578 (and (eq_attr "type" "pop")
579 (not (match_operand 0 "memory_operand")))
581 (and (eq_attr "type" "imov")
582 (and (not (eq_attr "mode" "DI"))
583 (ior (and (match_operand 0 "register_operand")
584 (match_operand 1 "immediate_operand"))
585 (ior (and (match_operand 0 "ax_reg_operand")
586 (match_operand 1 "memory_displacement_only_operand"))
587 (and (match_operand 0 "memory_displacement_only_operand")
588 (match_operand 1 "ax_reg_operand"))))))
590 (and (eq_attr "type" "call")
591 (match_operand 0 "constant_call_address_operand"))
593 (and (eq_attr "type" "callv")
594 (match_operand 1 "constant_call_address_operand"))
596 (and (eq_attr "type" "alu,alu1,icmp,test")
597 (match_operand 0 "ax_reg_operand"))
598 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
602 ;; The (bounding maximum) length of an instruction in bytes.
603 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
604 ;; Later we may want to split them and compute proper length as for
606 (define_attr "length" ""
607 (cond [(eq_attr "type" "other,multi,fistp,frndint")
609 (eq_attr "type" "fcmp")
611 (eq_attr "unit" "i387")
613 (plus (attr "prefix_data16")
614 (attr "length_address")))
615 (ior (eq_attr "prefix" "evex")
616 (and (ior (eq_attr "prefix" "maybe_evex")
617 (eq_attr "prefix" "maybe_vex"))
618 (match_test "TARGET_AVX512F")))
619 (plus (attr "length_evex")
620 (plus (attr "length_immediate")
622 (attr "length_address"))))
623 (ior (eq_attr "prefix" "vex")
624 (and (ior (eq_attr "prefix" "maybe_vex")
625 (eq_attr "prefix" "maybe_evex"))
626 (match_test "TARGET_AVX")))
627 (plus (attr "length_vex")
628 (plus (attr "length_immediate")
630 (attr "length_address"))))]
631 (plus (plus (attr "modrm")
632 (plus (attr "prefix_0f")
633 (plus (attr "prefix_rex")
634 (plus (attr "prefix_extra")
636 (plus (attr "prefix_rep")
637 (plus (attr "prefix_data16")
638 (plus (attr "length_immediate")
639 (attr "length_address")))))))
641 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
642 ;; `store' if there is a simple memory reference therein, or `unknown'
643 ;; if the instruction is complex.
645 (define_attr "memory" "none,load,store,both,unknown"
646 (cond [(eq_attr "type" "other,multi,str,lwp")
647 (const_string "unknown")
648 (eq_attr "type" "lea,fcmov,fpspc")
649 (const_string "none")
650 (eq_attr "type" "fistp,leave")
651 (const_string "both")
652 (eq_attr "type" "frndint")
653 (const_string "load")
654 (eq_attr "type" "push")
655 (if_then_else (match_operand 1 "memory_operand")
656 (const_string "both")
657 (const_string "store"))
658 (eq_attr "type" "pop")
659 (if_then_else (match_operand 0 "memory_operand")
660 (const_string "both")
661 (const_string "load"))
662 (eq_attr "type" "setcc")
663 (if_then_else (match_operand 0 "memory_operand")
664 (const_string "store")
665 (const_string "none"))
666 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
667 (if_then_else (ior (match_operand 0 "memory_operand")
668 (match_operand 1 "memory_operand"))
669 (const_string "load")
670 (const_string "none"))
671 (eq_attr "type" "ibr")
672 (if_then_else (match_operand 0 "memory_operand")
673 (const_string "load")
674 (const_string "none"))
675 (eq_attr "type" "call")
676 (if_then_else (match_operand 0 "constant_call_address_operand")
677 (const_string "none")
678 (const_string "load"))
679 (eq_attr "type" "callv")
680 (if_then_else (match_operand 1 "constant_call_address_operand")
681 (const_string "none")
682 (const_string "load"))
683 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
684 (match_operand 1 "memory_operand"))
685 (const_string "both")
686 (and (match_operand 0 "memory_operand")
687 (match_operand 1 "memory_operand"))
688 (const_string "both")
689 (match_operand 0 "memory_operand")
690 (const_string "store")
691 (match_operand 1 "memory_operand")
692 (const_string "load")
694 "!alu1,negnot,ishift1,
695 imov,imovx,icmp,test,bitmanip,
697 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
698 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
699 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
700 (match_operand 2 "memory_operand"))
701 (const_string "load")
702 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
703 (match_operand 3 "memory_operand"))
704 (const_string "load")
706 (const_string "none")))
708 ;; Indicates if an instruction has both an immediate and a displacement.
710 (define_attr "imm_disp" "false,true,unknown"
711 (cond [(eq_attr "type" "other,multi")
712 (const_string "unknown")
713 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
714 (and (match_operand 0 "memory_displacement_operand")
715 (match_operand 1 "immediate_operand")))
716 (const_string "true")
717 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
718 (and (match_operand 0 "memory_displacement_operand")
719 (match_operand 2 "immediate_operand")))
720 (const_string "true")
722 (const_string "false")))
724 ;; Indicates if an FP operation has an integer source.
726 (define_attr "fp_int_src" "false,true"
727 (const_string "false"))
729 ;; Defines rounding mode of an FP operation.
731 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
732 (const_string "any"))
734 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
735 (define_attr "use_carry" "0,1" (const_string "0"))
737 ;; Define attribute to indicate unaligned ssemov insns
738 (define_attr "movu" "0,1" (const_string "0"))
740 ;; Used to control the "enabled" attribute on a per-instruction basis.
741 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
742 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
743 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
744 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
745 (const_string "base"))
747 (define_attr "enabled" ""
748 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
749 (eq_attr "isa" "x64_sse4")
750 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
751 (eq_attr "isa" "x64_sse4_noavx")
752 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
753 (eq_attr "isa" "x64_avx")
754 (symbol_ref "TARGET_64BIT && TARGET_AVX")
755 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
756 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
757 (eq_attr "isa" "sse2_noavx")
758 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
759 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
760 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
761 (eq_attr "isa" "sse4_noavx")
762 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
763 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
764 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
765 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
766 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
767 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
768 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
769 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
770 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
771 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
772 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
773 (eq_attr "isa" "fma_avx512f")
774 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
775 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
776 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
777 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
778 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
782 ;; Describe a user's asm statement.
783 (define_asm_attributes
784 [(set_attr "length" "128")
785 (set_attr "type" "multi")])
787 (define_code_iterator plusminus [plus minus])
789 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
791 (define_code_iterator multdiv [mult div])
793 ;; Base name for define_insn
794 (define_code_attr plusminus_insn
795 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
796 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
798 ;; Base name for insn mnemonic.
799 (define_code_attr plusminus_mnemonic
800 [(plus "add") (ss_plus "adds") (us_plus "addus")
801 (minus "sub") (ss_minus "subs") (us_minus "subus")])
802 (define_code_attr plusminus_carry_mnemonic
803 [(plus "adc") (minus "sbb")])
804 (define_code_attr multdiv_mnemonic
805 [(mult "mul") (div "div")])
807 ;; Mark commutative operators as such in constraints.
808 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
809 (minus "") (ss_minus "") (us_minus "")])
811 ;; Mapping of max and min
812 (define_code_iterator maxmin [smax smin umax umin])
814 ;; Mapping of signed max and min
815 (define_code_iterator smaxmin [smax smin])
817 ;; Mapping of unsigned max and min
818 (define_code_iterator umaxmin [umax umin])
820 ;; Base name for integer and FP insn mnemonic
821 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
822 (umax "maxu") (umin "minu")])
823 (define_code_attr maxmin_float [(smax "max") (smin "min")])
825 ;; Mapping of logic operators
826 (define_code_iterator any_logic [and ior xor])
827 (define_code_iterator any_or [ior xor])
828 (define_code_iterator fpint_logic [and xor])
830 ;; Base name for insn mnemonic.
831 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
833 ;; Mapping of logic-shift operators
834 (define_code_iterator any_lshift [ashift lshiftrt])
836 ;; Mapping of shift-right operators
837 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
839 ;; Mapping of all shift operators
840 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
842 ;; Base name for define_insn
843 (define_code_attr shift_insn
844 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
846 ;; Base name for insn mnemonic.
847 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
848 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
850 ;; Mapping of rotate operators
851 (define_code_iterator any_rotate [rotate rotatert])
853 ;; Base name for define_insn
854 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
856 ;; Base name for insn mnemonic.
857 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
859 ;; Mapping of abs neg operators
860 (define_code_iterator absneg [abs neg])
862 ;; Base name for x87 insn mnemonic.
863 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
865 ;; Used in signed and unsigned widening multiplications.
866 (define_code_iterator any_extend [sign_extend zero_extend])
868 ;; Prefix for insn menmonic.
869 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
871 ;; Prefix for define_insn
872 (define_code_attr u [(sign_extend "") (zero_extend "u")])
873 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
874 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
876 ;; Used in signed and unsigned truncations.
877 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
878 ;; Instruction suffix for truncations.
879 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
881 ;; Used in signed and unsigned fix.
882 (define_code_iterator any_fix [fix unsigned_fix])
883 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
884 (define_code_attr ufix_bool [(fix "false") (unsigned_fix "true")])
886 ;; Used in signed and unsigned float.
887 (define_code_iterator any_float [float unsigned_float])
888 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
890 ;; All integer modes.
891 (define_mode_iterator SWI1248x [QI HI SI DI])
893 ;; All integer modes without QImode.
894 (define_mode_iterator SWI248x [HI SI DI])
896 ;; All integer modes without QImode and HImode.
897 (define_mode_iterator SWI48x [SI DI])
899 ;; All integer modes without SImode and DImode.
900 (define_mode_iterator SWI12 [QI HI])
902 ;; All integer modes without DImode.
903 (define_mode_iterator SWI124 [QI HI SI])
905 ;; All integer modes without QImode and DImode.
906 (define_mode_iterator SWI24 [HI SI])
908 ;; Single word integer modes.
909 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
911 ;; Single word integer modes without QImode.
912 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
914 ;; Single word integer modes without QImode and HImode.
915 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
917 ;; All math-dependant single and double word integer modes.
918 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
919 (HI "TARGET_HIMODE_MATH")
920 SI DI (TI "TARGET_64BIT")])
922 ;; Math-dependant single word integer modes.
923 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
924 (HI "TARGET_HIMODE_MATH")
925 SI (DI "TARGET_64BIT")])
927 ;; Math-dependant integer modes without DImode.
928 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
929 (HI "TARGET_HIMODE_MATH")
932 ;; Math-dependant single word integer modes without QImode.
933 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
934 SI (DI "TARGET_64BIT")])
936 ;; Double word integer modes.
937 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
938 (TI "TARGET_64BIT")])
940 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
941 ;; compile time constant, it is faster to use <MODE_SIZE> than
942 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
943 ;; command line options just use GET_MODE_SIZE macro.
944 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
945 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
946 (V16QI "16") (V32QI "32") (V64QI "64")
947 (V8HI "16") (V16HI "32") (V32HI "64")
948 (V4SI "16") (V8SI "32") (V16SI "64")
949 (V2DI "16") (V4DI "32") (V8DI "64")
950 (V1TI "16") (V2TI "32") (V4TI "64")
951 (V2DF "16") (V4DF "32") (V8DF "64")
952 (V4SF "16") (V8SF "32") (V16SF "64")])
954 ;; Double word integer modes as mode attribute.
955 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
956 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
958 ;; Half mode for double word integer modes.
959 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
960 (DI "TARGET_64BIT")])
962 ;; Instruction suffix for integer modes.
963 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
965 ;; Instruction suffix for masks.
966 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
968 ;; Pointer size prefix for integer modes (Intel asm dialect)
969 (define_mode_attr iptrsize [(QI "BYTE")
974 ;; Register class for integer modes.
975 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
977 ;; Immediate operand constraint for integer modes.
978 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
980 ;; General operand constraint for word modes.
981 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
983 ;; Immediate operand constraint for double integer modes.
984 (define_mode_attr di [(SI "nF") (DI "e")])
986 ;; Immediate operand constraint for shifts.
987 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
989 ;; General operand predicate for integer modes.
990 (define_mode_attr general_operand
991 [(QI "general_operand")
992 (HI "general_operand")
993 (SI "x86_64_general_operand")
994 (DI "x86_64_general_operand")
995 (TI "x86_64_general_operand")])
997 ;; General sign extend operand predicate for integer modes,
998 ;; which disallows VOIDmode operands and thus it is suitable
999 ;; for use inside sign_extend.
1000 (define_mode_attr general_sext_operand
1001 [(QI "sext_operand")
1003 (SI "x86_64_sext_operand")
1004 (DI "x86_64_sext_operand")])
1006 ;; General sign/zero extend operand predicate for integer modes.
1007 (define_mode_attr general_szext_operand
1008 [(QI "general_operand")
1009 (HI "general_operand")
1010 (SI "x86_64_szext_general_operand")
1011 (DI "x86_64_szext_general_operand")])
1013 ;; Immediate operand predicate for integer modes.
1014 (define_mode_attr immediate_operand
1015 [(QI "immediate_operand")
1016 (HI "immediate_operand")
1017 (SI "x86_64_immediate_operand")
1018 (DI "x86_64_immediate_operand")])
1020 ;; Nonmemory operand predicate for integer modes.
1021 (define_mode_attr nonmemory_operand
1022 [(QI "nonmemory_operand")
1023 (HI "nonmemory_operand")
1024 (SI "x86_64_nonmemory_operand")
1025 (DI "x86_64_nonmemory_operand")])
1027 ;; Operand predicate for shifts.
1028 (define_mode_attr shift_operand
1029 [(QI "nonimmediate_operand")
1030 (HI "nonimmediate_operand")
1031 (SI "nonimmediate_operand")
1032 (DI "shiftdi_operand")
1033 (TI "register_operand")])
1035 ;; Operand predicate for shift argument.
1036 (define_mode_attr shift_immediate_operand
1037 [(QI "const_1_to_31_operand")
1038 (HI "const_1_to_31_operand")
1039 (SI "const_1_to_31_operand")
1040 (DI "const_1_to_63_operand")])
1042 ;; Input operand predicate for arithmetic left shifts.
1043 (define_mode_attr ashl_input_operand
1044 [(QI "nonimmediate_operand")
1045 (HI "nonimmediate_operand")
1046 (SI "nonimmediate_operand")
1047 (DI "ashldi_input_operand")
1048 (TI "reg_or_pm1_operand")])
1050 ;; SSE and x87 SFmode and DFmode floating point modes
1051 (define_mode_iterator MODEF [SF DF])
1053 ;; All x87 floating point modes
1054 (define_mode_iterator X87MODEF [SF DF XF])
1056 ;; SSE instruction suffix for various modes
1057 (define_mode_attr ssemodesuffix
1058 [(SF "ss") (DF "sd")
1059 (V16SF "ps") (V8DF "pd")
1060 (V8SF "ps") (V4DF "pd")
1061 (V4SF "ps") (V2DF "pd")
1062 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1063 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1064 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1066 ;; SSE vector suffix for floating point modes
1067 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1069 ;; SSE vector mode corresponding to a scalar mode
1070 (define_mode_attr ssevecmode
1071 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1072 (define_mode_attr ssevecmodelower
1073 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1075 ;; Instruction suffix for REX 64bit operators.
1076 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1078 ;; This mode iterator allows :P to be used for patterns that operate on
1079 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1080 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1082 ;; This mode iterator allows :W to be used for patterns that operate on
1083 ;; word_mode sized quantities.
1084 (define_mode_iterator W
1085 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1087 ;; This mode iterator allows :PTR to be used for patterns that operate on
1088 ;; ptr_mode sized quantities.
1089 (define_mode_iterator PTR
1090 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1092 ;; Scheduling descriptions
1094 (include "pentium.md")
1097 (include "athlon.md")
1098 (include "bdver1.md")
1099 (include "bdver3.md")
1100 (include "btver2.md")
1101 (include "geode.md")
1104 (include "core2.md")
1107 ;; Operand and operator predicates and constraints
1109 (include "predicates.md")
1110 (include "constraints.md")
1113 ;; Compare and branch/compare and store instructions.
1115 (define_expand "cbranch<mode>4"
1116 [(set (reg:CC FLAGS_REG)
1117 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1118 (match_operand:SDWIM 2 "<general_operand>")))
1119 (set (pc) (if_then_else
1120 (match_operator 0 "ordered_comparison_operator"
1121 [(reg:CC FLAGS_REG) (const_int 0)])
1122 (label_ref (match_operand 3))
1126 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1127 operands[1] = force_reg (<MODE>mode, operands[1]);
1128 ix86_expand_branch (GET_CODE (operands[0]),
1129 operands[1], operands[2], operands[3]);
1133 (define_expand "cstore<mode>4"
1134 [(set (reg:CC FLAGS_REG)
1135 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1136 (match_operand:SWIM 3 "<general_operand>")))
1137 (set (match_operand:QI 0 "register_operand")
1138 (match_operator 1 "ordered_comparison_operator"
1139 [(reg:CC FLAGS_REG) (const_int 0)]))]
1142 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1143 operands[2] = force_reg (<MODE>mode, operands[2]);
1144 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1145 operands[2], operands[3]);
1149 (define_expand "cmp<mode>_1"
1150 [(set (reg:CC FLAGS_REG)
1151 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1152 (match_operand:SWI48 1 "<general_operand>")))])
1154 (define_insn "*cmp<mode>_ccno_1"
1155 [(set (reg FLAGS_REG)
1156 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1157 (match_operand:SWI 1 "const0_operand")))]
1158 "ix86_match_ccmode (insn, CCNOmode)"
1160 test{<imodesuffix>}\t%0, %0
1161 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1162 [(set_attr "type" "test,icmp")
1163 (set_attr "length_immediate" "0,1")
1164 (set_attr "mode" "<MODE>")])
1166 (define_insn "*cmp<mode>_1"
1167 [(set (reg FLAGS_REG)
1168 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1169 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1170 "ix86_match_ccmode (insn, CCmode)"
1171 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1172 [(set_attr "type" "icmp")
1173 (set_attr "mode" "<MODE>")])
1175 (define_insn "*cmp<mode>_minus_1"
1176 [(set (reg FLAGS_REG)
1178 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1179 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1181 "ix86_match_ccmode (insn, CCGOCmode)"
1182 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1183 [(set_attr "type" "icmp")
1184 (set_attr "mode" "<MODE>")])
1186 (define_insn "*cmpqi_ext_1"
1187 [(set (reg FLAGS_REG)
1189 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1192 (match_operand 1 "ext_register_operand" "Q,Q")
1194 (const_int 8)) 0)))]
1195 "ix86_match_ccmode (insn, CCmode)"
1196 "cmp{b}\t{%h1, %0|%0, %h1}"
1197 [(set_attr "isa" "*,nox64")
1198 (set_attr "type" "icmp")
1199 (set_attr "mode" "QI")])
1201 (define_insn "*cmpqi_ext_2"
1202 [(set (reg FLAGS_REG)
1206 (match_operand 0 "ext_register_operand" "Q")
1209 (match_operand:QI 1 "const0_operand")))]
1210 "ix86_match_ccmode (insn, CCNOmode)"
1212 [(set_attr "type" "test")
1213 (set_attr "length_immediate" "0")
1214 (set_attr "mode" "QI")])
1216 (define_expand "cmpqi_ext_3"
1217 [(set (reg:CC FLAGS_REG)
1221 (match_operand 0 "ext_register_operand")
1224 (match_operand:QI 1 "const_int_operand")))])
1226 (define_insn "*cmpqi_ext_3"
1227 [(set (reg FLAGS_REG)
1231 (match_operand 0 "ext_register_operand" "Q,Q")
1234 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1235 "ix86_match_ccmode (insn, CCmode)"
1236 "cmp{b}\t{%1, %h0|%h0, %1}"
1237 [(set_attr "isa" "*,nox64")
1238 (set_attr "type" "icmp")
1239 (set_attr "modrm" "1")
1240 (set_attr "mode" "QI")])
1242 (define_insn "*cmpqi_ext_4"
1243 [(set (reg FLAGS_REG)
1247 (match_operand 0 "ext_register_operand" "Q")
1252 (match_operand 1 "ext_register_operand" "Q")
1254 (const_int 8)) 0)))]
1255 "ix86_match_ccmode (insn, CCmode)"
1256 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1257 [(set_attr "type" "icmp")
1258 (set_attr "mode" "QI")])
1260 ;; These implement float point compares.
1261 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1262 ;; which would allow mix and match FP modes on the compares. Which is what
1263 ;; the old patterns did, but with many more of them.
1265 (define_expand "cbranchxf4"
1266 [(set (reg:CC FLAGS_REG)
1267 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1268 (match_operand:XF 2 "nonmemory_operand")))
1269 (set (pc) (if_then_else
1270 (match_operator 0 "ix86_fp_comparison_operator"
1273 (label_ref (match_operand 3))
1277 ix86_expand_branch (GET_CODE (operands[0]),
1278 operands[1], operands[2], operands[3]);
1282 (define_expand "cstorexf4"
1283 [(set (reg:CC FLAGS_REG)
1284 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1285 (match_operand:XF 3 "nonmemory_operand")))
1286 (set (match_operand:QI 0 "register_operand")
1287 (match_operator 1 "ix86_fp_comparison_operator"
1292 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1293 operands[2], operands[3]);
1297 (define_expand "cbranch<mode>4"
1298 [(set (reg:CC FLAGS_REG)
1299 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1300 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1301 (set (pc) (if_then_else
1302 (match_operator 0 "ix86_fp_comparison_operator"
1305 (label_ref (match_operand 3))
1307 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1309 ix86_expand_branch (GET_CODE (operands[0]),
1310 operands[1], operands[2], operands[3]);
1314 (define_expand "cstore<mode>4"
1315 [(set (reg:CC FLAGS_REG)
1316 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1317 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1318 (set (match_operand:QI 0 "register_operand")
1319 (match_operator 1 "ix86_fp_comparison_operator"
1322 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1324 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1325 operands[2], operands[3]);
1329 (define_expand "cbranchcc4"
1330 [(set (pc) (if_then_else
1331 (match_operator 0 "comparison_operator"
1332 [(match_operand 1 "flags_reg_operand")
1333 (match_operand 2 "const0_operand")])
1334 (label_ref (match_operand 3))
1338 ix86_expand_branch (GET_CODE (operands[0]),
1339 operands[1], operands[2], operands[3]);
1343 (define_expand "cstorecc4"
1344 [(set (match_operand:QI 0 "register_operand")
1345 (match_operator 1 "comparison_operator"
1346 [(match_operand 2 "flags_reg_operand")
1347 (match_operand 3 "const0_operand")]))]
1350 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1351 operands[2], operands[3]);
1356 ;; FP compares, step 1:
1357 ;; Set the FP condition codes.
1359 ;; CCFPmode compare with exceptions
1360 ;; CCFPUmode compare with no exceptions
1362 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1363 ;; used to manage the reg stack popping would not be preserved.
1365 (define_insn "*cmp<mode>_0_i387"
1366 [(set (match_operand:HI 0 "register_operand" "=a")
1369 (match_operand:X87MODEF 1 "register_operand" "f")
1370 (match_operand:X87MODEF 2 "const0_operand"))]
1373 "* return output_fp_compare (insn, operands, false, false);"
1374 [(set_attr "type" "multi")
1375 (set_attr "unit" "i387")
1376 (set_attr "mode" "<MODE>")])
1378 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1379 [(set (reg:CCFP FLAGS_REG)
1381 (match_operand:X87MODEF 1 "register_operand" "f")
1382 (match_operand:X87MODEF 2 "const0_operand")))
1383 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1384 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1386 "&& reload_completed"
1389 [(compare:CCFP (match_dup 1)(match_dup 2))]
1391 (set (reg:CC FLAGS_REG)
1392 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1394 [(set_attr "type" "multi")
1395 (set_attr "unit" "i387")
1396 (set_attr "mode" "<MODE>")])
1398 (define_insn "*cmpxf_i387"
1399 [(set (match_operand:HI 0 "register_operand" "=a")
1402 (match_operand:XF 1 "register_operand" "f")
1403 (match_operand:XF 2 "register_operand" "f"))]
1406 "* return output_fp_compare (insn, operands, false, false);"
1407 [(set_attr "type" "multi")
1408 (set_attr "unit" "i387")
1409 (set_attr "mode" "XF")])
1411 (define_insn_and_split "*cmpxf_cc_i387"
1412 [(set (reg:CCFP FLAGS_REG)
1414 (match_operand:XF 1 "register_operand" "f")
1415 (match_operand:XF 2 "register_operand" "f")))
1416 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1417 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1419 "&& reload_completed"
1422 [(compare:CCFP (match_dup 1)(match_dup 2))]
1424 (set (reg:CC FLAGS_REG)
1425 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1427 [(set_attr "type" "multi")
1428 (set_attr "unit" "i387")
1429 (set_attr "mode" "XF")])
1431 (define_insn "*cmp<mode>_i387"
1432 [(set (match_operand:HI 0 "register_operand" "=a")
1435 (match_operand:MODEF 1 "register_operand" "f")
1436 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1439 "* return output_fp_compare (insn, operands, false, false);"
1440 [(set_attr "type" "multi")
1441 (set_attr "unit" "i387")
1442 (set_attr "mode" "<MODE>")])
1444 (define_insn_and_split "*cmp<mode>_cc_i387"
1445 [(set (reg:CCFP FLAGS_REG)
1447 (match_operand:MODEF 1 "register_operand" "f")
1448 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1449 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1450 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1452 "&& reload_completed"
1455 [(compare:CCFP (match_dup 1)(match_dup 2))]
1457 (set (reg:CC FLAGS_REG)
1458 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1460 [(set_attr "type" "multi")
1461 (set_attr "unit" "i387")
1462 (set_attr "mode" "<MODE>")])
1464 (define_insn "*cmpu<mode>_i387"
1465 [(set (match_operand:HI 0 "register_operand" "=a")
1468 (match_operand:X87MODEF 1 "register_operand" "f")
1469 (match_operand:X87MODEF 2 "register_operand" "f"))]
1472 "* return output_fp_compare (insn, operands, false, true);"
1473 [(set_attr "type" "multi")
1474 (set_attr "unit" "i387")
1475 (set_attr "mode" "<MODE>")])
1477 (define_insn_and_split "*cmpu<mode>_cc_i387"
1478 [(set (reg:CCFPU FLAGS_REG)
1480 (match_operand:X87MODEF 1 "register_operand" "f")
1481 (match_operand:X87MODEF 2 "register_operand" "f")))
1482 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1483 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1485 "&& reload_completed"
1488 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1490 (set (reg:CC FLAGS_REG)
1491 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1493 [(set_attr "type" "multi")
1494 (set_attr "unit" "i387")
1495 (set_attr "mode" "<MODE>")])
1497 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1498 [(set (match_operand:HI 0 "register_operand" "=a")
1501 (match_operand:X87MODEF 1 "register_operand" "f")
1502 (match_operator:X87MODEF 3 "float_operator"
1503 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1506 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1507 || optimize_function_for_size_p (cfun))"
1508 "* return output_fp_compare (insn, operands, false, false);"
1509 [(set_attr "type" "multi")
1510 (set_attr "unit" "i387")
1511 (set_attr "fp_int_src" "true")
1512 (set_attr "mode" "<SWI24:MODE>")])
1514 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1515 [(set (reg:CCFP FLAGS_REG)
1517 (match_operand:X87MODEF 1 "register_operand" "f")
1518 (match_operator:X87MODEF 3 "float_operator"
1519 [(match_operand:SWI24 2 "memory_operand" "m")])))
1520 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1521 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1522 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1523 || optimize_function_for_size_p (cfun))"
1525 "&& reload_completed"
1530 (match_op_dup 3 [(match_dup 2)]))]
1532 (set (reg:CC FLAGS_REG)
1533 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1535 [(set_attr "type" "multi")
1536 (set_attr "unit" "i387")
1537 (set_attr "fp_int_src" "true")
1538 (set_attr "mode" "<SWI24:MODE>")])
1540 ;; FP compares, step 2
1541 ;; Move the fpsw to ax.
1543 (define_insn "x86_fnstsw_1"
1544 [(set (match_operand:HI 0 "register_operand" "=a")
1545 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1548 [(set_attr "length" "2")
1549 (set_attr "mode" "SI")
1550 (set_attr "unit" "i387")])
1552 ;; FP compares, step 3
1553 ;; Get ax into flags, general case.
1555 (define_insn "x86_sahf_1"
1556 [(set (reg:CC FLAGS_REG)
1557 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1561 #ifndef HAVE_AS_IX86_SAHF
1563 return ASM_BYTE "0x9e";
1568 [(set_attr "length" "1")
1569 (set_attr "athlon_decode" "vector")
1570 (set_attr "amdfam10_decode" "direct")
1571 (set_attr "bdver1_decode" "direct")
1572 (set_attr "mode" "SI")])
1574 ;; Pentium Pro can do steps 1 through 3 in one go.
1575 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1576 ;; (these i387 instructions set flags directly)
1578 (define_mode_iterator FPCMP [CCFP CCFPU])
1579 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1581 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1582 [(set (reg:FPCMP FLAGS_REG)
1584 (match_operand:MODEF 0 "register_operand" "f,x")
1585 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1586 "TARGET_MIX_SSE_I387
1587 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1588 "* return output_fp_compare (insn, operands, true,
1589 <FPCMP:MODE>mode == CCFPUmode);"
1590 [(set_attr "type" "fcmp,ssecomi")
1591 (set_attr "prefix" "orig,maybe_vex")
1592 (set_attr "mode" "<MODEF:MODE>")
1593 (set (attr "prefix_rep")
1594 (if_then_else (eq_attr "type" "ssecomi")
1596 (const_string "*")))
1597 (set (attr "prefix_data16")
1598 (cond [(eq_attr "type" "fcmp")
1600 (eq_attr "mode" "DF")
1603 (const_string "0")))
1604 (set_attr "athlon_decode" "vector")
1605 (set_attr "amdfam10_decode" "direct")
1606 (set_attr "bdver1_decode" "double")])
1608 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1609 [(set (reg:FPCMP FLAGS_REG)
1611 (match_operand:MODEF 0 "register_operand" "x")
1612 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1614 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1615 "* return output_fp_compare (insn, operands, true,
1616 <FPCMP:MODE>mode == CCFPUmode);"
1617 [(set_attr "type" "ssecomi")
1618 (set_attr "prefix" "maybe_vex")
1619 (set_attr "mode" "<MODEF:MODE>")
1620 (set_attr "prefix_rep" "0")
1621 (set (attr "prefix_data16")
1622 (if_then_else (eq_attr "mode" "DF")
1624 (const_string "0")))
1625 (set_attr "athlon_decode" "vector")
1626 (set_attr "amdfam10_decode" "direct")
1627 (set_attr "bdver1_decode" "double")])
1629 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1630 [(set (reg:FPCMP FLAGS_REG)
1632 (match_operand:X87MODEF 0 "register_operand" "f")
1633 (match_operand:X87MODEF 1 "register_operand" "f")))]
1634 "TARGET_80387 && TARGET_CMOVE
1635 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1636 "* return output_fp_compare (insn, operands, true,
1637 <FPCMP:MODE>mode == CCFPUmode);"
1638 [(set_attr "type" "fcmp")
1639 (set_attr "mode" "<X87MODEF:MODE>")
1640 (set_attr "athlon_decode" "vector")
1641 (set_attr "amdfam10_decode" "direct")
1642 (set_attr "bdver1_decode" "double")])
1644 ;; Push/pop instructions.
1646 (define_insn "*push<mode>2"
1647 [(set (match_operand:DWI 0 "push_operand" "=<")
1648 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1651 [(set_attr "type" "multi")
1652 (set_attr "mode" "<MODE>")])
1655 [(set (match_operand:TI 0 "push_operand")
1656 (match_operand:TI 1 "general_operand"))]
1657 "TARGET_64BIT && reload_completed
1658 && !SSE_REG_P (operands[1])"
1660 "ix86_split_long_move (operands); DONE;")
1662 (define_insn "*pushdi2_rex64"
1663 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1664 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1669 [(set_attr "type" "push,multi")
1670 (set_attr "mode" "DI")])
1672 ;; Convert impossible pushes of immediate to existing instructions.
1673 ;; First try to get scratch register and go through it. In case this
1674 ;; fails, push sign extended lower part first and then overwrite
1675 ;; upper part by 32bit move.
1677 [(match_scratch:DI 2 "r")
1678 (set (match_operand:DI 0 "push_operand")
1679 (match_operand:DI 1 "immediate_operand"))]
1680 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1681 && !x86_64_immediate_operand (operands[1], DImode)"
1682 [(set (match_dup 2) (match_dup 1))
1683 (set (match_dup 0) (match_dup 2))])
1685 ;; We need to define this as both peepholer and splitter for case
1686 ;; peephole2 pass is not run.
1687 ;; "&& 1" is needed to keep it from matching the previous pattern.
1689 [(set (match_operand:DI 0 "push_operand")
1690 (match_operand:DI 1 "immediate_operand"))]
1691 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1692 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1693 [(set (match_dup 0) (match_dup 1))
1694 (set (match_dup 2) (match_dup 3))]
1696 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1698 operands[1] = gen_lowpart (DImode, operands[2]);
1699 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1704 [(set (match_operand:DI 0 "push_operand")
1705 (match_operand:DI 1 "immediate_operand"))]
1706 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1707 ? epilogue_completed : reload_completed)
1708 && !symbolic_operand (operands[1], DImode)
1709 && !x86_64_immediate_operand (operands[1], DImode)"
1710 [(set (match_dup 0) (match_dup 1))
1711 (set (match_dup 2) (match_dup 3))]
1713 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1715 operands[1] = gen_lowpart (DImode, operands[2]);
1716 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1721 [(set (match_operand:DI 0 "push_operand")
1722 (match_operand:DI 1 "general_operand"))]
1723 "!TARGET_64BIT && reload_completed
1724 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1726 "ix86_split_long_move (operands); DONE;")
1728 (define_insn "*pushsi2"
1729 [(set (match_operand:SI 0 "push_operand" "=<")
1730 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1733 [(set_attr "type" "push")
1734 (set_attr "mode" "SI")])
1736 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1737 ;; "push a byte/word". But actually we use pushl, which has the effect
1738 ;; of rounding the amount pushed up to a word.
1740 ;; For TARGET_64BIT we always round up to 8 bytes.
1741 (define_insn "*push<mode>2_rex64"
1742 [(set (match_operand:SWI124 0 "push_operand" "=X")
1743 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1746 [(set_attr "type" "push")
1747 (set_attr "mode" "DI")])
1749 (define_insn "*push<mode>2"
1750 [(set (match_operand:SWI12 0 "push_operand" "=X")
1751 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1754 [(set_attr "type" "push")
1755 (set_attr "mode" "SI")])
1757 (define_insn "*push<mode>2_prologue"
1758 [(set (match_operand:W 0 "push_operand" "=<")
1759 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1760 (clobber (mem:BLK (scratch)))]
1762 "push{<imodesuffix>}\t%1"
1763 [(set_attr "type" "push")
1764 (set_attr "mode" "<MODE>")])
1766 (define_insn "*pop<mode>1"
1767 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1768 (match_operand:W 1 "pop_operand" ">"))]
1770 "pop{<imodesuffix>}\t%0"
1771 [(set_attr "type" "pop")
1772 (set_attr "mode" "<MODE>")])
1774 (define_insn "*pop<mode>1_epilogue"
1775 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1776 (match_operand:W 1 "pop_operand" ">"))
1777 (clobber (mem:BLK (scratch)))]
1779 "pop{<imodesuffix>}\t%0"
1780 [(set_attr "type" "pop")
1781 (set_attr "mode" "<MODE>")])
1783 (define_insn "*pushfl<mode>2"
1784 [(set (match_operand:W 0 "push_operand" "=<")
1785 (match_operand:W 1 "flags_reg_operand"))]
1787 "pushf{<imodesuffix>}"
1788 [(set_attr "type" "push")
1789 (set_attr "mode" "<MODE>")])
1791 (define_insn "*popfl<mode>1"
1792 [(set (match_operand:W 0 "flags_reg_operand")
1793 (match_operand:W 1 "pop_operand" ">"))]
1795 "popf{<imodesuffix>}"
1796 [(set_attr "type" "pop")
1797 (set_attr "mode" "<MODE>")])
1800 ;; Move instructions.
1802 (define_expand "movxi"
1803 [(set (match_operand:XI 0 "nonimmediate_operand")
1804 (match_operand:XI 1 "general_operand"))]
1806 "ix86_expand_move (XImode, operands); DONE;")
1808 ;; Reload patterns to support multi-word load/store
1809 ;; with non-offsetable address.
1810 (define_expand "reload_noff_store"
1811 [(parallel [(match_operand 0 "memory_operand" "=m")
1812 (match_operand 1 "register_operand" "r")
1813 (match_operand:DI 2 "register_operand" "=&r")])]
1816 rtx mem = operands[0];
1817 rtx addr = XEXP (mem, 0);
1819 emit_move_insn (operands[2], addr);
1820 mem = replace_equiv_address_nv (mem, operands[2]);
1822 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1826 (define_expand "reload_noff_load"
1827 [(parallel [(match_operand 0 "register_operand" "=r")
1828 (match_operand 1 "memory_operand" "m")
1829 (match_operand:DI 2 "register_operand" "=r")])]
1832 rtx mem = operands[1];
1833 rtx addr = XEXP (mem, 0);
1835 emit_move_insn (operands[2], addr);
1836 mem = replace_equiv_address_nv (mem, operands[2]);
1838 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1842 (define_expand "movoi"
1843 [(set (match_operand:OI 0 "nonimmediate_operand")
1844 (match_operand:OI 1 "general_operand"))]
1846 "ix86_expand_move (OImode, operands); DONE;")
1848 (define_expand "movti"
1849 [(set (match_operand:TI 0 "nonimmediate_operand")
1850 (match_operand:TI 1 "nonimmediate_operand"))]
1851 "TARGET_64BIT || TARGET_SSE"
1854 ix86_expand_move (TImode, operands);
1856 ix86_expand_vector_move (TImode, operands);
1860 ;; This expands to what emit_move_complex would generate if we didn't
1861 ;; have a movti pattern. Having this avoids problems with reload on
1862 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1863 ;; to have around all the time.
1864 (define_expand "movcdi"
1865 [(set (match_operand:CDI 0 "nonimmediate_operand")
1866 (match_operand:CDI 1 "general_operand"))]
1869 if (push_operand (operands[0], CDImode))
1870 emit_move_complex_push (CDImode, operands[0], operands[1]);
1872 emit_move_complex_parts (operands[0], operands[1]);
1876 (define_expand "mov<mode>"
1877 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1878 (match_operand:SWI1248x 1 "general_operand"))]
1880 "ix86_expand_move (<MODE>mode, operands); DONE;")
1882 (define_insn "*mov<mode>_xor"
1883 [(set (match_operand:SWI48 0 "register_operand" "=r")
1884 (match_operand:SWI48 1 "const0_operand"))
1885 (clobber (reg:CC FLAGS_REG))]
1888 [(set_attr "type" "alu1")
1889 (set_attr "mode" "SI")
1890 (set_attr "length_immediate" "0")])
1892 (define_insn "*mov<mode>_or"
1893 [(set (match_operand:SWI48 0 "register_operand" "=r")
1894 (match_operand:SWI48 1 "const_int_operand"))
1895 (clobber (reg:CC FLAGS_REG))]
1897 && operands[1] == constm1_rtx"
1898 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1899 [(set_attr "type" "alu1")
1900 (set_attr "mode" "<MODE>")
1901 (set_attr "length_immediate" "1")])
1903 (define_insn "*movxi_internal_avx512f"
1904 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1905 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1906 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1908 switch (which_alternative)
1911 return standard_sse_constant_opcode (insn, operands[1]);
1914 if (misaligned_operand (operands[0], XImode)
1915 || misaligned_operand (operands[1], XImode))
1916 return "vmovdqu32\t{%1, %0|%0, %1}";
1918 return "vmovdqa32\t{%1, %0|%0, %1}";
1923 [(set_attr "type" "sselog1,ssemov,ssemov")
1924 (set_attr "prefix" "evex")
1925 (set_attr "mode" "XI")])
1927 (define_insn "*movoi_internal_avx"
1928 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1929 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
1930 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1932 switch (get_attr_type (insn))
1935 return standard_sse_constant_opcode (insn, operands[1]);
1938 if (misaligned_operand (operands[0], OImode)
1939 || misaligned_operand (operands[1], OImode))
1941 if (get_attr_mode (insn) == MODE_V8SF)
1942 return "vmovups\t{%1, %0|%0, %1}";
1943 else if (get_attr_mode (insn) == MODE_XI)
1944 return "vmovdqu32\t{%1, %0|%0, %1}";
1946 return "vmovdqu\t{%1, %0|%0, %1}";
1950 if (get_attr_mode (insn) == MODE_V8SF)
1951 return "vmovaps\t{%1, %0|%0, %1}";
1952 else if (get_attr_mode (insn) == MODE_XI)
1953 return "vmovdqa32\t{%1, %0|%0, %1}";
1955 return "vmovdqa\t{%1, %0|%0, %1}";
1962 [(set_attr "type" "sselog1,ssemov,ssemov")
1963 (set_attr "prefix" "vex")
1965 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1966 (match_operand 1 "ext_sse_reg_operand"))
1968 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1969 (const_string "V8SF")
1970 (and (eq_attr "alternative" "2")
1971 (match_test "TARGET_SSE_TYPELESS_STORES"))
1972 (const_string "V8SF")
1974 (const_string "OI")))])
1976 (define_insn "*movti_internal"
1977 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
1978 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
1979 "(TARGET_64BIT || TARGET_SSE)
1980 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1982 switch (get_attr_type (insn))
1988 return standard_sse_constant_opcode (insn, operands[1]);
1991 /* TDmode values are passed as TImode on the stack. Moving them
1992 to stack may result in unaligned memory access. */
1993 if (misaligned_operand (operands[0], TImode)
1994 || misaligned_operand (operands[1], TImode))
1996 if (get_attr_mode (insn) == MODE_V4SF)
1997 return "%vmovups\t{%1, %0|%0, %1}";
1998 else if (get_attr_mode (insn) == MODE_XI)
1999 return "vmovdqu32\t{%1, %0|%0, %1}";
2001 return "%vmovdqu\t{%1, %0|%0, %1}";
2005 if (get_attr_mode (insn) == MODE_V4SF)
2006 return "%vmovaps\t{%1, %0|%0, %1}";
2007 else if (get_attr_mode (insn) == MODE_XI)
2008 return "vmovdqa32\t{%1, %0|%0, %1}";
2010 return "%vmovdqa\t{%1, %0|%0, %1}";
2017 [(set_attr "isa" "x64,x64,*,*,*")
2018 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2019 (set (attr "prefix")
2020 (if_then_else (eq_attr "type" "sselog1,ssemov")
2021 (const_string "maybe_vex")
2022 (const_string "orig")))
2024 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2025 (match_operand 1 "ext_sse_reg_operand"))
2027 (eq_attr "alternative" "0,1")
2029 (ior (not (match_test "TARGET_SSE2"))
2030 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2031 (const_string "V4SF")
2032 (and (eq_attr "alternative" "4")
2033 (match_test "TARGET_SSE_TYPELESS_STORES"))
2034 (const_string "V4SF")
2035 (match_test "TARGET_AVX")
2037 (match_test "optimize_function_for_size_p (cfun)")
2038 (const_string "V4SF")
2040 (const_string "TI")))])
2043 [(set (match_operand:TI 0 "nonimmediate_operand")
2044 (match_operand:TI 1 "general_operand"))]
2046 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2048 "ix86_split_long_move (operands); DONE;")
2050 (define_insn "*movdi_internal"
2051 [(set (match_operand:DI 0 "nonimmediate_operand"
2052 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2053 (match_operand:DI 1 "general_operand"
2054 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2055 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2057 switch (get_attr_type (insn))
2060 return "kmovq\t{%1, %0|%0, %1}";
2066 return "pxor\t%0, %0";
2069 /* Handle broken assemblers that require movd instead of movq. */
2070 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2071 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2072 return "movd\t{%1, %0|%0, %1}";
2073 return "movq\t{%1, %0|%0, %1}";
2076 if (GENERAL_REG_P (operands[0]))
2077 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2079 return standard_sse_constant_opcode (insn, operands[1]);
2082 switch (get_attr_mode (insn))
2085 /* Handle broken assemblers that require movd instead of movq. */
2086 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2087 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2088 return "%vmovd\t{%1, %0|%0, %1}";
2089 return "%vmovq\t{%1, %0|%0, %1}";
2091 return "%vmovdqa\t{%1, %0|%0, %1}";
2093 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2096 gcc_assert (!TARGET_AVX);
2097 return "movlps\t{%1, %0|%0, %1}";
2099 return "%vmovaps\t{%1, %0|%0, %1}";
2106 if (SSE_REG_P (operands[0]))
2107 return "movq2dq\t{%1, %0|%0, %1}";
2109 return "movdq2q\t{%1, %0|%0, %1}";
2112 return "lea{q}\t{%E1, %0|%0, %E1}";
2115 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2116 if (get_attr_mode (insn) == MODE_SI)
2117 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2118 else if (which_alternative == 4)
2119 return "movabs{q}\t{%1, %0|%0, %1}";
2120 else if (ix86_use_lea_for_mov (insn, operands))
2121 return "lea{q}\t{%E1, %0|%0, %E1}";
2123 return "mov{q}\t{%1, %0|%0, %1}";
2130 (cond [(eq_attr "alternative" "0,1")
2131 (const_string "nox64")
2132 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2133 (const_string "x64")
2134 (eq_attr "alternative" "17")
2135 (const_string "x64_sse4")
2137 (const_string "*")))
2139 (cond [(eq_attr "alternative" "0,1")
2140 (const_string "multi")
2141 (eq_attr "alternative" "6")
2142 (const_string "mmx")
2143 (eq_attr "alternative" "7,8,9,10,11")
2144 (const_string "mmxmov")
2145 (eq_attr "alternative" "12,17")
2146 (const_string "sselog1")
2147 (eq_attr "alternative" "13,14,15,16,18")
2148 (const_string "ssemov")
2149 (eq_attr "alternative" "19,20")
2150 (const_string "ssecvt")
2151 (eq_attr "alternative" "21,22,23,24")
2152 (const_string "mskmov")
2153 (match_operand 1 "pic_32bit_operand")
2154 (const_string "lea")
2156 (const_string "imov")))
2159 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2161 (const_string "*")))
2162 (set (attr "length_immediate")
2163 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2165 (eq_attr "alternative" "17")
2168 (const_string "*")))
2169 (set (attr "prefix_rex")
2170 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2172 (const_string "*")))
2173 (set (attr "prefix_extra")
2174 (if_then_else (eq_attr "alternative" "17")
2176 (const_string "*")))
2177 (set (attr "prefix")
2178 (if_then_else (eq_attr "type" "sselog1,ssemov")
2179 (const_string "maybe_vex")
2180 (const_string "orig")))
2181 (set (attr "prefix_data16")
2182 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2184 (const_string "*")))
2186 (cond [(eq_attr "alternative" "2")
2188 (eq_attr "alternative" "12,13")
2189 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2190 (match_operand 1 "ext_sse_reg_operand"))
2192 (ior (not (match_test "TARGET_SSE2"))
2193 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2194 (const_string "V4SF")
2195 (match_test "TARGET_AVX")
2197 (match_test "optimize_function_for_size_p (cfun)")
2198 (const_string "V4SF")
2200 (const_string "TI"))
2202 (and (eq_attr "alternative" "14,15")
2203 (not (match_test "TARGET_SSE2")))
2204 (const_string "V2SF")
2205 (eq_attr "alternative" "17")
2208 (const_string "DI")))])
2211 [(set (match_operand:DI 0 "nonimmediate_operand")
2212 (match_operand:DI 1 "general_operand"))]
2213 "!TARGET_64BIT && reload_completed
2214 && !(MMX_REG_P (operands[0])
2215 || SSE_REG_P (operands[0])
2216 || MASK_REG_P (operands[0]))
2217 && !(MMX_REG_P (operands[1])
2218 || SSE_REG_P (operands[1])
2219 || MASK_REG_P (operands[1]))"
2221 "ix86_split_long_move (operands); DONE;")
2223 (define_insn "*movsi_internal"
2224 [(set (match_operand:SI 0 "nonimmediate_operand"
2225 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2226 (match_operand:SI 1 "general_operand"
2227 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2228 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2230 switch (get_attr_type (insn))
2233 if (GENERAL_REG_P (operands[0]))
2234 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2236 return standard_sse_constant_opcode (insn, operands[1]);
2239 return "kmovd\t{%1, %0|%0, %1}";
2242 switch (get_attr_mode (insn))
2245 return "%vmovd\t{%1, %0|%0, %1}";
2247 return "%vmovdqa\t{%1, %0|%0, %1}";
2249 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2252 return "%vmovaps\t{%1, %0|%0, %1}";
2255 gcc_assert (!TARGET_AVX);
2256 return "movss\t{%1, %0|%0, %1}";
2263 return "pxor\t%0, %0";
2266 switch (get_attr_mode (insn))
2269 return "movq\t{%1, %0|%0, %1}";
2271 return "movd\t{%1, %0|%0, %1}";
2278 return "lea{l}\t{%E1, %0|%0, %E1}";
2281 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2282 if (ix86_use_lea_for_mov (insn, operands))
2283 return "lea{l}\t{%E1, %0|%0, %E1}";
2285 return "mov{l}\t{%1, %0|%0, %1}";
2292 (if_then_else (eq_attr "alternative" "11")
2293 (const_string "sse4")
2294 (const_string "*")))
2296 (cond [(eq_attr "alternative" "2")
2297 (const_string "mmx")
2298 (eq_attr "alternative" "3,4,5")
2299 (const_string "mmxmov")
2300 (eq_attr "alternative" "6,11")
2301 (const_string "sselog1")
2302 (eq_attr "alternative" "7,8,9,10,12")
2303 (const_string "ssemov")
2304 (eq_attr "alternative" "13,14")
2305 (const_string "mskmov")
2306 (match_operand 1 "pic_32bit_operand")
2307 (const_string "lea")
2309 (const_string "imov")))
2310 (set (attr "length_immediate")
2311 (if_then_else (eq_attr "alternative" "11")
2313 (const_string "*")))
2314 (set (attr "prefix_extra")
2315 (if_then_else (eq_attr "alternative" "11")
2317 (const_string "*")))
2318 (set (attr "prefix")
2319 (if_then_else (eq_attr "type" "sselog1,ssemov")
2320 (const_string "maybe_vex")
2321 (const_string "orig")))
2322 (set (attr "prefix_data16")
2323 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2325 (const_string "*")))
2327 (cond [(eq_attr "alternative" "2,3")
2329 (eq_attr "alternative" "6,7")
2330 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2331 (match_operand 1 "ext_sse_reg_operand"))
2333 (ior (not (match_test "TARGET_SSE2"))
2334 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2335 (const_string "V4SF")
2336 (match_test "TARGET_AVX")
2338 (match_test "optimize_function_for_size_p (cfun)")
2339 (const_string "V4SF")
2341 (const_string "TI"))
2343 (and (eq_attr "alternative" "8,9")
2344 (not (match_test "TARGET_SSE2")))
2346 (eq_attr "alternative" "11")
2349 (const_string "SI")))])
2351 (define_insn "kmovw"
2352 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2354 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2356 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2358 kmovw\t{%k1, %0|%0, %k1}
2359 kmovw\t{%1, %0|%0, %1}";
2360 [(set_attr "mode" "HI")
2361 (set_attr "type" "mskmov")
2362 (set_attr "prefix" "vex")])
2365 (define_insn "*movhi_internal"
2366 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2367 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2368 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2370 switch (get_attr_type (insn))
2373 /* movzwl is faster than movw on p2 due to partial word stalls,
2374 though not as fast as an aligned movl. */
2375 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2378 switch (which_alternative)
2380 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2381 case 5: return "kmovw\t{%1, %0|%0, %1}";
2382 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2383 default: gcc_unreachable ();
2387 if (get_attr_mode (insn) == MODE_SI)
2388 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2390 return "mov{w}\t{%1, %0|%0, %1}";
2394 (cond [(match_test "optimize_function_for_size_p (cfun)")
2395 (const_string "imov")
2396 (and (eq_attr "alternative" "0")
2397 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2398 (not (match_test "TARGET_HIMODE_MATH"))))
2399 (const_string "imov")
2400 (and (eq_attr "alternative" "1,2")
2401 (match_operand:HI 1 "aligned_operand"))
2402 (const_string "imov")
2403 (eq_attr "alternative" "4,5,6")
2404 (const_string "mskmov")
2405 (and (match_test "TARGET_MOVX")
2406 (eq_attr "alternative" "0,2"))
2407 (const_string "imovx")
2409 (const_string "imov")))
2410 (set (attr "prefix")
2411 (if_then_else (eq_attr "alternative" "4,5,6")
2412 (const_string "vex")
2413 (const_string "orig")))
2415 (cond [(eq_attr "type" "imovx")
2417 (and (eq_attr "alternative" "1,2")
2418 (match_operand:HI 1 "aligned_operand"))
2420 (and (eq_attr "alternative" "0")
2421 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2422 (not (match_test "TARGET_HIMODE_MATH"))))
2425 (const_string "HI")))])
2427 ;; Situation is quite tricky about when to choose full sized (SImode) move
2428 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2429 ;; partial register dependency machines (such as AMD Athlon), where QImode
2430 ;; moves issue extra dependency and for partial register stalls machines
2431 ;; that don't use QImode patterns (and QImode move cause stall on the next
2434 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2435 ;; register stall machines with, where we use QImode instructions, since
2436 ;; partial register stall can be caused there. Then we use movzx.
2438 (define_insn "*movqi_internal"
2439 [(set (match_operand:QI 0 "nonimmediate_operand"
2440 "=q,q ,q ,r,r ,?r,m ,k,k,r")
2441 (match_operand:QI 1 "general_operand"
2442 "q ,qn,qm,q,rn,qm,qn,r ,k,k"))]
2443 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2445 switch (get_attr_type (insn))
2448 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2449 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2452 switch (which_alternative)
2454 case 7: return TARGET_AVX512BW ? "kmovb\t{%k1, %0|%0, %k1}"
2455 : "kmovw\t{%k1, %0|%0, %k1}";
2456 case 8: return TARGET_AVX512BW ? "kmovb\t{%1, %0|%0, %1}"
2457 : "kmovw\t{%1, %0|%0, %1}";
2458 case 9: return TARGET_AVX512BW ? "kmovb\t{%1, %k0|%k0, %1}"
2459 : "kmovw\t{%1, %k0|%k0, %1}";
2460 default: gcc_unreachable ();
2464 if (get_attr_mode (insn) == MODE_SI)
2465 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2467 return "mov{b}\t{%1, %0|%0, %1}";
2471 (cond [(and (eq_attr "alternative" "5")
2472 (not (match_operand:QI 1 "aligned_operand")))
2473 (const_string "imovx")
2474 (match_test "optimize_function_for_size_p (cfun)")
2475 (const_string "imov")
2476 (and (eq_attr "alternative" "3")
2477 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2478 (not (match_test "TARGET_QIMODE_MATH"))))
2479 (const_string "imov")
2480 (eq_attr "alternative" "3,5")
2481 (const_string "imovx")
2482 (eq_attr "alternative" "7,8,9")
2483 (const_string "mskmov")
2484 (and (match_test "TARGET_MOVX")
2485 (eq_attr "alternative" "2"))
2486 (const_string "imovx")
2488 (const_string "imov")))
2489 (set (attr "prefix")
2490 (if_then_else (eq_attr "alternative" "7,8,9")
2491 (const_string "vex")
2492 (const_string "orig")))
2494 (cond [(eq_attr "alternative" "3,4,5")
2496 (eq_attr "alternative" "6")
2498 (eq_attr "type" "imovx")
2500 (and (eq_attr "type" "imov")
2501 (and (eq_attr "alternative" "0,1")
2502 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2503 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2504 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2506 ;; Avoid partial register stalls when not using QImode arithmetic
2507 (and (eq_attr "type" "imov")
2508 (and (eq_attr "alternative" "0,1")
2509 (and (match_test "TARGET_PARTIAL_REG_STALL")
2510 (not (match_test "TARGET_QIMODE_MATH")))))
2513 (const_string "QI")))])
2515 ;; Stores and loads of ax to arbitrary constant address.
2516 ;; We fake an second form of instruction to force reload to load address
2517 ;; into register when rax is not available
2518 (define_insn "*movabs<mode>_1"
2519 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2520 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2521 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2523 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2524 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2525 [(set_attr "type" "imov")
2526 (set_attr "modrm" "0,*")
2527 (set_attr "length_address" "8,0")
2528 (set_attr "length_immediate" "0,*")
2529 (set_attr "memory" "store")
2530 (set_attr "mode" "<MODE>")])
2532 (define_insn "*movabs<mode>_2"
2533 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2534 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2535 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2537 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2538 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2539 [(set_attr "type" "imov")
2540 (set_attr "modrm" "0,*")
2541 (set_attr "length_address" "8,0")
2542 (set_attr "length_immediate" "0")
2543 (set_attr "memory" "load")
2544 (set_attr "mode" "<MODE>")])
2546 (define_insn "*swap<mode>"
2547 [(set (match_operand:SWI48 0 "register_operand" "+r")
2548 (match_operand:SWI48 1 "register_operand" "+r"))
2552 "xchg{<imodesuffix>}\t%1, %0"
2553 [(set_attr "type" "imov")
2554 (set_attr "mode" "<MODE>")
2555 (set_attr "pent_pair" "np")
2556 (set_attr "athlon_decode" "vector")
2557 (set_attr "amdfam10_decode" "double")
2558 (set_attr "bdver1_decode" "double")])
2560 (define_insn "*swap<mode>_1"
2561 [(set (match_operand:SWI12 0 "register_operand" "+r")
2562 (match_operand:SWI12 1 "register_operand" "+r"))
2565 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2567 [(set_attr "type" "imov")
2568 (set_attr "mode" "SI")
2569 (set_attr "pent_pair" "np")
2570 (set_attr "athlon_decode" "vector")
2571 (set_attr "amdfam10_decode" "double")
2572 (set_attr "bdver1_decode" "double")])
2574 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2575 ;; is disabled for AMDFAM10
2576 (define_insn "*swap<mode>_2"
2577 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2578 (match_operand:SWI12 1 "register_operand" "+<r>"))
2581 "TARGET_PARTIAL_REG_STALL"
2582 "xchg{<imodesuffix>}\t%1, %0"
2583 [(set_attr "type" "imov")
2584 (set_attr "mode" "<MODE>")
2585 (set_attr "pent_pair" "np")
2586 (set_attr "athlon_decode" "vector")])
2588 (define_expand "movstrict<mode>"
2589 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2590 (match_operand:SWI12 1 "general_operand"))]
2593 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2595 if (GET_CODE (operands[0]) == SUBREG
2596 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2598 /* Don't generate memory->memory moves, go through a register */
2599 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2600 operands[1] = force_reg (<MODE>mode, operands[1]);
2603 (define_insn "*movstrict<mode>_1"
2604 [(set (strict_low_part
2605 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2606 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2607 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2608 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2609 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2610 [(set_attr "type" "imov")
2611 (set_attr "mode" "<MODE>")])
2613 (define_insn "*movstrict<mode>_xor"
2614 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2615 (match_operand:SWI12 1 "const0_operand"))
2616 (clobber (reg:CC FLAGS_REG))]
2618 "xor{<imodesuffix>}\t%0, %0"
2619 [(set_attr "type" "alu1")
2620 (set_attr "mode" "<MODE>")
2621 (set_attr "length_immediate" "0")])
2623 (define_insn "*mov<mode>_extv_1"
2624 [(set (match_operand:SWI24 0 "register_operand" "=R")
2625 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2629 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2630 [(set_attr "type" "imovx")
2631 (set_attr "mode" "SI")])
2633 (define_insn "*movqi_extv_1"
2634 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2635 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2640 switch (get_attr_type (insn))
2643 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2645 return "mov{b}\t{%h1, %0|%0, %h1}";
2648 [(set_attr "isa" "*,*,nox64")
2650 (if_then_else (and (match_operand:QI 0 "register_operand")
2651 (ior (not (match_operand:QI 0 "QIreg_operand"))
2652 (match_test "TARGET_MOVX")))
2653 (const_string "imovx")
2654 (const_string "imov")))
2656 (if_then_else (eq_attr "type" "imovx")
2658 (const_string "QI")))])
2660 (define_insn "*mov<mode>_extzv_1"
2661 [(set (match_operand:SWI48 0 "register_operand" "=R")
2662 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2666 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2667 [(set_attr "type" "imovx")
2668 (set_attr "mode" "SI")])
2670 (define_insn "*movqi_extzv_2"
2671 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2673 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2678 switch (get_attr_type (insn))
2681 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2683 return "mov{b}\t{%h1, %0|%0, %h1}";
2686 [(set_attr "isa" "*,*,nox64")
2688 (if_then_else (and (match_operand:QI 0 "register_operand")
2689 (ior (not (match_operand:QI 0 "QIreg_operand"))
2690 (match_test "TARGET_MOVX")))
2691 (const_string "imovx")
2692 (const_string "imov")))
2694 (if_then_else (eq_attr "type" "imovx")
2696 (const_string "QI")))])
2698 (define_insn "mov<mode>_insv_1"
2699 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2702 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2705 if (CONST_INT_P (operands[1]))
2706 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2707 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2709 [(set_attr "isa" "*,nox64")
2710 (set_attr "type" "imov")
2711 (set_attr "mode" "QI")])
2713 (define_insn "*movqi_insv_2"
2714 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2717 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2720 "mov{b}\t{%h1, %h0|%h0, %h1}"
2721 [(set_attr "type" "imov")
2722 (set_attr "mode" "QI")])
2724 ;; Floating point push instructions.
2726 (define_insn "*pushtf"
2727 [(set (match_operand:TF 0 "push_operand" "=<,<")
2728 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2729 "TARGET_64BIT || TARGET_SSE"
2731 /* This insn should be already split before reg-stack. */
2734 [(set_attr "isa" "*,x64")
2735 (set_attr "type" "multi")
2736 (set_attr "unit" "sse,*")
2737 (set_attr "mode" "TF,DI")])
2739 ;; %%% Kill this when call knows how to work this out.
2741 [(set (match_operand:TF 0 "push_operand")
2742 (match_operand:TF 1 "sse_reg_operand"))]
2743 "TARGET_SSE && reload_completed"
2744 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2745 (set (match_dup 0) (match_dup 1))]
2747 /* Preserve memory attributes. */
2748 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2751 (define_insn "*pushxf"
2752 [(set (match_operand:XF 0 "push_operand" "=<,<")
2753 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2756 /* This insn should be already split before reg-stack. */
2759 [(set_attr "type" "multi")
2760 (set_attr "unit" "i387,*")
2762 (cond [(eq_attr "alternative" "1")
2763 (if_then_else (match_test "TARGET_64BIT")
2765 (const_string "SI"))
2767 (const_string "XF")))])
2769 ;; %%% Kill this when call knows how to work this out.
2771 [(set (match_operand:XF 0 "push_operand")
2772 (match_operand:XF 1 "fp_register_operand"))]
2774 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2775 (set (match_dup 0) (match_dup 1))]
2777 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2778 /* Preserve memory attributes. */
2779 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2782 (define_insn "*pushdf"
2783 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2784 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2787 /* This insn should be already split before reg-stack. */
2790 [(set_attr "isa" "*,nox64,x64,sse2")
2791 (set_attr "type" "multi")
2792 (set_attr "unit" "i387,*,*,sse")
2793 (set_attr "mode" "DF,SI,DI,DF")])
2795 ;; %%% Kill this when call knows how to work this out.
2797 [(set (match_operand:DF 0 "push_operand")
2798 (match_operand:DF 1 "any_fp_register_operand"))]
2800 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2801 (set (match_dup 0) (match_dup 1))]
2803 /* Preserve memory attributes. */
2804 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2807 (define_insn "*pushsf_rex64"
2808 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2809 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2812 /* Anything else should be already split before reg-stack. */
2813 gcc_assert (which_alternative == 1);
2814 return "push{q}\t%q1";
2816 [(set_attr "type" "multi,push,multi")
2817 (set_attr "unit" "i387,*,*")
2818 (set_attr "mode" "SF,DI,SF")])
2820 (define_insn "*pushsf"
2821 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2822 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2825 /* Anything else should be already split before reg-stack. */
2826 gcc_assert (which_alternative == 1);
2827 return "push{l}\t%1";
2829 [(set_attr "type" "multi,push,multi")
2830 (set_attr "unit" "i387,*,*")
2831 (set_attr "mode" "SF,SI,SF")])
2833 ;; %%% Kill this when call knows how to work this out.
2835 [(set (match_operand:SF 0 "push_operand")
2836 (match_operand:SF 1 "any_fp_register_operand"))]
2838 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2839 (set (match_dup 0) (match_dup 1))]
2841 rtx op = XEXP (operands[0], 0);
2842 if (GET_CODE (op) == PRE_DEC)
2844 gcc_assert (!TARGET_64BIT);
2849 op = XEXP (XEXP (op, 1), 1);
2850 gcc_assert (CONST_INT_P (op));
2853 /* Preserve memory attributes. */
2854 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2858 [(set (match_operand:SF 0 "push_operand")
2859 (match_operand:SF 1 "memory_operand"))]
2861 && (operands[2] = find_constant_src (insn))"
2862 [(set (match_dup 0) (match_dup 2))])
2865 [(set (match_operand 0 "push_operand")
2866 (match_operand 1 "general_operand"))]
2868 && (GET_MODE (operands[0]) == TFmode
2869 || GET_MODE (operands[0]) == XFmode
2870 || GET_MODE (operands[0]) == DFmode)
2871 && !ANY_FP_REG_P (operands[1])"
2873 "ix86_split_long_move (operands); DONE;")
2875 ;; Floating point move instructions.
2877 (define_expand "movtf"
2878 [(set (match_operand:TF 0 "nonimmediate_operand")
2879 (match_operand:TF 1 "nonimmediate_operand"))]
2880 "TARGET_64BIT || TARGET_SSE"
2881 "ix86_expand_move (TFmode, operands); DONE;")
2883 (define_expand "mov<mode>"
2884 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2885 (match_operand:X87MODEF 1 "general_operand"))]
2887 "ix86_expand_move (<MODE>mode, operands); DONE;")
2889 (define_insn "*movtf_internal"
2890 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2891 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2892 "(TARGET_64BIT || TARGET_SSE)
2893 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2894 && (!can_create_pseudo_p ()
2895 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2896 || GET_CODE (operands[1]) != CONST_DOUBLE
2897 || (optimize_function_for_size_p (cfun)
2898 && standard_sse_constant_p (operands[1])
2899 && !memory_operand (operands[0], TFmode))
2900 || (!TARGET_MEMORY_MISMATCH_STALL
2901 && memory_operand (operands[0], TFmode)))"
2903 switch (get_attr_type (insn))
2906 return standard_sse_constant_opcode (insn, operands[1]);
2909 /* Handle misaligned load/store since we
2910 don't have movmisaligntf pattern. */
2911 if (misaligned_operand (operands[0], TFmode)
2912 || misaligned_operand (operands[1], TFmode))
2914 if (get_attr_mode (insn) == MODE_V4SF)
2915 return "%vmovups\t{%1, %0|%0, %1}";
2917 return "%vmovdqu\t{%1, %0|%0, %1}";
2921 if (get_attr_mode (insn) == MODE_V4SF)
2922 return "%vmovaps\t{%1, %0|%0, %1}";
2924 return "%vmovdqa\t{%1, %0|%0, %1}";
2934 [(set_attr "isa" "*,*,*,x64,x64")
2935 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2936 (set (attr "prefix")
2937 (if_then_else (eq_attr "type" "sselog1,ssemov")
2938 (const_string "maybe_vex")
2939 (const_string "orig")))
2941 (cond [(eq_attr "alternative" "3,4")
2943 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2944 (const_string "V4SF")
2945 (and (eq_attr "alternative" "2")
2946 (match_test "TARGET_SSE_TYPELESS_STORES"))
2947 (const_string "V4SF")
2948 (match_test "TARGET_AVX")
2950 (ior (not (match_test "TARGET_SSE2"))
2951 (match_test "optimize_function_for_size_p (cfun)"))
2952 (const_string "V4SF")
2954 (const_string "TI")))])
2956 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2957 (define_insn "*movxf_internal"
2958 [(set (match_operand:XF 0 "nonimmediate_operand"
2959 "=f,m,f,?Yx*r ,!o ,!o")
2960 (match_operand:XF 1 "general_operand"
2961 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2962 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2963 && (!can_create_pseudo_p ()
2964 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2965 || GET_CODE (operands[1]) != CONST_DOUBLE
2966 || (optimize_function_for_size_p (cfun)
2967 && standard_80387_constant_p (operands[1]) > 0
2968 && !memory_operand (operands[0], XFmode))
2969 || (!TARGET_MEMORY_MISMATCH_STALL
2970 && memory_operand (operands[0], XFmode)))"
2972 switch (get_attr_type (insn))
2975 if (which_alternative == 2)
2976 return standard_80387_constant_opcode (operands[1]);
2977 return output_387_reg_move (insn, operands);
2986 [(set_attr "isa" "*,*,*,*,nox64,x64")
2987 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2989 (cond [(eq_attr "alternative" "3,4,5")
2990 (if_then_else (match_test "TARGET_64BIT")
2992 (const_string "SI"))
2994 (const_string "XF")))])
2996 ;; Possible store forwarding (partial memory) stall in alternative 4.
2997 (define_insn "*movdf_internal"
2998 [(set (match_operand:DF 0 "nonimmediate_operand"
2999 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3000 (match_operand:DF 1 "general_operand"
3001 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3002 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3003 && (!can_create_pseudo_p ()
3004 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3005 || GET_CODE (operands[1]) != CONST_DOUBLE
3006 || (optimize_function_for_size_p (cfun)
3007 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3008 && standard_80387_constant_p (operands[1]) > 0)
3009 || (TARGET_SSE2 && TARGET_SSE_MATH
3010 && standard_sse_constant_p (operands[1])))
3011 && !memory_operand (operands[0], DFmode))
3012 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3013 && memory_operand (operands[0], DFmode)))"
3015 switch (get_attr_type (insn))
3018 if (which_alternative == 2)
3019 return standard_80387_constant_opcode (operands[1]);
3020 return output_387_reg_move (insn, operands);
3026 if (get_attr_mode (insn) == MODE_SI)
3027 return "mov{l}\t{%1, %k0|%k0, %1}";
3028 else if (which_alternative == 8)
3029 return "movabs{q}\t{%1, %0|%0, %1}";
3031 return "mov{q}\t{%1, %0|%0, %1}";
3034 return standard_sse_constant_opcode (insn, operands[1]);
3037 switch (get_attr_mode (insn))
3040 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3041 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3042 return "%vmovsd\t{%1, %0|%0, %1}";
3045 return "%vmovaps\t{%1, %0|%0, %1}";
3047 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3049 return "%vmovapd\t{%1, %0|%0, %1}";
3052 gcc_assert (!TARGET_AVX);
3053 return "movlps\t{%1, %0|%0, %1}";
3055 gcc_assert (!TARGET_AVX);
3056 return "movlpd\t{%1, %0|%0, %1}";
3059 /* Handle broken assemblers that require movd instead of movq. */
3060 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3061 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3062 return "%vmovd\t{%1, %0|%0, %1}";
3063 return "%vmovq\t{%1, %0|%0, %1}";
3074 (cond [(eq_attr "alternative" "3,4")
3075 (const_string "nox64")
3076 (eq_attr "alternative" "5,6,7,8,17,18")
3077 (const_string "x64")
3078 (eq_attr "alternative" "9,10,11,12")
3079 (const_string "sse2")
3081 (const_string "*")))
3083 (cond [(eq_attr "alternative" "0,1,2")
3084 (const_string "fmov")
3085 (eq_attr "alternative" "3,4")
3086 (const_string "multi")
3087 (eq_attr "alternative" "5,6,7,8")
3088 (const_string "imov")
3089 (eq_attr "alternative" "9,13")
3090 (const_string "sselog1")
3092 (const_string "ssemov")))
3094 (if_then_else (eq_attr "alternative" "8")
3096 (const_string "*")))
3097 (set (attr "length_immediate")
3098 (if_then_else (eq_attr "alternative" "8")
3100 (const_string "*")))
3101 (set (attr "prefix")
3102 (if_then_else (eq_attr "type" "sselog1,ssemov")
3103 (const_string "maybe_vex")
3104 (const_string "orig")))
3105 (set (attr "prefix_data16")
3107 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3108 (eq_attr "mode" "V1DF"))
3110 (const_string "*")))
3112 (cond [(eq_attr "alternative" "3,4,7")
3114 (eq_attr "alternative" "5,6,8,17,18")
3117 /* xorps is one byte shorter for non-AVX targets. */
3118 (eq_attr "alternative" "9,13")
3119 (cond [(not (match_test "TARGET_SSE2"))
3120 (const_string "V4SF")
3121 (match_test "TARGET_AVX512F")
3123 (match_test "TARGET_AVX")
3124 (const_string "V2DF")
3125 (match_test "optimize_function_for_size_p (cfun)")
3126 (const_string "V4SF")
3127 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3130 (const_string "V2DF"))
3132 /* For architectures resolving dependencies on
3133 whole SSE registers use movapd to break dependency
3134 chains, otherwise use short move to avoid extra work. */
3136 /* movaps is one byte shorter for non-AVX targets. */
3137 (eq_attr "alternative" "10,14")
3138 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3139 (match_operand 1 "ext_sse_reg_operand"))
3140 (const_string "V8DF")
3141 (ior (not (match_test "TARGET_SSE2"))
3142 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3143 (const_string "V4SF")
3144 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3145 (const_string "V2DF")
3146 (match_test "TARGET_AVX")
3148 (match_test "optimize_function_for_size_p (cfun)")
3149 (const_string "V4SF")
3151 (const_string "DF"))
3153 /* For architectures resolving dependencies on register
3154 parts we may avoid extra work to zero out upper part
3156 (eq_attr "alternative" "11,15")
3157 (cond [(not (match_test "TARGET_SSE2"))
3158 (const_string "V2SF")
3159 (match_test "TARGET_AVX")
3161 (match_test "TARGET_SSE_SPLIT_REGS")
3162 (const_string "V1DF")
3164 (const_string "DF"))
3166 (and (eq_attr "alternative" "12,16")
3167 (not (match_test "TARGET_SSE2")))
3168 (const_string "V2SF")
3170 (const_string "DF")))])
3172 (define_insn "*movsf_internal"
3173 [(set (match_operand:SF 0 "nonimmediate_operand"
3174 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3175 (match_operand:SF 1 "general_operand"
3176 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3177 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3178 && (!can_create_pseudo_p ()
3179 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3180 || GET_CODE (operands[1]) != CONST_DOUBLE
3181 || (optimize_function_for_size_p (cfun)
3182 && ((!TARGET_SSE_MATH
3183 && standard_80387_constant_p (operands[1]) > 0)
3185 && standard_sse_constant_p (operands[1]))))
3186 || memory_operand (operands[0], SFmode))"
3188 switch (get_attr_type (insn))
3191 if (which_alternative == 2)
3192 return standard_80387_constant_opcode (operands[1]);
3193 return output_387_reg_move (insn, operands);
3196 return "mov{l}\t{%1, %0|%0, %1}";
3199 return standard_sse_constant_opcode (insn, operands[1]);
3202 switch (get_attr_mode (insn))
3205 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3206 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3207 return "%vmovss\t{%1, %0|%0, %1}";
3210 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3212 return "%vmovaps\t{%1, %0|%0, %1}";
3215 return "%vmovd\t{%1, %0|%0, %1}";
3222 switch (get_attr_mode (insn))
3225 return "movq\t{%1, %0|%0, %1}";
3227 return "movd\t{%1, %0|%0, %1}";
3238 (cond [(eq_attr "alternative" "0,1,2")
3239 (const_string "fmov")
3240 (eq_attr "alternative" "3,4")
3241 (const_string "imov")
3242 (eq_attr "alternative" "5")
3243 (const_string "sselog1")
3244 (eq_attr "alternative" "11,12,13,14,15")
3245 (const_string "mmxmov")
3247 (const_string "ssemov")))
3248 (set (attr "prefix")
3249 (if_then_else (eq_attr "type" "sselog1,ssemov")
3250 (const_string "maybe_vex")
3251 (const_string "orig")))
3252 (set (attr "prefix_data16")
3253 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3255 (const_string "*")))
3257 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3259 (eq_attr "alternative" "11")
3261 (eq_attr "alternative" "5")
3262 (cond [(not (match_test "TARGET_SSE2"))
3263 (const_string "V4SF")
3264 (match_test "TARGET_AVX512F")
3265 (const_string "V16SF")
3266 (match_test "TARGET_AVX")
3267 (const_string "V4SF")
3268 (match_test "optimize_function_for_size_p (cfun)")
3269 (const_string "V4SF")
3270 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3273 (const_string "V4SF"))
3275 /* For architectures resolving dependencies on
3276 whole SSE registers use APS move to break dependency
3277 chains, otherwise use short move to avoid extra work.
3279 Do the same for architectures resolving dependencies on
3280 the parts. While in DF mode it is better to always handle
3281 just register parts, the SF mode is different due to lack
3282 of instructions to load just part of the register. It is
3283 better to maintain the whole registers in single format
3284 to avoid problems on using packed logical operations. */
3285 (eq_attr "alternative" "6")
3286 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3287 (match_operand 1 "ext_sse_reg_operand"))
3288 (const_string "V16SF")
3289 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3290 (match_test "TARGET_SSE_SPLIT_REGS"))
3291 (const_string "V4SF")
3293 (const_string "SF"))
3295 (const_string "SF")))])
3298 [(set (match_operand 0 "any_fp_register_operand")
3299 (match_operand 1 "memory_operand"))]
3301 && (GET_MODE (operands[0]) == TFmode
3302 || GET_MODE (operands[0]) == XFmode
3303 || GET_MODE (operands[0]) == DFmode
3304 || GET_MODE (operands[0]) == SFmode)
3305 && (operands[2] = find_constant_src (insn))"
3306 [(set (match_dup 0) (match_dup 2))]
3308 rtx c = operands[2];
3309 int r = REGNO (operands[0]);
3311 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3312 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3317 [(set (match_operand 0 "any_fp_register_operand")
3318 (float_extend (match_operand 1 "memory_operand")))]
3320 && (GET_MODE (operands[0]) == TFmode
3321 || GET_MODE (operands[0]) == XFmode
3322 || GET_MODE (operands[0]) == DFmode)
3323 && (operands[2] = find_constant_src (insn))"
3324 [(set (match_dup 0) (match_dup 2))]
3326 rtx c = operands[2];
3327 int r = REGNO (operands[0]);
3329 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3330 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3334 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3336 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3337 (match_operand:X87MODEF 1 "immediate_operand"))]
3339 && (standard_80387_constant_p (operands[1]) == 8
3340 || standard_80387_constant_p (operands[1]) == 9)"
3341 [(set (match_dup 0)(match_dup 1))
3343 (neg:X87MODEF (match_dup 0)))]
3347 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3348 if (real_isnegzero (&r))
3349 operands[1] = CONST0_RTX (<MODE>mode);
3351 operands[1] = CONST1_RTX (<MODE>mode);
3355 [(set (match_operand 0 "nonimmediate_operand")
3356 (match_operand 1 "general_operand"))]
3358 && (GET_MODE (operands[0]) == TFmode
3359 || GET_MODE (operands[0]) == XFmode
3360 || GET_MODE (operands[0]) == DFmode)
3361 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3363 "ix86_split_long_move (operands); DONE;")
3365 (define_insn "swapxf"
3366 [(set (match_operand:XF 0 "register_operand" "+f")
3367 (match_operand:XF 1 "register_operand" "+f"))
3372 if (STACK_TOP_P (operands[0]))
3377 [(set_attr "type" "fxch")
3378 (set_attr "mode" "XF")])
3380 (define_insn "*swap<mode>"
3381 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3382 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3385 "TARGET_80387 || reload_completed"
3387 if (STACK_TOP_P (operands[0]))
3392 [(set_attr "type" "fxch")
3393 (set_attr "mode" "<MODE>")])
3395 ;; Zero extension instructions
3397 (define_expand "zero_extendsidi2"
3398 [(set (match_operand:DI 0 "nonimmediate_operand")
3399 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3401 (define_insn "*zero_extendsidi2"
3402 [(set (match_operand:DI 0 "nonimmediate_operand"
3403 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3405 (match_operand:SI 1 "x86_64_zext_operand"
3406 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3409 switch (get_attr_type (insn))
3412 if (ix86_use_lea_for_mov (insn, operands))
3413 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3415 return "mov{l}\t{%1, %k0|%k0, %1}";
3421 return "movd\t{%1, %0|%0, %1}";
3424 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3427 if (GENERAL_REG_P (operands[0]))
3428 return "%vmovd\t{%1, %k0|%k0, %1}";
3430 return "%vmovd\t{%1, %0|%0, %1}";
3437 (cond [(eq_attr "alternative" "0,1,2")
3438 (const_string "nox64")
3439 (eq_attr "alternative" "3,7")
3440 (const_string "x64")
3441 (eq_attr "alternative" "8")
3442 (const_string "x64_sse4")
3443 (eq_attr "alternative" "10")
3444 (const_string "sse2")
3446 (const_string "*")))
3448 (cond [(eq_attr "alternative" "0,1,2,4")
3449 (const_string "multi")
3450 (eq_attr "alternative" "5,6")
3451 (const_string "mmxmov")
3452 (eq_attr "alternative" "7,9,10")
3453 (const_string "ssemov")
3454 (eq_attr "alternative" "8")
3455 (const_string "sselog1")
3457 (const_string "imovx")))
3458 (set (attr "prefix_extra")
3459 (if_then_else (eq_attr "alternative" "8")
3461 (const_string "*")))
3462 (set (attr "length_immediate")
3463 (if_then_else (eq_attr "alternative" "8")
3465 (const_string "*")))
3466 (set (attr "prefix")
3467 (if_then_else (eq_attr "type" "ssemov,sselog1")
3468 (const_string "maybe_vex")
3469 (const_string "orig")))
3470 (set (attr "prefix_0f")
3471 (if_then_else (eq_attr "type" "imovx")
3473 (const_string "*")))
3475 (cond [(eq_attr "alternative" "5,6")
3477 (eq_attr "alternative" "7,8,9")
3480 (const_string "SI")))])
3483 [(set (match_operand:DI 0 "memory_operand")
3484 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3486 [(set (match_dup 4) (const_int 0))]
3487 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3490 [(set (match_operand:DI 0 "register_operand")
3491 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3492 "!TARGET_64BIT && reload_completed
3493 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3494 && true_regnum (operands[0]) == true_regnum (operands[1])"
3495 [(set (match_dup 4) (const_int 0))]
3496 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3499 [(set (match_operand:DI 0 "nonimmediate_operand")
3500 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3501 "!TARGET_64BIT && reload_completed
3502 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3503 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3504 [(set (match_dup 3) (match_dup 1))
3505 (set (match_dup 4) (const_int 0))]
3506 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3508 (define_insn "zero_extend<mode>di2"
3509 [(set (match_operand:DI 0 "register_operand" "=r")
3511 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3513 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3514 [(set_attr "type" "imovx")
3515 (set_attr "mode" "SI")])
3517 (define_expand "zero_extend<mode>si2"
3518 [(set (match_operand:SI 0 "register_operand")
3519 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3522 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3524 operands[1] = force_reg (<MODE>mode, operands[1]);
3525 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3530 (define_insn_and_split "zero_extend<mode>si2_and"
3531 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3533 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3534 (clobber (reg:CC FLAGS_REG))]
3535 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3537 "&& reload_completed"
3538 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3539 (clobber (reg:CC FLAGS_REG))])]
3541 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3543 ix86_expand_clear (operands[0]);
3545 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3546 emit_insn (gen_movstrict<mode>
3547 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3551 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3553 [(set_attr "type" "alu1")
3554 (set_attr "mode" "SI")])
3556 (define_insn "*zero_extend<mode>si2"
3557 [(set (match_operand:SI 0 "register_operand" "=r")
3559 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3560 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3561 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3562 [(set_attr "type" "imovx")
3563 (set_attr "mode" "SI")])
3565 (define_expand "zero_extendqihi2"
3566 [(set (match_operand:HI 0 "register_operand")
3567 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3570 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3572 operands[1] = force_reg (QImode, operands[1]);
3573 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3578 (define_insn_and_split "zero_extendqihi2_and"
3579 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3580 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3581 (clobber (reg:CC FLAGS_REG))]
3582 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3584 "&& reload_completed"
3585 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3586 (clobber (reg:CC FLAGS_REG))])]
3588 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3590 ix86_expand_clear (operands[0]);
3592 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3593 emit_insn (gen_movstrictqi
3594 (gen_lowpart (QImode, operands[0]), operands[1]));
3598 operands[0] = gen_lowpart (SImode, operands[0]);
3600 [(set_attr "type" "alu1")
3601 (set_attr "mode" "SI")])
3603 ; zero extend to SImode to avoid partial register stalls
3604 (define_insn "*zero_extendqihi2"
3605 [(set (match_operand:HI 0 "register_operand" "=r")
3606 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3607 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3608 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3609 [(set_attr "type" "imovx")
3610 (set_attr "mode" "SI")])
3612 ;; Sign extension instructions
3614 (define_expand "extendsidi2"
3615 [(set (match_operand:DI 0 "register_operand")
3616 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3621 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3626 (define_insn "*extendsidi2_rex64"
3627 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3628 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3632 movs{lq|x}\t{%1, %0|%0, %1}"
3633 [(set_attr "type" "imovx")
3634 (set_attr "mode" "DI")
3635 (set_attr "prefix_0f" "0")
3636 (set_attr "modrm" "0,1")])
3638 (define_insn "extendsidi2_1"
3639 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3640 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3641 (clobber (reg:CC FLAGS_REG))
3642 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3646 ;; Split the memory case. If the source register doesn't die, it will stay
3647 ;; this way, if it does die, following peephole2s take care of it.
3649 [(set (match_operand:DI 0 "memory_operand")
3650 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3651 (clobber (reg:CC FLAGS_REG))
3652 (clobber (match_operand:SI 2 "register_operand"))]
3656 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3658 emit_move_insn (operands[3], operands[1]);
3660 /* Generate a cltd if possible and doing so it profitable. */
3661 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3662 && true_regnum (operands[1]) == AX_REG
3663 && true_regnum (operands[2]) == DX_REG)
3665 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3669 emit_move_insn (operands[2], operands[1]);
3670 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3672 emit_move_insn (operands[4], operands[2]);
3676 ;; Peepholes for the case where the source register does die, after
3677 ;; being split with the above splitter.
3679 [(set (match_operand:SI 0 "memory_operand")
3680 (match_operand:SI 1 "register_operand"))
3681 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3682 (parallel [(set (match_dup 2)
3683 (ashiftrt:SI (match_dup 2) (const_int 31)))
3684 (clobber (reg:CC FLAGS_REG))])
3685 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3686 "REGNO (operands[1]) != REGNO (operands[2])
3687 && peep2_reg_dead_p (2, operands[1])
3688 && peep2_reg_dead_p (4, operands[2])
3689 && !reg_mentioned_p (operands[2], operands[3])"
3690 [(set (match_dup 0) (match_dup 1))
3691 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3692 (clobber (reg:CC FLAGS_REG))])
3693 (set (match_dup 3) (match_dup 1))])
3696 [(set (match_operand:SI 0 "memory_operand")
3697 (match_operand:SI 1 "register_operand"))
3698 (parallel [(set (match_operand:SI 2 "register_operand")
3699 (ashiftrt:SI (match_dup 1) (const_int 31)))
3700 (clobber (reg:CC FLAGS_REG))])
3701 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3702 "/* cltd is shorter than sarl $31, %eax */
3703 !optimize_function_for_size_p (cfun)
3704 && true_regnum (operands[1]) == AX_REG
3705 && true_regnum (operands[2]) == DX_REG
3706 && peep2_reg_dead_p (2, operands[1])
3707 && peep2_reg_dead_p (3, operands[2])
3708 && !reg_mentioned_p (operands[2], operands[3])"
3709 [(set (match_dup 0) (match_dup 1))
3710 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3711 (clobber (reg:CC FLAGS_REG))])
3712 (set (match_dup 3) (match_dup 1))])
3714 ;; Extend to register case. Optimize case where source and destination
3715 ;; registers match and cases where we can use cltd.
3717 [(set (match_operand:DI 0 "register_operand")
3718 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3719 (clobber (reg:CC FLAGS_REG))
3720 (clobber (match_scratch:SI 2))]
3724 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3726 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3727 emit_move_insn (operands[3], operands[1]);
3729 /* Generate a cltd if possible and doing so it profitable. */
3730 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3731 && true_regnum (operands[3]) == AX_REG
3732 && true_regnum (operands[4]) == DX_REG)
3734 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3738 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3739 emit_move_insn (operands[4], operands[1]);
3741 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3745 (define_insn "extend<mode>di2"
3746 [(set (match_operand:DI 0 "register_operand" "=r")
3748 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3750 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3751 [(set_attr "type" "imovx")
3752 (set_attr "mode" "DI")])
3754 (define_insn "extendhisi2"
3755 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3756 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3759 switch (get_attr_prefix_0f (insn))
3762 return "{cwtl|cwde}";
3764 return "movs{wl|x}\t{%1, %0|%0, %1}";
3767 [(set_attr "type" "imovx")
3768 (set_attr "mode" "SI")
3769 (set (attr "prefix_0f")
3770 ;; movsx is short decodable while cwtl is vector decoded.
3771 (if_then_else (and (eq_attr "cpu" "!k6")
3772 (eq_attr "alternative" "0"))
3774 (const_string "1")))
3776 (if_then_else (eq_attr "prefix_0f" "0")
3778 (const_string "1")))])
3780 (define_insn "*extendhisi2_zext"
3781 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3784 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3787 switch (get_attr_prefix_0f (insn))
3790 return "{cwtl|cwde}";
3792 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3795 [(set_attr "type" "imovx")
3796 (set_attr "mode" "SI")
3797 (set (attr "prefix_0f")
3798 ;; movsx is short decodable while cwtl is vector decoded.
3799 (if_then_else (and (eq_attr "cpu" "!k6")
3800 (eq_attr "alternative" "0"))
3802 (const_string "1")))
3804 (if_then_else (eq_attr "prefix_0f" "0")
3806 (const_string "1")))])
3808 (define_insn "extendqisi2"
3809 [(set (match_operand:SI 0 "register_operand" "=r")
3810 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3812 "movs{bl|x}\t{%1, %0|%0, %1}"
3813 [(set_attr "type" "imovx")
3814 (set_attr "mode" "SI")])
3816 (define_insn "*extendqisi2_zext"
3817 [(set (match_operand:DI 0 "register_operand" "=r")
3819 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3821 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3822 [(set_attr "type" "imovx")
3823 (set_attr "mode" "SI")])
3825 (define_insn "extendqihi2"
3826 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3827 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3830 switch (get_attr_prefix_0f (insn))
3833 return "{cbtw|cbw}";
3835 return "movs{bw|x}\t{%1, %0|%0, %1}";
3838 [(set_attr "type" "imovx")
3839 (set_attr "mode" "HI")
3840 (set (attr "prefix_0f")
3841 ;; movsx is short decodable while cwtl is vector decoded.
3842 (if_then_else (and (eq_attr "cpu" "!k6")
3843 (eq_attr "alternative" "0"))
3845 (const_string "1")))
3847 (if_then_else (eq_attr "prefix_0f" "0")
3849 (const_string "1")))])
3851 ;; Conversions between float and double.
3853 ;; These are all no-ops in the model used for the 80387.
3854 ;; So just emit moves.
3856 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3858 [(set (match_operand:DF 0 "push_operand")
3859 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3861 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3862 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3865 [(set (match_operand:XF 0 "push_operand")
3866 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3868 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3869 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3870 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3872 (define_expand "extendsfdf2"
3873 [(set (match_operand:DF 0 "nonimmediate_operand")
3874 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3875 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3877 /* ??? Needed for compress_float_constant since all fp constants
3878 are TARGET_LEGITIMATE_CONSTANT_P. */
3879 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3881 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3882 && standard_80387_constant_p (operands[1]) > 0)
3884 operands[1] = simplify_const_unary_operation
3885 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3886 emit_move_insn_1 (operands[0], operands[1]);
3889 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3893 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3895 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3897 We do the conversion post reload to avoid producing of 128bit spills
3898 that might lead to ICE on 32bit target. The sequence unlikely combine
3901 [(set (match_operand:DF 0 "register_operand")
3903 (match_operand:SF 1 "nonimmediate_operand")))]
3904 "TARGET_USE_VECTOR_FP_CONVERTS
3905 && optimize_insn_for_speed_p ()
3906 && reload_completed && SSE_REG_P (operands[0])"
3911 (parallel [(const_int 0) (const_int 1)]))))]
3913 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3914 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3915 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3916 Try to avoid move when unpacking can be done in source. */
3917 if (REG_P (operands[1]))
3919 /* If it is unsafe to overwrite upper half of source, we need
3920 to move to destination and unpack there. */
3921 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3922 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3923 && true_regnum (operands[0]) != true_regnum (operands[1]))
3925 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3926 emit_move_insn (tmp, operands[1]);
3929 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3930 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3934 emit_insn (gen_vec_setv4sf_0 (operands[3],
3935 CONST0_RTX (V4SFmode), operands[1]));
3938 ;; It's more profitable to split and then extend in the same register.
3940 [(set (match_operand:DF 0 "register_operand")
3942 (match_operand:SF 1 "memory_operand")))]
3943 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3944 && optimize_insn_for_speed_p ()
3945 && SSE_REG_P (operands[0])"
3946 [(set (match_dup 2) (match_dup 1))
3947 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3948 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3950 (define_insn "*extendsfdf2_mixed"
3951 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3953 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3954 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3956 switch (which_alternative)
3960 return output_387_reg_move (insn, operands);
3963 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3969 [(set_attr "type" "fmov,fmov,ssecvt")
3970 (set_attr "prefix" "orig,orig,maybe_vex")
3971 (set_attr "mode" "SF,XF,DF")])
3973 (define_insn "*extendsfdf2_sse"
3974 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3975 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3976 "TARGET_SSE2 && TARGET_SSE_MATH"
3977 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3978 [(set_attr "type" "ssecvt")
3979 (set_attr "prefix" "maybe_vex")
3980 (set_attr "mode" "DF")])
3982 (define_insn "*extendsfdf2_i387"
3983 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3984 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3986 "* return output_387_reg_move (insn, operands);"
3987 [(set_attr "type" "fmov")
3988 (set_attr "mode" "SF,XF")])
3990 (define_expand "extend<mode>xf2"
3991 [(set (match_operand:XF 0 "nonimmediate_operand")
3992 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3995 /* ??? Needed for compress_float_constant since all fp constants
3996 are TARGET_LEGITIMATE_CONSTANT_P. */
3997 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3999 if (standard_80387_constant_p (operands[1]) > 0)
4001 operands[1] = simplify_const_unary_operation
4002 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4003 emit_move_insn_1 (operands[0], operands[1]);
4006 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4010 (define_insn "*extend<mode>xf2_i387"
4011 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4013 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4015 "* return output_387_reg_move (insn, operands);"
4016 [(set_attr "type" "fmov")
4017 (set_attr "mode" "<MODE>,XF")])
4019 ;; %%% This seems bad bad news.
4020 ;; This cannot output into an f-reg because there is no way to be sure
4021 ;; of truncating in that case. Otherwise this is just like a simple move
4022 ;; insn. So we pretend we can output to a reg in order to get better
4023 ;; register preferencing, but we really use a stack slot.
4025 ;; Conversion from DFmode to SFmode.
4027 (define_expand "truncdfsf2"
4028 [(set (match_operand:SF 0 "nonimmediate_operand")
4030 (match_operand:DF 1 "nonimmediate_operand")))]
4031 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4033 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4035 else if (flag_unsafe_math_optimizations)
4039 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4040 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4045 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4047 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4049 We do the conversion post reload to avoid producing of 128bit spills
4050 that might lead to ICE on 32bit target. The sequence unlikely combine
4053 [(set (match_operand:SF 0 "register_operand")
4055 (match_operand:DF 1 "nonimmediate_operand")))]
4056 "TARGET_USE_VECTOR_FP_CONVERTS
4057 && optimize_insn_for_speed_p ()
4058 && reload_completed && SSE_REG_P (operands[0])"
4061 (float_truncate:V2SF
4065 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4066 operands[3] = CONST0_RTX (V2SFmode);
4067 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4068 /* Use movsd for loading from memory, unpcklpd for registers.
4069 Try to avoid move when unpacking can be done in source, or SSE3
4070 movddup is available. */
4071 if (REG_P (operands[1]))
4074 && true_regnum (operands[0]) != true_regnum (operands[1])
4075 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4076 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4078 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4079 emit_move_insn (tmp, operands[1]);
4082 else if (!TARGET_SSE3)
4083 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4084 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4087 emit_insn (gen_sse2_loadlpd (operands[4],
4088 CONST0_RTX (V2DFmode), operands[1]));
4091 ;; It's more profitable to split and then extend in the same register.
4093 [(set (match_operand:SF 0 "register_operand")
4095 (match_operand:DF 1 "memory_operand")))]
4096 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4097 && optimize_insn_for_speed_p ()
4098 && SSE_REG_P (operands[0])"
4099 [(set (match_dup 2) (match_dup 1))
4100 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4101 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4103 (define_expand "truncdfsf2_with_temp"
4104 [(parallel [(set (match_operand:SF 0)
4105 (float_truncate:SF (match_operand:DF 1)))
4106 (clobber (match_operand:SF 2))])])
4108 (define_insn "*truncdfsf_fast_mixed"
4109 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4111 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4112 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4114 switch (which_alternative)
4117 return output_387_reg_move (insn, operands);
4119 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4124 [(set_attr "type" "fmov,ssecvt")
4125 (set_attr "prefix" "orig,maybe_vex")
4126 (set_attr "mode" "SF")])
4128 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4129 ;; because nothing we do here is unsafe.
4130 (define_insn "*truncdfsf_fast_sse"
4131 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4133 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4134 "TARGET_SSE2 && TARGET_SSE_MATH"
4135 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4136 [(set_attr "type" "ssecvt")
4137 (set_attr "prefix" "maybe_vex")
4138 (set_attr "mode" "SF")])
4140 (define_insn "*truncdfsf_fast_i387"
4141 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4143 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4144 "TARGET_80387 && flag_unsafe_math_optimizations"
4145 "* return output_387_reg_move (insn, operands);"
4146 [(set_attr "type" "fmov")
4147 (set_attr "mode" "SF")])
4149 (define_insn "*truncdfsf_mixed"
4150 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4152 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4153 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4154 "TARGET_MIX_SSE_I387"
4156 switch (which_alternative)
4159 return output_387_reg_move (insn, operands);
4161 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4167 [(set_attr "isa" "*,sse2,*,*,*")
4168 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4169 (set_attr "unit" "*,*,i387,i387,i387")
4170 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4171 (set_attr "mode" "SF")])
4173 (define_insn "*truncdfsf_i387"
4174 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4176 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4177 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4180 switch (which_alternative)
4183 return output_387_reg_move (insn, operands);
4189 [(set_attr "type" "fmov,multi,multi,multi")
4190 (set_attr "unit" "*,i387,i387,i387")
4191 (set_attr "mode" "SF")])
4193 (define_insn "*truncdfsf2_i387_1"
4194 [(set (match_operand:SF 0 "memory_operand" "=m")
4196 (match_operand:DF 1 "register_operand" "f")))]
4198 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4199 && !TARGET_MIX_SSE_I387"
4200 "* return output_387_reg_move (insn, operands);"
4201 [(set_attr "type" "fmov")
4202 (set_attr "mode" "SF")])
4205 [(set (match_operand:SF 0 "register_operand")
4207 (match_operand:DF 1 "fp_register_operand")))
4208 (clobber (match_operand 2))]
4210 [(set (match_dup 2) (match_dup 1))
4211 (set (match_dup 0) (match_dup 2))]
4212 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4214 ;; Conversion from XFmode to {SF,DF}mode
4216 (define_expand "truncxf<mode>2"
4217 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4218 (float_truncate:MODEF
4219 (match_operand:XF 1 "register_operand")))
4220 (clobber (match_dup 2))])]
4223 if (flag_unsafe_math_optimizations)
4225 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4226 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4227 if (reg != operands[0])
4228 emit_move_insn (operands[0], reg);
4232 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4235 (define_insn "*truncxfsf2_mixed"
4236 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4238 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4239 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4242 gcc_assert (!which_alternative);
4243 return output_387_reg_move (insn, operands);
4245 [(set_attr "type" "fmov,multi,multi,multi")
4246 (set_attr "unit" "*,i387,i387,i387")
4247 (set_attr "mode" "SF")])
4249 (define_insn "*truncxfdf2_mixed"
4250 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4252 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4253 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4256 gcc_assert (!which_alternative);
4257 return output_387_reg_move (insn, operands);
4259 [(set_attr "isa" "*,*,sse2,*")
4260 (set_attr "type" "fmov,multi,multi,multi")
4261 (set_attr "unit" "*,i387,i387,i387")
4262 (set_attr "mode" "DF")])
4264 (define_insn "truncxf<mode>2_i387_noop"
4265 [(set (match_operand:MODEF 0 "register_operand" "=f")
4266 (float_truncate:MODEF
4267 (match_operand:XF 1 "register_operand" "f")))]
4268 "TARGET_80387 && flag_unsafe_math_optimizations"
4269 "* return output_387_reg_move (insn, operands);"
4270 [(set_attr "type" "fmov")
4271 (set_attr "mode" "<MODE>")])
4273 (define_insn "*truncxf<mode>2_i387"
4274 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4275 (float_truncate:MODEF
4276 (match_operand:XF 1 "register_operand" "f")))]
4278 "* return output_387_reg_move (insn, operands);"
4279 [(set_attr "type" "fmov")
4280 (set_attr "mode" "<MODE>")])
4283 [(set (match_operand:MODEF 0 "register_operand")
4284 (float_truncate:MODEF
4285 (match_operand:XF 1 "register_operand")))
4286 (clobber (match_operand:MODEF 2 "memory_operand"))]
4287 "TARGET_80387 && reload_completed"
4288 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4289 (set (match_dup 0) (match_dup 2))])
4292 [(set (match_operand:MODEF 0 "memory_operand")
4293 (float_truncate:MODEF
4294 (match_operand:XF 1 "register_operand")))
4295 (clobber (match_operand:MODEF 2 "memory_operand"))]
4297 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4299 ;; Signed conversion to DImode.
4301 (define_expand "fix_truncxfdi2"
4302 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4303 (fix:DI (match_operand:XF 1 "register_operand")))
4304 (clobber (reg:CC FLAGS_REG))])]
4309 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4314 (define_expand "fix_trunc<mode>di2"
4315 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4316 (fix:DI (match_operand:MODEF 1 "register_operand")))
4317 (clobber (reg:CC FLAGS_REG))])]
4318 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4321 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4323 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4326 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4328 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4329 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4330 if (out != operands[0])
4331 emit_move_insn (operands[0], out);
4336 ;; Signed conversion to SImode.
4338 (define_expand "fix_truncxfsi2"
4339 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4340 (fix:SI (match_operand:XF 1 "register_operand")))
4341 (clobber (reg:CC FLAGS_REG))])]
4346 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4351 (define_expand "fix_trunc<mode>si2"
4352 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4353 (fix:SI (match_operand:MODEF 1 "register_operand")))
4354 (clobber (reg:CC FLAGS_REG))])]
4355 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4358 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4360 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4363 if (SSE_FLOAT_MODE_P (<MODE>mode))
4365 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4366 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4367 if (out != operands[0])
4368 emit_move_insn (operands[0], out);
4373 ;; Signed conversion to HImode.
4375 (define_expand "fix_trunc<mode>hi2"
4376 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4377 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4378 (clobber (reg:CC FLAGS_REG))])]
4380 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4384 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4389 ;; Unsigned conversion to SImode.
4391 (define_expand "fixuns_trunc<mode>si2"
4393 [(set (match_operand:SI 0 "register_operand")
4395 (match_operand:MODEF 1 "nonimmediate_operand")))
4397 (clobber (match_scratch:<ssevecmode> 3))
4398 (clobber (match_scratch:<ssevecmode> 4))])]
4399 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4401 enum machine_mode mode = <MODE>mode;
4402 enum machine_mode vecmode = <ssevecmode>mode;
4403 REAL_VALUE_TYPE TWO31r;
4406 if (optimize_insn_for_size_p ())
4409 real_ldexp (&TWO31r, &dconst1, 31);
4410 two31 = const_double_from_real_value (TWO31r, mode);
4411 two31 = ix86_build_const_vector (vecmode, true, two31);
4412 operands[2] = force_reg (vecmode, two31);
4415 (define_insn_and_split "*fixuns_trunc<mode>_1"
4416 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4418 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4419 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4420 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4421 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4422 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4423 && optimize_function_for_speed_p (cfun)"
4425 "&& reload_completed"
4428 ix86_split_convert_uns_si_sse (operands);
4432 ;; Unsigned conversion to HImode.
4433 ;; Without these patterns, we'll try the unsigned SI conversion which
4434 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4436 (define_expand "fixuns_trunc<mode>hi2"
4438 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4439 (set (match_operand:HI 0 "nonimmediate_operand")
4440 (subreg:HI (match_dup 2) 0))]
4441 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4442 "operands[2] = gen_reg_rtx (SImode);")
4444 ;; When SSE is available, it is always faster to use it!
4445 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4446 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4447 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4448 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4449 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4450 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4451 [(set_attr "type" "sseicvt")
4452 (set_attr "prefix" "maybe_vex")
4453 (set (attr "prefix_rex")
4455 (match_test "<SWI48:MODE>mode == DImode")
4457 (const_string "*")))
4458 (set_attr "mode" "<MODEF:MODE>")
4459 (set_attr "athlon_decode" "double,vector")
4460 (set_attr "amdfam10_decode" "double,double")
4461 (set_attr "bdver1_decode" "double,double")])
4463 ;; Avoid vector decoded forms of the instruction.
4465 [(match_scratch:MODEF 2 "x")
4466 (set (match_operand:SWI48 0 "register_operand")
4467 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4468 "TARGET_AVOID_VECTOR_DECODE
4469 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4470 && optimize_insn_for_speed_p ()"
4471 [(set (match_dup 2) (match_dup 1))
4472 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4474 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4475 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4476 (fix:SWI248x (match_operand 1 "register_operand")))]
4477 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4479 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4480 && (TARGET_64BIT || <MODE>mode != DImode))
4482 && can_create_pseudo_p ()"
4487 if (memory_operand (operands[0], VOIDmode))
4488 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4491 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4492 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4498 [(set_attr "type" "fisttp")
4499 (set_attr "mode" "<MODE>")])
4501 (define_insn "fix_trunc<mode>_i387_fisttp"
4502 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4503 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4504 (clobber (match_scratch:XF 2 "=&1f"))]
4505 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4507 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4508 && (TARGET_64BIT || <MODE>mode != DImode))
4509 && TARGET_SSE_MATH)"
4510 "* return output_fix_trunc (insn, operands, true);"
4511 [(set_attr "type" "fisttp")
4512 (set_attr "mode" "<MODE>")])
4514 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4515 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4516 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4517 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4518 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4519 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4521 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4522 && (TARGET_64BIT || <MODE>mode != DImode))
4523 && TARGET_SSE_MATH)"
4525 [(set_attr "type" "fisttp")
4526 (set_attr "mode" "<MODE>")])
4529 [(set (match_operand:SWI248x 0 "register_operand")
4530 (fix:SWI248x (match_operand 1 "register_operand")))
4531 (clobber (match_operand:SWI248x 2 "memory_operand"))
4532 (clobber (match_scratch 3))]
4534 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4535 (clobber (match_dup 3))])
4536 (set (match_dup 0) (match_dup 2))])
4539 [(set (match_operand:SWI248x 0 "memory_operand")
4540 (fix:SWI248x (match_operand 1 "register_operand")))
4541 (clobber (match_operand:SWI248x 2 "memory_operand"))
4542 (clobber (match_scratch 3))]
4544 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4545 (clobber (match_dup 3))])])
4547 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4548 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4549 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4550 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4551 ;; function in i386.c.
4552 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4553 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4554 (fix:SWI248x (match_operand 1 "register_operand")))
4555 (clobber (reg:CC FLAGS_REG))]
4556 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4558 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4559 && (TARGET_64BIT || <MODE>mode != DImode))
4560 && can_create_pseudo_p ()"
4565 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4567 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4568 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4569 if (memory_operand (operands[0], VOIDmode))
4570 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4571 operands[2], operands[3]));
4574 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4575 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4576 operands[2], operands[3],
4581 [(set_attr "type" "fistp")
4582 (set_attr "i387_cw" "trunc")
4583 (set_attr "mode" "<MODE>")])
4585 (define_insn "fix_truncdi_i387"
4586 [(set (match_operand:DI 0 "memory_operand" "=m")
4587 (fix:DI (match_operand 1 "register_operand" "f")))
4588 (use (match_operand:HI 2 "memory_operand" "m"))
4589 (use (match_operand:HI 3 "memory_operand" "m"))
4590 (clobber (match_scratch:XF 4 "=&1f"))]
4591 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4593 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4594 "* return output_fix_trunc (insn, operands, false);"
4595 [(set_attr "type" "fistp")
4596 (set_attr "i387_cw" "trunc")
4597 (set_attr "mode" "DI")])
4599 (define_insn "fix_truncdi_i387_with_temp"
4600 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4601 (fix:DI (match_operand 1 "register_operand" "f,f")))
4602 (use (match_operand:HI 2 "memory_operand" "m,m"))
4603 (use (match_operand:HI 3 "memory_operand" "m,m"))
4604 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4605 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4606 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4608 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4610 [(set_attr "type" "fistp")
4611 (set_attr "i387_cw" "trunc")
4612 (set_attr "mode" "DI")])
4615 [(set (match_operand:DI 0 "register_operand")
4616 (fix:DI (match_operand 1 "register_operand")))
4617 (use (match_operand:HI 2 "memory_operand"))
4618 (use (match_operand:HI 3 "memory_operand"))
4619 (clobber (match_operand:DI 4 "memory_operand"))
4620 (clobber (match_scratch 5))]
4622 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4625 (clobber (match_dup 5))])
4626 (set (match_dup 0) (match_dup 4))])
4629 [(set (match_operand:DI 0 "memory_operand")
4630 (fix:DI (match_operand 1 "register_operand")))
4631 (use (match_operand:HI 2 "memory_operand"))
4632 (use (match_operand:HI 3 "memory_operand"))
4633 (clobber (match_operand:DI 4 "memory_operand"))
4634 (clobber (match_scratch 5))]
4636 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4639 (clobber (match_dup 5))])])
4641 (define_insn "fix_trunc<mode>_i387"
4642 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4643 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4644 (use (match_operand:HI 2 "memory_operand" "m"))
4645 (use (match_operand:HI 3 "memory_operand" "m"))]
4646 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4648 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4649 "* return output_fix_trunc (insn, operands, false);"
4650 [(set_attr "type" "fistp")
4651 (set_attr "i387_cw" "trunc")
4652 (set_attr "mode" "<MODE>")])
4654 (define_insn "fix_trunc<mode>_i387_with_temp"
4655 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4656 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4657 (use (match_operand:HI 2 "memory_operand" "m,m"))
4658 (use (match_operand:HI 3 "memory_operand" "m,m"))
4659 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4660 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4662 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4664 [(set_attr "type" "fistp")
4665 (set_attr "i387_cw" "trunc")
4666 (set_attr "mode" "<MODE>")])
4669 [(set (match_operand:SWI24 0 "register_operand")
4670 (fix:SWI24 (match_operand 1 "register_operand")))
4671 (use (match_operand:HI 2 "memory_operand"))
4672 (use (match_operand:HI 3 "memory_operand"))
4673 (clobber (match_operand:SWI24 4 "memory_operand"))]
4675 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4677 (use (match_dup 3))])
4678 (set (match_dup 0) (match_dup 4))])
4681 [(set (match_operand:SWI24 0 "memory_operand")
4682 (fix:SWI24 (match_operand 1 "register_operand")))
4683 (use (match_operand:HI 2 "memory_operand"))
4684 (use (match_operand:HI 3 "memory_operand"))
4685 (clobber (match_operand:SWI24 4 "memory_operand"))]
4687 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4689 (use (match_dup 3))])])
4691 (define_insn "x86_fnstcw_1"
4692 [(set (match_operand:HI 0 "memory_operand" "=m")
4693 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4696 [(set (attr "length")
4697 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4698 (set_attr "mode" "HI")
4699 (set_attr "unit" "i387")
4700 (set_attr "bdver1_decode" "vector")])
4702 (define_insn "x86_fldcw_1"
4703 [(set (reg:HI FPCR_REG)
4704 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4707 [(set (attr "length")
4708 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4709 (set_attr "mode" "HI")
4710 (set_attr "unit" "i387")
4711 (set_attr "athlon_decode" "vector")
4712 (set_attr "amdfam10_decode" "vector")
4713 (set_attr "bdver1_decode" "vector")])
4715 ;; Conversion between fixed point and floating point.
4717 ;; Even though we only accept memory inputs, the backend _really_
4718 ;; wants to be able to do this between registers. Thankfully, LRA
4719 ;; will fix this up for us during register allocation.
4721 (define_insn "floathi<mode>2"
4722 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4723 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4725 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4726 || TARGET_MIX_SSE_I387)"
4728 [(set_attr "type" "fmov")
4729 (set_attr "mode" "<MODE>")
4730 (set_attr "fp_int_src" "true")])
4732 (define_insn "float<SWI48x:mode>xf2"
4733 [(set (match_operand:XF 0 "register_operand" "=f")
4734 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4737 [(set_attr "type" "fmov")
4738 (set_attr "mode" "XF")
4739 (set_attr "fp_int_src" "true")])
4741 (define_expand "float<SWI48:mode><MODEF:mode>2"
4742 [(set (match_operand:MODEF 0 "register_operand")
4743 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4744 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4746 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4747 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4749 rtx reg = gen_reg_rtx (XFmode);
4750 rtx (*insn)(rtx, rtx);
4752 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4754 if (<MODEF:MODE>mode == SFmode)
4755 insn = gen_truncxfsf2;
4756 else if (<MODEF:MODE>mode == DFmode)
4757 insn = gen_truncxfdf2;
4761 emit_insn (insn (operands[0], reg));
4766 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4767 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4769 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4770 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4773 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4774 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4775 [(set_attr "type" "fmov,sseicvt,sseicvt")
4776 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4777 (set_attr "mode" "<MODEF:MODE>")
4778 (set (attr "prefix_rex")
4780 (and (eq_attr "prefix" "maybe_vex")
4781 (match_test "<SWI48:MODE>mode == DImode"))
4783 (const_string "*")))
4784 (set_attr "unit" "i387,*,*")
4785 (set_attr "athlon_decode" "*,double,direct")
4786 (set_attr "amdfam10_decode" "*,vector,double")
4787 (set_attr "bdver1_decode" "*,double,direct")
4788 (set_attr "fp_int_src" "true")
4789 (set (attr "enabled")
4790 (cond [(eq_attr "alternative" "0")
4791 (symbol_ref "TARGET_MIX_SSE_I387
4792 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4794 (eq_attr "alternative" "1")
4795 /* ??? For sched1 we need constrain_operands to be able to
4796 select an alternative. Leave this enabled before RA. */
4797 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS
4798 || optimize_function_for_size_p (cfun)
4799 || !(reload_completed
4800 || reload_in_progress
4801 || lra_in_progress)")
4803 (symbol_ref "true")))
4806 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4807 [(set (match_operand:MODEF 0 "register_operand" "=f")
4808 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4809 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4811 [(set_attr "type" "fmov")
4812 (set_attr "mode" "<MODEF:MODE>")
4813 (set_attr "fp_int_src" "true")])
4815 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4816 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4817 ;; alternative in sse2_loadld.
4819 [(set (match_operand:MODEF 0 "register_operand")
4820 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4821 "TARGET_SSE2 && TARGET_SSE_MATH
4822 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4823 && reload_completed && SSE_REG_P (operands[0])
4824 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4827 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4829 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4831 emit_insn (gen_sse2_loadld (operands[4],
4832 CONST0_RTX (V4SImode), operands[1]));
4834 if (<ssevecmode>mode == V4SFmode)
4835 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4837 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4841 ;; Avoid partial SSE register dependency stalls
4843 [(set (match_operand:MODEF 0 "register_operand")
4844 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4845 "TARGET_SSE2 && TARGET_SSE_MATH
4846 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4847 && optimize_function_for_speed_p (cfun)
4848 && reload_completed && SSE_REG_P (operands[0])"
4851 const enum machine_mode vmode = <MODEF:ssevecmode>mode;
4852 const enum machine_mode mode = <MODEF:MODE>mode;
4853 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4855 emit_move_insn (op0, CONST0_RTX (vmode));
4857 t = gen_rtx_FLOAT (mode, operands[1]);
4858 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4859 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4860 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4864 ;; Break partial reg stall for cvtsd2ss.
4867 [(set (match_operand:SF 0 "register_operand")
4869 (match_operand:DF 1 "nonimmediate_operand")))]
4870 "TARGET_SSE2 && TARGET_SSE_MATH
4871 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4872 && optimize_function_for_speed_p (cfun)
4873 && SSE_REG_P (operands[0])
4874 && (!SSE_REG_P (operands[1])
4875 || REGNO (operands[0]) != REGNO (operands[1]))"
4879 (float_truncate:V2SF
4884 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4886 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4888 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4891 ;; Break partial reg stall for cvtss2sd.
4894 [(set (match_operand:DF 0 "register_operand")
4896 (match_operand:SF 1 "nonimmediate_operand")))]
4897 "TARGET_SSE2 && TARGET_SSE_MATH
4898 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4899 && optimize_function_for_speed_p (cfun)
4900 && SSE_REG_P (operands[0])
4901 && (!SSE_REG_P (operands[1])
4902 || REGNO (operands[0]) != REGNO (operands[1]))"
4908 (parallel [(const_int 0) (const_int 1)])))
4912 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4914 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4916 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4919 ;; Avoid store forwarding (partial memory) stall penalty
4920 ;; by passing DImode value through XMM registers. */
4922 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4923 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4925 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4926 (clobber (match_scratch:V4SI 3 "=X,x"))
4927 (clobber (match_scratch:V4SI 4 "=X,x"))
4928 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4929 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4930 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4931 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4933 [(set_attr "type" "multi")
4934 (set_attr "mode" "<X87MODEF:MODE>")
4935 (set_attr "unit" "i387")
4936 (set_attr "fp_int_src" "true")])
4939 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4940 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4941 (clobber (match_scratch:V4SI 3))
4942 (clobber (match_scratch:V4SI 4))
4943 (clobber (match_operand:DI 2 "memory_operand"))]
4944 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4945 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4946 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4947 && reload_completed"
4948 [(set (match_dup 2) (match_dup 3))
4949 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4951 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4952 Assemble the 64-bit DImode value in an xmm register. */
4953 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4954 gen_rtx_SUBREG (SImode, operands[1], 0)));
4955 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4956 gen_rtx_SUBREG (SImode, operands[1], 4)));
4957 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4960 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4964 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4965 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4966 (clobber (match_scratch:V4SI 3))
4967 (clobber (match_scratch:V4SI 4))
4968 (clobber (match_operand:DI 2 "memory_operand"))]
4969 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4970 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4971 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4972 && reload_completed"
4973 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4975 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
4976 [(set (match_operand:MODEF 0 "register_operand")
4977 (unsigned_float:MODEF
4978 (match_operand:SWI12 1 "nonimmediate_operand")))]
4980 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4982 operands[1] = convert_to_mode (SImode, operands[1], 1);
4983 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
4987 ;; Avoid store forwarding (partial memory) stall penalty by extending
4988 ;; SImode value to DImode through XMM register instead of pushing two
4989 ;; SImode values to stack. Also note that fild loads from memory only.
4991 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
4992 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4993 (unsigned_float:X87MODEF
4994 (match_operand:SI 1 "nonimmediate_operand" "rm")))
4995 (clobber (match_scratch:DI 3 "=x"))
4996 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
4998 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4999 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5001 "&& reload_completed"
5002 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5003 (set (match_dup 2) (match_dup 3))
5005 (float:X87MODEF (match_dup 2)))]
5007 [(set_attr "type" "multi")
5008 (set_attr "mode" "<MODE>")])
5010 (define_expand "floatunssi<mode>2"
5012 [(set (match_operand:X87MODEF 0 "register_operand")
5013 (unsigned_float:X87MODEF
5014 (match_operand:SI 1 "nonimmediate_operand")))
5015 (clobber (match_scratch:DI 3))
5016 (clobber (match_dup 2))])]
5018 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5019 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5020 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5022 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5024 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5028 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5031 (define_expand "floatunsdisf2"
5032 [(use (match_operand:SF 0 "register_operand"))
5033 (use (match_operand:DI 1 "nonimmediate_operand"))]
5034 "TARGET_64BIT && TARGET_SSE_MATH"
5035 "x86_emit_floatuns (operands); DONE;")
5037 (define_expand "floatunsdidf2"
5038 [(use (match_operand:DF 0 "register_operand"))
5039 (use (match_operand:DI 1 "nonimmediate_operand"))]
5040 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5041 && TARGET_SSE2 && TARGET_SSE_MATH"
5044 x86_emit_floatuns (operands);
5046 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5050 ;; Load effective address instructions
5052 (define_insn_and_split "*lea<mode>"
5053 [(set (match_operand:SWI48 0 "register_operand" "=r")
5054 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5057 if (SImode_address_operand (operands[1], VOIDmode))
5059 gcc_assert (TARGET_64BIT);
5060 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5063 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5065 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5068 enum machine_mode mode = <MODE>mode;
5071 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5072 change operands[] array behind our back. */
5073 pat = PATTERN (curr_insn);
5075 operands[0] = SET_DEST (pat);
5076 operands[1] = SET_SRC (pat);
5078 /* Emit all operations in SImode for zero-extended addresses. */
5079 if (SImode_address_operand (operands[1], VOIDmode))
5082 ix86_split_lea_for_addr (curr_insn, operands, mode);
5084 /* Zero-extend return register to DImode for zero-extended addresses. */
5085 if (mode != <MODE>mode)
5086 emit_insn (gen_zero_extendsidi2
5087 (operands[0], gen_lowpart (mode, operands[0])));
5091 [(set_attr "type" "lea")
5094 (match_operand 1 "SImode_address_operand")
5096 (const_string "<MODE>")))])
5100 (define_expand "add<mode>3"
5101 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5102 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5103 (match_operand:SDWIM 2 "<general_operand>")))]
5105 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5107 (define_insn_and_split "*add<dwi>3_doubleword"
5108 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5110 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5111 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5112 (clobber (reg:CC FLAGS_REG))]
5113 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5116 [(parallel [(set (reg:CC FLAGS_REG)
5117 (unspec:CC [(match_dup 1) (match_dup 2)]
5120 (plus:DWIH (match_dup 1) (match_dup 2)))])
5121 (parallel [(set (match_dup 3)
5125 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5127 (clobber (reg:CC FLAGS_REG))])]
5128 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5130 (define_insn "*add<mode>3_cc"
5131 [(set (reg:CC FLAGS_REG)
5133 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5134 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5136 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5137 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5138 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5139 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5140 [(set_attr "type" "alu")
5141 (set_attr "mode" "<MODE>")])
5143 (define_insn "addqi3_cc"
5144 [(set (reg:CC FLAGS_REG)
5146 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5147 (match_operand:QI 2 "general_operand" "qn,qm")]
5149 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5150 (plus:QI (match_dup 1) (match_dup 2)))]
5151 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5152 "add{b}\t{%2, %0|%0, %2}"
5153 [(set_attr "type" "alu")
5154 (set_attr "mode" "QI")])
5156 (define_insn "*add<mode>_1"
5157 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5159 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5160 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5161 (clobber (reg:CC FLAGS_REG))]
5162 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5164 switch (get_attr_type (insn))
5170 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5171 if (operands[2] == const1_rtx)
5172 return "inc{<imodesuffix>}\t%0";
5175 gcc_assert (operands[2] == constm1_rtx);
5176 return "dec{<imodesuffix>}\t%0";
5180 /* For most processors, ADD is faster than LEA. This alternative
5181 was added to use ADD as much as possible. */
5182 if (which_alternative == 2)
5185 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5188 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5189 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5190 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5192 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5196 (cond [(eq_attr "alternative" "3")
5197 (const_string "lea")
5198 (match_operand:SWI48 2 "incdec_operand")
5199 (const_string "incdec")
5201 (const_string "alu")))
5202 (set (attr "length_immediate")
5204 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5206 (const_string "*")))
5207 (set_attr "mode" "<MODE>")])
5209 ;; It may seem that nonimmediate operand is proper one for operand 1.
5210 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5211 ;; we take care in ix86_binary_operator_ok to not allow two memory
5212 ;; operands so proper swapping will be done in reload. This allow
5213 ;; patterns constructed from addsi_1 to match.
5215 (define_insn "addsi_1_zext"
5216 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5218 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5219 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5220 (clobber (reg:CC FLAGS_REG))]
5221 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5223 switch (get_attr_type (insn))
5229 if (operands[2] == const1_rtx)
5230 return "inc{l}\t%k0";
5233 gcc_assert (operands[2] == constm1_rtx);
5234 return "dec{l}\t%k0";
5238 /* For most processors, ADD is faster than LEA. This alternative
5239 was added to use ADD as much as possible. */
5240 if (which_alternative == 1)
5243 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5246 if (x86_maybe_negate_const_int (&operands[2], SImode))
5247 return "sub{l}\t{%2, %k0|%k0, %2}";
5249 return "add{l}\t{%2, %k0|%k0, %2}";
5253 (cond [(eq_attr "alternative" "2")
5254 (const_string "lea")
5255 (match_operand:SI 2 "incdec_operand")
5256 (const_string "incdec")
5258 (const_string "alu")))
5259 (set (attr "length_immediate")
5261 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5263 (const_string "*")))
5264 (set_attr "mode" "SI")])
5266 (define_insn "*addhi_1"
5267 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5268 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5269 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5270 (clobber (reg:CC FLAGS_REG))]
5271 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5273 switch (get_attr_type (insn))
5279 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5280 if (operands[2] == const1_rtx)
5281 return "inc{w}\t%0";
5284 gcc_assert (operands[2] == constm1_rtx);
5285 return "dec{w}\t%0";
5289 /* For most processors, ADD is faster than LEA. This alternative
5290 was added to use ADD as much as possible. */
5291 if (which_alternative == 2)
5294 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5297 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5298 if (x86_maybe_negate_const_int (&operands[2], HImode))
5299 return "sub{w}\t{%2, %0|%0, %2}";
5301 return "add{w}\t{%2, %0|%0, %2}";
5305 (cond [(eq_attr "alternative" "3")
5306 (const_string "lea")
5307 (match_operand:HI 2 "incdec_operand")
5308 (const_string "incdec")
5310 (const_string "alu")))
5311 (set (attr "length_immediate")
5313 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5315 (const_string "*")))
5316 (set_attr "mode" "HI,HI,HI,SI")])
5318 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5319 (define_insn "*addqi_1"
5320 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5321 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5322 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5323 (clobber (reg:CC FLAGS_REG))]
5324 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5326 bool widen = (which_alternative == 3 || which_alternative == 4);
5328 switch (get_attr_type (insn))
5334 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5335 if (operands[2] == const1_rtx)
5336 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5339 gcc_assert (operands[2] == constm1_rtx);
5340 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5344 /* For most processors, ADD is faster than LEA. These alternatives
5345 were added to use ADD as much as possible. */
5346 if (which_alternative == 2 || which_alternative == 4)
5349 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5352 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5353 if (x86_maybe_negate_const_int (&operands[2], QImode))
5356 return "sub{l}\t{%2, %k0|%k0, %2}";
5358 return "sub{b}\t{%2, %0|%0, %2}";
5361 return "add{l}\t{%k2, %k0|%k0, %k2}";
5363 return "add{b}\t{%2, %0|%0, %2}";
5367 (cond [(eq_attr "alternative" "5")
5368 (const_string "lea")
5369 (match_operand:QI 2 "incdec_operand")
5370 (const_string "incdec")
5372 (const_string "alu")))
5373 (set (attr "length_immediate")
5375 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5377 (const_string "*")))
5378 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5380 (define_insn "*addqi_1_slp"
5381 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5382 (plus:QI (match_dup 0)
5383 (match_operand:QI 1 "general_operand" "qn,qm")))
5384 (clobber (reg:CC FLAGS_REG))]
5385 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5386 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5388 switch (get_attr_type (insn))
5391 if (operands[1] == const1_rtx)
5392 return "inc{b}\t%0";
5395 gcc_assert (operands[1] == constm1_rtx);
5396 return "dec{b}\t%0";
5400 if (x86_maybe_negate_const_int (&operands[1], QImode))
5401 return "sub{b}\t{%1, %0|%0, %1}";
5403 return "add{b}\t{%1, %0|%0, %1}";
5407 (if_then_else (match_operand:QI 1 "incdec_operand")
5408 (const_string "incdec")
5409 (const_string "alu1")))
5410 (set (attr "memory")
5411 (if_then_else (match_operand 1 "memory_operand")
5412 (const_string "load")
5413 (const_string "none")))
5414 (set_attr "mode" "QI")])
5416 ;; Split non destructive adds if we cannot use lea.
5418 [(set (match_operand:SWI48 0 "register_operand")
5419 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5420 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5421 (clobber (reg:CC FLAGS_REG))]
5422 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5423 [(set (match_dup 0) (match_dup 1))
5424 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5425 (clobber (reg:CC FLAGS_REG))])])
5427 ;; Convert add to the lea pattern to avoid flags dependency.
5429 [(set (match_operand:SWI 0 "register_operand")
5430 (plus:SWI (match_operand:SWI 1 "register_operand")
5431 (match_operand:SWI 2 "<nonmemory_operand>")))
5432 (clobber (reg:CC FLAGS_REG))]
5433 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5436 enum machine_mode mode = <MODE>mode;
5439 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5442 operands[0] = gen_lowpart (mode, operands[0]);
5443 operands[1] = gen_lowpart (mode, operands[1]);
5444 operands[2] = gen_lowpart (mode, operands[2]);
5447 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5449 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5453 ;; Split non destructive adds if we cannot use lea.
5455 [(set (match_operand:DI 0 "register_operand")
5457 (plus:SI (match_operand:SI 1 "register_operand")
5458 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5459 (clobber (reg:CC FLAGS_REG))]
5461 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5462 [(set (match_dup 3) (match_dup 1))
5463 (parallel [(set (match_dup 0)
5464 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5465 (clobber (reg:CC FLAGS_REG))])]
5466 "operands[3] = gen_lowpart (SImode, operands[0]);")
5468 ;; Convert add to the lea pattern to avoid flags dependency.
5470 [(set (match_operand:DI 0 "register_operand")
5472 (plus:SI (match_operand:SI 1 "register_operand")
5473 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5474 (clobber (reg:CC FLAGS_REG))]
5475 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5477 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5479 (define_insn "*add<mode>_2"
5480 [(set (reg FLAGS_REG)
5483 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5484 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5486 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5487 (plus:SWI (match_dup 1) (match_dup 2)))]
5488 "ix86_match_ccmode (insn, CCGOCmode)
5489 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5491 switch (get_attr_type (insn))
5494 if (operands[2] == const1_rtx)
5495 return "inc{<imodesuffix>}\t%0";
5498 gcc_assert (operands[2] == constm1_rtx);
5499 return "dec{<imodesuffix>}\t%0";
5503 if (which_alternative == 2)
5506 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5509 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5510 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5511 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5513 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5517 (if_then_else (match_operand:SWI 2 "incdec_operand")
5518 (const_string "incdec")
5519 (const_string "alu")))
5520 (set (attr "length_immediate")
5522 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5524 (const_string "*")))
5525 (set_attr "mode" "<MODE>")])
5527 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5528 (define_insn "*addsi_2_zext"
5529 [(set (reg FLAGS_REG)
5531 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5532 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5534 (set (match_operand:DI 0 "register_operand" "=r,r")
5535 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5536 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5537 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5539 switch (get_attr_type (insn))
5542 if (operands[2] == const1_rtx)
5543 return "inc{l}\t%k0";
5546 gcc_assert (operands[2] == constm1_rtx);
5547 return "dec{l}\t%k0";
5551 if (which_alternative == 1)
5554 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5557 if (x86_maybe_negate_const_int (&operands[2], SImode))
5558 return "sub{l}\t{%2, %k0|%k0, %2}";
5560 return "add{l}\t{%2, %k0|%k0, %2}";
5564 (if_then_else (match_operand:SI 2 "incdec_operand")
5565 (const_string "incdec")
5566 (const_string "alu")))
5567 (set (attr "length_immediate")
5569 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5571 (const_string "*")))
5572 (set_attr "mode" "SI")])
5574 (define_insn "*add<mode>_3"
5575 [(set (reg FLAGS_REG)
5577 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5578 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5579 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5580 "ix86_match_ccmode (insn, CCZmode)
5581 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5583 switch (get_attr_type (insn))
5586 if (operands[2] == const1_rtx)
5587 return "inc{<imodesuffix>}\t%0";
5590 gcc_assert (operands[2] == constm1_rtx);
5591 return "dec{<imodesuffix>}\t%0";
5595 if (which_alternative == 1)
5598 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5601 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5602 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5603 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5605 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5609 (if_then_else (match_operand:SWI 2 "incdec_operand")
5610 (const_string "incdec")
5611 (const_string "alu")))
5612 (set (attr "length_immediate")
5614 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5616 (const_string "*")))
5617 (set_attr "mode" "<MODE>")])
5619 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5620 (define_insn "*addsi_3_zext"
5621 [(set (reg FLAGS_REG)
5623 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5624 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5625 (set (match_operand:DI 0 "register_operand" "=r,r")
5626 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5627 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5628 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5630 switch (get_attr_type (insn))
5633 if (operands[2] == const1_rtx)
5634 return "inc{l}\t%k0";
5637 gcc_assert (operands[2] == constm1_rtx);
5638 return "dec{l}\t%k0";
5642 if (which_alternative == 1)
5645 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5648 if (x86_maybe_negate_const_int (&operands[2], SImode))
5649 return "sub{l}\t{%2, %k0|%k0, %2}";
5651 return "add{l}\t{%2, %k0|%k0, %2}";
5655 (if_then_else (match_operand:SI 2 "incdec_operand")
5656 (const_string "incdec")
5657 (const_string "alu")))
5658 (set (attr "length_immediate")
5660 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5662 (const_string "*")))
5663 (set_attr "mode" "SI")])
5665 ; For comparisons against 1, -1 and 128, we may generate better code
5666 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5667 ; is matched then. We can't accept general immediate, because for
5668 ; case of overflows, the result is messed up.
5669 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5670 ; only for comparisons not depending on it.
5672 (define_insn "*adddi_4"
5673 [(set (reg FLAGS_REG)
5675 (match_operand:DI 1 "nonimmediate_operand" "0")
5676 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5677 (clobber (match_scratch:DI 0 "=rm"))]
5679 && ix86_match_ccmode (insn, CCGCmode)"
5681 switch (get_attr_type (insn))
5684 if (operands[2] == constm1_rtx)
5685 return "inc{q}\t%0";
5688 gcc_assert (operands[2] == const1_rtx);
5689 return "dec{q}\t%0";
5693 if (x86_maybe_negate_const_int (&operands[2], DImode))
5694 return "add{q}\t{%2, %0|%0, %2}";
5696 return "sub{q}\t{%2, %0|%0, %2}";
5700 (if_then_else (match_operand:DI 2 "incdec_operand")
5701 (const_string "incdec")
5702 (const_string "alu")))
5703 (set (attr "length_immediate")
5705 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5707 (const_string "*")))
5708 (set_attr "mode" "DI")])
5710 ; For comparisons against 1, -1 and 128, we may generate better code
5711 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5712 ; is matched then. We can't accept general immediate, because for
5713 ; case of overflows, the result is messed up.
5714 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5715 ; only for comparisons not depending on it.
5717 (define_insn "*add<mode>_4"
5718 [(set (reg FLAGS_REG)
5720 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5721 (match_operand:SWI124 2 "const_int_operand" "n")))
5722 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5723 "ix86_match_ccmode (insn, CCGCmode)"
5725 switch (get_attr_type (insn))
5728 if (operands[2] == constm1_rtx)
5729 return "inc{<imodesuffix>}\t%0";
5732 gcc_assert (operands[2] == const1_rtx);
5733 return "dec{<imodesuffix>}\t%0";
5737 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5738 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5740 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5744 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5745 (const_string "incdec")
5746 (const_string "alu")))
5747 (set (attr "length_immediate")
5749 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5751 (const_string "*")))
5752 (set_attr "mode" "<MODE>")])
5754 (define_insn "*add<mode>_5"
5755 [(set (reg FLAGS_REG)
5758 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5759 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5761 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5762 "ix86_match_ccmode (insn, CCGOCmode)
5763 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5765 switch (get_attr_type (insn))
5768 if (operands[2] == const1_rtx)
5769 return "inc{<imodesuffix>}\t%0";
5772 gcc_assert (operands[2] == constm1_rtx);
5773 return "dec{<imodesuffix>}\t%0";
5777 if (which_alternative == 1)
5780 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5783 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5785 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5787 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5791 (if_then_else (match_operand:SWI 2 "incdec_operand")
5792 (const_string "incdec")
5793 (const_string "alu")))
5794 (set (attr "length_immediate")
5796 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5798 (const_string "*")))
5799 (set_attr "mode" "<MODE>")])
5801 (define_insn "addqi_ext_1"
5802 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5807 (match_operand 1 "ext_register_operand" "0,0")
5810 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5811 (clobber (reg:CC FLAGS_REG))]
5814 switch (get_attr_type (insn))
5817 if (operands[2] == const1_rtx)
5818 return "inc{b}\t%h0";
5821 gcc_assert (operands[2] == constm1_rtx);
5822 return "dec{b}\t%h0";
5826 return "add{b}\t{%2, %h0|%h0, %2}";
5829 [(set_attr "isa" "*,nox64")
5831 (if_then_else (match_operand:QI 2 "incdec_operand")
5832 (const_string "incdec")
5833 (const_string "alu")))
5834 (set_attr "modrm" "1")
5835 (set_attr "mode" "QI")])
5837 (define_insn "*addqi_ext_2"
5838 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5843 (match_operand 1 "ext_register_operand" "%0")
5847 (match_operand 2 "ext_register_operand" "Q")
5850 (clobber (reg:CC FLAGS_REG))]
5852 "add{b}\t{%h2, %h0|%h0, %h2}"
5853 [(set_attr "type" "alu")
5854 (set_attr "mode" "QI")])
5856 ;; Add with jump on overflow.
5857 (define_expand "addv<mode>4"
5858 [(parallel [(set (reg:CCO FLAGS_REG)
5861 (match_operand:SWI 1 "nonimmediate_operand"))
5864 (plus:SWI (match_dup 1)
5865 (match_operand:SWI 2
5866 "<general_operand>")))))
5867 (set (match_operand:SWI 0 "register_operand")
5868 (plus:SWI (match_dup 1) (match_dup 2)))])
5869 (set (pc) (if_then_else
5870 (eq (reg:CCO FLAGS_REG) (const_int 0))
5871 (label_ref (match_operand 3))
5875 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5876 if (CONST_INT_P (operands[2]))
5877 operands[4] = operands[2];
5879 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5882 (define_insn "*addv<mode>4"
5883 [(set (reg:CCO FLAGS_REG)
5886 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5888 (match_operand:SWI 2 "<general_sext_operand>"
5891 (plus:SWI (match_dup 1) (match_dup 2)))))
5892 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5893 (plus:SWI (match_dup 1) (match_dup 2)))]
5894 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5895 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5896 [(set_attr "type" "alu")
5897 (set_attr "mode" "<MODE>")])
5899 (define_insn "*addv<mode>4_1"
5900 [(set (reg:CCO FLAGS_REG)
5903 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5904 (match_operand:<DWI> 3 "const_int_operand" "i"))
5906 (plus:SWI (match_dup 1)
5907 (match_operand:SWI 2 "x86_64_immediate_operand"
5909 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5910 (plus:SWI (match_dup 1) (match_dup 2)))]
5911 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5912 && CONST_INT_P (operands[2])
5913 && INTVAL (operands[2]) == INTVAL (operands[3])"
5914 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5915 [(set_attr "type" "alu")
5916 (set_attr "mode" "<MODE>")
5917 (set (attr "length_immediate")
5918 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5920 (match_test "<MODE_SIZE> == 8")
5922 (const_string "<MODE_SIZE>")))])
5924 ;; The lea patterns for modes less than 32 bits need to be matched by
5925 ;; several insns converted to real lea by splitters.
5927 (define_insn_and_split "*lea_general_1"
5928 [(set (match_operand 0 "register_operand" "=r")
5929 (plus (plus (match_operand 1 "index_register_operand" "l")
5930 (match_operand 2 "register_operand" "r"))
5931 (match_operand 3 "immediate_operand" "i")))]
5932 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5933 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5934 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5935 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5936 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5937 || GET_MODE (operands[3]) == VOIDmode)"
5939 "&& reload_completed"
5942 enum machine_mode mode = SImode;
5945 operands[0] = gen_lowpart (mode, operands[0]);
5946 operands[1] = gen_lowpart (mode, operands[1]);
5947 operands[2] = gen_lowpart (mode, operands[2]);
5948 operands[3] = gen_lowpart (mode, operands[3]);
5950 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5953 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5956 [(set_attr "type" "lea")
5957 (set_attr "mode" "SI")])
5959 (define_insn_and_split "*lea_general_2"
5960 [(set (match_operand 0 "register_operand" "=r")
5961 (plus (mult (match_operand 1 "index_register_operand" "l")
5962 (match_operand 2 "const248_operand" "n"))
5963 (match_operand 3 "nonmemory_operand" "ri")))]
5964 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5965 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5966 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5967 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5968 || GET_MODE (operands[3]) == VOIDmode)"
5970 "&& reload_completed"
5973 enum machine_mode mode = SImode;
5976 operands[0] = gen_lowpart (mode, operands[0]);
5977 operands[1] = gen_lowpart (mode, operands[1]);
5978 operands[3] = gen_lowpart (mode, operands[3]);
5980 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5983 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5986 [(set_attr "type" "lea")
5987 (set_attr "mode" "SI")])
5989 (define_insn_and_split "*lea_general_3"
5990 [(set (match_operand 0 "register_operand" "=r")
5991 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5992 (match_operand 2 "const248_operand" "n"))
5993 (match_operand 3 "register_operand" "r"))
5994 (match_operand 4 "immediate_operand" "i")))]
5995 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5996 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5997 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5998 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6000 "&& reload_completed"
6003 enum machine_mode mode = SImode;
6006 operands[0] = gen_lowpart (mode, operands[0]);
6007 operands[1] = gen_lowpart (mode, operands[1]);
6008 operands[3] = gen_lowpart (mode, operands[3]);
6009 operands[4] = gen_lowpart (mode, operands[4]);
6011 pat = gen_rtx_PLUS (mode,
6013 gen_rtx_MULT (mode, operands[1],
6018 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6021 [(set_attr "type" "lea")
6022 (set_attr "mode" "SI")])
6024 (define_insn_and_split "*lea_general_4"
6025 [(set (match_operand 0 "register_operand" "=r")
6027 (match_operand 1 "index_register_operand" "l")
6028 (match_operand 2 "const_int_operand" "n"))
6029 (match_operand 3 "const_int_operand" "n")))]
6030 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6031 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6032 || GET_MODE (operands[0]) == SImode
6033 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6034 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6035 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6036 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6037 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6039 "&& reload_completed"
6042 enum machine_mode mode = GET_MODE (operands[0]);
6045 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6048 operands[0] = gen_lowpart (mode, operands[0]);
6049 operands[1] = gen_lowpart (mode, operands[1]);
6052 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6054 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6055 INTVAL (operands[3]));
6057 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6060 [(set_attr "type" "lea")
6062 (if_then_else (match_operand:DI 0)
6064 (const_string "SI")))])
6066 ;; Subtract instructions
6068 (define_expand "sub<mode>3"
6069 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6070 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6071 (match_operand:SDWIM 2 "<general_operand>")))]
6073 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6075 (define_insn_and_split "*sub<dwi>3_doubleword"
6076 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6078 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6079 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6080 (clobber (reg:CC FLAGS_REG))]
6081 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6084 [(parallel [(set (reg:CC FLAGS_REG)
6085 (compare:CC (match_dup 1) (match_dup 2)))
6087 (minus:DWIH (match_dup 1) (match_dup 2)))])
6088 (parallel [(set (match_dup 3)
6092 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6094 (clobber (reg:CC FLAGS_REG))])]
6095 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6097 (define_insn "*sub<mode>_1"
6098 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6100 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6101 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6102 (clobber (reg:CC FLAGS_REG))]
6103 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6104 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6105 [(set_attr "type" "alu")
6106 (set_attr "mode" "<MODE>")])
6108 (define_insn "*subsi_1_zext"
6109 [(set (match_operand:DI 0 "register_operand" "=r")
6111 (minus:SI (match_operand:SI 1 "register_operand" "0")
6112 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6113 (clobber (reg:CC FLAGS_REG))]
6114 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6115 "sub{l}\t{%2, %k0|%k0, %2}"
6116 [(set_attr "type" "alu")
6117 (set_attr "mode" "SI")])
6119 (define_insn "*subqi_1_slp"
6120 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6121 (minus:QI (match_dup 0)
6122 (match_operand:QI 1 "general_operand" "qn,qm")))
6123 (clobber (reg:CC FLAGS_REG))]
6124 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6125 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6126 "sub{b}\t{%1, %0|%0, %1}"
6127 [(set_attr "type" "alu1")
6128 (set_attr "mode" "QI")])
6130 (define_insn "*sub<mode>_2"
6131 [(set (reg FLAGS_REG)
6134 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6135 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6137 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6138 (minus:SWI (match_dup 1) (match_dup 2)))]
6139 "ix86_match_ccmode (insn, CCGOCmode)
6140 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6141 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6142 [(set_attr "type" "alu")
6143 (set_attr "mode" "<MODE>")])
6145 (define_insn "*subsi_2_zext"
6146 [(set (reg FLAGS_REG)
6148 (minus:SI (match_operand:SI 1 "register_operand" "0")
6149 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6151 (set (match_operand:DI 0 "register_operand" "=r")
6153 (minus:SI (match_dup 1)
6155 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6156 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6157 "sub{l}\t{%2, %k0|%k0, %2}"
6158 [(set_attr "type" "alu")
6159 (set_attr "mode" "SI")])
6161 ;; Subtract with jump on overflow.
6162 (define_expand "subv<mode>4"
6163 [(parallel [(set (reg:CCO FLAGS_REG)
6164 (eq:CCO (minus:<DWI>
6166 (match_operand:SWI 1 "nonimmediate_operand"))
6169 (minus:SWI (match_dup 1)
6170 (match_operand:SWI 2
6171 "<general_operand>")))))
6172 (set (match_operand:SWI 0 "register_operand")
6173 (minus:SWI (match_dup 1) (match_dup 2)))])
6174 (set (pc) (if_then_else
6175 (eq (reg:CCO FLAGS_REG) (const_int 0))
6176 (label_ref (match_operand 3))
6180 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6181 if (CONST_INT_P (operands[2]))
6182 operands[4] = operands[2];
6184 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6187 (define_insn "*subv<mode>4"
6188 [(set (reg:CCO FLAGS_REG)
6189 (eq:CCO (minus:<DWI>
6191 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6193 (match_operand:SWI 2 "<general_sext_operand>"
6196 (minus:SWI (match_dup 1) (match_dup 2)))))
6197 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6198 (minus:SWI (match_dup 1) (match_dup 2)))]
6199 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6200 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6201 [(set_attr "type" "alu")
6202 (set_attr "mode" "<MODE>")])
6204 (define_insn "*subv<mode>4_1"
6205 [(set (reg:CCO FLAGS_REG)
6206 (eq:CCO (minus:<DWI>
6208 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6209 (match_operand:<DWI> 3 "const_int_operand" "i"))
6211 (minus:SWI (match_dup 1)
6212 (match_operand:SWI 2 "x86_64_immediate_operand"
6214 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6215 (minus:SWI (match_dup 1) (match_dup 2)))]
6216 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6217 && CONST_INT_P (operands[2])
6218 && INTVAL (operands[2]) == INTVAL (operands[3])"
6219 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6220 [(set_attr "type" "alu")
6221 (set_attr "mode" "<MODE>")
6222 (set (attr "length_immediate")
6223 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6225 (match_test "<MODE_SIZE> == 8")
6227 (const_string "<MODE_SIZE>")))])
6229 (define_insn "*sub<mode>_3"
6230 [(set (reg FLAGS_REG)
6231 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6232 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6233 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6234 (minus:SWI (match_dup 1) (match_dup 2)))]
6235 "ix86_match_ccmode (insn, CCmode)
6236 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6237 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6238 [(set_attr "type" "alu")
6239 (set_attr "mode" "<MODE>")])
6241 (define_insn "*subsi_3_zext"
6242 [(set (reg FLAGS_REG)
6243 (compare (match_operand:SI 1 "register_operand" "0")
6244 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6245 (set (match_operand:DI 0 "register_operand" "=r")
6247 (minus:SI (match_dup 1)
6249 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6250 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6251 "sub{l}\t{%2, %1|%1, %2}"
6252 [(set_attr "type" "alu")
6253 (set_attr "mode" "SI")])
6255 ;; Add with carry and subtract with borrow
6257 (define_expand "<plusminus_insn><mode>3_carry"
6259 [(set (match_operand:SWI 0 "nonimmediate_operand")
6261 (match_operand:SWI 1 "nonimmediate_operand")
6262 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6263 [(match_operand 3 "flags_reg_operand")
6265 (match_operand:SWI 2 "<general_operand>"))))
6266 (clobber (reg:CC FLAGS_REG))])]
6267 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6269 (define_insn "*<plusminus_insn><mode>3_carry"
6270 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6272 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6274 (match_operator 3 "ix86_carry_flag_operator"
6275 [(reg FLAGS_REG) (const_int 0)])
6276 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6277 (clobber (reg:CC FLAGS_REG))]
6278 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6279 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6280 [(set_attr "type" "alu")
6281 (set_attr "use_carry" "1")
6282 (set_attr "pent_pair" "pu")
6283 (set_attr "mode" "<MODE>")])
6285 (define_insn "*addsi3_carry_zext"
6286 [(set (match_operand:DI 0 "register_operand" "=r")
6288 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6289 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6290 [(reg FLAGS_REG) (const_int 0)])
6291 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6292 (clobber (reg:CC FLAGS_REG))]
6293 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6294 "adc{l}\t{%2, %k0|%k0, %2}"
6295 [(set_attr "type" "alu")
6296 (set_attr "use_carry" "1")
6297 (set_attr "pent_pair" "pu")
6298 (set_attr "mode" "SI")])
6300 (define_insn "*subsi3_carry_zext"
6301 [(set (match_operand:DI 0 "register_operand" "=r")
6303 (minus:SI (match_operand:SI 1 "register_operand" "0")
6304 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6305 [(reg FLAGS_REG) (const_int 0)])
6306 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6307 (clobber (reg:CC FLAGS_REG))]
6308 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6309 "sbb{l}\t{%2, %k0|%k0, %2}"
6310 [(set_attr "type" "alu")
6311 (set_attr "pent_pair" "pu")
6312 (set_attr "mode" "SI")])
6316 (define_insn "adcx<mode>3"
6317 [(set (reg:CCC FLAGS_REG)
6320 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6322 (match_operator 4 "ix86_carry_flag_operator"
6323 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6324 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6326 (set (match_operand:SWI48 0 "register_operand" "=r")
6327 (plus:SWI48 (match_dup 1)
6328 (plus:SWI48 (match_op_dup 4
6329 [(match_dup 3) (const_int 0)])
6331 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6332 "adcx\t{%2, %0|%0, %2}"
6333 [(set_attr "type" "alu")
6334 (set_attr "use_carry" "1")
6335 (set_attr "mode" "<MODE>")])
6337 ;; Overflow setting add instructions
6339 (define_insn "*add<mode>3_cconly_overflow"
6340 [(set (reg:CCC FLAGS_REG)
6343 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6344 (match_operand:SWI 2 "<general_operand>" "<g>"))
6346 (clobber (match_scratch:SWI 0 "=<r>"))]
6347 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6348 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6349 [(set_attr "type" "alu")
6350 (set_attr "mode" "<MODE>")])
6352 (define_insn "*add<mode>3_cc_overflow"
6353 [(set (reg:CCC FLAGS_REG)
6356 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6357 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6359 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6360 (plus:SWI (match_dup 1) (match_dup 2)))]
6361 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6362 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6363 [(set_attr "type" "alu")
6364 (set_attr "mode" "<MODE>")])
6366 (define_insn "*addsi3_zext_cc_overflow"
6367 [(set (reg:CCC FLAGS_REG)
6370 (match_operand:SI 1 "nonimmediate_operand" "%0")
6371 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6373 (set (match_operand:DI 0 "register_operand" "=r")
6374 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6375 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6376 "add{l}\t{%2, %k0|%k0, %2}"
6377 [(set_attr "type" "alu")
6378 (set_attr "mode" "SI")])
6380 ;; The patterns that match these are at the end of this file.
6382 (define_expand "<plusminus_insn>xf3"
6383 [(set (match_operand:XF 0 "register_operand")
6385 (match_operand:XF 1 "register_operand")
6386 (match_operand:XF 2 "register_operand")))]
6389 (define_expand "<plusminus_insn><mode>3"
6390 [(set (match_operand:MODEF 0 "register_operand")
6392 (match_operand:MODEF 1 "register_operand")
6393 (match_operand:MODEF 2 "nonimmediate_operand")))]
6394 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6395 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6397 ;; Multiply instructions
6399 (define_expand "mul<mode>3"
6400 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6402 (match_operand:SWIM248 1 "register_operand")
6403 (match_operand:SWIM248 2 "<general_operand>")))
6404 (clobber (reg:CC FLAGS_REG))])])
6406 (define_expand "mulqi3"
6407 [(parallel [(set (match_operand:QI 0 "register_operand")
6409 (match_operand:QI 1 "register_operand")
6410 (match_operand:QI 2 "nonimmediate_operand")))
6411 (clobber (reg:CC FLAGS_REG))])]
6412 "TARGET_QIMODE_MATH")
6415 ;; IMUL reg32/64, reg32/64, imm8 Direct
6416 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6417 ;; IMUL reg32/64, reg32/64, imm32 Direct
6418 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6419 ;; IMUL reg32/64, reg32/64 Direct
6420 ;; IMUL reg32/64, mem32/64 Direct
6422 ;; On BDVER1, all above IMULs use DirectPath
6424 (define_insn "*mul<mode>3_1"
6425 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6427 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6428 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6429 (clobber (reg:CC FLAGS_REG))]
6430 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6432 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6433 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6434 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6435 [(set_attr "type" "imul")
6436 (set_attr "prefix_0f" "0,0,1")
6437 (set (attr "athlon_decode")
6438 (cond [(eq_attr "cpu" "athlon")
6439 (const_string "vector")
6440 (eq_attr "alternative" "1")
6441 (const_string "vector")
6442 (and (eq_attr "alternative" "2")
6443 (match_operand 1 "memory_operand"))
6444 (const_string "vector")]
6445 (const_string "direct")))
6446 (set (attr "amdfam10_decode")
6447 (cond [(and (eq_attr "alternative" "0,1")
6448 (match_operand 1 "memory_operand"))
6449 (const_string "vector")]
6450 (const_string "direct")))
6451 (set_attr "bdver1_decode" "direct")
6452 (set_attr "mode" "<MODE>")])
6454 (define_insn "*mulsi3_1_zext"
6455 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6457 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6458 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6459 (clobber (reg:CC FLAGS_REG))]
6461 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6463 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6464 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6465 imul{l}\t{%2, %k0|%k0, %2}"
6466 [(set_attr "type" "imul")
6467 (set_attr "prefix_0f" "0,0,1")
6468 (set (attr "athlon_decode")
6469 (cond [(eq_attr "cpu" "athlon")
6470 (const_string "vector")
6471 (eq_attr "alternative" "1")
6472 (const_string "vector")
6473 (and (eq_attr "alternative" "2")
6474 (match_operand 1 "memory_operand"))
6475 (const_string "vector")]
6476 (const_string "direct")))
6477 (set (attr "amdfam10_decode")
6478 (cond [(and (eq_attr "alternative" "0,1")
6479 (match_operand 1 "memory_operand"))
6480 (const_string "vector")]
6481 (const_string "direct")))
6482 (set_attr "bdver1_decode" "direct")
6483 (set_attr "mode" "SI")])
6486 ;; IMUL reg16, reg16, imm8 VectorPath
6487 ;; IMUL reg16, mem16, imm8 VectorPath
6488 ;; IMUL reg16, reg16, imm16 VectorPath
6489 ;; IMUL reg16, mem16, imm16 VectorPath
6490 ;; IMUL reg16, reg16 Direct
6491 ;; IMUL reg16, mem16 Direct
6493 ;; On BDVER1, all HI MULs use DoublePath
6495 (define_insn "*mulhi3_1"
6496 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6497 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6498 (match_operand:HI 2 "general_operand" "K,n,mr")))
6499 (clobber (reg:CC FLAGS_REG))]
6501 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6503 imul{w}\t{%2, %1, %0|%0, %1, %2}
6504 imul{w}\t{%2, %1, %0|%0, %1, %2}
6505 imul{w}\t{%2, %0|%0, %2}"
6506 [(set_attr "type" "imul")
6507 (set_attr "prefix_0f" "0,0,1")
6508 (set (attr "athlon_decode")
6509 (cond [(eq_attr "cpu" "athlon")
6510 (const_string "vector")
6511 (eq_attr "alternative" "1,2")
6512 (const_string "vector")]
6513 (const_string "direct")))
6514 (set (attr "amdfam10_decode")
6515 (cond [(eq_attr "alternative" "0,1")
6516 (const_string "vector")]
6517 (const_string "direct")))
6518 (set_attr "bdver1_decode" "double")
6519 (set_attr "mode" "HI")])
6521 ;;On AMDFAM10 and BDVER1
6525 (define_insn "*mulqi3_1"
6526 [(set (match_operand:QI 0 "register_operand" "=a")
6527 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6528 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6529 (clobber (reg:CC FLAGS_REG))]
6531 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6533 [(set_attr "type" "imul")
6534 (set_attr "length_immediate" "0")
6535 (set (attr "athlon_decode")
6536 (if_then_else (eq_attr "cpu" "athlon")
6537 (const_string "vector")
6538 (const_string "direct")))
6539 (set_attr "amdfam10_decode" "direct")
6540 (set_attr "bdver1_decode" "direct")
6541 (set_attr "mode" "QI")])
6543 ;; Multiply with jump on overflow.
6544 (define_expand "mulv<mode>4"
6545 [(parallel [(set (reg:CCO FLAGS_REG)
6548 (match_operand:SWI48 1 "register_operand"))
6551 (mult:SWI48 (match_dup 1)
6552 (match_operand:SWI48 2
6553 "<general_operand>")))))
6554 (set (match_operand:SWI48 0 "register_operand")
6555 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6556 (set (pc) (if_then_else
6557 (eq (reg:CCO FLAGS_REG) (const_int 0))
6558 (label_ref (match_operand 3))
6562 if (CONST_INT_P (operands[2]))
6563 operands[4] = operands[2];
6565 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6568 (define_insn "*mulv<mode>4"
6569 [(set (reg:CCO FLAGS_REG)
6572 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6574 (match_operand:SWI48 2 "<general_sext_operand>"
6577 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6578 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6579 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6580 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6582 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6583 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6584 [(set_attr "type" "imul")
6585 (set_attr "prefix_0f" "0,1")
6586 (set (attr "athlon_decode")
6587 (cond [(eq_attr "cpu" "athlon")
6588 (const_string "vector")
6589 (eq_attr "alternative" "0")
6590 (const_string "vector")
6591 (and (eq_attr "alternative" "1")
6592 (match_operand 1 "memory_operand"))
6593 (const_string "vector")]
6594 (const_string "direct")))
6595 (set (attr "amdfam10_decode")
6596 (cond [(and (eq_attr "alternative" "1")
6597 (match_operand 1 "memory_operand"))
6598 (const_string "vector")]
6599 (const_string "direct")))
6600 (set_attr "bdver1_decode" "direct")
6601 (set_attr "mode" "<MODE>")])
6603 (define_insn "*mulv<mode>4_1"
6604 [(set (reg:CCO FLAGS_REG)
6607 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6608 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6610 (mult:SWI48 (match_dup 1)
6611 (match_operand:SWI 2 "x86_64_immediate_operand"
6613 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6614 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6615 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6616 && CONST_INT_P (operands[2])
6617 && INTVAL (operands[2]) == INTVAL (operands[3])"
6619 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6620 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6621 [(set_attr "type" "imul")
6622 (set (attr "athlon_decode")
6623 (cond [(eq_attr "cpu" "athlon")
6624 (const_string "vector")
6625 (eq_attr "alternative" "1")
6626 (const_string "vector")]
6627 (const_string "direct")))
6628 (set (attr "amdfam10_decode")
6629 (cond [(match_operand 1 "memory_operand")
6630 (const_string "vector")]
6631 (const_string "direct")))
6632 (set_attr "bdver1_decode" "direct")
6633 (set_attr "mode" "<MODE>")
6634 (set (attr "length_immediate")
6635 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6637 (match_test "<MODE_SIZE> == 8")
6639 (const_string "<MODE_SIZE>")))])
6641 (define_expand "<u>mul<mode><dwi>3"
6642 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6645 (match_operand:DWIH 1 "nonimmediate_operand"))
6647 (match_operand:DWIH 2 "register_operand"))))
6648 (clobber (reg:CC FLAGS_REG))])])
6650 (define_expand "<u>mulqihi3"
6651 [(parallel [(set (match_operand:HI 0 "register_operand")
6654 (match_operand:QI 1 "nonimmediate_operand"))
6656 (match_operand:QI 2 "register_operand"))))
6657 (clobber (reg:CC FLAGS_REG))])]
6658 "TARGET_QIMODE_MATH")
6660 (define_insn "*bmi2_umulditi3_1"
6661 [(set (match_operand:DI 0 "register_operand" "=r")
6663 (match_operand:DI 2 "nonimmediate_operand" "%d")
6664 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6665 (set (match_operand:DI 1 "register_operand" "=r")
6668 (mult:TI (zero_extend:TI (match_dup 2))
6669 (zero_extend:TI (match_dup 3)))
6671 "TARGET_64BIT && TARGET_BMI2
6672 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6673 "mulx\t{%3, %0, %1|%1, %0, %3}"
6674 [(set_attr "type" "imulx")
6675 (set_attr "prefix" "vex")
6676 (set_attr "mode" "DI")])
6678 (define_insn "*bmi2_umulsidi3_1"
6679 [(set (match_operand:SI 0 "register_operand" "=r")
6681 (match_operand:SI 2 "nonimmediate_operand" "%d")
6682 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6683 (set (match_operand:SI 1 "register_operand" "=r")
6686 (mult:DI (zero_extend:DI (match_dup 2))
6687 (zero_extend:DI (match_dup 3)))
6689 "!TARGET_64BIT && TARGET_BMI2
6690 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6691 "mulx\t{%3, %0, %1|%1, %0, %3}"
6692 [(set_attr "type" "imulx")
6693 (set_attr "prefix" "vex")
6694 (set_attr "mode" "SI")])
6696 (define_insn "*umul<mode><dwi>3_1"
6697 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6700 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6702 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6703 (clobber (reg:CC FLAGS_REG))]
6704 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6707 mul{<imodesuffix>}\t%2"
6708 [(set_attr "isa" "bmi2,*")
6709 (set_attr "type" "imulx,imul")
6710 (set_attr "length_immediate" "*,0")
6711 (set (attr "athlon_decode")
6712 (cond [(eq_attr "alternative" "1")
6713 (if_then_else (eq_attr "cpu" "athlon")
6714 (const_string "vector")
6715 (const_string "double"))]
6716 (const_string "*")))
6717 (set_attr "amdfam10_decode" "*,double")
6718 (set_attr "bdver1_decode" "*,direct")
6719 (set_attr "prefix" "vex,orig")
6720 (set_attr "mode" "<MODE>")])
6722 ;; Convert mul to the mulx pattern to avoid flags dependency.
6724 [(set (match_operand:<DWI> 0 "register_operand")
6727 (match_operand:DWIH 1 "register_operand"))
6729 (match_operand:DWIH 2 "nonimmediate_operand"))))
6730 (clobber (reg:CC FLAGS_REG))]
6731 "TARGET_BMI2 && reload_completed
6732 && true_regnum (operands[1]) == DX_REG"
6733 [(parallel [(set (match_dup 3)
6734 (mult:DWIH (match_dup 1) (match_dup 2)))
6738 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6739 (zero_extend:<DWI> (match_dup 2)))
6742 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6744 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6747 (define_insn "*mul<mode><dwi>3_1"
6748 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6751 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6753 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6754 (clobber (reg:CC FLAGS_REG))]
6755 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6756 "imul{<imodesuffix>}\t%2"
6757 [(set_attr "type" "imul")
6758 (set_attr "length_immediate" "0")
6759 (set (attr "athlon_decode")
6760 (if_then_else (eq_attr "cpu" "athlon")
6761 (const_string "vector")
6762 (const_string "double")))
6763 (set_attr "amdfam10_decode" "double")
6764 (set_attr "bdver1_decode" "direct")
6765 (set_attr "mode" "<MODE>")])
6767 (define_insn "*<u>mulqihi3_1"
6768 [(set (match_operand:HI 0 "register_operand" "=a")
6771 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6773 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6774 (clobber (reg:CC FLAGS_REG))]
6776 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6777 "<sgnprefix>mul{b}\t%2"
6778 [(set_attr "type" "imul")
6779 (set_attr "length_immediate" "0")
6780 (set (attr "athlon_decode")
6781 (if_then_else (eq_attr "cpu" "athlon")
6782 (const_string "vector")
6783 (const_string "direct")))
6784 (set_attr "amdfam10_decode" "direct")
6785 (set_attr "bdver1_decode" "direct")
6786 (set_attr "mode" "QI")])
6788 (define_expand "<s>mul<mode>3_highpart"
6789 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6794 (match_operand:SWI48 1 "nonimmediate_operand"))
6796 (match_operand:SWI48 2 "register_operand")))
6798 (clobber (match_scratch:SWI48 3))
6799 (clobber (reg:CC FLAGS_REG))])]
6801 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6803 (define_insn "*<s>muldi3_highpart_1"
6804 [(set (match_operand:DI 0 "register_operand" "=d")
6809 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6811 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6813 (clobber (match_scratch:DI 3 "=1"))
6814 (clobber (reg:CC FLAGS_REG))]
6816 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6817 "<sgnprefix>mul{q}\t%2"
6818 [(set_attr "type" "imul")
6819 (set_attr "length_immediate" "0")
6820 (set (attr "athlon_decode")
6821 (if_then_else (eq_attr "cpu" "athlon")
6822 (const_string "vector")
6823 (const_string "double")))
6824 (set_attr "amdfam10_decode" "double")
6825 (set_attr "bdver1_decode" "direct")
6826 (set_attr "mode" "DI")])
6828 (define_insn "*<s>mulsi3_highpart_1"
6829 [(set (match_operand:SI 0 "register_operand" "=d")
6834 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6836 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6838 (clobber (match_scratch:SI 3 "=1"))
6839 (clobber (reg:CC FLAGS_REG))]
6840 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6841 "<sgnprefix>mul{l}\t%2"
6842 [(set_attr "type" "imul")
6843 (set_attr "length_immediate" "0")
6844 (set (attr "athlon_decode")
6845 (if_then_else (eq_attr "cpu" "athlon")
6846 (const_string "vector")
6847 (const_string "double")))
6848 (set_attr "amdfam10_decode" "double")
6849 (set_attr "bdver1_decode" "direct")
6850 (set_attr "mode" "SI")])
6852 (define_insn "*<s>mulsi3_highpart_zext"
6853 [(set (match_operand:DI 0 "register_operand" "=d")
6854 (zero_extend:DI (truncate:SI
6856 (mult:DI (any_extend:DI
6857 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6859 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6861 (clobber (match_scratch:SI 3 "=1"))
6862 (clobber (reg:CC FLAGS_REG))]
6864 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6865 "<sgnprefix>mul{l}\t%2"
6866 [(set_attr "type" "imul")
6867 (set_attr "length_immediate" "0")
6868 (set (attr "athlon_decode")
6869 (if_then_else (eq_attr "cpu" "athlon")
6870 (const_string "vector")
6871 (const_string "double")))
6872 (set_attr "amdfam10_decode" "double")
6873 (set_attr "bdver1_decode" "direct")
6874 (set_attr "mode" "SI")])
6876 ;; The patterns that match these are at the end of this file.
6878 (define_expand "mulxf3"
6879 [(set (match_operand:XF 0 "register_operand")
6880 (mult:XF (match_operand:XF 1 "register_operand")
6881 (match_operand:XF 2 "register_operand")))]
6884 (define_expand "mul<mode>3"
6885 [(set (match_operand:MODEF 0 "register_operand")
6886 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6887 (match_operand:MODEF 2 "nonimmediate_operand")))]
6888 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6889 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6891 ;; Divide instructions
6893 ;; The patterns that match these are at the end of this file.
6895 (define_expand "divxf3"
6896 [(set (match_operand:XF 0 "register_operand")
6897 (div:XF (match_operand:XF 1 "register_operand")
6898 (match_operand:XF 2 "register_operand")))]
6901 (define_expand "divdf3"
6902 [(set (match_operand:DF 0 "register_operand")
6903 (div:DF (match_operand:DF 1 "register_operand")
6904 (match_operand:DF 2 "nonimmediate_operand")))]
6905 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6906 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6908 (define_expand "divsf3"
6909 [(set (match_operand:SF 0 "register_operand")
6910 (div:SF (match_operand:SF 1 "register_operand")
6911 (match_operand:SF 2 "nonimmediate_operand")))]
6912 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6917 && optimize_insn_for_speed_p ()
6918 && flag_finite_math_only && !flag_trapping_math
6919 && flag_unsafe_math_optimizations)
6921 ix86_emit_swdivsf (operands[0], operands[1],
6922 operands[2], SFmode);
6927 ;; Divmod instructions.
6929 (define_expand "divmod<mode>4"
6930 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6932 (match_operand:SWIM248 1 "register_operand")
6933 (match_operand:SWIM248 2 "nonimmediate_operand")))
6934 (set (match_operand:SWIM248 3 "register_operand")
6935 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6936 (clobber (reg:CC FLAGS_REG))])])
6938 ;; Split with 8bit unsigned divide:
6939 ;; if (dividend an divisor are in [0-255])
6940 ;; use 8bit unsigned integer divide
6942 ;; use original integer divide
6944 [(set (match_operand:SWI48 0 "register_operand")
6945 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6946 (match_operand:SWI48 3 "nonimmediate_operand")))
6947 (set (match_operand:SWI48 1 "register_operand")
6948 (mod:SWI48 (match_dup 2) (match_dup 3)))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "TARGET_USE_8BIT_IDIV
6951 && TARGET_QIMODE_MATH
6952 && can_create_pseudo_p ()
6953 && !optimize_insn_for_size_p ()"
6955 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6957 (define_insn_and_split "divmod<mode>4_1"
6958 [(set (match_operand:SWI48 0 "register_operand" "=a")
6959 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6960 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6961 (set (match_operand:SWI48 1 "register_operand" "=&d")
6962 (mod:SWI48 (match_dup 2) (match_dup 3)))
6963 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6964 (clobber (reg:CC FLAGS_REG))]
6968 [(parallel [(set (match_dup 1)
6969 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6970 (clobber (reg:CC FLAGS_REG))])
6971 (parallel [(set (match_dup 0)
6972 (div:SWI48 (match_dup 2) (match_dup 3)))
6974 (mod:SWI48 (match_dup 2) (match_dup 3)))
6976 (clobber (reg:CC FLAGS_REG))])]
6978 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6980 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6981 operands[4] = operands[2];
6984 /* Avoid use of cltd in favor of a mov+shift. */
6985 emit_move_insn (operands[1], operands[2]);
6986 operands[4] = operands[1];
6989 [(set_attr "type" "multi")
6990 (set_attr "mode" "<MODE>")])
6992 (define_insn_and_split "*divmod<mode>4"
6993 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6994 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6995 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6996 (set (match_operand:SWIM248 1 "register_operand" "=&d")
6997 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6998 (clobber (reg:CC FLAGS_REG))]
7002 [(parallel [(set (match_dup 1)
7003 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7004 (clobber (reg:CC FLAGS_REG))])
7005 (parallel [(set (match_dup 0)
7006 (div:SWIM248 (match_dup 2) (match_dup 3)))
7008 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7010 (clobber (reg:CC FLAGS_REG))])]
7012 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7014 if (<MODE>mode != HImode
7015 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7016 operands[4] = operands[2];
7019 /* Avoid use of cltd in favor of a mov+shift. */
7020 emit_move_insn (operands[1], operands[2]);
7021 operands[4] = operands[1];
7024 [(set_attr "type" "multi")
7025 (set_attr "mode" "<MODE>")])
7027 (define_insn "*divmod<mode>4_noext"
7028 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7029 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7030 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7031 (set (match_operand:SWIM248 1 "register_operand" "=d")
7032 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7033 (use (match_operand:SWIM248 4 "register_operand" "1"))
7034 (clobber (reg:CC FLAGS_REG))]
7036 "idiv{<imodesuffix>}\t%3"
7037 [(set_attr "type" "idiv")
7038 (set_attr "mode" "<MODE>")])
7040 (define_expand "divmodqi4"
7041 [(parallel [(set (match_operand:QI 0 "register_operand")
7043 (match_operand:QI 1 "register_operand")
7044 (match_operand:QI 2 "nonimmediate_operand")))
7045 (set (match_operand:QI 3 "register_operand")
7046 (mod:QI (match_dup 1) (match_dup 2)))
7047 (clobber (reg:CC FLAGS_REG))])]
7048 "TARGET_QIMODE_MATH"
7053 tmp0 = gen_reg_rtx (HImode);
7054 tmp1 = gen_reg_rtx (HImode);
7056 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7058 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7059 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7061 /* Extract remainder from AH. */
7062 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7063 insn = emit_move_insn (operands[3], tmp1);
7065 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7066 set_unique_reg_note (insn, REG_EQUAL, mod);
7068 /* Extract quotient from AL. */
7069 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7071 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7072 set_unique_reg_note (insn, REG_EQUAL, div);
7077 ;; Divide AX by r/m8, with result stored in
7080 ;; Change div/mod to HImode and extend the second argument to HImode
7081 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7082 ;; combine may fail.
7083 (define_insn "divmodhiqi3"
7084 [(set (match_operand:HI 0 "register_operand" "=a")
7089 (mod:HI (match_operand:HI 1 "register_operand" "0")
7091 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7095 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7096 (clobber (reg:CC FLAGS_REG))]
7097 "TARGET_QIMODE_MATH"
7099 [(set_attr "type" "idiv")
7100 (set_attr "mode" "QI")])
7102 (define_expand "udivmod<mode>4"
7103 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7105 (match_operand:SWIM248 1 "register_operand")
7106 (match_operand:SWIM248 2 "nonimmediate_operand")))
7107 (set (match_operand:SWIM248 3 "register_operand")
7108 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7109 (clobber (reg:CC FLAGS_REG))])])
7111 ;; Split with 8bit unsigned divide:
7112 ;; if (dividend an divisor are in [0-255])
7113 ;; use 8bit unsigned integer divide
7115 ;; use original integer divide
7117 [(set (match_operand:SWI48 0 "register_operand")
7118 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7119 (match_operand:SWI48 3 "nonimmediate_operand")))
7120 (set (match_operand:SWI48 1 "register_operand")
7121 (umod:SWI48 (match_dup 2) (match_dup 3)))
7122 (clobber (reg:CC FLAGS_REG))]
7123 "TARGET_USE_8BIT_IDIV
7124 && TARGET_QIMODE_MATH
7125 && can_create_pseudo_p ()
7126 && !optimize_insn_for_size_p ()"
7128 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7130 (define_insn_and_split "udivmod<mode>4_1"
7131 [(set (match_operand:SWI48 0 "register_operand" "=a")
7132 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7133 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7134 (set (match_operand:SWI48 1 "register_operand" "=&d")
7135 (umod:SWI48 (match_dup 2) (match_dup 3)))
7136 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7137 (clobber (reg:CC FLAGS_REG))]
7141 [(set (match_dup 1) (const_int 0))
7142 (parallel [(set (match_dup 0)
7143 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7145 (umod:SWI48 (match_dup 2) (match_dup 3)))
7147 (clobber (reg:CC FLAGS_REG))])]
7149 [(set_attr "type" "multi")
7150 (set_attr "mode" "<MODE>")])
7152 (define_insn_and_split "*udivmod<mode>4"
7153 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7154 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7155 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7156 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7157 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7158 (clobber (reg:CC FLAGS_REG))]
7162 [(set (match_dup 1) (const_int 0))
7163 (parallel [(set (match_dup 0)
7164 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7166 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7168 (clobber (reg:CC FLAGS_REG))])]
7170 [(set_attr "type" "multi")
7171 (set_attr "mode" "<MODE>")])
7173 (define_insn "*udivmod<mode>4_noext"
7174 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7175 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7176 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7177 (set (match_operand:SWIM248 1 "register_operand" "=d")
7178 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7179 (use (match_operand:SWIM248 4 "register_operand" "1"))
7180 (clobber (reg:CC FLAGS_REG))]
7182 "div{<imodesuffix>}\t%3"
7183 [(set_attr "type" "idiv")
7184 (set_attr "mode" "<MODE>")])
7186 (define_expand "udivmodqi4"
7187 [(parallel [(set (match_operand:QI 0 "register_operand")
7189 (match_operand:QI 1 "register_operand")
7190 (match_operand:QI 2 "nonimmediate_operand")))
7191 (set (match_operand:QI 3 "register_operand")
7192 (umod:QI (match_dup 1) (match_dup 2)))
7193 (clobber (reg:CC FLAGS_REG))])]
7194 "TARGET_QIMODE_MATH"
7199 tmp0 = gen_reg_rtx (HImode);
7200 tmp1 = gen_reg_rtx (HImode);
7202 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7204 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7205 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7207 /* Extract remainder from AH. */
7208 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7209 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7210 insn = emit_move_insn (operands[3], tmp1);
7212 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7213 set_unique_reg_note (insn, REG_EQUAL, mod);
7215 /* Extract quotient from AL. */
7216 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7218 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7219 set_unique_reg_note (insn, REG_EQUAL, div);
7224 (define_insn "udivmodhiqi3"
7225 [(set (match_operand:HI 0 "register_operand" "=a")
7230 (mod:HI (match_operand:HI 1 "register_operand" "0")
7232 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7236 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7237 (clobber (reg:CC FLAGS_REG))]
7238 "TARGET_QIMODE_MATH"
7240 [(set_attr "type" "idiv")
7241 (set_attr "mode" "QI")])
7243 ;; We cannot use div/idiv for double division, because it causes
7244 ;; "division by zero" on the overflow and that's not what we expect
7245 ;; from truncate. Because true (non truncating) double division is
7246 ;; never generated, we can't create this insn anyway.
7249 ; [(set (match_operand:SI 0 "register_operand" "=a")
7251 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7253 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7254 ; (set (match_operand:SI 3 "register_operand" "=d")
7256 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7257 ; (clobber (reg:CC FLAGS_REG))]
7259 ; "div{l}\t{%2, %0|%0, %2}"
7260 ; [(set_attr "type" "idiv")])
7262 ;;- Logical AND instructions
7264 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7265 ;; Note that this excludes ah.
7267 (define_expand "testsi_ccno_1"
7268 [(set (reg:CCNO FLAGS_REG)
7270 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7271 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7274 (define_expand "testqi_ccz_1"
7275 [(set (reg:CCZ FLAGS_REG)
7276 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7277 (match_operand:QI 1 "nonmemory_operand"))
7280 (define_expand "testdi_ccno_1"
7281 [(set (reg:CCNO FLAGS_REG)
7283 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7284 (match_operand:DI 1 "x86_64_szext_general_operand"))
7286 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7288 (define_insn "*testdi_1"
7289 [(set (reg FLAGS_REG)
7292 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7293 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7295 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7296 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7298 test{l}\t{%k1, %k0|%k0, %k1}
7299 test{l}\t{%k1, %k0|%k0, %k1}
7300 test{q}\t{%1, %0|%0, %1}
7301 test{q}\t{%1, %0|%0, %1}
7302 test{q}\t{%1, %0|%0, %1}"
7303 [(set_attr "type" "test")
7304 (set_attr "modrm" "0,1,0,1,1")
7305 (set_attr "mode" "SI,SI,DI,DI,DI")])
7307 (define_insn "*testqi_1_maybe_si"
7308 [(set (reg FLAGS_REG)
7311 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7312 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7314 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7315 && ix86_match_ccmode (insn,
7316 CONST_INT_P (operands[1])
7317 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7319 if (which_alternative == 3)
7321 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7322 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7323 return "test{l}\t{%1, %k0|%k0, %1}";
7325 return "test{b}\t{%1, %0|%0, %1}";
7327 [(set_attr "type" "test")
7328 (set_attr "modrm" "0,1,1,1")
7329 (set_attr "mode" "QI,QI,QI,SI")
7330 (set_attr "pent_pair" "uv,np,uv,np")])
7332 (define_insn "*test<mode>_1"
7333 [(set (reg FLAGS_REG)
7336 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7337 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7339 "ix86_match_ccmode (insn, CCNOmode)
7340 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7341 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7342 [(set_attr "type" "test")
7343 (set_attr "modrm" "0,1,1")
7344 (set_attr "mode" "<MODE>")
7345 (set_attr "pent_pair" "uv,np,uv")])
7347 (define_expand "testqi_ext_ccno_0"
7348 [(set (reg:CCNO FLAGS_REG)
7352 (match_operand 0 "ext_register_operand")
7355 (match_operand 1 "const_int_operand"))
7358 (define_insn "*testqi_ext_0"
7359 [(set (reg FLAGS_REG)
7363 (match_operand 0 "ext_register_operand" "Q")
7366 (match_operand 1 "const_int_operand" "n"))
7368 "ix86_match_ccmode (insn, CCNOmode)"
7369 "test{b}\t{%1, %h0|%h0, %1}"
7370 [(set_attr "type" "test")
7371 (set_attr "mode" "QI")
7372 (set_attr "length_immediate" "1")
7373 (set_attr "modrm" "1")
7374 (set_attr "pent_pair" "np")])
7376 (define_insn "*testqi_ext_1"
7377 [(set (reg FLAGS_REG)
7381 (match_operand 0 "ext_register_operand" "Q,Q")
7385 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7387 "ix86_match_ccmode (insn, CCNOmode)"
7388 "test{b}\t{%1, %h0|%h0, %1}"
7389 [(set_attr "isa" "*,nox64")
7390 (set_attr "type" "test")
7391 (set_attr "mode" "QI")])
7393 (define_insn "*testqi_ext_2"
7394 [(set (reg FLAGS_REG)
7398 (match_operand 0 "ext_register_operand" "Q")
7402 (match_operand 1 "ext_register_operand" "Q")
7406 "ix86_match_ccmode (insn, CCNOmode)"
7407 "test{b}\t{%h1, %h0|%h0, %h1}"
7408 [(set_attr "type" "test")
7409 (set_attr "mode" "QI")])
7411 ;; Combine likes to form bit extractions for some tests. Humor it.
7412 (define_insn "*testqi_ext_3"
7413 [(set (reg FLAGS_REG)
7414 (compare (zero_extract:SWI48
7415 (match_operand 0 "nonimmediate_operand" "rm")
7416 (match_operand:SWI48 1 "const_int_operand")
7417 (match_operand:SWI48 2 "const_int_operand"))
7419 "ix86_match_ccmode (insn, CCNOmode)
7420 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7421 || GET_MODE (operands[0]) == SImode
7422 || GET_MODE (operands[0]) == HImode
7423 || GET_MODE (operands[0]) == QImode)
7424 /* Ensure that resulting mask is zero or sign extended operand. */
7425 && INTVAL (operands[2]) >= 0
7426 && ((INTVAL (operands[1]) > 0
7427 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7428 || (<MODE>mode == DImode
7429 && INTVAL (operands[1]) > 32
7430 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7434 [(set (match_operand 0 "flags_reg_operand")
7435 (match_operator 1 "compare_operator"
7437 (match_operand 2 "nonimmediate_operand")
7438 (match_operand 3 "const_int_operand")
7439 (match_operand 4 "const_int_operand"))
7441 "ix86_match_ccmode (insn, CCNOmode)"
7442 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7444 rtx val = operands[2];
7445 HOST_WIDE_INT len = INTVAL (operands[3]);
7446 HOST_WIDE_INT pos = INTVAL (operands[4]);
7448 enum machine_mode mode, submode;
7450 mode = GET_MODE (val);
7453 /* ??? Combine likes to put non-volatile mem extractions in QImode
7454 no matter the size of the test. So find a mode that works. */
7455 if (! MEM_VOLATILE_P (val))
7457 mode = smallest_mode_for_size (pos + len, MODE_INT);
7458 val = adjust_address (val, mode, 0);
7461 else if (GET_CODE (val) == SUBREG
7462 && (submode = GET_MODE (SUBREG_REG (val)),
7463 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7464 && pos + len <= GET_MODE_BITSIZE (submode)
7465 && GET_MODE_CLASS (submode) == MODE_INT)
7467 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7469 val = SUBREG_REG (val);
7471 else if (mode == HImode && pos + len <= 8)
7473 /* Small HImode tests can be converted to QImode. */
7475 val = gen_lowpart (QImode, val);
7478 if (len == HOST_BITS_PER_WIDE_INT)
7481 mask = ((HOST_WIDE_INT)1 << len) - 1;
7484 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7487 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7488 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7489 ;; this is relatively important trick.
7490 ;; Do the conversion only post-reload to avoid limiting of the register class
7493 [(set (match_operand 0 "flags_reg_operand")
7494 (match_operator 1 "compare_operator"
7495 [(and (match_operand 2 "register_operand")
7496 (match_operand 3 "const_int_operand"))
7499 && QI_REG_P (operands[2])
7500 && GET_MODE (operands[2]) != QImode
7501 && ((ix86_match_ccmode (insn, CCZmode)
7502 && !(INTVAL (operands[3]) & ~(255 << 8)))
7503 || (ix86_match_ccmode (insn, CCNOmode)
7504 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7507 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7511 operands[2] = gen_lowpart (SImode, operands[2]);
7512 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7516 [(set (match_operand 0 "flags_reg_operand")
7517 (match_operator 1 "compare_operator"
7518 [(and (match_operand 2 "nonimmediate_operand")
7519 (match_operand 3 "const_int_operand"))
7522 && GET_MODE (operands[2]) != QImode
7523 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7524 && ((ix86_match_ccmode (insn, CCZmode)
7525 && !(INTVAL (operands[3]) & ~255))
7526 || (ix86_match_ccmode (insn, CCNOmode)
7527 && !(INTVAL (operands[3]) & ~127)))"
7529 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7532 operands[2] = gen_lowpart (QImode, operands[2]);
7533 operands[3] = gen_lowpart (QImode, operands[3]);
7537 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7538 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7539 (match_operand:SWI1248x 2 "mask_reg_operand")))
7540 (clobber (reg:CC FLAGS_REG))]
7541 ;;TODO removed avx512f check because mask_reg implies it.
7544 (any_logic:SWI1248x (match_dup 1)
7547 (define_insn "*k<logic>qi"
7548 [(set (match_operand:QI 0 "mask_reg_operand" "=k")
7549 (any_logic:QI (match_operand:QI 1 "mask_reg_operand" "k")
7550 (match_operand:QI 2 "mask_reg_operand" "k")))]
7553 return TARGET_AVX512DQ ? "k<logic>b\t{%2, %1, %0|%0, %1, %2}"
7554 : "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7556 [(set_attr "mode" "QI")
7557 (set_attr "type" "msklog")
7558 (set_attr "prefix" "vex")])
7560 (define_insn "*k<logic>hi"
7561 [(set (match_operand:HI 0 "mask_reg_operand" "=k")
7562 (any_logic:HI (match_operand:HI 1 "mask_reg_operand" "k")
7563 (match_operand:HI 2 "mask_reg_operand" "k")))]
7565 "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7566 [(set_attr "mode" "HI")
7567 (set_attr "type" "msklog")
7568 (set_attr "prefix" "vex")])
7570 (define_insn "*k<logic><mode>"
7571 [(set (match_operand:SWI48x 0 "mask_reg_operand" "=k")
7572 (any_logic:SWI48x (match_operand:SWI48x 1 "mask_reg_operand" "k")
7573 (match_operand:SWI48x 2 "mask_reg_operand" "k")))]
7575 "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7576 [(set_attr "mode" "<MODE>")
7577 (set_attr "type" "msklog")
7578 (set_attr "prefix" "vex")])
7580 ;; %%% This used to optimize known byte-wide and operations to memory,
7581 ;; and sometimes to QImode registers. If this is considered useful,
7582 ;; it should be done with splitters.
7584 (define_expand "and<mode>3"
7585 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7586 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7587 (match_operand:SWIM 2 "<general_szext_operand>")))]
7590 enum machine_mode mode = <MODE>mode;
7591 rtx (*insn) (rtx, rtx);
7593 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7595 HOST_WIDE_INT ival = INTVAL (operands[2]);
7597 if (ival == (HOST_WIDE_INT) 0xffffffff)
7599 else if (ival == 0xffff)
7601 else if (ival == 0xff)
7605 if (mode == <MODE>mode)
7607 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7611 if (<MODE>mode == DImode)
7612 insn = (mode == SImode)
7613 ? gen_zero_extendsidi2
7615 ? gen_zero_extendhidi2
7616 : gen_zero_extendqidi2;
7617 else if (<MODE>mode == SImode)
7618 insn = (mode == HImode)
7619 ? gen_zero_extendhisi2
7620 : gen_zero_extendqisi2;
7621 else if (<MODE>mode == HImode)
7622 insn = gen_zero_extendqihi2;
7626 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7630 (define_insn "*anddi_1"
7631 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7633 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7634 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7635 (clobber (reg:CC FLAGS_REG))]
7636 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7638 switch (get_attr_type (insn))
7644 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7647 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7648 if (get_attr_mode (insn) == MODE_SI)
7649 return "and{l}\t{%k2, %k0|%k0, %k2}";
7651 return "and{q}\t{%2, %0|%0, %2}";
7654 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7655 (set_attr "length_immediate" "*,*,*,0,0")
7656 (set (attr "prefix_rex")
7658 (and (eq_attr "type" "imovx")
7659 (and (match_test "INTVAL (operands[2]) == 0xff")
7660 (match_operand 1 "ext_QIreg_operand")))
7662 (const_string "*")))
7663 (set_attr "mode" "SI,DI,DI,SI,DI")])
7665 (define_insn "*andsi_1"
7666 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7667 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7668 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7669 (clobber (reg:CC FLAGS_REG))]
7670 "ix86_binary_operator_ok (AND, SImode, operands)"
7672 switch (get_attr_type (insn))
7678 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7681 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7682 return "and{l}\t{%2, %0|%0, %2}";
7685 [(set_attr "type" "alu,alu,imovx,msklog")
7686 (set (attr "prefix_rex")
7688 (and (eq_attr "type" "imovx")
7689 (and (match_test "INTVAL (operands[2]) == 0xff")
7690 (match_operand 1 "ext_QIreg_operand")))
7692 (const_string "*")))
7693 (set_attr "length_immediate" "*,*,0,0")
7694 (set_attr "mode" "SI")])
7696 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7697 (define_insn "*andsi_1_zext"
7698 [(set (match_operand:DI 0 "register_operand" "=r")
7700 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7701 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7702 (clobber (reg:CC FLAGS_REG))]
7703 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7704 "and{l}\t{%2, %k0|%k0, %2}"
7705 [(set_attr "type" "alu")
7706 (set_attr "mode" "SI")])
7708 (define_insn "*andhi_1"
7709 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7710 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7711 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7712 (clobber (reg:CC FLAGS_REG))]
7713 "ix86_binary_operator_ok (AND, HImode, operands)"
7715 switch (get_attr_type (insn))
7721 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7724 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7725 return "and{w}\t{%2, %0|%0, %2}";
7728 [(set_attr "type" "alu,alu,imovx,msklog")
7729 (set_attr "length_immediate" "*,*,0,*")
7730 (set (attr "prefix_rex")
7732 (and (eq_attr "type" "imovx")
7733 (match_operand 1 "ext_QIreg_operand"))
7735 (const_string "*")))
7736 (set_attr "mode" "HI,HI,SI,HI")])
7738 ;; %%% Potential partial reg stall on alternative 2. What to do?
7739 (define_insn "*andqi_1"
7740 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7741 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7742 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7743 (clobber (reg:CC FLAGS_REG))]
7744 "ix86_binary_operator_ok (AND, QImode, operands)"
7746 switch (which_alternative)
7750 return "and{b}\t{%2, %0|%0, %2}";
7752 return "and{l}\t{%k2, %k0|%k0, %k2}";
7754 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7755 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7760 [(set_attr "type" "alu,alu,alu,msklog")
7761 (set_attr "mode" "QI,QI,SI,HI")])
7763 (define_insn "*andqi_1_slp"
7764 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7765 (and:QI (match_dup 0)
7766 (match_operand:QI 1 "general_operand" "qn,qmn")))
7767 (clobber (reg:CC FLAGS_REG))]
7768 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7769 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7770 "and{b}\t{%1, %0|%0, %1}"
7771 [(set_attr "type" "alu1")
7772 (set_attr "mode" "QI")])
7774 (define_insn "kandn<mode>"
7775 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7778 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7779 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7780 (clobber (reg:CC FLAGS_REG))]
7783 switch (which_alternative)
7786 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7790 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7791 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7793 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7798 [(set_attr "isa" "bmi,*,avx512f")
7799 (set_attr "type" "bitmanip,*,msklog")
7800 (set_attr "prefix" "*,*,vex")
7801 (set_attr "btver2_decode" "direct,*,*")
7802 (set_attr "mode" "<MODE>")])
7805 [(set (match_operand:SWI12 0 "general_reg_operand")
7809 (match_operand:SWI12 1 "general_reg_operand")))
7810 (clobber (reg:CC FLAGS_REG))]
7811 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7813 (not:HI (match_dup 0)))
7814 (parallel [(set (match_dup 0)
7815 (and:HI (match_dup 0)
7817 (clobber (reg:CC FLAGS_REG))])])
7819 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7821 [(set (match_operand:DI 0 "register_operand")
7822 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7823 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7824 (clobber (reg:CC FLAGS_REG))]
7826 [(parallel [(set (match_dup 0)
7827 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7828 (clobber (reg:CC FLAGS_REG))])]
7829 "operands[2] = gen_lowpart (SImode, operands[2]);")
7832 [(set (match_operand:SWI248 0 "register_operand")
7833 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7834 (match_operand:SWI248 2 "const_int_operand")))
7835 (clobber (reg:CC FLAGS_REG))]
7837 && true_regnum (operands[0]) != true_regnum (operands[1])"
7840 HOST_WIDE_INT ival = INTVAL (operands[2]);
7841 enum machine_mode mode;
7842 rtx (*insn) (rtx, rtx);
7844 if (ival == (HOST_WIDE_INT) 0xffffffff)
7846 else if (ival == 0xffff)
7850 gcc_assert (ival == 0xff);
7854 if (<MODE>mode == DImode)
7855 insn = (mode == SImode)
7856 ? gen_zero_extendsidi2
7858 ? gen_zero_extendhidi2
7859 : gen_zero_extendqidi2;
7862 if (<MODE>mode != SImode)
7863 /* Zero extend to SImode to avoid partial register stalls. */
7864 operands[0] = gen_lowpart (SImode, operands[0]);
7866 insn = (mode == HImode)
7867 ? gen_zero_extendhisi2
7868 : gen_zero_extendqisi2;
7870 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7875 [(set (match_operand 0 "register_operand")
7877 (const_int -65536)))
7878 (clobber (reg:CC FLAGS_REG))]
7879 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7880 || optimize_function_for_size_p (cfun)"
7881 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7882 "operands[1] = gen_lowpart (HImode, operands[0]);")
7885 [(set (match_operand 0 "ext_register_operand")
7888 (clobber (reg:CC FLAGS_REG))]
7889 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7890 && reload_completed"
7891 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7892 "operands[1] = gen_lowpart (QImode, operands[0]);")
7895 [(set (match_operand 0 "ext_register_operand")
7897 (const_int -65281)))
7898 (clobber (reg:CC FLAGS_REG))]
7899 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7900 && reload_completed"
7901 [(parallel [(set (zero_extract:SI (match_dup 0)
7905 (zero_extract:SI (match_dup 0)
7908 (zero_extract:SI (match_dup 0)
7911 (clobber (reg:CC FLAGS_REG))])]
7912 "operands[0] = gen_lowpart (SImode, operands[0]);")
7914 (define_insn "*anddi_2"
7915 [(set (reg FLAGS_REG)
7918 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7919 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7921 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7922 (and:DI (match_dup 1) (match_dup 2)))]
7924 && ix86_match_ccmode
7926 /* If we are going to emit andl instead of andq, and the operands[2]
7927 constant might have the SImode sign bit set, make sure the sign
7928 flag isn't tested, because the instruction will set the sign flag
7929 based on bit 31 rather than bit 63. If it isn't CONST_INT,
7930 conservatively assume it might have bit 31 set. */
7931 (satisfies_constraint_Z (operands[2])
7932 && (!CONST_INT_P (operands[2])
7933 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7934 ? CCZmode : CCNOmode)
7935 && ix86_binary_operator_ok (AND, DImode, operands)"
7937 and{l}\t{%k2, %k0|%k0, %k2}
7938 and{q}\t{%2, %0|%0, %2}
7939 and{q}\t{%2, %0|%0, %2}"
7940 [(set_attr "type" "alu")
7941 (set_attr "mode" "SI,DI,DI")])
7943 (define_insn "*andqi_2_maybe_si"
7944 [(set (reg FLAGS_REG)
7946 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7947 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7949 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7950 (and:QI (match_dup 1) (match_dup 2)))]
7951 "ix86_binary_operator_ok (AND, QImode, operands)
7952 && ix86_match_ccmode (insn,
7953 CONST_INT_P (operands[2])
7954 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7956 if (which_alternative == 2)
7958 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7959 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7960 return "and{l}\t{%2, %k0|%k0, %2}";
7962 return "and{b}\t{%2, %0|%0, %2}";
7964 [(set_attr "type" "alu")
7965 (set_attr "mode" "QI,QI,SI")])
7967 (define_insn "*and<mode>_2"
7968 [(set (reg FLAGS_REG)
7969 (compare (and:SWI124
7970 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7971 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7973 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7974 (and:SWI124 (match_dup 1) (match_dup 2)))]
7975 "ix86_match_ccmode (insn, CCNOmode)
7976 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7977 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7978 [(set_attr "type" "alu")
7979 (set_attr "mode" "<MODE>")])
7981 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7982 (define_insn "*andsi_2_zext"
7983 [(set (reg FLAGS_REG)
7985 (match_operand:SI 1 "nonimmediate_operand" "%0")
7986 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7988 (set (match_operand:DI 0 "register_operand" "=r")
7989 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7990 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7991 && ix86_binary_operator_ok (AND, SImode, operands)"
7992 "and{l}\t{%2, %k0|%k0, %2}"
7993 [(set_attr "type" "alu")
7994 (set_attr "mode" "SI")])
7996 (define_insn "*andqi_2_slp"
7997 [(set (reg FLAGS_REG)
7999 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8000 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8002 (set (strict_low_part (match_dup 0))
8003 (and:QI (match_dup 0) (match_dup 1)))]
8004 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8005 && ix86_match_ccmode (insn, CCNOmode)
8006 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8007 "and{b}\t{%1, %0|%0, %1}"
8008 [(set_attr "type" "alu1")
8009 (set_attr "mode" "QI")])
8011 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8012 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8013 ;; for a QImode operand, which of course failed.
8014 (define_insn "andqi_ext_0"
8015 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8020 (match_operand 1 "ext_register_operand" "0")
8023 (match_operand 2 "const_int_operand" "n")))
8024 (clobber (reg:CC FLAGS_REG))]
8026 "and{b}\t{%2, %h0|%h0, %2}"
8027 [(set_attr "type" "alu")
8028 (set_attr "length_immediate" "1")
8029 (set_attr "modrm" "1")
8030 (set_attr "mode" "QI")])
8032 ;; Generated by peephole translating test to and. This shows up
8033 ;; often in fp comparisons.
8034 (define_insn "*andqi_ext_0_cc"
8035 [(set (reg FLAGS_REG)
8039 (match_operand 1 "ext_register_operand" "0")
8042 (match_operand 2 "const_int_operand" "n"))
8044 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8053 "ix86_match_ccmode (insn, CCNOmode)"
8054 "and{b}\t{%2, %h0|%h0, %2}"
8055 [(set_attr "type" "alu")
8056 (set_attr "length_immediate" "1")
8057 (set_attr "modrm" "1")
8058 (set_attr "mode" "QI")])
8060 (define_insn "*andqi_ext_1"
8061 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8066 (match_operand 1 "ext_register_operand" "0,0")
8070 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8071 (clobber (reg:CC FLAGS_REG))]
8073 "and{b}\t{%2, %h0|%h0, %2}"
8074 [(set_attr "isa" "*,nox64")
8075 (set_attr "type" "alu")
8076 (set_attr "length_immediate" "0")
8077 (set_attr "mode" "QI")])
8079 (define_insn "*andqi_ext_2"
8080 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8085 (match_operand 1 "ext_register_operand" "%0")
8089 (match_operand 2 "ext_register_operand" "Q")
8092 (clobber (reg:CC FLAGS_REG))]
8094 "and{b}\t{%h2, %h0|%h0, %h2}"
8095 [(set_attr "type" "alu")
8096 (set_attr "length_immediate" "0")
8097 (set_attr "mode" "QI")])
8099 ;; Convert wide AND instructions with immediate operand to shorter QImode
8100 ;; equivalents when possible.
8101 ;; Don't do the splitting with memory operands, since it introduces risk
8102 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8103 ;; for size, but that can (should?) be handled by generic code instead.
8105 [(set (match_operand 0 "register_operand")
8106 (and (match_operand 1 "register_operand")
8107 (match_operand 2 "const_int_operand")))
8108 (clobber (reg:CC FLAGS_REG))]
8110 && QI_REG_P (operands[0])
8111 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8112 && !(~INTVAL (operands[2]) & ~(255 << 8))
8113 && GET_MODE (operands[0]) != QImode"
8114 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8115 (and:SI (zero_extract:SI (match_dup 1)
8116 (const_int 8) (const_int 8))
8118 (clobber (reg:CC FLAGS_REG))])]
8120 operands[0] = gen_lowpart (SImode, operands[0]);
8121 operands[1] = gen_lowpart (SImode, operands[1]);
8122 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8125 ;; Since AND can be encoded with sign extended immediate, this is only
8126 ;; profitable when 7th bit is not set.
8128 [(set (match_operand 0 "register_operand")
8129 (and (match_operand 1 "general_operand")
8130 (match_operand 2 "const_int_operand")))
8131 (clobber (reg:CC FLAGS_REG))]
8133 && ANY_QI_REG_P (operands[0])
8134 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8135 && !(~INTVAL (operands[2]) & ~255)
8136 && !(INTVAL (operands[2]) & 128)
8137 && GET_MODE (operands[0]) != QImode"
8138 [(parallel [(set (strict_low_part (match_dup 0))
8139 (and:QI (match_dup 1)
8141 (clobber (reg:CC FLAGS_REG))])]
8143 operands[0] = gen_lowpart (QImode, operands[0]);
8144 operands[1] = gen_lowpart (QImode, operands[1]);
8145 operands[2] = gen_lowpart (QImode, operands[2]);
8148 ;; Logical inclusive and exclusive OR instructions
8150 ;; %%% This used to optimize known byte-wide and operations to memory.
8151 ;; If this is considered useful, it should be done with splitters.
8153 (define_expand "<code><mode>3"
8154 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8155 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8156 (match_operand:SWIM 2 "<general_operand>")))]
8158 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8160 (define_insn "*<code><mode>_1"
8161 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8163 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8164 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8165 (clobber (reg:CC FLAGS_REG))]
8166 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8168 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8169 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8170 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8171 [(set_attr "type" "alu,alu,msklog")
8172 (set_attr "mode" "<MODE>")])
8174 (define_insn "*<code>hi_1"
8175 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8177 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8178 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8179 (clobber (reg:CC FLAGS_REG))]
8180 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8182 <logic>{w}\t{%2, %0|%0, %2}
8183 <logic>{w}\t{%2, %0|%0, %2}
8184 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8185 [(set_attr "type" "alu,alu,msklog")
8186 (set_attr "mode" "HI")])
8188 ;; %%% Potential partial reg stall on alternative 2. What to do?
8189 (define_insn "*<code>qi_1"
8190 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8191 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8192 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8193 (clobber (reg:CC FLAGS_REG))]
8194 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8196 <logic>{b}\t{%2, %0|%0, %2}
8197 <logic>{b}\t{%2, %0|%0, %2}
8198 <logic>{l}\t{%k2, %k0|%k0, %k2}
8199 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8200 [(set_attr "type" "alu,alu,alu,msklog")
8201 (set_attr "mode" "QI,QI,SI,HI")])
8203 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8204 (define_insn "*<code>si_1_zext"
8205 [(set (match_operand:DI 0 "register_operand" "=r")
8207 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8208 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8209 (clobber (reg:CC FLAGS_REG))]
8210 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8211 "<logic>{l}\t{%2, %k0|%k0, %2}"
8212 [(set_attr "type" "alu")
8213 (set_attr "mode" "SI")])
8215 (define_insn "*<code>si_1_zext_imm"
8216 [(set (match_operand:DI 0 "register_operand" "=r")
8218 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8219 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8220 (clobber (reg:CC FLAGS_REG))]
8221 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8222 "<logic>{l}\t{%2, %k0|%k0, %2}"
8223 [(set_attr "type" "alu")
8224 (set_attr "mode" "SI")])
8226 (define_insn "*<code>qi_1_slp"
8227 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8228 (any_or:QI (match_dup 0)
8229 (match_operand:QI 1 "general_operand" "qmn,qn")))
8230 (clobber (reg:CC FLAGS_REG))]
8231 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8232 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8233 "<logic>{b}\t{%1, %0|%0, %1}"
8234 [(set_attr "type" "alu1")
8235 (set_attr "mode" "QI")])
8237 (define_insn "*<code><mode>_2"
8238 [(set (reg FLAGS_REG)
8239 (compare (any_or:SWI
8240 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8241 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8243 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8244 (any_or:SWI (match_dup 1) (match_dup 2)))]
8245 "ix86_match_ccmode (insn, CCNOmode)
8246 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8247 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8248 [(set_attr "type" "alu")
8249 (set_attr "mode" "<MODE>")])
8251 (define_insn "kxnor<mode>"
8252 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8255 (match_operand:SWI12 1 "register_operand" "0,k")
8256 (match_operand:SWI12 2 "register_operand" "r,k"))))
8257 (clobber (reg:CC FLAGS_REG))]
8260 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8261 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8262 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8264 [(set_attr "type" "*,msklog")
8265 (set_attr "prefix" "*,vex")
8266 (set_attr "mode" "<MODE>")])
8268 (define_insn "kxnor<mode>"
8269 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8272 (match_operand:SWI48x 1 "register_operand" "0,k")
8273 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8274 (clobber (reg:CC FLAGS_REG))]
8278 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8279 [(set_attr "type" "*,msklog")
8280 (set_attr "prefix" "*,vex")
8281 (set_attr "mode" "<MODE>")])
8284 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8288 (match_operand:SWI1248x 1 "general_reg_operand"))))
8289 (clobber (reg:CC FLAGS_REG))]
8290 "TARGET_AVX512F && reload_completed"
8291 [(parallel [(set (match_dup 0)
8292 (xor:HI (match_dup 0)
8294 (clobber (reg:CC FLAGS_REG))])
8296 (not:HI (match_dup 0)))])
8298 ;;There are kortrest[bdq] but no intrinsics for them.
8299 ;;We probably don't need to implement them.
8300 (define_insn "kortestzhi"
8301 [(set (reg:CCZ FLAGS_REG)
8304 (match_operand:HI 0 "register_operand" "k")
8305 (match_operand:HI 1 "register_operand" "k"))
8307 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8308 "kortestw\t{%1, %0|%0, %1}"
8309 [(set_attr "mode" "HI")
8310 (set_attr "type" "msklog")
8311 (set_attr "prefix" "vex")])
8313 (define_insn "kortestchi"
8314 [(set (reg:CCC FLAGS_REG)
8317 (match_operand:HI 0 "register_operand" "k")
8318 (match_operand:HI 1 "register_operand" "k"))
8320 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8321 "kortestw\t{%1, %0|%0, %1}"
8322 [(set_attr "mode" "HI")
8323 (set_attr "type" "msklog")
8324 (set_attr "prefix" "vex")])
8326 (define_insn "kunpckhi"
8327 [(set (match_operand:HI 0 "register_operand" "=k")
8330 (match_operand:HI 1 "register_operand" "k")
8332 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8334 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8335 [(set_attr "mode" "HI")
8336 (set_attr "type" "msklog")
8337 (set_attr "prefix" "vex")])
8339 (define_insn "kunpcksi"
8340 [(set (match_operand:SI 0 "register_operand" "=k")
8343 (match_operand:SI 1 "register_operand" "k")
8345 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8347 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8348 [(set_attr "mode" "SI")])
8350 (define_insn "kunpckdi"
8351 [(set (match_operand:DI 0 "register_operand" "=k")
8354 (match_operand:DI 1 "register_operand" "k")
8356 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8358 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8359 [(set_attr "mode" "DI")])
8361 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8362 ;; ??? Special case for immediate operand is missing - it is tricky.
8363 (define_insn "*<code>si_2_zext"
8364 [(set (reg FLAGS_REG)
8365 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8366 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8368 (set (match_operand:DI 0 "register_operand" "=r")
8369 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8370 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8371 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8372 "<logic>{l}\t{%2, %k0|%k0, %2}"
8373 [(set_attr "type" "alu")
8374 (set_attr "mode" "SI")])
8376 (define_insn "*<code>si_2_zext_imm"
8377 [(set (reg FLAGS_REG)
8379 (match_operand:SI 1 "nonimmediate_operand" "%0")
8380 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8382 (set (match_operand:DI 0 "register_operand" "=r")
8383 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8384 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8385 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8386 "<logic>{l}\t{%2, %k0|%k0, %2}"
8387 [(set_attr "type" "alu")
8388 (set_attr "mode" "SI")])
8390 (define_insn "*<code>qi_2_slp"
8391 [(set (reg FLAGS_REG)
8392 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8393 (match_operand:QI 1 "general_operand" "qmn,qn"))
8395 (set (strict_low_part (match_dup 0))
8396 (any_or:QI (match_dup 0) (match_dup 1)))]
8397 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8398 && ix86_match_ccmode (insn, CCNOmode)
8399 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8400 "<logic>{b}\t{%1, %0|%0, %1}"
8401 [(set_attr "type" "alu1")
8402 (set_attr "mode" "QI")])
8404 (define_insn "*<code><mode>_3"
8405 [(set (reg FLAGS_REG)
8406 (compare (any_or:SWI
8407 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8408 (match_operand:SWI 2 "<general_operand>" "<g>"))
8410 (clobber (match_scratch:SWI 0 "=<r>"))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8413 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "<MODE>")])
8417 (define_insn "*<code>qi_ext_0"
8418 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8423 (match_operand 1 "ext_register_operand" "0")
8426 (match_operand 2 "const_int_operand" "n")))
8427 (clobber (reg:CC FLAGS_REG))]
8428 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8429 "<logic>{b}\t{%2, %h0|%h0, %2}"
8430 [(set_attr "type" "alu")
8431 (set_attr "length_immediate" "1")
8432 (set_attr "modrm" "1")
8433 (set_attr "mode" "QI")])
8435 (define_insn "*<code>qi_ext_1"
8436 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8441 (match_operand 1 "ext_register_operand" "0,0")
8445 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8446 (clobber (reg:CC FLAGS_REG))]
8447 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8448 "<logic>{b}\t{%2, %h0|%h0, %2}"
8449 [(set_attr "isa" "*,nox64")
8450 (set_attr "type" "alu")
8451 (set_attr "length_immediate" "0")
8452 (set_attr "mode" "QI")])
8454 (define_insn "*<code>qi_ext_2"
8455 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8462 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8465 (clobber (reg:CC FLAGS_REG))]
8466 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8467 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8468 [(set_attr "type" "alu")
8469 (set_attr "length_immediate" "0")
8470 (set_attr "mode" "QI")])
8473 [(set (match_operand 0 "register_operand")
8474 (any_or (match_operand 1 "register_operand")
8475 (match_operand 2 "const_int_operand")))
8476 (clobber (reg:CC FLAGS_REG))]
8478 && QI_REG_P (operands[0])
8479 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8480 && !(INTVAL (operands[2]) & ~(255 << 8))
8481 && GET_MODE (operands[0]) != QImode"
8482 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8483 (any_or:SI (zero_extract:SI (match_dup 1)
8484 (const_int 8) (const_int 8))
8486 (clobber (reg:CC FLAGS_REG))])]
8488 operands[0] = gen_lowpart (SImode, operands[0]);
8489 operands[1] = gen_lowpart (SImode, operands[1]);
8490 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8493 ;; Since OR can be encoded with sign extended immediate, this is only
8494 ;; profitable when 7th bit is set.
8496 [(set (match_operand 0 "register_operand")
8497 (any_or (match_operand 1 "general_operand")
8498 (match_operand 2 "const_int_operand")))
8499 (clobber (reg:CC FLAGS_REG))]
8501 && ANY_QI_REG_P (operands[0])
8502 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8503 && !(INTVAL (operands[2]) & ~255)
8504 && (INTVAL (operands[2]) & 128)
8505 && GET_MODE (operands[0]) != QImode"
8506 [(parallel [(set (strict_low_part (match_dup 0))
8507 (any_or:QI (match_dup 1)
8509 (clobber (reg:CC FLAGS_REG))])]
8511 operands[0] = gen_lowpart (QImode, operands[0]);
8512 operands[1] = gen_lowpart (QImode, operands[1]);
8513 operands[2] = gen_lowpart (QImode, operands[2]);
8516 (define_expand "xorqi_cc_ext_1"
8518 (set (reg:CCNO FLAGS_REG)
8522 (match_operand 1 "ext_register_operand")
8525 (match_operand:QI 2 "const_int_operand"))
8527 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8537 (define_insn "*xorqi_cc_ext_1"
8538 [(set (reg FLAGS_REG)
8542 (match_operand 1 "ext_register_operand" "0,0")
8545 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8547 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8556 "ix86_match_ccmode (insn, CCNOmode)"
8557 "xor{b}\t{%2, %h0|%h0, %2}"
8558 [(set_attr "isa" "*,nox64")
8559 (set_attr "type" "alu")
8560 (set_attr "modrm" "1")
8561 (set_attr "mode" "QI")])
8563 ;; Negation instructions
8565 (define_expand "neg<mode>2"
8566 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8567 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8569 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8571 (define_insn_and_split "*neg<dwi>2_doubleword"
8572 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8573 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8574 (clobber (reg:CC FLAGS_REG))]
8575 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8579 [(set (reg:CCZ FLAGS_REG)
8580 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8581 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8584 (plus:DWIH (match_dup 3)
8585 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8587 (clobber (reg:CC FLAGS_REG))])
8590 (neg:DWIH (match_dup 2)))
8591 (clobber (reg:CC FLAGS_REG))])]
8592 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8594 (define_insn "*neg<mode>2_1"
8595 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8596 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8597 (clobber (reg:CC FLAGS_REG))]
8598 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8599 "neg{<imodesuffix>}\t%0"
8600 [(set_attr "type" "negnot")
8601 (set_attr "mode" "<MODE>")])
8603 ;; Combine is quite creative about this pattern.
8604 (define_insn "*negsi2_1_zext"
8605 [(set (match_operand:DI 0 "register_operand" "=r")
8607 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8610 (clobber (reg:CC FLAGS_REG))]
8611 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8613 [(set_attr "type" "negnot")
8614 (set_attr "mode" "SI")])
8616 ;; The problem with neg is that it does not perform (compare x 0),
8617 ;; it really performs (compare 0 x), which leaves us with the zero
8618 ;; flag being the only useful item.
8620 (define_insn "*neg<mode>2_cmpz"
8621 [(set (reg:CCZ FLAGS_REG)
8623 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8625 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8626 (neg:SWI (match_dup 1)))]
8627 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8628 "neg{<imodesuffix>}\t%0"
8629 [(set_attr "type" "negnot")
8630 (set_attr "mode" "<MODE>")])
8632 (define_insn "*negsi2_cmpz_zext"
8633 [(set (reg:CCZ FLAGS_REG)
8637 (match_operand:DI 1 "register_operand" "0")
8641 (set (match_operand:DI 0 "register_operand" "=r")
8642 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8645 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8647 [(set_attr "type" "negnot")
8648 (set_attr "mode" "SI")])
8650 ;; Negate with jump on overflow.
8651 (define_expand "negv<mode>3"
8652 [(parallel [(set (reg:CCO FLAGS_REG)
8653 (ne:CCO (match_operand:SWI 1 "register_operand")
8655 (set (match_operand:SWI 0 "register_operand")
8656 (neg:SWI (match_dup 1)))])
8657 (set (pc) (if_then_else
8658 (eq (reg:CCO FLAGS_REG) (const_int 0))
8659 (label_ref (match_operand 2))
8664 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8668 (define_insn "*negv<mode>3"
8669 [(set (reg:CCO FLAGS_REG)
8670 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8671 (match_operand:SWI 2 "const_int_operand")))
8672 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8673 (neg:SWI (match_dup 1)))]
8674 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8675 && mode_signbit_p (<MODE>mode, operands[2])"
8676 "neg{<imodesuffix>}\t%0"
8677 [(set_attr "type" "negnot")
8678 (set_attr "mode" "<MODE>")])
8680 ;; Changing of sign for FP values is doable using integer unit too.
8682 (define_expand "<code><mode>2"
8683 [(set (match_operand:X87MODEF 0 "register_operand")
8684 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8685 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8686 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8688 (define_insn "*absneg<mode>2_mixed"
8689 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8690 (match_operator:MODEF 3 "absneg_operator"
8691 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8692 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8693 (clobber (reg:CC FLAGS_REG))]
8694 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8697 (define_insn "*absneg<mode>2_sse"
8698 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8699 (match_operator:MODEF 3 "absneg_operator"
8700 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8701 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8702 (clobber (reg:CC FLAGS_REG))]
8703 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8706 (define_insn "*absneg<mode>2_i387"
8707 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8708 (match_operator:X87MODEF 3 "absneg_operator"
8709 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8710 (use (match_operand 2))
8711 (clobber (reg:CC FLAGS_REG))]
8712 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8715 (define_expand "<code>tf2"
8716 [(set (match_operand:TF 0 "register_operand")
8717 (absneg:TF (match_operand:TF 1 "register_operand")))]
8719 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8721 (define_insn "*absnegtf2_sse"
8722 [(set (match_operand:TF 0 "register_operand" "=x,x")
8723 (match_operator:TF 3 "absneg_operator"
8724 [(match_operand:TF 1 "register_operand" "0,x")]))
8725 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8726 (clobber (reg:CC FLAGS_REG))]
8730 ;; Splitters for fp abs and neg.
8733 [(set (match_operand 0 "fp_register_operand")
8734 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8735 (use (match_operand 2))
8736 (clobber (reg:CC FLAGS_REG))]
8738 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8741 [(set (match_operand 0 "register_operand")
8742 (match_operator 3 "absneg_operator"
8743 [(match_operand 1 "register_operand")]))
8744 (use (match_operand 2 "nonimmediate_operand"))
8745 (clobber (reg:CC FLAGS_REG))]
8746 "reload_completed && SSE_REG_P (operands[0])"
8747 [(set (match_dup 0) (match_dup 3))]
8749 enum machine_mode mode = GET_MODE (operands[0]);
8750 enum machine_mode vmode = GET_MODE (operands[2]);
8753 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8754 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8755 if (operands_match_p (operands[0], operands[2]))
8758 operands[1] = operands[2];
8761 if (GET_CODE (operands[3]) == ABS)
8762 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8764 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8769 [(set (match_operand:SF 0 "register_operand")
8770 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8771 (use (match_operand:V4SF 2))
8772 (clobber (reg:CC FLAGS_REG))]
8774 [(parallel [(set (match_dup 0) (match_dup 1))
8775 (clobber (reg:CC FLAGS_REG))])]
8778 operands[0] = gen_lowpart (SImode, operands[0]);
8779 if (GET_CODE (operands[1]) == ABS)
8781 tmp = gen_int_mode (0x7fffffff, SImode);
8782 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8786 tmp = gen_int_mode (0x80000000, SImode);
8787 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8793 [(set (match_operand:DF 0 "register_operand")
8794 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8795 (use (match_operand 2))
8796 (clobber (reg:CC FLAGS_REG))]
8798 [(parallel [(set (match_dup 0) (match_dup 1))
8799 (clobber (reg:CC FLAGS_REG))])]
8804 tmp = gen_lowpart (DImode, operands[0]);
8805 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8808 if (GET_CODE (operands[1]) == ABS)
8811 tmp = gen_rtx_NOT (DImode, tmp);
8815 operands[0] = gen_highpart (SImode, operands[0]);
8816 if (GET_CODE (operands[1]) == ABS)
8818 tmp = gen_int_mode (0x7fffffff, SImode);
8819 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8823 tmp = gen_int_mode (0x80000000, SImode);
8824 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8831 [(set (match_operand:XF 0 "register_operand")
8832 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8833 (use (match_operand 2))
8834 (clobber (reg:CC FLAGS_REG))]
8836 [(parallel [(set (match_dup 0) (match_dup 1))
8837 (clobber (reg:CC FLAGS_REG))])]
8840 operands[0] = gen_rtx_REG (SImode,
8841 true_regnum (operands[0])
8842 + (TARGET_64BIT ? 1 : 2));
8843 if (GET_CODE (operands[1]) == ABS)
8845 tmp = GEN_INT (0x7fff);
8846 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8850 tmp = GEN_INT (0x8000);
8851 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8856 ;; Conditionalize these after reload. If they match before reload, we
8857 ;; lose the clobber and ability to use integer instructions.
8859 (define_insn "*<code><mode>2_1"
8860 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8861 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8863 && (reload_completed
8864 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8865 "f<absneg_mnemonic>"
8866 [(set_attr "type" "fsgn")
8867 (set_attr "mode" "<MODE>")])
8869 (define_insn "*<code>extendsfdf2"
8870 [(set (match_operand:DF 0 "register_operand" "=f")
8871 (absneg:DF (float_extend:DF
8872 (match_operand:SF 1 "register_operand" "0"))))]
8873 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8874 "f<absneg_mnemonic>"
8875 [(set_attr "type" "fsgn")
8876 (set_attr "mode" "DF")])
8878 (define_insn "*<code>extendsfxf2"
8879 [(set (match_operand:XF 0 "register_operand" "=f")
8880 (absneg:XF (float_extend:XF
8881 (match_operand:SF 1 "register_operand" "0"))))]
8883 "f<absneg_mnemonic>"
8884 [(set_attr "type" "fsgn")
8885 (set_attr "mode" "XF")])
8887 (define_insn "*<code>extenddfxf2"
8888 [(set (match_operand:XF 0 "register_operand" "=f")
8889 (absneg:XF (float_extend:XF
8890 (match_operand:DF 1 "register_operand" "0"))))]
8892 "f<absneg_mnemonic>"
8893 [(set_attr "type" "fsgn")
8894 (set_attr "mode" "XF")])
8896 ;; Copysign instructions
8898 (define_mode_iterator CSGNMODE [SF DF TF])
8899 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8901 (define_expand "copysign<mode>3"
8902 [(match_operand:CSGNMODE 0 "register_operand")
8903 (match_operand:CSGNMODE 1 "nonmemory_operand")
8904 (match_operand:CSGNMODE 2 "register_operand")]
8905 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8906 || (TARGET_SSE && (<MODE>mode == TFmode))"
8907 "ix86_expand_copysign (operands); DONE;")
8909 (define_insn_and_split "copysign<mode>3_const"
8910 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8912 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8913 (match_operand:CSGNMODE 2 "register_operand" "0")
8914 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8916 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8917 || (TARGET_SSE && (<MODE>mode == TFmode))"
8919 "&& reload_completed"
8921 "ix86_split_copysign_const (operands); DONE;")
8923 (define_insn "copysign<mode>3_var"
8924 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8926 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8927 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8928 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8929 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8931 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8932 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8933 || (TARGET_SSE && (<MODE>mode == TFmode))"
8937 [(set (match_operand:CSGNMODE 0 "register_operand")
8939 [(match_operand:CSGNMODE 2 "register_operand")
8940 (match_operand:CSGNMODE 3 "register_operand")
8941 (match_operand:<CSGNVMODE> 4)
8942 (match_operand:<CSGNVMODE> 5)]
8944 (clobber (match_scratch:<CSGNVMODE> 1))]
8945 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8946 || (TARGET_SSE && (<MODE>mode == TFmode)))
8947 && reload_completed"
8949 "ix86_split_copysign_var (operands); DONE;")
8951 ;; One complement instructions
8953 (define_expand "one_cmpl<mode>2"
8954 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8955 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8957 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8959 (define_insn "*one_cmpl<mode>2_1"
8960 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
8961 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
8962 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8964 not{<imodesuffix>}\t%0
8965 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
8966 [(set_attr "isa" "*,avx512bw")
8967 (set_attr "type" "negnot,msklog")
8968 (set_attr "prefix" "*,vex")
8969 (set_attr "mode" "<MODE>")])
8971 (define_insn "*one_cmplhi2_1"
8972 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
8973 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
8974 "ix86_unary_operator_ok (NOT, HImode, operands)"
8977 knotw\t{%1, %0|%0, %1}"
8978 [(set_attr "isa" "*,avx512f")
8979 (set_attr "type" "negnot,msklog")
8980 (set_attr "prefix" "*,vex")
8981 (set_attr "mode" "HI")])
8983 ;; %%% Potential partial reg stall on alternative 1. What to do?
8984 (define_insn "*one_cmplqi2_1"
8985 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
8986 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
8987 "ix86_unary_operator_ok (NOT, QImode, operands)"
8989 switch (which_alternative)
8992 return "not{b}\t%0";
8994 return "not{l}\t%k0";
8996 if (TARGET_AVX512DQ)
8997 return "knotb\t{%1, %0|%0, %1}";
8998 return "knotw\t{%1, %0|%0, %1}";
9003 [(set_attr "isa" "*,*,avx512f")
9004 (set_attr "type" "negnot,negnot,msklog")
9005 (set_attr "prefix" "*,*,vex")
9006 (set_attr "mode" "QI,SI,QI")])
9008 ;; ??? Currently never generated - xor is used instead.
9009 (define_insn "*one_cmplsi2_1_zext"
9010 [(set (match_operand:DI 0 "register_operand" "=r")
9012 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9013 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9015 [(set_attr "type" "negnot")
9016 (set_attr "mode" "SI")])
9018 (define_insn "*one_cmpl<mode>2_2"
9019 [(set (reg FLAGS_REG)
9020 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9022 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9023 (not:SWI (match_dup 1)))]
9024 "ix86_match_ccmode (insn, CCNOmode)
9025 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9027 [(set_attr "type" "alu1")
9028 (set_attr "mode" "<MODE>")])
9031 [(set (match_operand 0 "flags_reg_operand")
9032 (match_operator 2 "compare_operator"
9033 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9035 (set (match_operand:SWI 1 "nonimmediate_operand")
9036 (not:SWI (match_dup 3)))]
9037 "ix86_match_ccmode (insn, CCNOmode)"
9038 [(parallel [(set (match_dup 0)
9039 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9042 (xor:SWI (match_dup 3) (const_int -1)))])])
9044 ;; ??? Currently never generated - xor is used instead.
9045 (define_insn "*one_cmplsi2_2_zext"
9046 [(set (reg FLAGS_REG)
9047 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9049 (set (match_operand:DI 0 "register_operand" "=r")
9050 (zero_extend:DI (not:SI (match_dup 1))))]
9051 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9052 && ix86_unary_operator_ok (NOT, SImode, operands)"
9054 [(set_attr "type" "alu1")
9055 (set_attr "mode" "SI")])
9058 [(set (match_operand 0 "flags_reg_operand")
9059 (match_operator 2 "compare_operator"
9060 [(not:SI (match_operand:SI 3 "register_operand"))
9062 (set (match_operand:DI 1 "register_operand")
9063 (zero_extend:DI (not:SI (match_dup 3))))]
9064 "ix86_match_ccmode (insn, CCNOmode)"
9065 [(parallel [(set (match_dup 0)
9066 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9069 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9071 ;; Shift instructions
9073 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9074 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9075 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9076 ;; from the assembler input.
9078 ;; This instruction shifts the target reg/mem as usual, but instead of
9079 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9080 ;; is a left shift double, bits are taken from the high order bits of
9081 ;; reg, else if the insn is a shift right double, bits are taken from the
9082 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9083 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9085 ;; Since sh[lr]d does not change the `reg' operand, that is done
9086 ;; separately, making all shifts emit pairs of shift double and normal
9087 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9088 ;; support a 63 bit shift, each shift where the count is in a reg expands
9089 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9091 ;; If the shift count is a constant, we need never emit more than one
9092 ;; shift pair, instead using moves and sign extension for counts greater
9095 (define_expand "ashl<mode>3"
9096 [(set (match_operand:SDWIM 0 "<shift_operand>")
9097 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9098 (match_operand:QI 2 "nonmemory_operand")))]
9100 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9102 (define_insn "*ashl<mode>3_doubleword"
9103 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9104 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9105 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9106 (clobber (reg:CC FLAGS_REG))]
9109 [(set_attr "type" "multi")])
9112 [(set (match_operand:DWI 0 "register_operand")
9113 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9114 (match_operand:QI 2 "nonmemory_operand")))
9115 (clobber (reg:CC FLAGS_REG))]
9116 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9118 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9120 ;; By default we don't ask for a scratch register, because when DWImode
9121 ;; values are manipulated, registers are already at a premium. But if
9122 ;; we have one handy, we won't turn it away.
9125 [(match_scratch:DWIH 3 "r")
9126 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9128 (match_operand:<DWI> 1 "nonmemory_operand")
9129 (match_operand:QI 2 "nonmemory_operand")))
9130 (clobber (reg:CC FLAGS_REG))])
9134 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9136 (define_insn "x86_64_shld"
9137 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9138 (ior:DI (ashift:DI (match_dup 0)
9139 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9140 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9141 (minus:QI (const_int 64) (match_dup 2)))))
9142 (clobber (reg:CC FLAGS_REG))]
9144 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9145 [(set_attr "type" "ishift")
9146 (set_attr "prefix_0f" "1")
9147 (set_attr "mode" "DI")
9148 (set_attr "athlon_decode" "vector")
9149 (set_attr "amdfam10_decode" "vector")
9150 (set_attr "bdver1_decode" "vector")])
9152 (define_insn "x86_shld"
9153 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9154 (ior:SI (ashift:SI (match_dup 0)
9155 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9156 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9157 (minus:QI (const_int 32) (match_dup 2)))))
9158 (clobber (reg:CC FLAGS_REG))]
9160 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9161 [(set_attr "type" "ishift")
9162 (set_attr "prefix_0f" "1")
9163 (set_attr "mode" "SI")
9164 (set_attr "pent_pair" "np")
9165 (set_attr "athlon_decode" "vector")
9166 (set_attr "amdfam10_decode" "vector")
9167 (set_attr "bdver1_decode" "vector")])
9169 (define_expand "x86_shift<mode>_adj_1"
9170 [(set (reg:CCZ FLAGS_REG)
9171 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9174 (set (match_operand:SWI48 0 "register_operand")
9175 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9176 (match_operand:SWI48 1 "register_operand")
9179 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9180 (match_operand:SWI48 3 "register_operand")
9183 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9185 (define_expand "x86_shift<mode>_adj_2"
9186 [(use (match_operand:SWI48 0 "register_operand"))
9187 (use (match_operand:SWI48 1 "register_operand"))
9188 (use (match_operand:QI 2 "register_operand"))]
9191 rtx label = gen_label_rtx ();
9194 emit_insn (gen_testqi_ccz_1 (operands[2],
9195 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9197 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9198 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9199 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9200 gen_rtx_LABEL_REF (VOIDmode, label),
9202 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9203 JUMP_LABEL (tmp) = label;
9205 emit_move_insn (operands[0], operands[1]);
9206 ix86_expand_clear (operands[1]);
9209 LABEL_NUSES (label) = 1;
9214 ;; Avoid useless masking of count operand.
9215 (define_insn "*ashl<mode>3_mask"
9216 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9218 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9221 (match_operand:SI 2 "register_operand" "c")
9222 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9223 (clobber (reg:CC FLAGS_REG))]
9224 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9225 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9226 == GET_MODE_BITSIZE (<MODE>mode)-1"
9228 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9230 [(set_attr "type" "ishift")
9231 (set_attr "mode" "<MODE>")])
9233 (define_insn "*bmi2_ashl<mode>3_1"
9234 [(set (match_operand:SWI48 0 "register_operand" "=r")
9235 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9236 (match_operand:SWI48 2 "register_operand" "r")))]
9238 "shlx\t{%2, %1, %0|%0, %1, %2}"
9239 [(set_attr "type" "ishiftx")
9240 (set_attr "mode" "<MODE>")])
9242 (define_insn "*ashl<mode>3_1"
9243 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9244 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9245 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9246 (clobber (reg:CC FLAGS_REG))]
9247 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9249 switch (get_attr_type (insn))
9256 gcc_assert (operands[2] == const1_rtx);
9257 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9258 return "add{<imodesuffix>}\t%0, %0";
9261 if (operands[2] == const1_rtx
9262 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9263 return "sal{<imodesuffix>}\t%0";
9265 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9268 [(set_attr "isa" "*,*,bmi2")
9270 (cond [(eq_attr "alternative" "1")
9271 (const_string "lea")
9272 (eq_attr "alternative" "2")
9273 (const_string "ishiftx")
9274 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9275 (match_operand 0 "register_operand"))
9276 (match_operand 2 "const1_operand"))
9277 (const_string "alu")
9279 (const_string "ishift")))
9280 (set (attr "length_immediate")
9282 (ior (eq_attr "type" "alu")
9283 (and (eq_attr "type" "ishift")
9284 (and (match_operand 2 "const1_operand")
9285 (ior (match_test "TARGET_SHIFT1")
9286 (match_test "optimize_function_for_size_p (cfun)")))))
9288 (const_string "*")))
9289 (set_attr "mode" "<MODE>")])
9291 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9293 [(set (match_operand:SWI48 0 "register_operand")
9294 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9295 (match_operand:QI 2 "register_operand")))
9296 (clobber (reg:CC FLAGS_REG))]
9297 "TARGET_BMI2 && reload_completed"
9299 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9300 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9302 (define_insn "*bmi2_ashlsi3_1_zext"
9303 [(set (match_operand:DI 0 "register_operand" "=r")
9305 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9306 (match_operand:SI 2 "register_operand" "r"))))]
9307 "TARGET_64BIT && TARGET_BMI2"
9308 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9309 [(set_attr "type" "ishiftx")
9310 (set_attr "mode" "SI")])
9312 (define_insn "*ashlsi3_1_zext"
9313 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9315 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9316 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9317 (clobber (reg:CC FLAGS_REG))]
9318 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9320 switch (get_attr_type (insn))
9327 gcc_assert (operands[2] == const1_rtx);
9328 return "add{l}\t%k0, %k0";
9331 if (operands[2] == const1_rtx
9332 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9333 return "sal{l}\t%k0";
9335 return "sal{l}\t{%2, %k0|%k0, %2}";
9338 [(set_attr "isa" "*,*,bmi2")
9340 (cond [(eq_attr "alternative" "1")
9341 (const_string "lea")
9342 (eq_attr "alternative" "2")
9343 (const_string "ishiftx")
9344 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9345 (match_operand 2 "const1_operand"))
9346 (const_string "alu")
9348 (const_string "ishift")))
9349 (set (attr "length_immediate")
9351 (ior (eq_attr "type" "alu")
9352 (and (eq_attr "type" "ishift")
9353 (and (match_operand 2 "const1_operand")
9354 (ior (match_test "TARGET_SHIFT1")
9355 (match_test "optimize_function_for_size_p (cfun)")))))
9357 (const_string "*")))
9358 (set_attr "mode" "SI")])
9360 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9362 [(set (match_operand:DI 0 "register_operand")
9364 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9365 (match_operand:QI 2 "register_operand"))))
9366 (clobber (reg:CC FLAGS_REG))]
9367 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9369 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9370 "operands[2] = gen_lowpart (SImode, operands[2]);")
9372 (define_insn "*ashlhi3_1"
9373 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9374 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9375 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9376 (clobber (reg:CC FLAGS_REG))]
9377 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9379 switch (get_attr_type (insn))
9385 gcc_assert (operands[2] == const1_rtx);
9386 return "add{w}\t%0, %0";
9389 if (operands[2] == const1_rtx
9390 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9391 return "sal{w}\t%0";
9393 return "sal{w}\t{%2, %0|%0, %2}";
9397 (cond [(eq_attr "alternative" "1")
9398 (const_string "lea")
9399 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9400 (match_operand 0 "register_operand"))
9401 (match_operand 2 "const1_operand"))
9402 (const_string "alu")
9404 (const_string "ishift")))
9405 (set (attr "length_immediate")
9407 (ior (eq_attr "type" "alu")
9408 (and (eq_attr "type" "ishift")
9409 (and (match_operand 2 "const1_operand")
9410 (ior (match_test "TARGET_SHIFT1")
9411 (match_test "optimize_function_for_size_p (cfun)")))))
9413 (const_string "*")))
9414 (set_attr "mode" "HI,SI")])
9416 ;; %%% Potential partial reg stall on alternative 1. What to do?
9417 (define_insn "*ashlqi3_1"
9418 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9419 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9420 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9421 (clobber (reg:CC FLAGS_REG))]
9422 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9424 switch (get_attr_type (insn))
9430 gcc_assert (operands[2] == const1_rtx);
9431 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9432 return "add{l}\t%k0, %k0";
9434 return "add{b}\t%0, %0";
9437 if (operands[2] == const1_rtx
9438 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9440 if (get_attr_mode (insn) == MODE_SI)
9441 return "sal{l}\t%k0";
9443 return "sal{b}\t%0";
9447 if (get_attr_mode (insn) == MODE_SI)
9448 return "sal{l}\t{%2, %k0|%k0, %2}";
9450 return "sal{b}\t{%2, %0|%0, %2}";
9455 (cond [(eq_attr "alternative" "2")
9456 (const_string "lea")
9457 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9458 (match_operand 0 "register_operand"))
9459 (match_operand 2 "const1_operand"))
9460 (const_string "alu")
9462 (const_string "ishift")))
9463 (set (attr "length_immediate")
9465 (ior (eq_attr "type" "alu")
9466 (and (eq_attr "type" "ishift")
9467 (and (match_operand 2 "const1_operand")
9468 (ior (match_test "TARGET_SHIFT1")
9469 (match_test "optimize_function_for_size_p (cfun)")))))
9471 (const_string "*")))
9472 (set_attr "mode" "QI,SI,SI")])
9474 (define_insn "*ashlqi3_1_slp"
9475 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9476 (ashift:QI (match_dup 0)
9477 (match_operand:QI 1 "nonmemory_operand" "cI")))
9478 (clobber (reg:CC FLAGS_REG))]
9479 "(optimize_function_for_size_p (cfun)
9480 || !TARGET_PARTIAL_FLAG_REG_STALL
9481 || (operands[1] == const1_rtx
9483 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9485 switch (get_attr_type (insn))
9488 gcc_assert (operands[1] == const1_rtx);
9489 return "add{b}\t%0, %0";
9492 if (operands[1] == const1_rtx
9493 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9494 return "sal{b}\t%0";
9496 return "sal{b}\t{%1, %0|%0, %1}";
9500 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9501 (match_operand 0 "register_operand"))
9502 (match_operand 1 "const1_operand"))
9503 (const_string "alu")
9505 (const_string "ishift1")))
9506 (set (attr "length_immediate")
9508 (ior (eq_attr "type" "alu")
9509 (and (eq_attr "type" "ishift1")
9510 (and (match_operand 1 "const1_operand")
9511 (ior (match_test "TARGET_SHIFT1")
9512 (match_test "optimize_function_for_size_p (cfun)")))))
9514 (const_string "*")))
9515 (set_attr "mode" "QI")])
9517 ;; Convert ashift to the lea pattern to avoid flags dependency.
9519 [(set (match_operand 0 "register_operand")
9520 (ashift (match_operand 1 "index_register_operand")
9521 (match_operand:QI 2 "const_int_operand")))
9522 (clobber (reg:CC FLAGS_REG))]
9523 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9525 && true_regnum (operands[0]) != true_regnum (operands[1])"
9528 enum machine_mode mode = GET_MODE (operands[0]);
9531 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9534 operands[0] = gen_lowpart (mode, operands[0]);
9535 operands[1] = gen_lowpart (mode, operands[1]);
9538 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9540 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9542 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9546 ;; Convert ashift to the lea pattern to avoid flags dependency.
9548 [(set (match_operand:DI 0 "register_operand")
9550 (ashift:SI (match_operand:SI 1 "index_register_operand")
9551 (match_operand:QI 2 "const_int_operand"))))
9552 (clobber (reg:CC FLAGS_REG))]
9553 "TARGET_64BIT && reload_completed
9554 && true_regnum (operands[0]) != true_regnum (operands[1])"
9556 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9558 operands[1] = gen_lowpart (SImode, operands[1]);
9559 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9562 ;; This pattern can't accept a variable shift count, since shifts by
9563 ;; zero don't affect the flags. We assume that shifts by constant
9564 ;; zero are optimized away.
9565 (define_insn "*ashl<mode>3_cmp"
9566 [(set (reg FLAGS_REG)
9568 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9569 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9571 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9572 (ashift:SWI (match_dup 1) (match_dup 2)))]
9573 "(optimize_function_for_size_p (cfun)
9574 || !TARGET_PARTIAL_FLAG_REG_STALL
9575 || (operands[2] == const1_rtx
9577 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9578 && ix86_match_ccmode (insn, CCGOCmode)
9579 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9581 switch (get_attr_type (insn))
9584 gcc_assert (operands[2] == const1_rtx);
9585 return "add{<imodesuffix>}\t%0, %0";
9588 if (operands[2] == const1_rtx
9589 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9590 return "sal{<imodesuffix>}\t%0";
9592 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9596 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9597 (match_operand 0 "register_operand"))
9598 (match_operand 2 "const1_operand"))
9599 (const_string "alu")
9601 (const_string "ishift")))
9602 (set (attr "length_immediate")
9604 (ior (eq_attr "type" "alu")
9605 (and (eq_attr "type" "ishift")
9606 (and (match_operand 2 "const1_operand")
9607 (ior (match_test "TARGET_SHIFT1")
9608 (match_test "optimize_function_for_size_p (cfun)")))))
9610 (const_string "*")))
9611 (set_attr "mode" "<MODE>")])
9613 (define_insn "*ashlsi3_cmp_zext"
9614 [(set (reg FLAGS_REG)
9616 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9617 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9619 (set (match_operand:DI 0 "register_operand" "=r")
9620 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9622 && (optimize_function_for_size_p (cfun)
9623 || !TARGET_PARTIAL_FLAG_REG_STALL
9624 || (operands[2] == const1_rtx
9626 || TARGET_DOUBLE_WITH_ADD)))
9627 && ix86_match_ccmode (insn, CCGOCmode)
9628 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9630 switch (get_attr_type (insn))
9633 gcc_assert (operands[2] == const1_rtx);
9634 return "add{l}\t%k0, %k0";
9637 if (operands[2] == const1_rtx
9638 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9639 return "sal{l}\t%k0";
9641 return "sal{l}\t{%2, %k0|%k0, %2}";
9645 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9646 (match_operand 2 "const1_operand"))
9647 (const_string "alu")
9649 (const_string "ishift")))
9650 (set (attr "length_immediate")
9652 (ior (eq_attr "type" "alu")
9653 (and (eq_attr "type" "ishift")
9654 (and (match_operand 2 "const1_operand")
9655 (ior (match_test "TARGET_SHIFT1")
9656 (match_test "optimize_function_for_size_p (cfun)")))))
9658 (const_string "*")))
9659 (set_attr "mode" "SI")])
9661 (define_insn "*ashl<mode>3_cconly"
9662 [(set (reg FLAGS_REG)
9664 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9665 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9667 (clobber (match_scratch:SWI 0 "=<r>"))]
9668 "(optimize_function_for_size_p (cfun)
9669 || !TARGET_PARTIAL_FLAG_REG_STALL
9670 || (operands[2] == const1_rtx
9672 || TARGET_DOUBLE_WITH_ADD)))
9673 && ix86_match_ccmode (insn, CCGOCmode)"
9675 switch (get_attr_type (insn))
9678 gcc_assert (operands[2] == const1_rtx);
9679 return "add{<imodesuffix>}\t%0, %0";
9682 if (operands[2] == const1_rtx
9683 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9684 return "sal{<imodesuffix>}\t%0";
9686 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9690 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9691 (match_operand 0 "register_operand"))
9692 (match_operand 2 "const1_operand"))
9693 (const_string "alu")
9695 (const_string "ishift")))
9696 (set (attr "length_immediate")
9698 (ior (eq_attr "type" "alu")
9699 (and (eq_attr "type" "ishift")
9700 (and (match_operand 2 "const1_operand")
9701 (ior (match_test "TARGET_SHIFT1")
9702 (match_test "optimize_function_for_size_p (cfun)")))))
9704 (const_string "*")))
9705 (set_attr "mode" "<MODE>")])
9707 ;; See comment above `ashl<mode>3' about how this works.
9709 (define_expand "<shift_insn><mode>3"
9710 [(set (match_operand:SDWIM 0 "<shift_operand>")
9711 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9712 (match_operand:QI 2 "nonmemory_operand")))]
9714 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9716 ;; Avoid useless masking of count operand.
9717 (define_insn "*<shift_insn><mode>3_mask"
9718 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9720 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9723 (match_operand:SI 2 "register_operand" "c")
9724 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9725 (clobber (reg:CC FLAGS_REG))]
9726 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9727 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9728 == GET_MODE_BITSIZE (<MODE>mode)-1"
9730 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9732 [(set_attr "type" "ishift")
9733 (set_attr "mode" "<MODE>")])
9735 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9736 [(set (match_operand:DWI 0 "register_operand" "=r")
9737 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9738 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9739 (clobber (reg:CC FLAGS_REG))]
9742 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9744 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9745 [(set_attr "type" "multi")])
9747 ;; By default we don't ask for a scratch register, because when DWImode
9748 ;; values are manipulated, registers are already at a premium. But if
9749 ;; we have one handy, we won't turn it away.
9752 [(match_scratch:DWIH 3 "r")
9753 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9755 (match_operand:<DWI> 1 "register_operand")
9756 (match_operand:QI 2 "nonmemory_operand")))
9757 (clobber (reg:CC FLAGS_REG))])
9761 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9763 (define_insn "x86_64_shrd"
9764 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9765 (ior:DI (lshiftrt:DI (match_dup 0)
9766 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9767 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9768 (minus:QI (const_int 64) (match_dup 2)))))
9769 (clobber (reg:CC FLAGS_REG))]
9771 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9772 [(set_attr "type" "ishift")
9773 (set_attr "prefix_0f" "1")
9774 (set_attr "mode" "DI")
9775 (set_attr "athlon_decode" "vector")
9776 (set_attr "amdfam10_decode" "vector")
9777 (set_attr "bdver1_decode" "vector")])
9779 (define_insn "x86_shrd"
9780 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9781 (ior:SI (lshiftrt:SI (match_dup 0)
9782 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9783 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9784 (minus:QI (const_int 32) (match_dup 2)))))
9785 (clobber (reg:CC FLAGS_REG))]
9787 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9788 [(set_attr "type" "ishift")
9789 (set_attr "prefix_0f" "1")
9790 (set_attr "mode" "SI")
9791 (set_attr "pent_pair" "np")
9792 (set_attr "athlon_decode" "vector")
9793 (set_attr "amdfam10_decode" "vector")
9794 (set_attr "bdver1_decode" "vector")])
9796 (define_insn "ashrdi3_cvt"
9797 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9798 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9799 (match_operand:QI 2 "const_int_operand")))
9800 (clobber (reg:CC FLAGS_REG))]
9801 "TARGET_64BIT && INTVAL (operands[2]) == 63
9802 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9803 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9806 sar{q}\t{%2, %0|%0, %2}"
9807 [(set_attr "type" "imovx,ishift")
9808 (set_attr "prefix_0f" "0,*")
9809 (set_attr "length_immediate" "0,*")
9810 (set_attr "modrm" "0,1")
9811 (set_attr "mode" "DI")])
9813 (define_insn "ashrsi3_cvt"
9814 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9815 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9816 (match_operand:QI 2 "const_int_operand")))
9817 (clobber (reg:CC FLAGS_REG))]
9818 "INTVAL (operands[2]) == 31
9819 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9820 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9823 sar{l}\t{%2, %0|%0, %2}"
9824 [(set_attr "type" "imovx,ishift")
9825 (set_attr "prefix_0f" "0,*")
9826 (set_attr "length_immediate" "0,*")
9827 (set_attr "modrm" "0,1")
9828 (set_attr "mode" "SI")])
9830 (define_insn "*ashrsi3_cvt_zext"
9831 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9833 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9834 (match_operand:QI 2 "const_int_operand"))))
9835 (clobber (reg:CC FLAGS_REG))]
9836 "TARGET_64BIT && INTVAL (operands[2]) == 31
9837 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9838 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9841 sar{l}\t{%2, %k0|%k0, %2}"
9842 [(set_attr "type" "imovx,ishift")
9843 (set_attr "prefix_0f" "0,*")
9844 (set_attr "length_immediate" "0,*")
9845 (set_attr "modrm" "0,1")
9846 (set_attr "mode" "SI")])
9848 (define_expand "x86_shift<mode>_adj_3"
9849 [(use (match_operand:SWI48 0 "register_operand"))
9850 (use (match_operand:SWI48 1 "register_operand"))
9851 (use (match_operand:QI 2 "register_operand"))]
9854 rtx label = gen_label_rtx ();
9857 emit_insn (gen_testqi_ccz_1 (operands[2],
9858 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9860 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9861 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9862 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9863 gen_rtx_LABEL_REF (VOIDmode, label),
9865 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9866 JUMP_LABEL (tmp) = label;
9868 emit_move_insn (operands[0], operands[1]);
9869 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9870 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9872 LABEL_NUSES (label) = 1;
9877 (define_insn "*bmi2_<shift_insn><mode>3_1"
9878 [(set (match_operand:SWI48 0 "register_operand" "=r")
9879 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9880 (match_operand:SWI48 2 "register_operand" "r")))]
9882 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9883 [(set_attr "type" "ishiftx")
9884 (set_attr "mode" "<MODE>")])
9886 (define_insn "*<shift_insn><mode>3_1"
9887 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9889 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9890 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9891 (clobber (reg:CC FLAGS_REG))]
9892 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9894 switch (get_attr_type (insn))
9900 if (operands[2] == const1_rtx
9901 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9902 return "<shift>{<imodesuffix>}\t%0";
9904 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9907 [(set_attr "isa" "*,bmi2")
9908 (set_attr "type" "ishift,ishiftx")
9909 (set (attr "length_immediate")
9911 (and (match_operand 2 "const1_operand")
9912 (ior (match_test "TARGET_SHIFT1")
9913 (match_test "optimize_function_for_size_p (cfun)")))
9915 (const_string "*")))
9916 (set_attr "mode" "<MODE>")])
9918 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9920 [(set (match_operand:SWI48 0 "register_operand")
9921 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9922 (match_operand:QI 2 "register_operand")))
9923 (clobber (reg:CC FLAGS_REG))]
9924 "TARGET_BMI2 && reload_completed"
9926 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9927 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9929 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9930 [(set (match_operand:DI 0 "register_operand" "=r")
9932 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9933 (match_operand:SI 2 "register_operand" "r"))))]
9934 "TARGET_64BIT && TARGET_BMI2"
9935 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9936 [(set_attr "type" "ishiftx")
9937 (set_attr "mode" "SI")])
9939 (define_insn "*<shift_insn>si3_1_zext"
9940 [(set (match_operand:DI 0 "register_operand" "=r,r")
9942 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9943 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9944 (clobber (reg:CC FLAGS_REG))]
9945 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9947 switch (get_attr_type (insn))
9953 if (operands[2] == const1_rtx
9954 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9955 return "<shift>{l}\t%k0";
9957 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9960 [(set_attr "isa" "*,bmi2")
9961 (set_attr "type" "ishift,ishiftx")
9962 (set (attr "length_immediate")
9964 (and (match_operand 2 "const1_operand")
9965 (ior (match_test "TARGET_SHIFT1")
9966 (match_test "optimize_function_for_size_p (cfun)")))
9968 (const_string "*")))
9969 (set_attr "mode" "SI")])
9971 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9973 [(set (match_operand:DI 0 "register_operand")
9975 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9976 (match_operand:QI 2 "register_operand"))))
9977 (clobber (reg:CC FLAGS_REG))]
9978 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9980 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9981 "operands[2] = gen_lowpart (SImode, operands[2]);")
9983 (define_insn "*<shift_insn><mode>3_1"
9984 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9986 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9987 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9988 (clobber (reg:CC FLAGS_REG))]
9989 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9991 if (operands[2] == const1_rtx
9992 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9993 return "<shift>{<imodesuffix>}\t%0";
9995 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9997 [(set_attr "type" "ishift")
9998 (set (attr "length_immediate")
10000 (and (match_operand 2 "const1_operand")
10001 (ior (match_test "TARGET_SHIFT1")
10002 (match_test "optimize_function_for_size_p (cfun)")))
10004 (const_string "*")))
10005 (set_attr "mode" "<MODE>")])
10007 (define_insn "*<shift_insn>qi3_1_slp"
10008 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10009 (any_shiftrt:QI (match_dup 0)
10010 (match_operand:QI 1 "nonmemory_operand" "cI")))
10011 (clobber (reg:CC FLAGS_REG))]
10012 "(optimize_function_for_size_p (cfun)
10013 || !TARGET_PARTIAL_REG_STALL
10014 || (operands[1] == const1_rtx
10015 && TARGET_SHIFT1))"
10017 if (operands[1] == const1_rtx
10018 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10019 return "<shift>{b}\t%0";
10021 return "<shift>{b}\t{%1, %0|%0, %1}";
10023 [(set_attr "type" "ishift1")
10024 (set (attr "length_immediate")
10026 (and (match_operand 1 "const1_operand")
10027 (ior (match_test "TARGET_SHIFT1")
10028 (match_test "optimize_function_for_size_p (cfun)")))
10030 (const_string "*")))
10031 (set_attr "mode" "QI")])
10033 ;; This pattern can't accept a variable shift count, since shifts by
10034 ;; zero don't affect the flags. We assume that shifts by constant
10035 ;; zero are optimized away.
10036 (define_insn "*<shift_insn><mode>3_cmp"
10037 [(set (reg FLAGS_REG)
10040 (match_operand:SWI 1 "nonimmediate_operand" "0")
10041 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10043 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10044 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10045 "(optimize_function_for_size_p (cfun)
10046 || !TARGET_PARTIAL_FLAG_REG_STALL
10047 || (operands[2] == const1_rtx
10049 && ix86_match_ccmode (insn, CCGOCmode)
10050 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10052 if (operands[2] == const1_rtx
10053 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10054 return "<shift>{<imodesuffix>}\t%0";
10056 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10058 [(set_attr "type" "ishift")
10059 (set (attr "length_immediate")
10061 (and (match_operand 2 "const1_operand")
10062 (ior (match_test "TARGET_SHIFT1")
10063 (match_test "optimize_function_for_size_p (cfun)")))
10065 (const_string "*")))
10066 (set_attr "mode" "<MODE>")])
10068 (define_insn "*<shift_insn>si3_cmp_zext"
10069 [(set (reg FLAGS_REG)
10071 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10072 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10074 (set (match_operand:DI 0 "register_operand" "=r")
10075 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10077 && (optimize_function_for_size_p (cfun)
10078 || !TARGET_PARTIAL_FLAG_REG_STALL
10079 || (operands[2] == const1_rtx
10081 && ix86_match_ccmode (insn, CCGOCmode)
10082 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10084 if (operands[2] == const1_rtx
10085 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10086 return "<shift>{l}\t%k0";
10088 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10090 [(set_attr "type" "ishift")
10091 (set (attr "length_immediate")
10093 (and (match_operand 2 "const1_operand")
10094 (ior (match_test "TARGET_SHIFT1")
10095 (match_test "optimize_function_for_size_p (cfun)")))
10097 (const_string "*")))
10098 (set_attr "mode" "SI")])
10100 (define_insn "*<shift_insn><mode>3_cconly"
10101 [(set (reg FLAGS_REG)
10104 (match_operand:SWI 1 "register_operand" "0")
10105 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10107 (clobber (match_scratch:SWI 0 "=<r>"))]
10108 "(optimize_function_for_size_p (cfun)
10109 || !TARGET_PARTIAL_FLAG_REG_STALL
10110 || (operands[2] == const1_rtx
10112 && ix86_match_ccmode (insn, CCGOCmode)"
10114 if (operands[2] == const1_rtx
10115 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10116 return "<shift>{<imodesuffix>}\t%0";
10118 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10120 [(set_attr "type" "ishift")
10121 (set (attr "length_immediate")
10123 (and (match_operand 2 "const1_operand")
10124 (ior (match_test "TARGET_SHIFT1")
10125 (match_test "optimize_function_for_size_p (cfun)")))
10127 (const_string "*")))
10128 (set_attr "mode" "<MODE>")])
10130 ;; Rotate instructions
10132 (define_expand "<rotate_insn>ti3"
10133 [(set (match_operand:TI 0 "register_operand")
10134 (any_rotate:TI (match_operand:TI 1 "register_operand")
10135 (match_operand:QI 2 "nonmemory_operand")))]
10138 if (const_1_to_63_operand (operands[2], VOIDmode))
10139 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10140 (operands[0], operands[1], operands[2]));
10147 (define_expand "<rotate_insn>di3"
10148 [(set (match_operand:DI 0 "shiftdi_operand")
10149 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10150 (match_operand:QI 2 "nonmemory_operand")))]
10154 ix86_expand_binary_operator (<CODE>, DImode, operands);
10155 else if (const_1_to_31_operand (operands[2], VOIDmode))
10156 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10157 (operands[0], operands[1], operands[2]));
10164 (define_expand "<rotate_insn><mode>3"
10165 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10166 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10167 (match_operand:QI 2 "nonmemory_operand")))]
10169 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10171 ;; Avoid useless masking of count operand.
10172 (define_insn "*<rotate_insn><mode>3_mask"
10173 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10175 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10178 (match_operand:SI 2 "register_operand" "c")
10179 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10182 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10183 == GET_MODE_BITSIZE (<MODE>mode)-1"
10185 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10187 [(set_attr "type" "rotate")
10188 (set_attr "mode" "<MODE>")])
10190 ;; Implement rotation using two double-precision
10191 ;; shift instructions and a scratch register.
10193 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10194 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10195 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10196 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10197 (clobber (reg:CC FLAGS_REG))
10198 (clobber (match_scratch:DWIH 3 "=&r"))]
10202 [(set (match_dup 3) (match_dup 4))
10204 [(set (match_dup 4)
10205 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10206 (lshiftrt:DWIH (match_dup 5)
10207 (minus:QI (match_dup 6) (match_dup 2)))))
10208 (clobber (reg:CC FLAGS_REG))])
10210 [(set (match_dup 5)
10211 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10212 (lshiftrt:DWIH (match_dup 3)
10213 (minus:QI (match_dup 6) (match_dup 2)))))
10214 (clobber (reg:CC FLAGS_REG))])]
10216 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10218 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10221 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10222 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10223 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10224 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10225 (clobber (reg:CC FLAGS_REG))
10226 (clobber (match_scratch:DWIH 3 "=&r"))]
10230 [(set (match_dup 3) (match_dup 4))
10232 [(set (match_dup 4)
10233 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10234 (ashift:DWIH (match_dup 5)
10235 (minus:QI (match_dup 6) (match_dup 2)))))
10236 (clobber (reg:CC FLAGS_REG))])
10238 [(set (match_dup 5)
10239 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10240 (ashift:DWIH (match_dup 3)
10241 (minus:QI (match_dup 6) (match_dup 2)))))
10242 (clobber (reg:CC FLAGS_REG))])]
10244 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10246 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10249 (define_insn "*bmi2_rorx<mode>3_1"
10250 [(set (match_operand:SWI48 0 "register_operand" "=r")
10251 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10252 (match_operand:QI 2 "immediate_operand" "<S>")))]
10254 "rorx\t{%2, %1, %0|%0, %1, %2}"
10255 [(set_attr "type" "rotatex")
10256 (set_attr "mode" "<MODE>")])
10258 (define_insn "*<rotate_insn><mode>3_1"
10259 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10261 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10262 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10263 (clobber (reg:CC FLAGS_REG))]
10264 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10266 switch (get_attr_type (insn))
10272 if (operands[2] == const1_rtx
10273 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10274 return "<rotate>{<imodesuffix>}\t%0";
10276 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10279 [(set_attr "isa" "*,bmi2")
10280 (set_attr "type" "rotate,rotatex")
10281 (set (attr "length_immediate")
10283 (and (eq_attr "type" "rotate")
10284 (and (match_operand 2 "const1_operand")
10285 (ior (match_test "TARGET_SHIFT1")
10286 (match_test "optimize_function_for_size_p (cfun)"))))
10288 (const_string "*")))
10289 (set_attr "mode" "<MODE>")])
10291 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10293 [(set (match_operand:SWI48 0 "register_operand")
10294 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10295 (match_operand:QI 2 "immediate_operand")))
10296 (clobber (reg:CC FLAGS_REG))]
10297 "TARGET_BMI2 && reload_completed"
10298 [(set (match_dup 0)
10299 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10302 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10306 [(set (match_operand:SWI48 0 "register_operand")
10307 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10308 (match_operand:QI 2 "immediate_operand")))
10309 (clobber (reg:CC FLAGS_REG))]
10310 "TARGET_BMI2 && reload_completed"
10311 [(set (match_dup 0)
10312 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10314 (define_insn "*bmi2_rorxsi3_1_zext"
10315 [(set (match_operand:DI 0 "register_operand" "=r")
10317 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10318 (match_operand:QI 2 "immediate_operand" "I"))))]
10319 "TARGET_64BIT && TARGET_BMI2"
10320 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10321 [(set_attr "type" "rotatex")
10322 (set_attr "mode" "SI")])
10324 (define_insn "*<rotate_insn>si3_1_zext"
10325 [(set (match_operand:DI 0 "register_operand" "=r,r")
10327 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10328 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10329 (clobber (reg:CC FLAGS_REG))]
10330 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10332 switch (get_attr_type (insn))
10338 if (operands[2] == const1_rtx
10339 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10340 return "<rotate>{l}\t%k0";
10342 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10345 [(set_attr "isa" "*,bmi2")
10346 (set_attr "type" "rotate,rotatex")
10347 (set (attr "length_immediate")
10349 (and (eq_attr "type" "rotate")
10350 (and (match_operand 2 "const1_operand")
10351 (ior (match_test "TARGET_SHIFT1")
10352 (match_test "optimize_function_for_size_p (cfun)"))))
10354 (const_string "*")))
10355 (set_attr "mode" "SI")])
10357 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10359 [(set (match_operand:DI 0 "register_operand")
10361 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10362 (match_operand:QI 2 "immediate_operand"))))
10363 (clobber (reg:CC FLAGS_REG))]
10364 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10365 [(set (match_dup 0)
10366 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10369 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10373 [(set (match_operand:DI 0 "register_operand")
10375 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10376 (match_operand:QI 2 "immediate_operand"))))
10377 (clobber (reg:CC FLAGS_REG))]
10378 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10379 [(set (match_dup 0)
10380 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10382 (define_insn "*<rotate_insn><mode>3_1"
10383 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10384 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10385 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10386 (clobber (reg:CC FLAGS_REG))]
10387 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10389 if (operands[2] == const1_rtx
10390 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10391 return "<rotate>{<imodesuffix>}\t%0";
10393 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10395 [(set_attr "type" "rotate")
10396 (set (attr "length_immediate")
10398 (and (match_operand 2 "const1_operand")
10399 (ior (match_test "TARGET_SHIFT1")
10400 (match_test "optimize_function_for_size_p (cfun)")))
10402 (const_string "*")))
10403 (set_attr "mode" "<MODE>")])
10405 (define_insn "*<rotate_insn>qi3_1_slp"
10406 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10407 (any_rotate:QI (match_dup 0)
10408 (match_operand:QI 1 "nonmemory_operand" "cI")))
10409 (clobber (reg:CC FLAGS_REG))]
10410 "(optimize_function_for_size_p (cfun)
10411 || !TARGET_PARTIAL_REG_STALL
10412 || (operands[1] == const1_rtx
10413 && TARGET_SHIFT1))"
10415 if (operands[1] == const1_rtx
10416 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10417 return "<rotate>{b}\t%0";
10419 return "<rotate>{b}\t{%1, %0|%0, %1}";
10421 [(set_attr "type" "rotate1")
10422 (set (attr "length_immediate")
10424 (and (match_operand 1 "const1_operand")
10425 (ior (match_test "TARGET_SHIFT1")
10426 (match_test "optimize_function_for_size_p (cfun)")))
10428 (const_string "*")))
10429 (set_attr "mode" "QI")])
10432 [(set (match_operand:HI 0 "register_operand")
10433 (any_rotate:HI (match_dup 0) (const_int 8)))
10434 (clobber (reg:CC FLAGS_REG))]
10436 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10437 [(parallel [(set (strict_low_part (match_dup 0))
10438 (bswap:HI (match_dup 0)))
10439 (clobber (reg:CC FLAGS_REG))])])
10441 ;; Bit set / bit test instructions
10443 (define_expand "extv"
10444 [(set (match_operand:SI 0 "register_operand")
10445 (sign_extract:SI (match_operand:SI 1 "register_operand")
10446 (match_operand:SI 2 "const8_operand")
10447 (match_operand:SI 3 "const8_operand")))]
10450 /* Handle extractions from %ah et al. */
10451 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10454 /* From mips.md: extract_bit_field doesn't verify that our source
10455 matches the predicate, so check it again here. */
10456 if (! ext_register_operand (operands[1], VOIDmode))
10460 (define_expand "extzv"
10461 [(set (match_operand:SI 0 "register_operand")
10462 (zero_extract:SI (match_operand 1 "ext_register_operand")
10463 (match_operand:SI 2 "const8_operand")
10464 (match_operand:SI 3 "const8_operand")))]
10467 /* Handle extractions from %ah et al. */
10468 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10471 /* From mips.md: extract_bit_field doesn't verify that our source
10472 matches the predicate, so check it again here. */
10473 if (! ext_register_operand (operands[1], VOIDmode))
10477 (define_expand "insv"
10478 [(set (zero_extract (match_operand 0 "register_operand")
10479 (match_operand 1 "const_int_operand")
10480 (match_operand 2 "const_int_operand"))
10481 (match_operand 3 "register_operand"))]
10484 rtx (*gen_mov_insv_1) (rtx, rtx);
10486 if (ix86_expand_pinsr (operands))
10489 /* Handle insertions to %ah et al. */
10490 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10493 /* From mips.md: insert_bit_field doesn't verify that our source
10494 matches the predicate, so check it again here. */
10495 if (! ext_register_operand (operands[0], VOIDmode))
10498 gen_mov_insv_1 = (TARGET_64BIT
10499 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10501 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10505 ;; %%% bts, btr, btc, bt.
10506 ;; In general these instructions are *slow* when applied to memory,
10507 ;; since they enforce atomic operation. When applied to registers,
10508 ;; it depends on the cpu implementation. They're never faster than
10509 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10510 ;; no point. But in 64-bit, we can't hold the relevant immediates
10511 ;; within the instruction itself, so operating on bits in the high
10512 ;; 32-bits of a register becomes easier.
10514 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10515 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10516 ;; negdf respectively, so they can never be disabled entirely.
10518 (define_insn "*btsq"
10519 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10521 (match_operand:DI 1 "const_0_to_63_operand"))
10523 (clobber (reg:CC FLAGS_REG))]
10524 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10525 "bts{q}\t{%1, %0|%0, %1}"
10526 [(set_attr "type" "alu1")
10527 (set_attr "prefix_0f" "1")
10528 (set_attr "mode" "DI")])
10530 (define_insn "*btrq"
10531 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10533 (match_operand:DI 1 "const_0_to_63_operand"))
10535 (clobber (reg:CC FLAGS_REG))]
10536 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10537 "btr{q}\t{%1, %0|%0, %1}"
10538 [(set_attr "type" "alu1")
10539 (set_attr "prefix_0f" "1")
10540 (set_attr "mode" "DI")])
10542 (define_insn "*btcq"
10543 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10545 (match_operand:DI 1 "const_0_to_63_operand"))
10546 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10547 (clobber (reg:CC FLAGS_REG))]
10548 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10549 "btc{q}\t{%1, %0|%0, %1}"
10550 [(set_attr "type" "alu1")
10551 (set_attr "prefix_0f" "1")
10552 (set_attr "mode" "DI")])
10554 ;; Allow Nocona to avoid these instructions if a register is available.
10557 [(match_scratch:DI 2 "r")
10558 (parallel [(set (zero_extract:DI
10559 (match_operand:DI 0 "register_operand")
10561 (match_operand:DI 1 "const_0_to_63_operand"))
10563 (clobber (reg:CC FLAGS_REG))])]
10564 "TARGET_64BIT && !TARGET_USE_BT"
10567 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10570 if (HOST_BITS_PER_WIDE_INT >= 64)
10571 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10572 else if (i < HOST_BITS_PER_WIDE_INT)
10573 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10575 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10577 op1 = immed_double_const (lo, hi, DImode);
10580 emit_move_insn (operands[2], op1);
10584 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10589 [(match_scratch:DI 2 "r")
10590 (parallel [(set (zero_extract:DI
10591 (match_operand:DI 0 "register_operand")
10593 (match_operand:DI 1 "const_0_to_63_operand"))
10595 (clobber (reg:CC FLAGS_REG))])]
10596 "TARGET_64BIT && !TARGET_USE_BT"
10599 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10602 if (HOST_BITS_PER_WIDE_INT >= 64)
10603 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10604 else if (i < HOST_BITS_PER_WIDE_INT)
10605 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10607 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10609 op1 = immed_double_const (~lo, ~hi, DImode);
10612 emit_move_insn (operands[2], op1);
10616 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10621 [(match_scratch:DI 2 "r")
10622 (parallel [(set (zero_extract:DI
10623 (match_operand:DI 0 "register_operand")
10625 (match_operand:DI 1 "const_0_to_63_operand"))
10626 (not:DI (zero_extract:DI
10627 (match_dup 0) (const_int 1) (match_dup 1))))
10628 (clobber (reg:CC FLAGS_REG))])]
10629 "TARGET_64BIT && !TARGET_USE_BT"
10632 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10635 if (HOST_BITS_PER_WIDE_INT >= 64)
10636 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10637 else if (i < HOST_BITS_PER_WIDE_INT)
10638 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10640 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10642 op1 = immed_double_const (lo, hi, DImode);
10645 emit_move_insn (operands[2], op1);
10649 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10653 (define_insn "*bt<mode>"
10654 [(set (reg:CCC FLAGS_REG)
10656 (zero_extract:SWI48
10657 (match_operand:SWI48 0 "register_operand" "r")
10659 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10661 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10662 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10663 [(set_attr "type" "alu1")
10664 (set_attr "prefix_0f" "1")
10665 (set_attr "mode" "<MODE>")])
10667 ;; Store-flag instructions.
10669 ;; For all sCOND expanders, also expand the compare or test insn that
10670 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10672 (define_insn_and_split "*setcc_di_1"
10673 [(set (match_operand:DI 0 "register_operand" "=q")
10674 (match_operator:DI 1 "ix86_comparison_operator"
10675 [(reg FLAGS_REG) (const_int 0)]))]
10676 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10678 "&& reload_completed"
10679 [(set (match_dup 2) (match_dup 1))
10680 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10682 PUT_MODE (operands[1], QImode);
10683 operands[2] = gen_lowpart (QImode, operands[0]);
10686 (define_insn_and_split "*setcc_si_1_and"
10687 [(set (match_operand:SI 0 "register_operand" "=q")
10688 (match_operator:SI 1 "ix86_comparison_operator"
10689 [(reg FLAGS_REG) (const_int 0)]))
10690 (clobber (reg:CC FLAGS_REG))]
10691 "!TARGET_PARTIAL_REG_STALL
10692 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10694 "&& reload_completed"
10695 [(set (match_dup 2) (match_dup 1))
10696 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10697 (clobber (reg:CC FLAGS_REG))])]
10699 PUT_MODE (operands[1], QImode);
10700 operands[2] = gen_lowpart (QImode, operands[0]);
10703 (define_insn_and_split "*setcc_si_1_movzbl"
10704 [(set (match_operand:SI 0 "register_operand" "=q")
10705 (match_operator:SI 1 "ix86_comparison_operator"
10706 [(reg FLAGS_REG) (const_int 0)]))]
10707 "!TARGET_PARTIAL_REG_STALL
10708 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10710 "&& reload_completed"
10711 [(set (match_dup 2) (match_dup 1))
10712 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10714 PUT_MODE (operands[1], QImode);
10715 operands[2] = gen_lowpart (QImode, operands[0]);
10718 (define_insn "*setcc_qi"
10719 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10720 (match_operator:QI 1 "ix86_comparison_operator"
10721 [(reg FLAGS_REG) (const_int 0)]))]
10724 [(set_attr "type" "setcc")
10725 (set_attr "mode" "QI")])
10727 (define_insn "*setcc_qi_slp"
10728 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10729 (match_operator:QI 1 "ix86_comparison_operator"
10730 [(reg FLAGS_REG) (const_int 0)]))]
10733 [(set_attr "type" "setcc")
10734 (set_attr "mode" "QI")])
10736 ;; In general it is not safe to assume too much about CCmode registers,
10737 ;; so simplify-rtx stops when it sees a second one. Under certain
10738 ;; conditions this is safe on x86, so help combine not create
10745 [(set (match_operand:QI 0 "nonimmediate_operand")
10746 (ne:QI (match_operator 1 "ix86_comparison_operator"
10747 [(reg FLAGS_REG) (const_int 0)])
10750 [(set (match_dup 0) (match_dup 1))]
10751 "PUT_MODE (operands[1], QImode);")
10754 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10755 (ne:QI (match_operator 1 "ix86_comparison_operator"
10756 [(reg FLAGS_REG) (const_int 0)])
10759 [(set (match_dup 0) (match_dup 1))]
10760 "PUT_MODE (operands[1], QImode);")
10763 [(set (match_operand:QI 0 "nonimmediate_operand")
10764 (eq:QI (match_operator 1 "ix86_comparison_operator"
10765 [(reg FLAGS_REG) (const_int 0)])
10768 [(set (match_dup 0) (match_dup 1))]
10770 rtx new_op1 = copy_rtx (operands[1]);
10771 operands[1] = new_op1;
10772 PUT_MODE (new_op1, QImode);
10773 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10774 GET_MODE (XEXP (new_op1, 0))));
10776 /* Make sure that (a) the CCmode we have for the flags is strong
10777 enough for the reversed compare or (b) we have a valid FP compare. */
10778 if (! ix86_comparison_operator (new_op1, VOIDmode))
10783 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10784 (eq:QI (match_operator 1 "ix86_comparison_operator"
10785 [(reg FLAGS_REG) (const_int 0)])
10788 [(set (match_dup 0) (match_dup 1))]
10790 rtx new_op1 = copy_rtx (operands[1]);
10791 operands[1] = new_op1;
10792 PUT_MODE (new_op1, QImode);
10793 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10794 GET_MODE (XEXP (new_op1, 0))));
10796 /* Make sure that (a) the CCmode we have for the flags is strong
10797 enough for the reversed compare or (b) we have a valid FP compare. */
10798 if (! ix86_comparison_operator (new_op1, VOIDmode))
10802 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10803 ;; subsequent logical operations are used to imitate conditional moves.
10804 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10807 (define_insn "setcc_<mode>_sse"
10808 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10809 (match_operator:MODEF 3 "sse_comparison_operator"
10810 [(match_operand:MODEF 1 "register_operand" "0,x")
10811 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10812 "SSE_FLOAT_MODE_P (<MODE>mode)"
10814 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10815 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10816 [(set_attr "isa" "noavx,avx")
10817 (set_attr "type" "ssecmp")
10818 (set_attr "length_immediate" "1")
10819 (set_attr "prefix" "orig,vex")
10820 (set_attr "mode" "<MODE>")])
10822 ;; Basic conditional jump instructions.
10823 ;; We ignore the overflow flag for signed branch instructions.
10825 (define_insn "*jcc_1"
10827 (if_then_else (match_operator 1 "ix86_comparison_operator"
10828 [(reg FLAGS_REG) (const_int 0)])
10829 (label_ref (match_operand 0))
10833 [(set_attr "type" "ibr")
10834 (set_attr "modrm" "0")
10835 (set (attr "length")
10836 (if_then_else (and (ge (minus (match_dup 0) (pc))
10838 (lt (minus (match_dup 0) (pc))
10843 (define_insn "*jcc_2"
10845 (if_then_else (match_operator 1 "ix86_comparison_operator"
10846 [(reg FLAGS_REG) (const_int 0)])
10848 (label_ref (match_operand 0))))]
10851 [(set_attr "type" "ibr")
10852 (set_attr "modrm" "0")
10853 (set (attr "length")
10854 (if_then_else (and (ge (minus (match_dup 0) (pc))
10856 (lt (minus (match_dup 0) (pc))
10861 ;; In general it is not safe to assume too much about CCmode registers,
10862 ;; so simplify-rtx stops when it sees a second one. Under certain
10863 ;; conditions this is safe on x86, so help combine not create
10871 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10872 [(reg FLAGS_REG) (const_int 0)])
10874 (label_ref (match_operand 1))
10878 (if_then_else (match_dup 0)
10879 (label_ref (match_dup 1))
10881 "PUT_MODE (operands[0], VOIDmode);")
10885 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10886 [(reg FLAGS_REG) (const_int 0)])
10888 (label_ref (match_operand 1))
10892 (if_then_else (match_dup 0)
10893 (label_ref (match_dup 1))
10896 rtx new_op0 = copy_rtx (operands[0]);
10897 operands[0] = new_op0;
10898 PUT_MODE (new_op0, VOIDmode);
10899 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10900 GET_MODE (XEXP (new_op0, 0))));
10902 /* Make sure that (a) the CCmode we have for the flags is strong
10903 enough for the reversed compare or (b) we have a valid FP compare. */
10904 if (! ix86_comparison_operator (new_op0, VOIDmode))
10908 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10909 ;; pass generates from shift insn with QImode operand. Actually, the mode
10910 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10911 ;; appropriate modulo of the bit offset value.
10913 (define_insn_and_split "*jcc_bt<mode>"
10915 (if_then_else (match_operator 0 "bt_comparison_operator"
10916 [(zero_extract:SWI48
10917 (match_operand:SWI48 1 "register_operand" "r")
10920 (match_operand:QI 2 "register_operand" "r")))
10922 (label_ref (match_operand 3))
10924 (clobber (reg:CC FLAGS_REG))]
10925 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10928 [(set (reg:CCC FLAGS_REG)
10930 (zero_extract:SWI48
10936 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10937 (label_ref (match_dup 3))
10940 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10942 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10945 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10946 ;; zero extended to SImode.
10947 (define_insn_and_split "*jcc_bt<mode>_1"
10949 (if_then_else (match_operator 0 "bt_comparison_operator"
10950 [(zero_extract:SWI48
10951 (match_operand:SWI48 1 "register_operand" "r")
10953 (match_operand:SI 2 "register_operand" "r"))
10955 (label_ref (match_operand 3))
10957 (clobber (reg:CC FLAGS_REG))]
10958 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10961 [(set (reg:CCC FLAGS_REG)
10963 (zero_extract:SWI48
10969 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10970 (label_ref (match_dup 3))
10973 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10975 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10978 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10979 ;; also for DImode, this is what combine produces.
10980 (define_insn_and_split "*jcc_bt<mode>_mask"
10982 (if_then_else (match_operator 0 "bt_comparison_operator"
10983 [(zero_extract:SWI48
10984 (match_operand:SWI48 1 "register_operand" "r")
10987 (match_operand:SI 2 "register_operand" "r")
10988 (match_operand:SI 3 "const_int_operand" "n")))])
10989 (label_ref (match_operand 4))
10991 (clobber (reg:CC FLAGS_REG))]
10992 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10993 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10994 == GET_MODE_BITSIZE (<MODE>mode)-1"
10997 [(set (reg:CCC FLAGS_REG)
10999 (zero_extract:SWI48
11005 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11006 (label_ref (match_dup 4))
11009 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11011 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11014 (define_insn_and_split "*jcc_btsi_1"
11016 (if_then_else (match_operator 0 "bt_comparison_operator"
11019 (match_operand:SI 1 "register_operand" "r")
11020 (match_operand:QI 2 "register_operand" "r"))
11023 (label_ref (match_operand 3))
11025 (clobber (reg:CC FLAGS_REG))]
11026 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11029 [(set (reg:CCC FLAGS_REG)
11037 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11038 (label_ref (match_dup 3))
11041 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11043 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11046 ;; avoid useless masking of bit offset operand
11047 (define_insn_and_split "*jcc_btsi_mask_1"
11050 (match_operator 0 "bt_comparison_operator"
11053 (match_operand:SI 1 "register_operand" "r")
11056 (match_operand:SI 2 "register_operand" "r")
11057 (match_operand:SI 3 "const_int_operand" "n")) 0))
11060 (label_ref (match_operand 4))
11062 (clobber (reg:CC FLAGS_REG))]
11063 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11064 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11067 [(set (reg:CCC FLAGS_REG)
11075 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11076 (label_ref (match_dup 4))
11078 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11080 ;; Define combination compare-and-branch fp compare instructions to help
11083 (define_insn "*jcc<mode>_0_i387"
11085 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11086 [(match_operand:X87MODEF 1 "register_operand" "f")
11087 (match_operand:X87MODEF 2 "const0_operand")])
11088 (label_ref (match_operand 3))
11090 (clobber (reg:CCFP FPSR_REG))
11091 (clobber (reg:CCFP FLAGS_REG))
11092 (clobber (match_scratch:HI 4 "=a"))]
11093 "TARGET_80387 && !TARGET_CMOVE"
11096 (define_insn "*jcc<mode>_0_r_i387"
11098 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11099 [(match_operand:X87MODEF 1 "register_operand" "f")
11100 (match_operand:X87MODEF 2 "const0_operand")])
11102 (label_ref (match_operand 3))))
11103 (clobber (reg:CCFP FPSR_REG))
11104 (clobber (reg:CCFP FLAGS_REG))
11105 (clobber (match_scratch:HI 4 "=a"))]
11106 "TARGET_80387 && !TARGET_CMOVE"
11109 (define_insn "*jccxf_i387"
11111 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11112 [(match_operand:XF 1 "register_operand" "f")
11113 (match_operand:XF 2 "register_operand" "f")])
11114 (label_ref (match_operand 3))
11116 (clobber (reg:CCFP FPSR_REG))
11117 (clobber (reg:CCFP FLAGS_REG))
11118 (clobber (match_scratch:HI 4 "=a"))]
11119 "TARGET_80387 && !TARGET_CMOVE"
11122 (define_insn "*jccxf_r_i387"
11124 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11125 [(match_operand:XF 1 "register_operand" "f")
11126 (match_operand:XF 2 "register_operand" "f")])
11128 (label_ref (match_operand 3))))
11129 (clobber (reg:CCFP FPSR_REG))
11130 (clobber (reg:CCFP FLAGS_REG))
11131 (clobber (match_scratch:HI 4 "=a"))]
11132 "TARGET_80387 && !TARGET_CMOVE"
11135 (define_insn "*jcc<mode>_i387"
11137 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11138 [(match_operand:MODEF 1 "register_operand" "f")
11139 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11140 (label_ref (match_operand 3))
11142 (clobber (reg:CCFP FPSR_REG))
11143 (clobber (reg:CCFP FLAGS_REG))
11144 (clobber (match_scratch:HI 4 "=a"))]
11145 "TARGET_80387 && !TARGET_CMOVE"
11148 (define_insn "*jcc<mode>_r_i387"
11150 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11151 [(match_operand:MODEF 1 "register_operand" "f")
11152 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11154 (label_ref (match_operand 3))))
11155 (clobber (reg:CCFP FPSR_REG))
11156 (clobber (reg:CCFP FLAGS_REG))
11157 (clobber (match_scratch:HI 4 "=a"))]
11158 "TARGET_80387 && !TARGET_CMOVE"
11161 (define_insn "*jccu<mode>_i387"
11163 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11164 [(match_operand:X87MODEF 1 "register_operand" "f")
11165 (match_operand:X87MODEF 2 "register_operand" "f")])
11166 (label_ref (match_operand 3))
11168 (clobber (reg:CCFP FPSR_REG))
11169 (clobber (reg:CCFP FLAGS_REG))
11170 (clobber (match_scratch:HI 4 "=a"))]
11171 "TARGET_80387 && !TARGET_CMOVE"
11174 (define_insn "*jccu<mode>_r_i387"
11176 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11177 [(match_operand:X87MODEF 1 "register_operand" "f")
11178 (match_operand:X87MODEF 2 "register_operand" "f")])
11180 (label_ref (match_operand 3))))
11181 (clobber (reg:CCFP FPSR_REG))
11182 (clobber (reg:CCFP FLAGS_REG))
11183 (clobber (match_scratch:HI 4 "=a"))]
11184 "TARGET_80387 && !TARGET_CMOVE"
11189 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11190 [(match_operand:X87MODEF 1 "register_operand")
11191 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11193 (match_operand 4)))
11194 (clobber (reg:CCFP FPSR_REG))
11195 (clobber (reg:CCFP FLAGS_REG))]
11196 "TARGET_80387 && !TARGET_CMOVE
11197 && reload_completed"
11200 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11201 operands[3], operands[4], NULL_RTX);
11207 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11208 [(match_operand:X87MODEF 1 "register_operand")
11209 (match_operand:X87MODEF 2 "general_operand")])
11211 (match_operand 4)))
11212 (clobber (reg:CCFP FPSR_REG))
11213 (clobber (reg:CCFP FLAGS_REG))
11214 (clobber (match_scratch:HI 5))]
11215 "TARGET_80387 && !TARGET_CMOVE
11216 && reload_completed"
11219 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11220 operands[3], operands[4], operands[5]);
11224 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11225 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11226 ;; with a precedence over other operators and is always put in the first
11227 ;; place. Swap condition and operands to match ficom instruction.
11229 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11232 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11233 [(match_operator:X87MODEF 1 "float_operator"
11234 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11235 (match_operand:X87MODEF 3 "register_operand" "f")])
11236 (label_ref (match_operand 4))
11238 (clobber (reg:CCFP FPSR_REG))
11239 (clobber (reg:CCFP FLAGS_REG))
11240 (clobber (match_scratch:HI 5 "=a"))]
11241 "TARGET_80387 && !TARGET_CMOVE
11242 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11243 || optimize_function_for_size_p (cfun))"
11246 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11249 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11250 [(match_operator:X87MODEF 1 "float_operator"
11251 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11252 (match_operand:X87MODEF 3 "register_operand" "f")])
11254 (label_ref (match_operand 4))))
11255 (clobber (reg:CCFP FPSR_REG))
11256 (clobber (reg:CCFP FLAGS_REG))
11257 (clobber (match_scratch:HI 5 "=a"))]
11258 "TARGET_80387 && !TARGET_CMOVE
11259 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11260 || optimize_function_for_size_p (cfun))"
11266 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11267 [(match_operator:X87MODEF 1 "float_operator"
11268 [(match_operand:SWI24 2 "memory_operand")])
11269 (match_operand:X87MODEF 3 "register_operand")])
11271 (match_operand 5)))
11272 (clobber (reg:CCFP FPSR_REG))
11273 (clobber (reg:CCFP FLAGS_REG))
11274 (clobber (match_scratch:HI 6))]
11275 "TARGET_80387 && !TARGET_CMOVE
11276 && reload_completed"
11279 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11280 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11281 operands[4], operands[5], operands[6]);
11285 ;; Unconditional and other jump instructions
11287 (define_insn "jump"
11289 (label_ref (match_operand 0)))]
11292 [(set_attr "type" "ibr")
11293 (set (attr "length")
11294 (if_then_else (and (ge (minus (match_dup 0) (pc))
11296 (lt (minus (match_dup 0) (pc))
11300 (set_attr "modrm" "0")])
11302 (define_expand "indirect_jump"
11303 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11307 operands[0] = convert_memory_address (word_mode, operands[0]);
11310 (define_insn "*indirect_jump"
11311 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11314 [(set_attr "type" "ibr")
11315 (set_attr "length_immediate" "0")])
11317 (define_expand "tablejump"
11318 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11319 (use (label_ref (match_operand 1)))])]
11322 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11323 relative. Convert the relative address to an absolute address. */
11327 enum rtx_code code;
11329 /* We can't use @GOTOFF for text labels on VxWorks;
11330 see gotoff_operand. */
11331 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11335 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11337 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11341 op1 = pic_offset_table_rtx;
11346 op0 = pic_offset_table_rtx;
11350 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11355 operands[0] = convert_memory_address (word_mode, operands[0]);
11358 (define_insn "*tablejump_1"
11359 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11360 (use (label_ref (match_operand 1)))]
11363 [(set_attr "type" "ibr")
11364 (set_attr "length_immediate" "0")])
11366 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11369 [(set (reg FLAGS_REG) (match_operand 0))
11370 (set (match_operand:QI 1 "register_operand")
11371 (match_operator:QI 2 "ix86_comparison_operator"
11372 [(reg FLAGS_REG) (const_int 0)]))
11373 (set (match_operand 3 "q_regs_operand")
11374 (zero_extend (match_dup 1)))]
11375 "(peep2_reg_dead_p (3, operands[1])
11376 || operands_match_p (operands[1], operands[3]))
11377 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11378 [(set (match_dup 4) (match_dup 0))
11379 (set (strict_low_part (match_dup 5))
11382 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11383 operands[5] = gen_lowpart (QImode, operands[3]);
11384 ix86_expand_clear (operands[3]);
11388 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11389 (match_operand 4)])
11390 (set (match_operand:QI 1 "register_operand")
11391 (match_operator:QI 2 "ix86_comparison_operator"
11392 [(reg FLAGS_REG) (const_int 0)]))
11393 (set (match_operand 3 "q_regs_operand")
11394 (zero_extend (match_dup 1)))]
11395 "(peep2_reg_dead_p (3, operands[1])
11396 || operands_match_p (operands[1], operands[3]))
11397 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11398 [(parallel [(set (match_dup 5) (match_dup 0))
11400 (set (strict_low_part (match_dup 6))
11403 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11404 operands[6] = gen_lowpart (QImode, operands[3]);
11405 ix86_expand_clear (operands[3]);
11408 ;; Similar, but match zero extend with andsi3.
11411 [(set (reg FLAGS_REG) (match_operand 0))
11412 (set (match_operand:QI 1 "register_operand")
11413 (match_operator:QI 2 "ix86_comparison_operator"
11414 [(reg FLAGS_REG) (const_int 0)]))
11415 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11416 (and:SI (match_dup 3) (const_int 255)))
11417 (clobber (reg:CC FLAGS_REG))])]
11418 "REGNO (operands[1]) == REGNO (operands[3])
11419 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11420 [(set (match_dup 4) (match_dup 0))
11421 (set (strict_low_part (match_dup 5))
11424 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11425 operands[5] = gen_lowpart (QImode, operands[3]);
11426 ix86_expand_clear (operands[3]);
11430 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11431 (match_operand 4)])
11432 (set (match_operand:QI 1 "register_operand")
11433 (match_operator:QI 2 "ix86_comparison_operator"
11434 [(reg FLAGS_REG) (const_int 0)]))
11435 (parallel [(set (match_operand 3 "q_regs_operand")
11436 (zero_extend (match_dup 1)))
11437 (clobber (reg:CC FLAGS_REG))])]
11438 "(peep2_reg_dead_p (3, operands[1])
11439 || operands_match_p (operands[1], operands[3]))
11440 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11441 [(parallel [(set (match_dup 5) (match_dup 0))
11443 (set (strict_low_part (match_dup 6))
11446 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11447 operands[6] = gen_lowpart (QImode, operands[3]);
11448 ix86_expand_clear (operands[3]);
11451 ;; Call instructions.
11453 ;; The predicates normally associated with named expanders are not properly
11454 ;; checked for calls. This is a bug in the generic code, but it isn't that
11455 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11457 ;; P6 processors will jump to the address after the decrement when %esp
11458 ;; is used as a call operand, so they will execute return address as a code.
11459 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11461 ;; Register constraint for call instruction.
11462 (define_mode_attr c [(SI "l") (DI "r")])
11464 ;; Call subroutine returning no value.
11466 (define_expand "call"
11467 [(call (match_operand:QI 0)
11469 (use (match_operand 2))]
11472 ix86_expand_call (NULL, operands[0], operands[1],
11473 operands[2], NULL, false);
11477 (define_expand "sibcall"
11478 [(call (match_operand:QI 0)
11480 (use (match_operand 2))]
11483 ix86_expand_call (NULL, operands[0], operands[1],
11484 operands[2], NULL, true);
11488 (define_insn "*call"
11489 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11490 (match_operand 1))]
11491 "!SIBLING_CALL_P (insn)"
11492 "* return ix86_output_call_insn (insn, operands[0]);"
11493 [(set_attr "type" "call")])
11495 (define_insn "*call_rex64_ms_sysv"
11496 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11497 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rBwBz"))
11499 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11500 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11501 "* return ix86_output_call_insn (insn, operands[0]);"
11502 [(set_attr "type" "call")])
11504 (define_insn "*sibcall"
11505 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11506 (match_operand 1))]
11507 "SIBLING_CALL_P (insn)"
11508 "* return ix86_output_call_insn (insn, operands[0]);"
11509 [(set_attr "type" "call")])
11511 (define_insn "*sibcall_memory"
11512 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11514 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11516 "* return ix86_output_call_insn (insn, operands[0]);"
11517 [(set_attr "type" "call")])
11520 [(set (match_operand:W 0 "register_operand")
11521 (match_operand:W 1 "memory_operand"))
11522 (call (mem:QI (match_dup 0))
11523 (match_operand 3))]
11524 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11525 && peep2_reg_dead_p (2, operands[0])"
11526 [(parallel [(call (mem:QI (match_dup 1))
11528 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11531 [(set (match_operand:W 0 "register_operand")
11532 (match_operand:W 1 "memory_operand"))
11533 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11534 (call (mem:QI (match_dup 0))
11535 (match_operand 3))]
11536 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11537 && peep2_reg_dead_p (3, operands[0])"
11538 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11539 (parallel [(call (mem:QI (match_dup 1))
11541 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11543 (define_expand "call_pop"
11544 [(parallel [(call (match_operand:QI 0)
11545 (match_operand:SI 1))
11546 (set (reg:SI SP_REG)
11547 (plus:SI (reg:SI SP_REG)
11548 (match_operand:SI 3)))])]
11551 ix86_expand_call (NULL, operands[0], operands[1],
11552 operands[2], operands[3], false);
11556 (define_insn "*call_pop"
11557 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11559 (set (reg:SI SP_REG)
11560 (plus:SI (reg:SI SP_REG)
11561 (match_operand:SI 2 "immediate_operand" "i")))]
11562 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11563 "* return ix86_output_call_insn (insn, operands[0]);"
11564 [(set_attr "type" "call")])
11566 (define_insn "*sibcall_pop"
11567 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11569 (set (reg:SI SP_REG)
11570 (plus:SI (reg:SI SP_REG)
11571 (match_operand:SI 2 "immediate_operand" "i")))]
11572 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11573 "* return ix86_output_call_insn (insn, operands[0]);"
11574 [(set_attr "type" "call")])
11576 (define_insn "*sibcall_pop_memory"
11577 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11579 (set (reg:SI SP_REG)
11580 (plus:SI (reg:SI SP_REG)
11581 (match_operand:SI 2 "immediate_operand" "i")))
11582 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11584 "* return ix86_output_call_insn (insn, operands[0]);"
11585 [(set_attr "type" "call")])
11588 [(set (match_operand:SI 0 "register_operand")
11589 (match_operand:SI 1 "memory_operand"))
11590 (parallel [(call (mem:QI (match_dup 0))
11592 (set (reg:SI SP_REG)
11593 (plus:SI (reg:SI SP_REG)
11594 (match_operand:SI 4 "immediate_operand")))])]
11595 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11596 && peep2_reg_dead_p (2, operands[0])"
11597 [(parallel [(call (mem:QI (match_dup 1))
11599 (set (reg:SI SP_REG)
11600 (plus:SI (reg:SI SP_REG)
11602 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11605 [(set (match_operand:SI 0 "register_operand")
11606 (match_operand:SI 1 "memory_operand"))
11607 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11608 (parallel [(call (mem:QI (match_dup 0))
11610 (set (reg:SI SP_REG)
11611 (plus:SI (reg:SI SP_REG)
11612 (match_operand:SI 4 "immediate_operand")))])]
11613 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11614 && peep2_reg_dead_p (3, operands[0])"
11615 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11616 (parallel [(call (mem:QI (match_dup 1))
11618 (set (reg:SI SP_REG)
11619 (plus:SI (reg:SI SP_REG)
11621 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11623 ;; Combining simple memory jump instruction
11626 [(set (match_operand:W 0 "register_operand")
11627 (match_operand:W 1 "memory_operand"))
11628 (set (pc) (match_dup 0))]
11629 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11630 [(set (pc) (match_dup 1))])
11632 ;; Call subroutine, returning value in operand 0
11634 (define_expand "call_value"
11635 [(set (match_operand 0)
11636 (call (match_operand:QI 1)
11637 (match_operand 2)))
11638 (use (match_operand 3))]
11641 ix86_expand_call (operands[0], operands[1], operands[2],
11642 operands[3], NULL, false);
11646 (define_expand "sibcall_value"
11647 [(set (match_operand 0)
11648 (call (match_operand:QI 1)
11649 (match_operand 2)))
11650 (use (match_operand 3))]
11653 ix86_expand_call (operands[0], operands[1], operands[2],
11654 operands[3], NULL, true);
11658 (define_insn "*call_value"
11659 [(set (match_operand 0)
11660 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11661 (match_operand 2)))]
11662 "!SIBLING_CALL_P (insn)"
11663 "* return ix86_output_call_insn (insn, operands[1]);"
11664 [(set_attr "type" "callv")])
11666 (define_insn "*sibcall_value"
11667 [(set (match_operand 0)
11668 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11669 (match_operand 2)))]
11670 "SIBLING_CALL_P (insn)"
11671 "* return ix86_output_call_insn (insn, operands[1]);"
11672 [(set_attr "type" "callv")])
11674 (define_insn "*sibcall_value_memory"
11675 [(set (match_operand 0)
11676 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11677 (match_operand 2)))
11678 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11680 "* return ix86_output_call_insn (insn, operands[1]);"
11681 [(set_attr "type" "callv")])
11684 [(set (match_operand:W 0 "register_operand")
11685 (match_operand:W 1 "memory_operand"))
11686 (set (match_operand 2)
11687 (call (mem:QI (match_dup 0))
11688 (match_operand 3)))]
11689 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11690 && peep2_reg_dead_p (2, operands[0])"
11691 [(parallel [(set (match_dup 2)
11692 (call (mem:QI (match_dup 1))
11694 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11697 [(set (match_operand:W 0 "register_operand")
11698 (match_operand:W 1 "memory_operand"))
11699 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11700 (set (match_operand 2)
11701 (call (mem:QI (match_dup 0))
11702 (match_operand 3)))]
11703 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11704 && peep2_reg_dead_p (3, operands[0])"
11705 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11706 (parallel [(set (match_dup 2)
11707 (call (mem:QI (match_dup 1))
11709 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11711 (define_insn "*call_value_rex64_ms_sysv"
11712 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11713 [(set (match_operand 0)
11714 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rBwBz"))
11715 (match_operand 2)))
11716 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11717 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11718 "* return ix86_output_call_insn (insn, operands[1]);"
11719 [(set_attr "type" "callv")])
11721 (define_expand "call_value_pop"
11722 [(parallel [(set (match_operand 0)
11723 (call (match_operand:QI 1)
11724 (match_operand:SI 2)))
11725 (set (reg:SI SP_REG)
11726 (plus:SI (reg:SI SP_REG)
11727 (match_operand:SI 4)))])]
11730 ix86_expand_call (operands[0], operands[1], operands[2],
11731 operands[3], operands[4], false);
11735 (define_insn "*call_value_pop"
11736 [(set (match_operand 0)
11737 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11738 (match_operand 2)))
11739 (set (reg:SI SP_REG)
11740 (plus:SI (reg:SI SP_REG)
11741 (match_operand:SI 3 "immediate_operand" "i")))]
11742 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11743 "* return ix86_output_call_insn (insn, operands[1]);"
11744 [(set_attr "type" "callv")])
11746 (define_insn "*sibcall_value_pop"
11747 [(set (match_operand 0)
11748 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11749 (match_operand 2)))
11750 (set (reg:SI SP_REG)
11751 (plus:SI (reg:SI SP_REG)
11752 (match_operand:SI 3 "immediate_operand" "i")))]
11753 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11754 "* return ix86_output_call_insn (insn, operands[1]);"
11755 [(set_attr "type" "callv")])
11757 (define_insn "*sibcall_value_pop_memory"
11758 [(set (match_operand 0)
11759 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11760 (match_operand 2)))
11761 (set (reg:SI SP_REG)
11762 (plus:SI (reg:SI SP_REG)
11763 (match_operand:SI 3 "immediate_operand" "i")))
11764 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11766 "* return ix86_output_call_insn (insn, operands[1]);"
11767 [(set_attr "type" "callv")])
11770 [(set (match_operand:SI 0 "register_operand")
11771 (match_operand:SI 1 "memory_operand"))
11772 (parallel [(set (match_operand 2)
11773 (call (mem:QI (match_dup 0))
11774 (match_operand 3)))
11775 (set (reg:SI SP_REG)
11776 (plus:SI (reg:SI SP_REG)
11777 (match_operand:SI 4 "immediate_operand")))])]
11778 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11779 && peep2_reg_dead_p (2, operands[0])"
11780 [(parallel [(set (match_dup 2)
11781 (call (mem:QI (match_dup 1))
11783 (set (reg:SI SP_REG)
11784 (plus:SI (reg:SI SP_REG)
11786 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11789 [(set (match_operand:SI 0 "register_operand")
11790 (match_operand:SI 1 "memory_operand"))
11791 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11792 (parallel [(set (match_operand 2)
11793 (call (mem:QI (match_dup 0))
11794 (match_operand 3)))
11795 (set (reg:SI SP_REG)
11796 (plus:SI (reg:SI SP_REG)
11797 (match_operand:SI 4 "immediate_operand")))])]
11798 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11799 && peep2_reg_dead_p (3, operands[0])"
11800 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11801 (parallel [(set (match_dup 2)
11802 (call (mem:QI (match_dup 1))
11804 (set (reg:SI SP_REG)
11805 (plus:SI (reg:SI SP_REG)
11807 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11809 ;; Call subroutine returning any type.
11811 (define_expand "untyped_call"
11812 [(parallel [(call (match_operand 0)
11815 (match_operand 2)])]
11820 /* In order to give reg-stack an easier job in validating two
11821 coprocessor registers as containing a possible return value,
11822 simply pretend the untyped call returns a complex long double
11825 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11826 and should have the default ABI. */
11828 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11829 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11830 operands[0], const0_rtx,
11831 GEN_INT ((TARGET_64BIT
11832 ? (ix86_abi == SYSV_ABI
11833 ? X86_64_SSE_REGPARM_MAX
11834 : X86_64_MS_SSE_REGPARM_MAX)
11835 : X86_32_SSE_REGPARM_MAX)
11839 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11841 rtx set = XVECEXP (operands[2], 0, i);
11842 emit_move_insn (SET_DEST (set), SET_SRC (set));
11845 /* The optimizer does not know that the call sets the function value
11846 registers we stored in the result block. We avoid problems by
11847 claiming that all hard registers are used and clobbered at this
11849 emit_insn (gen_blockage ());
11854 ;; Prologue and epilogue instructions
11856 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11857 ;; all of memory. This blocks insns from being moved across this point.
11859 (define_insn "blockage"
11860 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11863 [(set_attr "length" "0")])
11865 ;; Do not schedule instructions accessing memory across this point.
11867 (define_expand "memory_blockage"
11868 [(set (match_dup 0)
11869 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11872 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11873 MEM_VOLATILE_P (operands[0]) = 1;
11876 (define_insn "*memory_blockage"
11877 [(set (match_operand:BLK 0)
11878 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11881 [(set_attr "length" "0")])
11883 ;; As USE insns aren't meaningful after reload, this is used instead
11884 ;; to prevent deleting instructions setting registers for PIC code
11885 (define_insn "prologue_use"
11886 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11889 [(set_attr "length" "0")])
11891 ;; Insn emitted into the body of a function to return from a function.
11892 ;; This is only done if the function's epilogue is known to be simple.
11893 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11895 (define_expand "return"
11897 "ix86_can_use_return_insn_p ()"
11899 if (crtl->args.pops_args)
11901 rtx popc = GEN_INT (crtl->args.pops_args);
11902 emit_jump_insn (gen_simple_return_pop_internal (popc));
11907 ;; We need to disable this for TARGET_SEH, as otherwise
11908 ;; shrink-wrapped prologue gets enabled too. This might exceed
11909 ;; the maximum size of prologue in unwind information.
11911 (define_expand "simple_return"
11915 if (crtl->args.pops_args)
11917 rtx popc = GEN_INT (crtl->args.pops_args);
11918 emit_jump_insn (gen_simple_return_pop_internal (popc));
11923 (define_insn "simple_return_internal"
11927 [(set_attr "length" "1")
11928 (set_attr "atom_unit" "jeu")
11929 (set_attr "length_immediate" "0")
11930 (set_attr "modrm" "0")])
11932 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11933 ;; instruction Athlon and K8 have.
11935 (define_insn "simple_return_internal_long"
11937 (unspec [(const_int 0)] UNSPEC_REP)]
11940 [(set_attr "length" "2")
11941 (set_attr "atom_unit" "jeu")
11942 (set_attr "length_immediate" "0")
11943 (set_attr "prefix_rep" "1")
11944 (set_attr "modrm" "0")])
11946 (define_insn "simple_return_pop_internal"
11948 (use (match_operand:SI 0 "const_int_operand"))]
11951 [(set_attr "length" "3")
11952 (set_attr "atom_unit" "jeu")
11953 (set_attr "length_immediate" "2")
11954 (set_attr "modrm" "0")])
11956 (define_insn "simple_return_indirect_internal"
11958 (use (match_operand:SI 0 "register_operand" "r"))]
11961 [(set_attr "type" "ibr")
11962 (set_attr "length_immediate" "0")])
11968 [(set_attr "length" "1")
11969 (set_attr "length_immediate" "0")
11970 (set_attr "modrm" "0")])
11972 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11973 (define_insn "nops"
11974 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11978 int num = INTVAL (operands[0]);
11980 gcc_assert (IN_RANGE (num, 1, 8));
11983 fputs ("\tnop\n", asm_out_file);
11987 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11988 (set_attr "length_immediate" "0")
11989 (set_attr "modrm" "0")])
11991 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11992 ;; branch prediction penalty for the third jump in a 16-byte
11996 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11999 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12000 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12002 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12003 The align insn is used to avoid 3 jump instructions in the row to improve
12004 branch prediction and the benefits hardly outweigh the cost of extra 8
12005 nops on the average inserted by full alignment pseudo operation. */
12009 [(set_attr "length" "16")])
12011 (define_expand "prologue"
12014 "ix86_expand_prologue (); DONE;")
12016 (define_insn "set_got"
12017 [(set (match_operand:SI 0 "register_operand" "=r")
12018 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12019 (clobber (reg:CC FLAGS_REG))]
12021 "* return output_set_got (operands[0], NULL_RTX);"
12022 [(set_attr "type" "multi")
12023 (set_attr "length" "12")])
12025 (define_insn "set_got_labelled"
12026 [(set (match_operand:SI 0 "register_operand" "=r")
12027 (unspec:SI [(label_ref (match_operand 1))]
12029 (clobber (reg:CC FLAGS_REG))]
12031 "* return output_set_got (operands[0], operands[1]);"
12032 [(set_attr "type" "multi")
12033 (set_attr "length" "12")])
12035 (define_insn "set_got_rex64"
12036 [(set (match_operand:DI 0 "register_operand" "=r")
12037 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12039 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12040 [(set_attr "type" "lea")
12041 (set_attr "length_address" "4")
12042 (set_attr "mode" "DI")])
12044 (define_insn "set_rip_rex64"
12045 [(set (match_operand:DI 0 "register_operand" "=r")
12046 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12048 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12049 [(set_attr "type" "lea")
12050 (set_attr "length_address" "4")
12051 (set_attr "mode" "DI")])
12053 (define_insn "set_got_offset_rex64"
12054 [(set (match_operand:DI 0 "register_operand" "=r")
12056 [(label_ref (match_operand 1))]
12057 UNSPEC_SET_GOT_OFFSET))]
12059 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12060 [(set_attr "type" "imov")
12061 (set_attr "length_immediate" "0")
12062 (set_attr "length_address" "8")
12063 (set_attr "mode" "DI")])
12065 (define_expand "epilogue"
12068 "ix86_expand_epilogue (1); DONE;")
12070 (define_expand "sibcall_epilogue"
12073 "ix86_expand_epilogue (0); DONE;")
12075 (define_expand "eh_return"
12076 [(use (match_operand 0 "register_operand"))]
12079 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12081 /* Tricky bit: we write the address of the handler to which we will
12082 be returning into someone else's stack frame, one word below the
12083 stack address we wish to restore. */
12084 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12085 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12086 tmp = gen_rtx_MEM (Pmode, tmp);
12087 emit_move_insn (tmp, ra);
12089 emit_jump_insn (gen_eh_return_internal ());
12094 (define_insn_and_split "eh_return_internal"
12098 "epilogue_completed"
12100 "ix86_expand_epilogue (2); DONE;")
12102 (define_insn "leave"
12103 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12104 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12105 (clobber (mem:BLK (scratch)))]
12108 [(set_attr "type" "leave")])
12110 (define_insn "leave_rex64"
12111 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12112 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12113 (clobber (mem:BLK (scratch)))]
12116 [(set_attr "type" "leave")])
12118 ;; Handle -fsplit-stack.
12120 (define_expand "split_stack_prologue"
12124 ix86_expand_split_stack_prologue ();
12128 ;; In order to support the call/return predictor, we use a return
12129 ;; instruction which the middle-end doesn't see.
12130 (define_insn "split_stack_return"
12131 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12132 UNSPECV_SPLIT_STACK_RETURN)]
12135 if (operands[0] == const0_rtx)
12140 [(set_attr "atom_unit" "jeu")
12141 (set_attr "modrm" "0")
12142 (set (attr "length")
12143 (if_then_else (match_operand:SI 0 "const0_operand")
12146 (set (attr "length_immediate")
12147 (if_then_else (match_operand:SI 0 "const0_operand")
12151 ;; If there are operand 0 bytes available on the stack, jump to
12154 (define_expand "split_stack_space_check"
12155 [(set (pc) (if_then_else
12156 (ltu (minus (reg SP_REG)
12157 (match_operand 0 "register_operand"))
12158 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12159 (label_ref (match_operand 1))
12163 rtx reg, size, limit;
12165 reg = gen_reg_rtx (Pmode);
12166 size = force_reg (Pmode, operands[0]);
12167 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12168 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12169 UNSPEC_STACK_CHECK);
12170 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12171 ix86_expand_branch (GEU, reg, limit, operands[1]);
12176 ;; Bit manipulation instructions.
12178 (define_expand "ffs<mode>2"
12179 [(set (match_dup 2) (const_int -1))
12180 (parallel [(set (match_dup 3) (match_dup 4))
12181 (set (match_operand:SWI48 0 "register_operand")
12183 (match_operand:SWI48 1 "nonimmediate_operand")))])
12184 (set (match_dup 0) (if_then_else:SWI48
12185 (eq (match_dup 3) (const_int 0))
12188 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12189 (clobber (reg:CC FLAGS_REG))])]
12192 enum machine_mode flags_mode;
12194 if (<MODE>mode == SImode && !TARGET_CMOVE)
12196 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12200 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12202 operands[2] = gen_reg_rtx (<MODE>mode);
12203 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12204 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12207 (define_insn_and_split "ffssi2_no_cmove"
12208 [(set (match_operand:SI 0 "register_operand" "=r")
12209 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12210 (clobber (match_scratch:SI 2 "=&q"))
12211 (clobber (reg:CC FLAGS_REG))]
12214 "&& reload_completed"
12215 [(parallel [(set (match_dup 4) (match_dup 5))
12216 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12217 (set (strict_low_part (match_dup 3))
12218 (eq:QI (match_dup 4) (const_int 0)))
12219 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12220 (clobber (reg:CC FLAGS_REG))])
12221 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12222 (clobber (reg:CC FLAGS_REG))])
12223 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12224 (clobber (reg:CC FLAGS_REG))])]
12226 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12228 operands[3] = gen_lowpart (QImode, operands[2]);
12229 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12230 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12232 ix86_expand_clear (operands[2]);
12235 (define_insn "*tzcnt<mode>_1"
12236 [(set (reg:CCC FLAGS_REG)
12237 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12239 (set (match_operand:SWI48 0 "register_operand" "=r")
12240 (ctz:SWI48 (match_dup 1)))]
12242 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12243 [(set_attr "type" "alu1")
12244 (set_attr "prefix_0f" "1")
12245 (set_attr "prefix_rep" "1")
12246 (set_attr "btver2_decode" "double")
12247 (set_attr "mode" "<MODE>")])
12249 (define_insn "*bsf<mode>_1"
12250 [(set (reg:CCZ FLAGS_REG)
12251 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12253 (set (match_operand:SWI48 0 "register_operand" "=r")
12254 (ctz:SWI48 (match_dup 1)))]
12256 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12257 [(set_attr "type" "alu1")
12258 (set_attr "prefix_0f" "1")
12259 (set_attr "btver2_decode" "double")
12260 (set_attr "mode" "<MODE>")])
12262 (define_insn "ctz<mode>2"
12263 [(set (match_operand:SWI248 0 "register_operand" "=r")
12264 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12265 (clobber (reg:CC FLAGS_REG))]
12269 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12270 else if (optimize_function_for_size_p (cfun))
12272 else if (TARGET_GENERIC)
12273 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12274 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12276 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12278 [(set_attr "type" "alu1")
12279 (set_attr "prefix_0f" "1")
12280 (set (attr "prefix_rep")
12282 (ior (match_test "TARGET_BMI")
12283 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12284 (match_test "TARGET_GENERIC")))
12286 (const_string "0")))
12287 (set_attr "mode" "<MODE>")])
12289 (define_expand "clz<mode>2"
12291 [(set (match_operand:SWI248 0 "register_operand")
12294 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12295 (clobber (reg:CC FLAGS_REG))])
12297 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12298 (clobber (reg:CC FLAGS_REG))])]
12303 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12306 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12309 (define_insn "clz<mode>2_lzcnt"
12310 [(set (match_operand:SWI248 0 "register_operand" "=r")
12311 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12312 (clobber (reg:CC FLAGS_REG))]
12314 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12315 [(set_attr "prefix_rep" "1")
12316 (set_attr "type" "bitmanip")
12317 (set_attr "mode" "<MODE>")])
12319 ;; BMI instructions.
12320 (define_insn "*bmi_andn_<mode>"
12321 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12324 (match_operand:SWI48 1 "register_operand" "r,r"))
12325 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12326 (clobber (reg:CC FLAGS_REG))]
12328 "andn\t{%2, %1, %0|%0, %1, %2}"
12329 [(set_attr "type" "bitmanip")
12330 (set_attr "btver2_decode" "direct, double")
12331 (set_attr "mode" "<MODE>")])
12333 (define_insn "bmi_bextr_<mode>"
12334 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12335 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12336 (match_operand:SWI48 2 "register_operand" "r,r")]
12338 (clobber (reg:CC FLAGS_REG))]
12340 "bextr\t{%2, %1, %0|%0, %1, %2}"
12341 [(set_attr "type" "bitmanip")
12342 (set_attr "btver2_decode" "direct, double")
12343 (set_attr "mode" "<MODE>")])
12345 (define_insn "*bmi_blsi_<mode>"
12346 [(set (match_operand:SWI48 0 "register_operand" "=r")
12349 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12351 (clobber (reg:CC FLAGS_REG))]
12353 "blsi\t{%1, %0|%0, %1}"
12354 [(set_attr "type" "bitmanip")
12355 (set_attr "btver2_decode" "double")
12356 (set_attr "mode" "<MODE>")])
12358 (define_insn "*bmi_blsmsk_<mode>"
12359 [(set (match_operand:SWI48 0 "register_operand" "=r")
12362 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12365 (clobber (reg:CC FLAGS_REG))]
12367 "blsmsk\t{%1, %0|%0, %1}"
12368 [(set_attr "type" "bitmanip")
12369 (set_attr "btver2_decode" "double")
12370 (set_attr "mode" "<MODE>")])
12372 (define_insn "*bmi_blsr_<mode>"
12373 [(set (match_operand:SWI48 0 "register_operand" "=r")
12376 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12379 (clobber (reg:CC FLAGS_REG))]
12381 "blsr\t{%1, %0|%0, %1}"
12382 [(set_attr "type" "bitmanip")
12383 (set_attr "btver2_decode" "double")
12384 (set_attr "mode" "<MODE>")])
12386 ;; BMI2 instructions.
12387 (define_insn "bmi2_bzhi_<mode>3"
12388 [(set (match_operand:SWI48 0 "register_operand" "=r")
12389 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12390 (match_operand:SWI48 2 "register_operand" "r"))
12391 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12392 (clobber (reg:CC FLAGS_REG))]
12394 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12395 [(set_attr "type" "bitmanip")
12396 (set_attr "prefix" "vex")
12397 (set_attr "mode" "<MODE>")])
12399 (define_insn "bmi2_pdep_<mode>3"
12400 [(set (match_operand:SWI48 0 "register_operand" "=r")
12401 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12402 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12405 "pdep\t{%2, %1, %0|%0, %1, %2}"
12406 [(set_attr "type" "bitmanip")
12407 (set_attr "prefix" "vex")
12408 (set_attr "mode" "<MODE>")])
12410 (define_insn "bmi2_pext_<mode>3"
12411 [(set (match_operand:SWI48 0 "register_operand" "=r")
12412 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12413 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12416 "pext\t{%2, %1, %0|%0, %1, %2}"
12417 [(set_attr "type" "bitmanip")
12418 (set_attr "prefix" "vex")
12419 (set_attr "mode" "<MODE>")])
12421 ;; TBM instructions.
12422 (define_insn "tbm_bextri_<mode>"
12423 [(set (match_operand:SWI48 0 "register_operand" "=r")
12424 (zero_extract:SWI48
12425 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12426 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12427 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12428 (clobber (reg:CC FLAGS_REG))]
12431 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12432 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12434 [(set_attr "type" "bitmanip")
12435 (set_attr "mode" "<MODE>")])
12437 (define_insn "*tbm_blcfill_<mode>"
12438 [(set (match_operand:SWI48 0 "register_operand" "=r")
12441 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12444 (clobber (reg:CC FLAGS_REG))]
12446 "blcfill\t{%1, %0|%0, %1}"
12447 [(set_attr "type" "bitmanip")
12448 (set_attr "mode" "<MODE>")])
12450 (define_insn "*tbm_blci_<mode>"
12451 [(set (match_operand:SWI48 0 "register_operand" "=r")
12455 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12458 (clobber (reg:CC FLAGS_REG))]
12460 "blci\t{%1, %0|%0, %1}"
12461 [(set_attr "type" "bitmanip")
12462 (set_attr "mode" "<MODE>")])
12464 (define_insn "*tbm_blcic_<mode>"
12465 [(set (match_operand:SWI48 0 "register_operand" "=r")
12468 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12472 (clobber (reg:CC FLAGS_REG))]
12474 "blcic\t{%1, %0|%0, %1}"
12475 [(set_attr "type" "bitmanip")
12476 (set_attr "mode" "<MODE>")])
12478 (define_insn "*tbm_blcmsk_<mode>"
12479 [(set (match_operand:SWI48 0 "register_operand" "=r")
12482 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12485 (clobber (reg:CC FLAGS_REG))]
12487 "blcmsk\t{%1, %0|%0, %1}"
12488 [(set_attr "type" "bitmanip")
12489 (set_attr "mode" "<MODE>")])
12491 (define_insn "*tbm_blcs_<mode>"
12492 [(set (match_operand:SWI48 0 "register_operand" "=r")
12495 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12498 (clobber (reg:CC FLAGS_REG))]
12500 "blcs\t{%1, %0|%0, %1}"
12501 [(set_attr "type" "bitmanip")
12502 (set_attr "mode" "<MODE>")])
12504 (define_insn "*tbm_blsfill_<mode>"
12505 [(set (match_operand:SWI48 0 "register_operand" "=r")
12508 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12511 (clobber (reg:CC FLAGS_REG))]
12513 "blsfill\t{%1, %0|%0, %1}"
12514 [(set_attr "type" "bitmanip")
12515 (set_attr "mode" "<MODE>")])
12517 (define_insn "*tbm_blsic_<mode>"
12518 [(set (match_operand:SWI48 0 "register_operand" "=r")
12521 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12525 (clobber (reg:CC FLAGS_REG))]
12527 "blsic\t{%1, %0|%0, %1}"
12528 [(set_attr "type" "bitmanip")
12529 (set_attr "mode" "<MODE>")])
12531 (define_insn "*tbm_t1mskc_<mode>"
12532 [(set (match_operand:SWI48 0 "register_operand" "=r")
12535 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12539 (clobber (reg:CC FLAGS_REG))]
12541 "t1mskc\t{%1, %0|%0, %1}"
12542 [(set_attr "type" "bitmanip")
12543 (set_attr "mode" "<MODE>")])
12545 (define_insn "*tbm_tzmsk_<mode>"
12546 [(set (match_operand:SWI48 0 "register_operand" "=r")
12549 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12553 (clobber (reg:CC FLAGS_REG))]
12555 "tzmsk\t{%1, %0|%0, %1}"
12556 [(set_attr "type" "bitmanip")
12557 (set_attr "mode" "<MODE>")])
12559 (define_insn "bsr_rex64"
12560 [(set (match_operand:DI 0 "register_operand" "=r")
12561 (minus:DI (const_int 63)
12562 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12563 (clobber (reg:CC FLAGS_REG))]
12565 "bsr{q}\t{%1, %0|%0, %1}"
12566 [(set_attr "type" "alu1")
12567 (set_attr "prefix_0f" "1")
12568 (set_attr "mode" "DI")])
12571 [(set (match_operand:SI 0 "register_operand" "=r")
12572 (minus:SI (const_int 31)
12573 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12574 (clobber (reg:CC FLAGS_REG))]
12576 "bsr{l}\t{%1, %0|%0, %1}"
12577 [(set_attr "type" "alu1")
12578 (set_attr "prefix_0f" "1")
12579 (set_attr "mode" "SI")])
12581 (define_insn "*bsrhi"
12582 [(set (match_operand:HI 0 "register_operand" "=r")
12583 (minus:HI (const_int 15)
12584 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12585 (clobber (reg:CC FLAGS_REG))]
12587 "bsr{w}\t{%1, %0|%0, %1}"
12588 [(set_attr "type" "alu1")
12589 (set_attr "prefix_0f" "1")
12590 (set_attr "mode" "HI")])
12592 (define_insn "popcount<mode>2"
12593 [(set (match_operand:SWI248 0 "register_operand" "=r")
12595 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12596 (clobber (reg:CC FLAGS_REG))]
12600 return "popcnt\t{%1, %0|%0, %1}";
12602 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12605 [(set_attr "prefix_rep" "1")
12606 (set_attr "type" "bitmanip")
12607 (set_attr "mode" "<MODE>")])
12609 (define_insn "*popcount<mode>2_cmp"
12610 [(set (reg FLAGS_REG)
12613 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12615 (set (match_operand:SWI248 0 "register_operand" "=r")
12616 (popcount:SWI248 (match_dup 1)))]
12617 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12620 return "popcnt\t{%1, %0|%0, %1}";
12622 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12625 [(set_attr "prefix_rep" "1")
12626 (set_attr "type" "bitmanip")
12627 (set_attr "mode" "<MODE>")])
12629 (define_insn "*popcountsi2_cmp_zext"
12630 [(set (reg FLAGS_REG)
12632 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12634 (set (match_operand:DI 0 "register_operand" "=r")
12635 (zero_extend:DI(popcount:SI (match_dup 1))))]
12636 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12639 return "popcnt\t{%1, %0|%0, %1}";
12641 return "popcnt{l}\t{%1, %0|%0, %1}";
12644 [(set_attr "prefix_rep" "1")
12645 (set_attr "type" "bitmanip")
12646 (set_attr "mode" "SI")])
12648 (define_expand "bswapdi2"
12649 [(set (match_operand:DI 0 "register_operand")
12650 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12654 operands[1] = force_reg (DImode, operands[1]);
12657 (define_expand "bswapsi2"
12658 [(set (match_operand:SI 0 "register_operand")
12659 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12664 else if (TARGET_BSWAP)
12665 operands[1] = force_reg (SImode, operands[1]);
12668 rtx x = operands[0];
12670 emit_move_insn (x, operands[1]);
12671 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12672 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12673 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12678 (define_insn "*bswap<mode>2_movbe"
12679 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12680 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12682 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12685 movbe\t{%1, %0|%0, %1}
12686 movbe\t{%1, %0|%0, %1}"
12687 [(set_attr "type" "bitmanip,imov,imov")
12688 (set_attr "modrm" "0,1,1")
12689 (set_attr "prefix_0f" "*,1,1")
12690 (set_attr "prefix_extra" "*,1,1")
12691 (set_attr "mode" "<MODE>")])
12693 (define_insn "*bswap<mode>2"
12694 [(set (match_operand:SWI48 0 "register_operand" "=r")
12695 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12698 [(set_attr "type" "bitmanip")
12699 (set_attr "modrm" "0")
12700 (set_attr "mode" "<MODE>")])
12702 (define_insn "*bswaphi_lowpart_1"
12703 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12704 (bswap:HI (match_dup 0)))
12705 (clobber (reg:CC FLAGS_REG))]
12706 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12708 xchg{b}\t{%h0, %b0|%b0, %h0}
12709 rol{w}\t{$8, %0|%0, 8}"
12710 [(set_attr "length" "2,4")
12711 (set_attr "mode" "QI,HI")])
12713 (define_insn "bswaphi_lowpart"
12714 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12715 (bswap:HI (match_dup 0)))
12716 (clobber (reg:CC FLAGS_REG))]
12718 "rol{w}\t{$8, %0|%0, 8}"
12719 [(set_attr "length" "4")
12720 (set_attr "mode" "HI")])
12722 (define_expand "paritydi2"
12723 [(set (match_operand:DI 0 "register_operand")
12724 (parity:DI (match_operand:DI 1 "register_operand")))]
12727 rtx scratch = gen_reg_rtx (QImode);
12730 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12731 NULL_RTX, operands[1]));
12733 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12734 gen_rtx_REG (CCmode, FLAGS_REG),
12736 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12739 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12742 rtx tmp = gen_reg_rtx (SImode);
12744 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12745 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12750 (define_expand "paritysi2"
12751 [(set (match_operand:SI 0 "register_operand")
12752 (parity:SI (match_operand:SI 1 "register_operand")))]
12755 rtx scratch = gen_reg_rtx (QImode);
12758 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12760 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12761 gen_rtx_REG (CCmode, FLAGS_REG),
12763 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12765 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12769 (define_insn_and_split "paritydi2_cmp"
12770 [(set (reg:CC FLAGS_REG)
12771 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12773 (clobber (match_scratch:DI 0 "=r"))
12774 (clobber (match_scratch:SI 1 "=&r"))
12775 (clobber (match_scratch:HI 2 "=Q"))]
12778 "&& reload_completed"
12780 [(set (match_dup 1)
12781 (xor:SI (match_dup 1) (match_dup 4)))
12782 (clobber (reg:CC FLAGS_REG))])
12784 [(set (reg:CC FLAGS_REG)
12785 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12786 (clobber (match_dup 1))
12787 (clobber (match_dup 2))])]
12789 operands[4] = gen_lowpart (SImode, operands[3]);
12793 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12794 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12797 operands[1] = gen_highpart (SImode, operands[3]);
12800 (define_insn_and_split "paritysi2_cmp"
12801 [(set (reg:CC FLAGS_REG)
12802 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12804 (clobber (match_scratch:SI 0 "=r"))
12805 (clobber (match_scratch:HI 1 "=&Q"))]
12808 "&& reload_completed"
12810 [(set (match_dup 1)
12811 (xor:HI (match_dup 1) (match_dup 3)))
12812 (clobber (reg:CC FLAGS_REG))])
12814 [(set (reg:CC FLAGS_REG)
12815 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12816 (clobber (match_dup 1))])]
12818 operands[3] = gen_lowpart (HImode, operands[2]);
12820 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12821 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12824 (define_insn "*parityhi2_cmp"
12825 [(set (reg:CC FLAGS_REG)
12826 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12828 (clobber (match_scratch:HI 0 "=Q"))]
12830 "xor{b}\t{%h0, %b0|%b0, %h0}"
12831 [(set_attr "length" "2")
12832 (set_attr "mode" "HI")])
12835 ;; Thread-local storage patterns for ELF.
12837 ;; Note that these code sequences must appear exactly as shown
12838 ;; in order to allow linker relaxation.
12840 (define_insn "*tls_global_dynamic_32_gnu"
12841 [(set (match_operand:SI 0 "register_operand" "=a")
12843 [(match_operand:SI 1 "register_operand" "b")
12844 (match_operand 2 "tls_symbolic_operand")
12845 (match_operand 3 "constant_call_address_operand" "Bz")
12848 (clobber (match_scratch:SI 4 "=d"))
12849 (clobber (match_scratch:SI 5 "=c"))
12850 (clobber (reg:CC FLAGS_REG))]
12851 "!TARGET_64BIT && TARGET_GNU_TLS"
12854 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12855 if (TARGET_SUN_TLS)
12856 #ifdef HAVE_AS_IX86_TLSGDPLT
12857 return "call\t%a2@tlsgdplt";
12859 return "call\t%p3@plt";
12861 return "call\t%P3";
12863 [(set_attr "type" "multi")
12864 (set_attr "length" "12")])
12866 (define_expand "tls_global_dynamic_32"
12868 [(set (match_operand:SI 0 "register_operand")
12869 (unspec:SI [(match_operand:SI 2 "register_operand")
12870 (match_operand 1 "tls_symbolic_operand")
12871 (match_operand 3 "constant_call_address_operand")
12874 (clobber (match_scratch:SI 4))
12875 (clobber (match_scratch:SI 5))
12876 (clobber (reg:CC FLAGS_REG))])]
12878 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12880 (define_insn "*tls_global_dynamic_64_<mode>"
12881 [(set (match_operand:P 0 "register_operand" "=a")
12883 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
12884 (match_operand 3)))
12885 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12890 fputs (ASM_BYTE "0x66\n", asm_out_file);
12892 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12893 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12894 fputs ("\trex64\n", asm_out_file);
12895 if (TARGET_SUN_TLS)
12896 return "call\t%p2@plt";
12897 return "call\t%P2";
12899 [(set_attr "type" "multi")
12900 (set (attr "length")
12901 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12903 (define_insn "*tls_global_dynamic_64_largepic"
12904 [(set (match_operand:DI 0 "register_operand" "=a")
12906 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12907 (match_operand:DI 3 "immediate_operand" "i")))
12908 (match_operand 4)))
12909 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12911 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12912 && GET_CODE (operands[3]) == CONST
12913 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12914 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12917 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12918 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12919 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12920 return "call\t{*%%rax|rax}";
12922 [(set_attr "type" "multi")
12923 (set_attr "length" "22")])
12925 (define_expand "tls_global_dynamic_64_<mode>"
12927 [(set (match_operand:P 0 "register_operand")
12929 (mem:QI (match_operand 2))
12931 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12934 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12936 (define_insn "*tls_local_dynamic_base_32_gnu"
12937 [(set (match_operand:SI 0 "register_operand" "=a")
12939 [(match_operand:SI 1 "register_operand" "b")
12940 (match_operand 2 "constant_call_address_operand" "Bz")
12942 UNSPEC_TLS_LD_BASE))
12943 (clobber (match_scratch:SI 3 "=d"))
12944 (clobber (match_scratch:SI 4 "=c"))
12945 (clobber (reg:CC FLAGS_REG))]
12946 "!TARGET_64BIT && TARGET_GNU_TLS"
12949 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12950 if (TARGET_SUN_TLS)
12952 if (HAVE_AS_IX86_TLSLDMPLT)
12953 return "call\t%&@tlsldmplt";
12955 return "call\t%p2@plt";
12957 return "call\t%P2";
12959 [(set_attr "type" "multi")
12960 (set_attr "length" "11")])
12962 (define_expand "tls_local_dynamic_base_32"
12964 [(set (match_operand:SI 0 "register_operand")
12966 [(match_operand:SI 1 "register_operand")
12967 (match_operand 2 "constant_call_address_operand")
12969 UNSPEC_TLS_LD_BASE))
12970 (clobber (match_scratch:SI 3))
12971 (clobber (match_scratch:SI 4))
12972 (clobber (reg:CC FLAGS_REG))])]
12974 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12976 (define_insn "*tls_local_dynamic_base_64_<mode>"
12977 [(set (match_operand:P 0 "register_operand" "=a")
12979 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
12980 (match_operand 2)))
12981 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12985 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12986 if (TARGET_SUN_TLS)
12987 return "call\t%p1@plt";
12988 return "call\t%P1";
12990 [(set_attr "type" "multi")
12991 (set_attr "length" "12")])
12993 (define_insn "*tls_local_dynamic_base_64_largepic"
12994 [(set (match_operand:DI 0 "register_operand" "=a")
12996 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12997 (match_operand:DI 2 "immediate_operand" "i")))
12998 (match_operand 3)))
12999 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13000 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13001 && GET_CODE (operands[2]) == CONST
13002 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13003 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13006 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13007 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13008 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13009 return "call\t{*%%rax|rax}";
13011 [(set_attr "type" "multi")
13012 (set_attr "length" "22")])
13014 (define_expand "tls_local_dynamic_base_64_<mode>"
13016 [(set (match_operand:P 0 "register_operand")
13018 (mem:QI (match_operand 1))
13020 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13022 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13024 ;; Local dynamic of a single variable is a lose. Show combine how
13025 ;; to convert that back to global dynamic.
13027 (define_insn_and_split "*tls_local_dynamic_32_once"
13028 [(set (match_operand:SI 0 "register_operand" "=a")
13030 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13031 (match_operand 2 "constant_call_address_operand" "Bz")
13033 UNSPEC_TLS_LD_BASE)
13034 (const:SI (unspec:SI
13035 [(match_operand 3 "tls_symbolic_operand")]
13037 (clobber (match_scratch:SI 4 "=d"))
13038 (clobber (match_scratch:SI 5 "=c"))
13039 (clobber (reg:CC FLAGS_REG))]
13044 [(set (match_dup 0)
13045 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13048 (clobber (match_dup 4))
13049 (clobber (match_dup 5))
13050 (clobber (reg:CC FLAGS_REG))])])
13052 ;; Segment register for the thread base ptr load
13053 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13055 ;; Load and add the thread base pointer from %<tp_seg>:0.
13056 (define_insn "*load_tp_x32"
13057 [(set (match_operand:SI 0 "register_operand" "=r")
13058 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13060 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13061 [(set_attr "type" "imov")
13062 (set_attr "modrm" "0")
13063 (set_attr "length" "7")
13064 (set_attr "memory" "load")
13065 (set_attr "imm_disp" "false")])
13067 (define_insn "*load_tp_x32_zext"
13068 [(set (match_operand:DI 0 "register_operand" "=r")
13069 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13071 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13072 [(set_attr "type" "imov")
13073 (set_attr "modrm" "0")
13074 (set_attr "length" "7")
13075 (set_attr "memory" "load")
13076 (set_attr "imm_disp" "false")])
13078 (define_insn "*load_tp_<mode>"
13079 [(set (match_operand:P 0 "register_operand" "=r")
13080 (unspec:P [(const_int 0)] UNSPEC_TP))]
13082 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13083 [(set_attr "type" "imov")
13084 (set_attr "modrm" "0")
13085 (set_attr "length" "7")
13086 (set_attr "memory" "load")
13087 (set_attr "imm_disp" "false")])
13089 (define_insn "*add_tp_x32"
13090 [(set (match_operand:SI 0 "register_operand" "=r")
13091 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13092 (match_operand:SI 1 "register_operand" "0")))
13093 (clobber (reg:CC FLAGS_REG))]
13095 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13096 [(set_attr "type" "alu")
13097 (set_attr "modrm" "0")
13098 (set_attr "length" "7")
13099 (set_attr "memory" "load")
13100 (set_attr "imm_disp" "false")])
13102 (define_insn "*add_tp_x32_zext"
13103 [(set (match_operand:DI 0 "register_operand" "=r")
13105 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13106 (match_operand:SI 1 "register_operand" "0"))))
13107 (clobber (reg:CC FLAGS_REG))]
13109 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13110 [(set_attr "type" "alu")
13111 (set_attr "modrm" "0")
13112 (set_attr "length" "7")
13113 (set_attr "memory" "load")
13114 (set_attr "imm_disp" "false")])
13116 (define_insn "*add_tp_<mode>"
13117 [(set (match_operand:P 0 "register_operand" "=r")
13118 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13119 (match_operand:P 1 "register_operand" "0")))
13120 (clobber (reg:CC FLAGS_REG))]
13122 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13123 [(set_attr "type" "alu")
13124 (set_attr "modrm" "0")
13125 (set_attr "length" "7")
13126 (set_attr "memory" "load")
13127 (set_attr "imm_disp" "false")])
13129 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13130 ;; %rax as destination of the initial executable code sequence.
13131 (define_insn "tls_initial_exec_64_sun"
13132 [(set (match_operand:DI 0 "register_operand" "=a")
13134 [(match_operand 1 "tls_symbolic_operand")]
13135 UNSPEC_TLS_IE_SUN))
13136 (clobber (reg:CC FLAGS_REG))]
13137 "TARGET_64BIT && TARGET_SUN_TLS"
13140 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13141 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13143 [(set_attr "type" "multi")])
13145 ;; GNU2 TLS patterns can be split.
13147 (define_expand "tls_dynamic_gnu2_32"
13148 [(set (match_dup 3)
13149 (plus:SI (match_operand:SI 2 "register_operand")
13151 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13154 [(set (match_operand:SI 0 "register_operand")
13155 (unspec:SI [(match_dup 1) (match_dup 3)
13156 (match_dup 2) (reg:SI SP_REG)]
13158 (clobber (reg:CC FLAGS_REG))])]
13159 "!TARGET_64BIT && TARGET_GNU2_TLS"
13161 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13162 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13165 (define_insn "*tls_dynamic_gnu2_lea_32"
13166 [(set (match_operand:SI 0 "register_operand" "=r")
13167 (plus:SI (match_operand:SI 1 "register_operand" "b")
13169 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13170 UNSPEC_TLSDESC))))]
13171 "!TARGET_64BIT && TARGET_GNU2_TLS"
13172 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13173 [(set_attr "type" "lea")
13174 (set_attr "mode" "SI")
13175 (set_attr "length" "6")
13176 (set_attr "length_address" "4")])
13178 (define_insn "*tls_dynamic_gnu2_call_32"
13179 [(set (match_operand:SI 0 "register_operand" "=a")
13180 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13181 (match_operand:SI 2 "register_operand" "0")
13182 ;; we have to make sure %ebx still points to the GOT
13183 (match_operand:SI 3 "register_operand" "b")
13186 (clobber (reg:CC FLAGS_REG))]
13187 "!TARGET_64BIT && TARGET_GNU2_TLS"
13188 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13189 [(set_attr "type" "call")
13190 (set_attr "length" "2")
13191 (set_attr "length_address" "0")])
13193 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13194 [(set (match_operand:SI 0 "register_operand" "=&a")
13196 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13197 (match_operand:SI 4)
13198 (match_operand:SI 2 "register_operand" "b")
13201 (const:SI (unspec:SI
13202 [(match_operand 1 "tls_symbolic_operand")]
13204 (clobber (reg:CC FLAGS_REG))]
13205 "!TARGET_64BIT && TARGET_GNU2_TLS"
13208 [(set (match_dup 0) (match_dup 5))]
13210 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13211 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13214 (define_expand "tls_dynamic_gnu2_64"
13215 [(set (match_dup 2)
13216 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13219 [(set (match_operand:DI 0 "register_operand")
13220 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13222 (clobber (reg:CC FLAGS_REG))])]
13223 "TARGET_64BIT && TARGET_GNU2_TLS"
13225 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13226 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13229 (define_insn "*tls_dynamic_gnu2_lea_64"
13230 [(set (match_operand:DI 0 "register_operand" "=r")
13231 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13233 "TARGET_64BIT && TARGET_GNU2_TLS"
13234 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13235 [(set_attr "type" "lea")
13236 (set_attr "mode" "DI")
13237 (set_attr "length" "7")
13238 (set_attr "length_address" "4")])
13240 (define_insn "*tls_dynamic_gnu2_call_64"
13241 [(set (match_operand:DI 0 "register_operand" "=a")
13242 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13243 (match_operand:DI 2 "register_operand" "0")
13246 (clobber (reg:CC FLAGS_REG))]
13247 "TARGET_64BIT && TARGET_GNU2_TLS"
13248 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13249 [(set_attr "type" "call")
13250 (set_attr "length" "2")
13251 (set_attr "length_address" "0")])
13253 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13254 [(set (match_operand:DI 0 "register_operand" "=&a")
13256 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13257 (match_operand:DI 3)
13260 (const:DI (unspec:DI
13261 [(match_operand 1 "tls_symbolic_operand")]
13263 (clobber (reg:CC FLAGS_REG))]
13264 "TARGET_64BIT && TARGET_GNU2_TLS"
13267 [(set (match_dup 0) (match_dup 4))]
13269 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13270 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13273 ;; These patterns match the binary 387 instructions for addM3, subM3,
13274 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13275 ;; SFmode. The first is the normal insn, the second the same insn but
13276 ;; with one operand a conversion, and the third the same insn but with
13277 ;; the other operand a conversion. The conversion may be SFmode or
13278 ;; SImode if the target mode DFmode, but only SImode if the target mode
13281 ;; Gcc is slightly more smart about handling normal two address instructions
13282 ;; so use special patterns for add and mull.
13284 (define_insn "*fop_<mode>_comm_mixed"
13285 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13286 (match_operator:MODEF 3 "binary_fp_operator"
13287 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13288 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13289 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13290 && COMMUTATIVE_ARITH_P (operands[3])
13291 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13292 "* return output_387_binary_op (insn, operands);"
13293 [(set (attr "type")
13294 (if_then_else (eq_attr "alternative" "1,2")
13295 (if_then_else (match_operand:MODEF 3 "mult_operator")
13296 (const_string "ssemul")
13297 (const_string "sseadd"))
13298 (if_then_else (match_operand:MODEF 3 "mult_operator")
13299 (const_string "fmul")
13300 (const_string "fop"))))
13301 (set_attr "isa" "*,noavx,avx")
13302 (set_attr "prefix" "orig,orig,vex")
13303 (set_attr "mode" "<MODE>")])
13305 (define_insn "*fop_<mode>_comm_sse"
13306 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13307 (match_operator:MODEF 3 "binary_fp_operator"
13308 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13309 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13310 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13311 && COMMUTATIVE_ARITH_P (operands[3])
13312 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13313 "* return output_387_binary_op (insn, operands);"
13314 [(set (attr "type")
13315 (if_then_else (match_operand:MODEF 3 "mult_operator")
13316 (const_string "ssemul")
13317 (const_string "sseadd")))
13318 (set_attr "isa" "noavx,avx")
13319 (set_attr "prefix" "orig,vex")
13320 (set_attr "mode" "<MODE>")])
13322 (define_insn "*fop_<mode>_comm_i387"
13323 [(set (match_operand:MODEF 0 "register_operand" "=f")
13324 (match_operator:MODEF 3 "binary_fp_operator"
13325 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13326 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13327 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13328 && COMMUTATIVE_ARITH_P (operands[3])
13329 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13330 "* return output_387_binary_op (insn, operands);"
13331 [(set (attr "type")
13332 (if_then_else (match_operand:MODEF 3 "mult_operator")
13333 (const_string "fmul")
13334 (const_string "fop")))
13335 (set_attr "mode" "<MODE>")])
13337 (define_insn "*fop_<mode>_1_mixed"
13338 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13339 (match_operator:MODEF 3 "binary_fp_operator"
13340 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13341 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13342 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13343 && !COMMUTATIVE_ARITH_P (operands[3])
13344 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13345 "* return output_387_binary_op (insn, operands);"
13346 [(set (attr "type")
13347 (cond [(and (eq_attr "alternative" "2,3")
13348 (match_operand:MODEF 3 "mult_operator"))
13349 (const_string "ssemul")
13350 (and (eq_attr "alternative" "2,3")
13351 (match_operand:MODEF 3 "div_operator"))
13352 (const_string "ssediv")
13353 (eq_attr "alternative" "2,3")
13354 (const_string "sseadd")
13355 (match_operand:MODEF 3 "mult_operator")
13356 (const_string "fmul")
13357 (match_operand:MODEF 3 "div_operator")
13358 (const_string "fdiv")
13360 (const_string "fop")))
13361 (set_attr "isa" "*,*,noavx,avx")
13362 (set_attr "prefix" "orig,orig,orig,vex")
13363 (set_attr "mode" "<MODE>")])
13365 (define_insn "*rcpsf2_sse"
13366 [(set (match_operand:SF 0 "register_operand" "=x")
13367 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13370 "%vrcpss\t{%1, %d0|%d0, %1}"
13371 [(set_attr "type" "sse")
13372 (set_attr "atom_sse_attr" "rcp")
13373 (set_attr "btver2_sse_attr" "rcp")
13374 (set_attr "prefix" "maybe_vex")
13375 (set_attr "mode" "SF")])
13377 (define_insn "*fop_<mode>_1_sse"
13378 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13379 (match_operator:MODEF 3 "binary_fp_operator"
13380 [(match_operand:MODEF 1 "register_operand" "0,x")
13381 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13382 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13383 && !COMMUTATIVE_ARITH_P (operands[3])"
13384 "* return output_387_binary_op (insn, operands);"
13385 [(set (attr "type")
13386 (cond [(match_operand:MODEF 3 "mult_operator")
13387 (const_string "ssemul")
13388 (match_operand:MODEF 3 "div_operator")
13389 (const_string "ssediv")
13391 (const_string "sseadd")))
13392 (set_attr "isa" "noavx,avx")
13393 (set_attr "prefix" "orig,vex")
13394 (set_attr "mode" "<MODE>")])
13396 ;; This pattern is not fully shadowed by the pattern above.
13397 (define_insn "*fop_<mode>_1_i387"
13398 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13399 (match_operator:MODEF 3 "binary_fp_operator"
13400 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13401 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13402 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13403 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13404 && !COMMUTATIVE_ARITH_P (operands[3])
13405 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13406 "* return output_387_binary_op (insn, operands);"
13407 [(set (attr "type")
13408 (cond [(match_operand:MODEF 3 "mult_operator")
13409 (const_string "fmul")
13410 (match_operand:MODEF 3 "div_operator")
13411 (const_string "fdiv")
13413 (const_string "fop")))
13414 (set_attr "mode" "<MODE>")])
13416 ;; ??? Add SSE splitters for these!
13417 (define_insn "*fop_<MODEF:mode>_2_i387"
13418 [(set (match_operand:MODEF 0 "register_operand" "=f")
13419 (match_operator:MODEF 3 "binary_fp_operator"
13421 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13422 (match_operand:MODEF 2 "register_operand" "0")]))]
13423 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13424 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13425 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13426 || optimize_function_for_size_p (cfun))"
13427 { return output_387_binary_op (insn, operands); }
13428 [(set (attr "type")
13429 (cond [(match_operand:MODEF 3 "mult_operator")
13430 (const_string "fmul")
13431 (match_operand:MODEF 3 "div_operator")
13432 (const_string "fdiv")
13434 (const_string "fop")))
13435 (set_attr "fp_int_src" "true")
13436 (set_attr "mode" "<SWI24:MODE>")])
13438 (define_insn "*fop_<MODEF:mode>_3_i387"
13439 [(set (match_operand:MODEF 0 "register_operand" "=f")
13440 (match_operator:MODEF 3 "binary_fp_operator"
13441 [(match_operand:MODEF 1 "register_operand" "0")
13443 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13444 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13445 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13446 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13447 || optimize_function_for_size_p (cfun))"
13448 { return output_387_binary_op (insn, operands); }
13449 [(set (attr "type")
13450 (cond [(match_operand:MODEF 3 "mult_operator")
13451 (const_string "fmul")
13452 (match_operand:MODEF 3 "div_operator")
13453 (const_string "fdiv")
13455 (const_string "fop")))
13456 (set_attr "fp_int_src" "true")
13457 (set_attr "mode" "<MODE>")])
13459 (define_insn "*fop_df_4_i387"
13460 [(set (match_operand:DF 0 "register_operand" "=f,f")
13461 (match_operator:DF 3 "binary_fp_operator"
13463 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13464 (match_operand:DF 2 "register_operand" "0,f")]))]
13465 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13466 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13467 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13468 "* return output_387_binary_op (insn, operands);"
13469 [(set (attr "type")
13470 (cond [(match_operand:DF 3 "mult_operator")
13471 (const_string "fmul")
13472 (match_operand:DF 3 "div_operator")
13473 (const_string "fdiv")
13475 (const_string "fop")))
13476 (set_attr "mode" "SF")])
13478 (define_insn "*fop_df_5_i387"
13479 [(set (match_operand:DF 0 "register_operand" "=f,f")
13480 (match_operator:DF 3 "binary_fp_operator"
13481 [(match_operand:DF 1 "register_operand" "0,f")
13483 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13484 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13485 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13486 "* return output_387_binary_op (insn, operands);"
13487 [(set (attr "type")
13488 (cond [(match_operand:DF 3 "mult_operator")
13489 (const_string "fmul")
13490 (match_operand:DF 3 "div_operator")
13491 (const_string "fdiv")
13493 (const_string "fop")))
13494 (set_attr "mode" "SF")])
13496 (define_insn "*fop_df_6_i387"
13497 [(set (match_operand:DF 0 "register_operand" "=f,f")
13498 (match_operator:DF 3 "binary_fp_operator"
13500 (match_operand:SF 1 "register_operand" "0,f"))
13502 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13503 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13504 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13505 "* return output_387_binary_op (insn, operands);"
13506 [(set (attr "type")
13507 (cond [(match_operand:DF 3 "mult_operator")
13508 (const_string "fmul")
13509 (match_operand:DF 3 "div_operator")
13510 (const_string "fdiv")
13512 (const_string "fop")))
13513 (set_attr "mode" "SF")])
13515 (define_insn "*fop_xf_comm_i387"
13516 [(set (match_operand:XF 0 "register_operand" "=f")
13517 (match_operator:XF 3 "binary_fp_operator"
13518 [(match_operand:XF 1 "register_operand" "%0")
13519 (match_operand:XF 2 "register_operand" "f")]))]
13521 && COMMUTATIVE_ARITH_P (operands[3])"
13522 "* return output_387_binary_op (insn, operands);"
13523 [(set (attr "type")
13524 (if_then_else (match_operand:XF 3 "mult_operator")
13525 (const_string "fmul")
13526 (const_string "fop")))
13527 (set_attr "mode" "XF")])
13529 (define_insn "*fop_xf_1_i387"
13530 [(set (match_operand:XF 0 "register_operand" "=f,f")
13531 (match_operator:XF 3 "binary_fp_operator"
13532 [(match_operand:XF 1 "register_operand" "0,f")
13533 (match_operand:XF 2 "register_operand" "f,0")]))]
13535 && !COMMUTATIVE_ARITH_P (operands[3])"
13536 "* return output_387_binary_op (insn, operands);"
13537 [(set (attr "type")
13538 (cond [(match_operand:XF 3 "mult_operator")
13539 (const_string "fmul")
13540 (match_operand:XF 3 "div_operator")
13541 (const_string "fdiv")
13543 (const_string "fop")))
13544 (set_attr "mode" "XF")])
13546 (define_insn "*fop_xf_2_i387"
13547 [(set (match_operand:XF 0 "register_operand" "=f")
13548 (match_operator:XF 3 "binary_fp_operator"
13550 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13551 (match_operand:XF 2 "register_operand" "0")]))]
13553 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13554 { return output_387_binary_op (insn, operands); }
13555 [(set (attr "type")
13556 (cond [(match_operand:XF 3 "mult_operator")
13557 (const_string "fmul")
13558 (match_operand:XF 3 "div_operator")
13559 (const_string "fdiv")
13561 (const_string "fop")))
13562 (set_attr "fp_int_src" "true")
13563 (set_attr "mode" "<MODE>")])
13565 (define_insn "*fop_xf_3_i387"
13566 [(set (match_operand:XF 0 "register_operand" "=f")
13567 (match_operator:XF 3 "binary_fp_operator"
13568 [(match_operand:XF 1 "register_operand" "0")
13570 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13572 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13573 { return output_387_binary_op (insn, operands); }
13574 [(set (attr "type")
13575 (cond [(match_operand:XF 3 "mult_operator")
13576 (const_string "fmul")
13577 (match_operand:XF 3 "div_operator")
13578 (const_string "fdiv")
13580 (const_string "fop")))
13581 (set_attr "fp_int_src" "true")
13582 (set_attr "mode" "<MODE>")])
13584 (define_insn "*fop_xf_4_i387"
13585 [(set (match_operand:XF 0 "register_operand" "=f,f")
13586 (match_operator:XF 3 "binary_fp_operator"
13588 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13589 (match_operand:XF 2 "register_operand" "0,f")]))]
13591 "* return output_387_binary_op (insn, operands);"
13592 [(set (attr "type")
13593 (cond [(match_operand:XF 3 "mult_operator")
13594 (const_string "fmul")
13595 (match_operand:XF 3 "div_operator")
13596 (const_string "fdiv")
13598 (const_string "fop")))
13599 (set_attr "mode" "<MODE>")])
13601 (define_insn "*fop_xf_5_i387"
13602 [(set (match_operand:XF 0 "register_operand" "=f,f")
13603 (match_operator:XF 3 "binary_fp_operator"
13604 [(match_operand:XF 1 "register_operand" "0,f")
13606 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13608 "* return output_387_binary_op (insn, operands);"
13609 [(set (attr "type")
13610 (cond [(match_operand:XF 3 "mult_operator")
13611 (const_string "fmul")
13612 (match_operand:XF 3 "div_operator")
13613 (const_string "fdiv")
13615 (const_string "fop")))
13616 (set_attr "mode" "<MODE>")])
13618 (define_insn "*fop_xf_6_i387"
13619 [(set (match_operand:XF 0 "register_operand" "=f,f")
13620 (match_operator:XF 3 "binary_fp_operator"
13622 (match_operand:MODEF 1 "register_operand" "0,f"))
13624 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13626 "* return output_387_binary_op (insn, operands);"
13627 [(set (attr "type")
13628 (cond [(match_operand:XF 3 "mult_operator")
13629 (const_string "fmul")
13630 (match_operand:XF 3 "div_operator")
13631 (const_string "fdiv")
13633 (const_string "fop")))
13634 (set_attr "mode" "<MODE>")])
13636 ;; FPU special functions.
13638 ;; This pattern implements a no-op XFmode truncation for
13639 ;; all fancy i386 XFmode math functions.
13641 (define_insn "truncxf<mode>2_i387_noop_unspec"
13642 [(set (match_operand:MODEF 0 "register_operand" "=f")
13643 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13644 UNSPEC_TRUNC_NOOP))]
13645 "TARGET_USE_FANCY_MATH_387"
13646 "* return output_387_reg_move (insn, operands);"
13647 [(set_attr "type" "fmov")
13648 (set_attr "mode" "<MODE>")])
13650 (define_insn "sqrtxf2"
13651 [(set (match_operand:XF 0 "register_operand" "=f")
13652 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13653 "TARGET_USE_FANCY_MATH_387"
13655 [(set_attr "type" "fpspc")
13656 (set_attr "mode" "XF")
13657 (set_attr "athlon_decode" "direct")
13658 (set_attr "amdfam10_decode" "direct")
13659 (set_attr "bdver1_decode" "direct")])
13661 (define_insn "sqrt_extend<mode>xf2_i387"
13662 [(set (match_operand:XF 0 "register_operand" "=f")
13665 (match_operand:MODEF 1 "register_operand" "0"))))]
13666 "TARGET_USE_FANCY_MATH_387"
13668 [(set_attr "type" "fpspc")
13669 (set_attr "mode" "XF")
13670 (set_attr "athlon_decode" "direct")
13671 (set_attr "amdfam10_decode" "direct")
13672 (set_attr "bdver1_decode" "direct")])
13674 (define_insn "*rsqrtsf2_sse"
13675 [(set (match_operand:SF 0 "register_operand" "=x")
13676 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13679 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13680 [(set_attr "type" "sse")
13681 (set_attr "atom_sse_attr" "rcp")
13682 (set_attr "btver2_sse_attr" "rcp")
13683 (set_attr "prefix" "maybe_vex")
13684 (set_attr "mode" "SF")])
13686 (define_expand "rsqrtsf2"
13687 [(set (match_operand:SF 0 "register_operand")
13688 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13692 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13696 (define_insn "*sqrt<mode>2_sse"
13697 [(set (match_operand:MODEF 0 "register_operand" "=x")
13699 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13700 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13701 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13702 [(set_attr "type" "sse")
13703 (set_attr "atom_sse_attr" "sqrt")
13704 (set_attr "btver2_sse_attr" "sqrt")
13705 (set_attr "prefix" "maybe_vex")
13706 (set_attr "mode" "<MODE>")
13707 (set_attr "athlon_decode" "*")
13708 (set_attr "amdfam10_decode" "*")
13709 (set_attr "bdver1_decode" "*")])
13711 (define_expand "sqrt<mode>2"
13712 [(set (match_operand:MODEF 0 "register_operand")
13714 (match_operand:MODEF 1 "nonimmediate_operand")))]
13715 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13716 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13718 if (<MODE>mode == SFmode
13720 && TARGET_RECIP_SQRT
13721 && !optimize_function_for_size_p (cfun)
13722 && flag_finite_math_only && !flag_trapping_math
13723 && flag_unsafe_math_optimizations)
13725 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13729 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13731 rtx op0 = gen_reg_rtx (XFmode);
13732 rtx op1 = force_reg (<MODE>mode, operands[1]);
13734 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13735 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13740 (define_insn "fpremxf4_i387"
13741 [(set (match_operand:XF 0 "register_operand" "=f")
13742 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13743 (match_operand:XF 3 "register_operand" "1")]
13745 (set (match_operand:XF 1 "register_operand" "=u")
13746 (unspec:XF [(match_dup 2) (match_dup 3)]
13748 (set (reg:CCFP FPSR_REG)
13749 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13751 "TARGET_USE_FANCY_MATH_387"
13753 [(set_attr "type" "fpspc")
13754 (set_attr "mode" "XF")])
13756 (define_expand "fmodxf3"
13757 [(use (match_operand:XF 0 "register_operand"))
13758 (use (match_operand:XF 1 "general_operand"))
13759 (use (match_operand:XF 2 "general_operand"))]
13760 "TARGET_USE_FANCY_MATH_387"
13762 rtx label = gen_label_rtx ();
13764 rtx op1 = gen_reg_rtx (XFmode);
13765 rtx op2 = gen_reg_rtx (XFmode);
13767 emit_move_insn (op2, operands[2]);
13768 emit_move_insn (op1, operands[1]);
13770 emit_label (label);
13771 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13772 ix86_emit_fp_unordered_jump (label);
13773 LABEL_NUSES (label) = 1;
13775 emit_move_insn (operands[0], op1);
13779 (define_expand "fmod<mode>3"
13780 [(use (match_operand:MODEF 0 "register_operand"))
13781 (use (match_operand:MODEF 1 "general_operand"))
13782 (use (match_operand:MODEF 2 "general_operand"))]
13783 "TARGET_USE_FANCY_MATH_387"
13785 rtx (*gen_truncxf) (rtx, rtx);
13787 rtx label = gen_label_rtx ();
13789 rtx op1 = gen_reg_rtx (XFmode);
13790 rtx op2 = gen_reg_rtx (XFmode);
13792 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13793 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13795 emit_label (label);
13796 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13797 ix86_emit_fp_unordered_jump (label);
13798 LABEL_NUSES (label) = 1;
13800 /* Truncate the result properly for strict SSE math. */
13801 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13802 && !TARGET_MIX_SSE_I387)
13803 gen_truncxf = gen_truncxf<mode>2;
13805 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13807 emit_insn (gen_truncxf (operands[0], op1));
13811 (define_insn "fprem1xf4_i387"
13812 [(set (match_operand:XF 0 "register_operand" "=f")
13813 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13814 (match_operand:XF 3 "register_operand" "1")]
13816 (set (match_operand:XF 1 "register_operand" "=u")
13817 (unspec:XF [(match_dup 2) (match_dup 3)]
13819 (set (reg:CCFP FPSR_REG)
13820 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13822 "TARGET_USE_FANCY_MATH_387"
13824 [(set_attr "type" "fpspc")
13825 (set_attr "mode" "XF")])
13827 (define_expand "remainderxf3"
13828 [(use (match_operand:XF 0 "register_operand"))
13829 (use (match_operand:XF 1 "general_operand"))
13830 (use (match_operand:XF 2 "general_operand"))]
13831 "TARGET_USE_FANCY_MATH_387"
13833 rtx label = gen_label_rtx ();
13835 rtx op1 = gen_reg_rtx (XFmode);
13836 rtx op2 = gen_reg_rtx (XFmode);
13838 emit_move_insn (op2, operands[2]);
13839 emit_move_insn (op1, operands[1]);
13841 emit_label (label);
13842 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13843 ix86_emit_fp_unordered_jump (label);
13844 LABEL_NUSES (label) = 1;
13846 emit_move_insn (operands[0], op1);
13850 (define_expand "remainder<mode>3"
13851 [(use (match_operand:MODEF 0 "register_operand"))
13852 (use (match_operand:MODEF 1 "general_operand"))
13853 (use (match_operand:MODEF 2 "general_operand"))]
13854 "TARGET_USE_FANCY_MATH_387"
13856 rtx (*gen_truncxf) (rtx, rtx);
13858 rtx label = gen_label_rtx ();
13860 rtx op1 = gen_reg_rtx (XFmode);
13861 rtx op2 = gen_reg_rtx (XFmode);
13863 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13864 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13866 emit_label (label);
13868 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13869 ix86_emit_fp_unordered_jump (label);
13870 LABEL_NUSES (label) = 1;
13872 /* Truncate the result properly for strict SSE math. */
13873 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13874 && !TARGET_MIX_SSE_I387)
13875 gen_truncxf = gen_truncxf<mode>2;
13877 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13879 emit_insn (gen_truncxf (operands[0], op1));
13883 (define_int_iterator SINCOS
13887 (define_int_attr sincos
13888 [(UNSPEC_SIN "sin")
13889 (UNSPEC_COS "cos")])
13891 (define_insn "*<sincos>xf2_i387"
13892 [(set (match_operand:XF 0 "register_operand" "=f")
13893 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13895 "TARGET_USE_FANCY_MATH_387
13896 && flag_unsafe_math_optimizations"
13898 [(set_attr "type" "fpspc")
13899 (set_attr "mode" "XF")])
13901 (define_insn "*<sincos>_extend<mode>xf2_i387"
13902 [(set (match_operand:XF 0 "register_operand" "=f")
13903 (unspec:XF [(float_extend:XF
13904 (match_operand:MODEF 1 "register_operand" "0"))]
13906 "TARGET_USE_FANCY_MATH_387
13907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13908 || TARGET_MIX_SSE_I387)
13909 && flag_unsafe_math_optimizations"
13911 [(set_attr "type" "fpspc")
13912 (set_attr "mode" "XF")])
13914 ;; When sincos pattern is defined, sin and cos builtin functions will be
13915 ;; expanded to sincos pattern with one of its outputs left unused.
13916 ;; CSE pass will figure out if two sincos patterns can be combined,
13917 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13918 ;; depending on the unused output.
13920 (define_insn "sincosxf3"
13921 [(set (match_operand:XF 0 "register_operand" "=f")
13922 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13923 UNSPEC_SINCOS_COS))
13924 (set (match_operand:XF 1 "register_operand" "=u")
13925 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13926 "TARGET_USE_FANCY_MATH_387
13927 && flag_unsafe_math_optimizations"
13929 [(set_attr "type" "fpspc")
13930 (set_attr "mode" "XF")])
13933 [(set (match_operand:XF 0 "register_operand")
13934 (unspec:XF [(match_operand:XF 2 "register_operand")]
13935 UNSPEC_SINCOS_COS))
13936 (set (match_operand:XF 1 "register_operand")
13937 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13938 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13939 && can_create_pseudo_p ()"
13940 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13943 [(set (match_operand:XF 0 "register_operand")
13944 (unspec:XF [(match_operand:XF 2 "register_operand")]
13945 UNSPEC_SINCOS_COS))
13946 (set (match_operand:XF 1 "register_operand")
13947 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13948 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13949 && can_create_pseudo_p ()"
13950 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13952 (define_insn "sincos_extend<mode>xf3_i387"
13953 [(set (match_operand:XF 0 "register_operand" "=f")
13954 (unspec:XF [(float_extend:XF
13955 (match_operand:MODEF 2 "register_operand" "0"))]
13956 UNSPEC_SINCOS_COS))
13957 (set (match_operand:XF 1 "register_operand" "=u")
13958 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13959 "TARGET_USE_FANCY_MATH_387
13960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13961 || TARGET_MIX_SSE_I387)
13962 && flag_unsafe_math_optimizations"
13964 [(set_attr "type" "fpspc")
13965 (set_attr "mode" "XF")])
13968 [(set (match_operand:XF 0 "register_operand")
13969 (unspec:XF [(float_extend:XF
13970 (match_operand:MODEF 2 "register_operand"))]
13971 UNSPEC_SINCOS_COS))
13972 (set (match_operand:XF 1 "register_operand")
13973 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13974 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13975 && can_create_pseudo_p ()"
13976 [(set (match_dup 1)
13977 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13980 [(set (match_operand:XF 0 "register_operand")
13981 (unspec:XF [(float_extend:XF
13982 (match_operand:MODEF 2 "register_operand"))]
13983 UNSPEC_SINCOS_COS))
13984 (set (match_operand:XF 1 "register_operand")
13985 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13986 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13987 && can_create_pseudo_p ()"
13988 [(set (match_dup 0)
13989 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13991 (define_expand "sincos<mode>3"
13992 [(use (match_operand:MODEF 0 "register_operand"))
13993 (use (match_operand:MODEF 1 "register_operand"))
13994 (use (match_operand:MODEF 2 "register_operand"))]
13995 "TARGET_USE_FANCY_MATH_387
13996 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13997 || TARGET_MIX_SSE_I387)
13998 && flag_unsafe_math_optimizations"
14000 rtx op0 = gen_reg_rtx (XFmode);
14001 rtx op1 = gen_reg_rtx (XFmode);
14003 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14004 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14005 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14009 (define_insn "fptanxf4_i387"
14010 [(set (match_operand:XF 0 "register_operand" "=f")
14011 (match_operand:XF 3 "const_double_operand" "F"))
14012 (set (match_operand:XF 1 "register_operand" "=u")
14013 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14015 "TARGET_USE_FANCY_MATH_387
14016 && flag_unsafe_math_optimizations
14017 && standard_80387_constant_p (operands[3]) == 2"
14019 [(set_attr "type" "fpspc")
14020 (set_attr "mode" "XF")])
14022 (define_insn "fptan_extend<mode>xf4_i387"
14023 [(set (match_operand:MODEF 0 "register_operand" "=f")
14024 (match_operand:MODEF 3 "const_double_operand" "F"))
14025 (set (match_operand:XF 1 "register_operand" "=u")
14026 (unspec:XF [(float_extend:XF
14027 (match_operand:MODEF 2 "register_operand" "0"))]
14029 "TARGET_USE_FANCY_MATH_387
14030 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14031 || TARGET_MIX_SSE_I387)
14032 && flag_unsafe_math_optimizations
14033 && standard_80387_constant_p (operands[3]) == 2"
14035 [(set_attr "type" "fpspc")
14036 (set_attr "mode" "XF")])
14038 (define_expand "tanxf2"
14039 [(use (match_operand:XF 0 "register_operand"))
14040 (use (match_operand:XF 1 "register_operand"))]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14044 rtx one = gen_reg_rtx (XFmode);
14045 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14047 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14051 (define_expand "tan<mode>2"
14052 [(use (match_operand:MODEF 0 "register_operand"))
14053 (use (match_operand:MODEF 1 "register_operand"))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056 || TARGET_MIX_SSE_I387)
14057 && flag_unsafe_math_optimizations"
14059 rtx op0 = gen_reg_rtx (XFmode);
14061 rtx one = gen_reg_rtx (<MODE>mode);
14062 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14064 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14065 operands[1], op2));
14066 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14070 (define_insn "*fpatanxf3_i387"
14071 [(set (match_operand:XF 0 "register_operand" "=f")
14072 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14073 (match_operand:XF 2 "register_operand" "u")]
14075 (clobber (match_scratch:XF 3 "=2"))]
14076 "TARGET_USE_FANCY_MATH_387
14077 && flag_unsafe_math_optimizations"
14079 [(set_attr "type" "fpspc")
14080 (set_attr "mode" "XF")])
14082 (define_insn "fpatan_extend<mode>xf3_i387"
14083 [(set (match_operand:XF 0 "register_operand" "=f")
14084 (unspec:XF [(float_extend:XF
14085 (match_operand:MODEF 1 "register_operand" "0"))
14087 (match_operand:MODEF 2 "register_operand" "u"))]
14089 (clobber (match_scratch:XF 3 "=2"))]
14090 "TARGET_USE_FANCY_MATH_387
14091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14092 || TARGET_MIX_SSE_I387)
14093 && flag_unsafe_math_optimizations"
14095 [(set_attr "type" "fpspc")
14096 (set_attr "mode" "XF")])
14098 (define_expand "atan2xf3"
14099 [(parallel [(set (match_operand:XF 0 "register_operand")
14100 (unspec:XF [(match_operand:XF 2 "register_operand")
14101 (match_operand:XF 1 "register_operand")]
14103 (clobber (match_scratch:XF 3))])]
14104 "TARGET_USE_FANCY_MATH_387
14105 && flag_unsafe_math_optimizations")
14107 (define_expand "atan2<mode>3"
14108 [(use (match_operand:MODEF 0 "register_operand"))
14109 (use (match_operand:MODEF 1 "register_operand"))
14110 (use (match_operand:MODEF 2 "register_operand"))]
14111 "TARGET_USE_FANCY_MATH_387
14112 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14113 || TARGET_MIX_SSE_I387)
14114 && flag_unsafe_math_optimizations"
14116 rtx op0 = gen_reg_rtx (XFmode);
14118 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14119 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14123 (define_expand "atanxf2"
14124 [(parallel [(set (match_operand:XF 0 "register_operand")
14125 (unspec:XF [(match_dup 2)
14126 (match_operand:XF 1 "register_operand")]
14128 (clobber (match_scratch:XF 3))])]
14129 "TARGET_USE_FANCY_MATH_387
14130 && flag_unsafe_math_optimizations"
14132 operands[2] = gen_reg_rtx (XFmode);
14133 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14136 (define_expand "atan<mode>2"
14137 [(use (match_operand:MODEF 0 "register_operand"))
14138 (use (match_operand:MODEF 1 "register_operand"))]
14139 "TARGET_USE_FANCY_MATH_387
14140 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14141 || TARGET_MIX_SSE_I387)
14142 && flag_unsafe_math_optimizations"
14144 rtx op0 = gen_reg_rtx (XFmode);
14146 rtx op2 = gen_reg_rtx (<MODE>mode);
14147 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14149 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14150 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14154 (define_expand "asinxf2"
14155 [(set (match_dup 2)
14156 (mult:XF (match_operand:XF 1 "register_operand")
14158 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14159 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14160 (parallel [(set (match_operand:XF 0 "register_operand")
14161 (unspec:XF [(match_dup 5) (match_dup 1)]
14163 (clobber (match_scratch:XF 6))])]
14164 "TARGET_USE_FANCY_MATH_387
14165 && flag_unsafe_math_optimizations"
14169 if (optimize_insn_for_size_p ())
14172 for (i = 2; i < 6; i++)
14173 operands[i] = gen_reg_rtx (XFmode);
14175 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14178 (define_expand "asin<mode>2"
14179 [(use (match_operand:MODEF 0 "register_operand"))
14180 (use (match_operand:MODEF 1 "general_operand"))]
14181 "TARGET_USE_FANCY_MATH_387
14182 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14183 || TARGET_MIX_SSE_I387)
14184 && flag_unsafe_math_optimizations"
14186 rtx op0 = gen_reg_rtx (XFmode);
14187 rtx op1 = gen_reg_rtx (XFmode);
14189 if (optimize_insn_for_size_p ())
14192 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14193 emit_insn (gen_asinxf2 (op0, op1));
14194 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14198 (define_expand "acosxf2"
14199 [(set (match_dup 2)
14200 (mult:XF (match_operand:XF 1 "register_operand")
14202 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14203 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14204 (parallel [(set (match_operand:XF 0 "register_operand")
14205 (unspec:XF [(match_dup 1) (match_dup 5)]
14207 (clobber (match_scratch:XF 6))])]
14208 "TARGET_USE_FANCY_MATH_387
14209 && flag_unsafe_math_optimizations"
14213 if (optimize_insn_for_size_p ())
14216 for (i = 2; i < 6; i++)
14217 operands[i] = gen_reg_rtx (XFmode);
14219 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14222 (define_expand "acos<mode>2"
14223 [(use (match_operand:MODEF 0 "register_operand"))
14224 (use (match_operand:MODEF 1 "general_operand"))]
14225 "TARGET_USE_FANCY_MATH_387
14226 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14227 || TARGET_MIX_SSE_I387)
14228 && flag_unsafe_math_optimizations"
14230 rtx op0 = gen_reg_rtx (XFmode);
14231 rtx op1 = gen_reg_rtx (XFmode);
14233 if (optimize_insn_for_size_p ())
14236 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14237 emit_insn (gen_acosxf2 (op0, op1));
14238 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14242 (define_insn "fyl2xxf3_i387"
14243 [(set (match_operand:XF 0 "register_operand" "=f")
14244 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14245 (match_operand:XF 2 "register_operand" "u")]
14247 (clobber (match_scratch:XF 3 "=2"))]
14248 "TARGET_USE_FANCY_MATH_387
14249 && flag_unsafe_math_optimizations"
14251 [(set_attr "type" "fpspc")
14252 (set_attr "mode" "XF")])
14254 (define_insn "fyl2x_extend<mode>xf3_i387"
14255 [(set (match_operand:XF 0 "register_operand" "=f")
14256 (unspec:XF [(float_extend:XF
14257 (match_operand:MODEF 1 "register_operand" "0"))
14258 (match_operand:XF 2 "register_operand" "u")]
14260 (clobber (match_scratch:XF 3 "=2"))]
14261 "TARGET_USE_FANCY_MATH_387
14262 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14263 || TARGET_MIX_SSE_I387)
14264 && flag_unsafe_math_optimizations"
14266 [(set_attr "type" "fpspc")
14267 (set_attr "mode" "XF")])
14269 (define_expand "logxf2"
14270 [(parallel [(set (match_operand:XF 0 "register_operand")
14271 (unspec:XF [(match_operand:XF 1 "register_operand")
14272 (match_dup 2)] UNSPEC_FYL2X))
14273 (clobber (match_scratch:XF 3))])]
14274 "TARGET_USE_FANCY_MATH_387
14275 && flag_unsafe_math_optimizations"
14277 operands[2] = gen_reg_rtx (XFmode);
14278 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14281 (define_expand "log<mode>2"
14282 [(use (match_operand:MODEF 0 "register_operand"))
14283 (use (match_operand:MODEF 1 "register_operand"))]
14284 "TARGET_USE_FANCY_MATH_387
14285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14286 || TARGET_MIX_SSE_I387)
14287 && flag_unsafe_math_optimizations"
14289 rtx op0 = gen_reg_rtx (XFmode);
14291 rtx op2 = gen_reg_rtx (XFmode);
14292 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14294 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14295 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14299 (define_expand "log10xf2"
14300 [(parallel [(set (match_operand:XF 0 "register_operand")
14301 (unspec:XF [(match_operand:XF 1 "register_operand")
14302 (match_dup 2)] UNSPEC_FYL2X))
14303 (clobber (match_scratch:XF 3))])]
14304 "TARGET_USE_FANCY_MATH_387
14305 && flag_unsafe_math_optimizations"
14307 operands[2] = gen_reg_rtx (XFmode);
14308 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14311 (define_expand "log10<mode>2"
14312 [(use (match_operand:MODEF 0 "register_operand"))
14313 (use (match_operand:MODEF 1 "register_operand"))]
14314 "TARGET_USE_FANCY_MATH_387
14315 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14316 || TARGET_MIX_SSE_I387)
14317 && flag_unsafe_math_optimizations"
14319 rtx op0 = gen_reg_rtx (XFmode);
14321 rtx op2 = gen_reg_rtx (XFmode);
14322 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14324 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14325 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14329 (define_expand "log2xf2"
14330 [(parallel [(set (match_operand:XF 0 "register_operand")
14331 (unspec:XF [(match_operand:XF 1 "register_operand")
14332 (match_dup 2)] UNSPEC_FYL2X))
14333 (clobber (match_scratch:XF 3))])]
14334 "TARGET_USE_FANCY_MATH_387
14335 && flag_unsafe_math_optimizations"
14337 operands[2] = gen_reg_rtx (XFmode);
14338 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14341 (define_expand "log2<mode>2"
14342 [(use (match_operand:MODEF 0 "register_operand"))
14343 (use (match_operand:MODEF 1 "register_operand"))]
14344 "TARGET_USE_FANCY_MATH_387
14345 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14346 || TARGET_MIX_SSE_I387)
14347 && flag_unsafe_math_optimizations"
14349 rtx op0 = gen_reg_rtx (XFmode);
14351 rtx op2 = gen_reg_rtx (XFmode);
14352 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14354 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14355 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14359 (define_insn "fyl2xp1xf3_i387"
14360 [(set (match_operand:XF 0 "register_operand" "=f")
14361 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14362 (match_operand:XF 2 "register_operand" "u")]
14364 (clobber (match_scratch:XF 3 "=2"))]
14365 "TARGET_USE_FANCY_MATH_387
14366 && flag_unsafe_math_optimizations"
14368 [(set_attr "type" "fpspc")
14369 (set_attr "mode" "XF")])
14371 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14372 [(set (match_operand:XF 0 "register_operand" "=f")
14373 (unspec:XF [(float_extend:XF
14374 (match_operand:MODEF 1 "register_operand" "0"))
14375 (match_operand:XF 2 "register_operand" "u")]
14377 (clobber (match_scratch:XF 3 "=2"))]
14378 "TARGET_USE_FANCY_MATH_387
14379 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380 || TARGET_MIX_SSE_I387)
14381 && flag_unsafe_math_optimizations"
14383 [(set_attr "type" "fpspc")
14384 (set_attr "mode" "XF")])
14386 (define_expand "log1pxf2"
14387 [(use (match_operand:XF 0 "register_operand"))
14388 (use (match_operand:XF 1 "register_operand"))]
14389 "TARGET_USE_FANCY_MATH_387
14390 && flag_unsafe_math_optimizations"
14392 if (optimize_insn_for_size_p ())
14395 ix86_emit_i387_log1p (operands[0], operands[1]);
14399 (define_expand "log1p<mode>2"
14400 [(use (match_operand:MODEF 0 "register_operand"))
14401 (use (match_operand:MODEF 1 "register_operand"))]
14402 "TARGET_USE_FANCY_MATH_387
14403 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14404 || TARGET_MIX_SSE_I387)
14405 && flag_unsafe_math_optimizations"
14409 if (optimize_insn_for_size_p ())
14412 op0 = gen_reg_rtx (XFmode);
14414 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14416 ix86_emit_i387_log1p (op0, operands[1]);
14417 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14421 (define_insn "fxtractxf3_i387"
14422 [(set (match_operand:XF 0 "register_operand" "=f")
14423 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14424 UNSPEC_XTRACT_FRACT))
14425 (set (match_operand:XF 1 "register_operand" "=u")
14426 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14427 "TARGET_USE_FANCY_MATH_387
14428 && flag_unsafe_math_optimizations"
14430 [(set_attr "type" "fpspc")
14431 (set_attr "mode" "XF")])
14433 (define_insn "fxtract_extend<mode>xf3_i387"
14434 [(set (match_operand:XF 0 "register_operand" "=f")
14435 (unspec:XF [(float_extend:XF
14436 (match_operand:MODEF 2 "register_operand" "0"))]
14437 UNSPEC_XTRACT_FRACT))
14438 (set (match_operand:XF 1 "register_operand" "=u")
14439 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14440 "TARGET_USE_FANCY_MATH_387
14441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14442 || TARGET_MIX_SSE_I387)
14443 && flag_unsafe_math_optimizations"
14445 [(set_attr "type" "fpspc")
14446 (set_attr "mode" "XF")])
14448 (define_expand "logbxf2"
14449 [(parallel [(set (match_dup 2)
14450 (unspec:XF [(match_operand:XF 1 "register_operand")]
14451 UNSPEC_XTRACT_FRACT))
14452 (set (match_operand:XF 0 "register_operand")
14453 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14454 "TARGET_USE_FANCY_MATH_387
14455 && flag_unsafe_math_optimizations"
14456 "operands[2] = gen_reg_rtx (XFmode);")
14458 (define_expand "logb<mode>2"
14459 [(use (match_operand:MODEF 0 "register_operand"))
14460 (use (match_operand:MODEF 1 "register_operand"))]
14461 "TARGET_USE_FANCY_MATH_387
14462 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14463 || TARGET_MIX_SSE_I387)
14464 && flag_unsafe_math_optimizations"
14466 rtx op0 = gen_reg_rtx (XFmode);
14467 rtx op1 = gen_reg_rtx (XFmode);
14469 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14470 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14474 (define_expand "ilogbxf2"
14475 [(use (match_operand:SI 0 "register_operand"))
14476 (use (match_operand:XF 1 "register_operand"))]
14477 "TARGET_USE_FANCY_MATH_387
14478 && flag_unsafe_math_optimizations"
14482 if (optimize_insn_for_size_p ())
14485 op0 = gen_reg_rtx (XFmode);
14486 op1 = gen_reg_rtx (XFmode);
14488 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14489 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14493 (define_expand "ilogb<mode>2"
14494 [(use (match_operand:SI 0 "register_operand"))
14495 (use (match_operand:MODEF 1 "register_operand"))]
14496 "TARGET_USE_FANCY_MATH_387
14497 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14498 || TARGET_MIX_SSE_I387)
14499 && flag_unsafe_math_optimizations"
14503 if (optimize_insn_for_size_p ())
14506 op0 = gen_reg_rtx (XFmode);
14507 op1 = gen_reg_rtx (XFmode);
14509 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14510 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14514 (define_insn "*f2xm1xf2_i387"
14515 [(set (match_operand:XF 0 "register_operand" "=f")
14516 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14518 "TARGET_USE_FANCY_MATH_387
14519 && flag_unsafe_math_optimizations"
14521 [(set_attr "type" "fpspc")
14522 (set_attr "mode" "XF")])
14524 (define_insn "fscalexf4_i387"
14525 [(set (match_operand:XF 0 "register_operand" "=f")
14526 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14527 (match_operand:XF 3 "register_operand" "1")]
14528 UNSPEC_FSCALE_FRACT))
14529 (set (match_operand:XF 1 "register_operand" "=u")
14530 (unspec:XF [(match_dup 2) (match_dup 3)]
14531 UNSPEC_FSCALE_EXP))]
14532 "TARGET_USE_FANCY_MATH_387
14533 && flag_unsafe_math_optimizations"
14535 [(set_attr "type" "fpspc")
14536 (set_attr "mode" "XF")])
14538 (define_expand "expNcorexf3"
14539 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14540 (match_operand:XF 2 "register_operand")))
14541 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14542 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14543 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14544 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14545 (parallel [(set (match_operand:XF 0 "register_operand")
14546 (unspec:XF [(match_dup 8) (match_dup 4)]
14547 UNSPEC_FSCALE_FRACT))
14549 (unspec:XF [(match_dup 8) (match_dup 4)]
14550 UNSPEC_FSCALE_EXP))])]
14551 "TARGET_USE_FANCY_MATH_387
14552 && flag_unsafe_math_optimizations"
14556 if (optimize_insn_for_size_p ())
14559 for (i = 3; i < 10; i++)
14560 operands[i] = gen_reg_rtx (XFmode);
14562 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14565 (define_expand "expxf2"
14566 [(use (match_operand:XF 0 "register_operand"))
14567 (use (match_operand:XF 1 "register_operand"))]
14568 "TARGET_USE_FANCY_MATH_387
14569 && flag_unsafe_math_optimizations"
14573 if (optimize_insn_for_size_p ())
14576 op2 = gen_reg_rtx (XFmode);
14577 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14579 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14583 (define_expand "exp<mode>2"
14584 [(use (match_operand:MODEF 0 "register_operand"))
14585 (use (match_operand:MODEF 1 "general_operand"))]
14586 "TARGET_USE_FANCY_MATH_387
14587 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14588 || TARGET_MIX_SSE_I387)
14589 && flag_unsafe_math_optimizations"
14593 if (optimize_insn_for_size_p ())
14596 op0 = gen_reg_rtx (XFmode);
14597 op1 = gen_reg_rtx (XFmode);
14599 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14600 emit_insn (gen_expxf2 (op0, op1));
14601 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14605 (define_expand "exp10xf2"
14606 [(use (match_operand:XF 0 "register_operand"))
14607 (use (match_operand:XF 1 "register_operand"))]
14608 "TARGET_USE_FANCY_MATH_387
14609 && flag_unsafe_math_optimizations"
14613 if (optimize_insn_for_size_p ())
14616 op2 = gen_reg_rtx (XFmode);
14617 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14619 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14623 (define_expand "exp10<mode>2"
14624 [(use (match_operand:MODEF 0 "register_operand"))
14625 (use (match_operand:MODEF 1 "general_operand"))]
14626 "TARGET_USE_FANCY_MATH_387
14627 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14628 || TARGET_MIX_SSE_I387)
14629 && flag_unsafe_math_optimizations"
14633 if (optimize_insn_for_size_p ())
14636 op0 = gen_reg_rtx (XFmode);
14637 op1 = gen_reg_rtx (XFmode);
14639 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14640 emit_insn (gen_exp10xf2 (op0, op1));
14641 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14645 (define_expand "exp2xf2"
14646 [(use (match_operand:XF 0 "register_operand"))
14647 (use (match_operand:XF 1 "register_operand"))]
14648 "TARGET_USE_FANCY_MATH_387
14649 && flag_unsafe_math_optimizations"
14653 if (optimize_insn_for_size_p ())
14656 op2 = gen_reg_rtx (XFmode);
14657 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14659 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14663 (define_expand "exp2<mode>2"
14664 [(use (match_operand:MODEF 0 "register_operand"))
14665 (use (match_operand:MODEF 1 "general_operand"))]
14666 "TARGET_USE_FANCY_MATH_387
14667 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14668 || TARGET_MIX_SSE_I387)
14669 && flag_unsafe_math_optimizations"
14673 if (optimize_insn_for_size_p ())
14676 op0 = gen_reg_rtx (XFmode);
14677 op1 = gen_reg_rtx (XFmode);
14679 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14680 emit_insn (gen_exp2xf2 (op0, op1));
14681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14685 (define_expand "expm1xf2"
14686 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14688 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14689 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14690 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14691 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14692 (parallel [(set (match_dup 7)
14693 (unspec:XF [(match_dup 6) (match_dup 4)]
14694 UNSPEC_FSCALE_FRACT))
14696 (unspec:XF [(match_dup 6) (match_dup 4)]
14697 UNSPEC_FSCALE_EXP))])
14698 (parallel [(set (match_dup 10)
14699 (unspec:XF [(match_dup 9) (match_dup 8)]
14700 UNSPEC_FSCALE_FRACT))
14701 (set (match_dup 11)
14702 (unspec:XF [(match_dup 9) (match_dup 8)]
14703 UNSPEC_FSCALE_EXP))])
14704 (set (match_dup 12) (minus:XF (match_dup 10)
14705 (float_extend:XF (match_dup 13))))
14706 (set (match_operand:XF 0 "register_operand")
14707 (plus:XF (match_dup 12) (match_dup 7)))]
14708 "TARGET_USE_FANCY_MATH_387
14709 && flag_unsafe_math_optimizations"
14713 if (optimize_insn_for_size_p ())
14716 for (i = 2; i < 13; i++)
14717 operands[i] = gen_reg_rtx (XFmode);
14720 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14722 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14725 (define_expand "expm1<mode>2"
14726 [(use (match_operand:MODEF 0 "register_operand"))
14727 (use (match_operand:MODEF 1 "general_operand"))]
14728 "TARGET_USE_FANCY_MATH_387
14729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14730 || TARGET_MIX_SSE_I387)
14731 && flag_unsafe_math_optimizations"
14735 if (optimize_insn_for_size_p ())
14738 op0 = gen_reg_rtx (XFmode);
14739 op1 = gen_reg_rtx (XFmode);
14741 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14742 emit_insn (gen_expm1xf2 (op0, op1));
14743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14747 (define_expand "ldexpxf3"
14748 [(match_operand:XF 0 "register_operand")
14749 (match_operand:XF 1 "register_operand")
14750 (match_operand:SI 2 "register_operand")]
14751 "TARGET_USE_FANCY_MATH_387
14752 && flag_unsafe_math_optimizations"
14755 if (optimize_insn_for_size_p ())
14758 tmp1 = gen_reg_rtx (XFmode);
14759 tmp2 = gen_reg_rtx (XFmode);
14761 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14762 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14763 operands[1], tmp1));
14767 (define_expand "ldexp<mode>3"
14768 [(use (match_operand:MODEF 0 "register_operand"))
14769 (use (match_operand:MODEF 1 "general_operand"))
14770 (use (match_operand:SI 2 "register_operand"))]
14771 "TARGET_USE_FANCY_MATH_387
14772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14773 || TARGET_MIX_SSE_I387)
14774 && flag_unsafe_math_optimizations"
14778 if (optimize_insn_for_size_p ())
14781 op0 = gen_reg_rtx (XFmode);
14782 op1 = gen_reg_rtx (XFmode);
14784 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14785 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14786 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14790 (define_expand "scalbxf3"
14791 [(parallel [(set (match_operand:XF 0 " register_operand")
14792 (unspec:XF [(match_operand:XF 1 "register_operand")
14793 (match_operand:XF 2 "register_operand")]
14794 UNSPEC_FSCALE_FRACT))
14796 (unspec:XF [(match_dup 1) (match_dup 2)]
14797 UNSPEC_FSCALE_EXP))])]
14798 "TARGET_USE_FANCY_MATH_387
14799 && flag_unsafe_math_optimizations"
14801 if (optimize_insn_for_size_p ())
14804 operands[3] = gen_reg_rtx (XFmode);
14807 (define_expand "scalb<mode>3"
14808 [(use (match_operand:MODEF 0 "register_operand"))
14809 (use (match_operand:MODEF 1 "general_operand"))
14810 (use (match_operand:MODEF 2 "general_operand"))]
14811 "TARGET_USE_FANCY_MATH_387
14812 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14813 || TARGET_MIX_SSE_I387)
14814 && flag_unsafe_math_optimizations"
14818 if (optimize_insn_for_size_p ())
14821 op0 = gen_reg_rtx (XFmode);
14822 op1 = gen_reg_rtx (XFmode);
14823 op2 = gen_reg_rtx (XFmode);
14825 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14826 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14827 emit_insn (gen_scalbxf3 (op0, op1, op2));
14828 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14832 (define_expand "significandxf2"
14833 [(parallel [(set (match_operand:XF 0 "register_operand")
14834 (unspec:XF [(match_operand:XF 1 "register_operand")]
14835 UNSPEC_XTRACT_FRACT))
14837 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14838 "TARGET_USE_FANCY_MATH_387
14839 && flag_unsafe_math_optimizations"
14840 "operands[2] = gen_reg_rtx (XFmode);")
14842 (define_expand "significand<mode>2"
14843 [(use (match_operand:MODEF 0 "register_operand"))
14844 (use (match_operand:MODEF 1 "register_operand"))]
14845 "TARGET_USE_FANCY_MATH_387
14846 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14847 || TARGET_MIX_SSE_I387)
14848 && flag_unsafe_math_optimizations"
14850 rtx op0 = gen_reg_rtx (XFmode);
14851 rtx op1 = gen_reg_rtx (XFmode);
14853 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14854 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14859 (define_insn "sse4_1_round<mode>2"
14860 [(set (match_operand:MODEF 0 "register_operand" "=x")
14861 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14862 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14865 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14866 [(set_attr "type" "ssecvt")
14867 (set_attr "prefix_extra" "1")
14868 (set_attr "prefix" "maybe_vex")
14869 (set_attr "mode" "<MODE>")])
14871 (define_insn "rintxf2"
14872 [(set (match_operand:XF 0 "register_operand" "=f")
14873 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14875 "TARGET_USE_FANCY_MATH_387
14876 && flag_unsafe_math_optimizations"
14878 [(set_attr "type" "fpspc")
14879 (set_attr "mode" "XF")])
14881 (define_expand "rint<mode>2"
14882 [(use (match_operand:MODEF 0 "register_operand"))
14883 (use (match_operand:MODEF 1 "register_operand"))]
14884 "(TARGET_USE_FANCY_MATH_387
14885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14886 || TARGET_MIX_SSE_I387)
14887 && flag_unsafe_math_optimizations)
14888 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14889 && !flag_trapping_math)"
14891 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14892 && !flag_trapping_math)
14895 emit_insn (gen_sse4_1_round<mode>2
14896 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14897 else if (optimize_insn_for_size_p ())
14900 ix86_expand_rint (operands[0], operands[1]);
14904 rtx op0 = gen_reg_rtx (XFmode);
14905 rtx op1 = gen_reg_rtx (XFmode);
14907 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14908 emit_insn (gen_rintxf2 (op0, op1));
14910 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14915 (define_expand "round<mode>2"
14916 [(match_operand:X87MODEF 0 "register_operand")
14917 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14918 "(TARGET_USE_FANCY_MATH_387
14919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14920 || TARGET_MIX_SSE_I387)
14921 && flag_unsafe_math_optimizations)
14922 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14923 && !flag_trapping_math && !flag_rounding_math)"
14925 if (optimize_insn_for_size_p ())
14928 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14929 && !flag_trapping_math && !flag_rounding_math)
14933 operands[1] = force_reg (<MODE>mode, operands[1]);
14934 ix86_expand_round_sse4 (operands[0], operands[1]);
14936 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14937 ix86_expand_round (operands[0], operands[1]);
14939 ix86_expand_rounddf_32 (operands[0], operands[1]);
14943 operands[1] = force_reg (<MODE>mode, operands[1]);
14944 ix86_emit_i387_round (operands[0], operands[1]);
14949 (define_insn_and_split "*fistdi2_1"
14950 [(set (match_operand:DI 0 "nonimmediate_operand")
14951 (unspec:DI [(match_operand:XF 1 "register_operand")]
14953 "TARGET_USE_FANCY_MATH_387
14954 && can_create_pseudo_p ()"
14959 if (memory_operand (operands[0], VOIDmode))
14960 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14963 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14964 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14969 [(set_attr "type" "fpspc")
14970 (set_attr "mode" "DI")])
14972 (define_insn "fistdi2"
14973 [(set (match_operand:DI 0 "memory_operand" "=m")
14974 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14976 (clobber (match_scratch:XF 2 "=&1f"))]
14977 "TARGET_USE_FANCY_MATH_387"
14978 "* return output_fix_trunc (insn, operands, false);"
14979 [(set_attr "type" "fpspc")
14980 (set_attr "mode" "DI")])
14982 (define_insn "fistdi2_with_temp"
14983 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14984 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14986 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14987 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14988 "TARGET_USE_FANCY_MATH_387"
14990 [(set_attr "type" "fpspc")
14991 (set_attr "mode" "DI")])
14994 [(set (match_operand:DI 0 "register_operand")
14995 (unspec:DI [(match_operand:XF 1 "register_operand")]
14997 (clobber (match_operand:DI 2 "memory_operand"))
14998 (clobber (match_scratch 3))]
15000 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15001 (clobber (match_dup 3))])
15002 (set (match_dup 0) (match_dup 2))])
15005 [(set (match_operand:DI 0 "memory_operand")
15006 (unspec:DI [(match_operand:XF 1 "register_operand")]
15008 (clobber (match_operand:DI 2 "memory_operand"))
15009 (clobber (match_scratch 3))]
15011 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15012 (clobber (match_dup 3))])])
15014 (define_insn_and_split "*fist<mode>2_1"
15015 [(set (match_operand:SWI24 0 "register_operand")
15016 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15018 "TARGET_USE_FANCY_MATH_387
15019 && can_create_pseudo_p ()"
15024 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15025 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15029 [(set_attr "type" "fpspc")
15030 (set_attr "mode" "<MODE>")])
15032 (define_insn "fist<mode>2"
15033 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15034 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15036 "TARGET_USE_FANCY_MATH_387"
15037 "* return output_fix_trunc (insn, operands, false);"
15038 [(set_attr "type" "fpspc")
15039 (set_attr "mode" "<MODE>")])
15041 (define_insn "fist<mode>2_with_temp"
15042 [(set (match_operand:SWI24 0 "register_operand" "=r")
15043 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15045 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15046 "TARGET_USE_FANCY_MATH_387"
15048 [(set_attr "type" "fpspc")
15049 (set_attr "mode" "<MODE>")])
15052 [(set (match_operand:SWI24 0 "register_operand")
15053 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15055 (clobber (match_operand:SWI24 2 "memory_operand"))]
15057 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15058 (set (match_dup 0) (match_dup 2))])
15061 [(set (match_operand:SWI24 0 "memory_operand")
15062 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15064 (clobber (match_operand:SWI24 2 "memory_operand"))]
15066 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15068 (define_expand "lrintxf<mode>2"
15069 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15070 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15072 "TARGET_USE_FANCY_MATH_387")
15074 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15075 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15076 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15077 UNSPEC_FIX_NOTRUNC))]
15078 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15080 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15081 [(match_operand:SWI248x 0 "nonimmediate_operand")
15082 (match_operand:X87MODEF 1 "register_operand")]
15083 "(TARGET_USE_FANCY_MATH_387
15084 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15085 || TARGET_MIX_SSE_I387)
15086 && flag_unsafe_math_optimizations)
15087 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15088 && <SWI248x:MODE>mode != HImode
15089 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15090 && !flag_trapping_math && !flag_rounding_math)"
15092 if (optimize_insn_for_size_p ())
15095 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15096 && <SWI248x:MODE>mode != HImode
15097 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15098 && !flag_trapping_math && !flag_rounding_math)
15099 ix86_expand_lround (operands[0], operands[1]);
15101 ix86_emit_i387_round (operands[0], operands[1]);
15105 (define_int_iterator FRNDINT_ROUNDING
15106 [UNSPEC_FRNDINT_FLOOR
15107 UNSPEC_FRNDINT_CEIL
15108 UNSPEC_FRNDINT_TRUNC])
15110 (define_int_iterator FIST_ROUNDING
15114 ;; Base name for define_insn
15115 (define_int_attr rounding_insn
15116 [(UNSPEC_FRNDINT_FLOOR "floor")
15117 (UNSPEC_FRNDINT_CEIL "ceil")
15118 (UNSPEC_FRNDINT_TRUNC "btrunc")
15119 (UNSPEC_FIST_FLOOR "floor")
15120 (UNSPEC_FIST_CEIL "ceil")])
15122 (define_int_attr rounding
15123 [(UNSPEC_FRNDINT_FLOOR "floor")
15124 (UNSPEC_FRNDINT_CEIL "ceil")
15125 (UNSPEC_FRNDINT_TRUNC "trunc")
15126 (UNSPEC_FIST_FLOOR "floor")
15127 (UNSPEC_FIST_CEIL "ceil")])
15129 (define_int_attr ROUNDING
15130 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15131 (UNSPEC_FRNDINT_CEIL "CEIL")
15132 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15133 (UNSPEC_FIST_FLOOR "FLOOR")
15134 (UNSPEC_FIST_CEIL "CEIL")])
15136 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15137 (define_insn_and_split "frndintxf2_<rounding>"
15138 [(set (match_operand:XF 0 "register_operand")
15139 (unspec:XF [(match_operand:XF 1 "register_operand")]
15141 (clobber (reg:CC FLAGS_REG))]
15142 "TARGET_USE_FANCY_MATH_387
15143 && flag_unsafe_math_optimizations
15144 && can_create_pseudo_p ()"
15149 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15151 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15152 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15154 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15155 operands[2], operands[3]));
15158 [(set_attr "type" "frndint")
15159 (set_attr "i387_cw" "<rounding>")
15160 (set_attr "mode" "XF")])
15162 (define_insn "frndintxf2_<rounding>_i387"
15163 [(set (match_operand:XF 0 "register_operand" "=f")
15164 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15166 (use (match_operand:HI 2 "memory_operand" "m"))
15167 (use (match_operand:HI 3 "memory_operand" "m"))]
15168 "TARGET_USE_FANCY_MATH_387
15169 && flag_unsafe_math_optimizations"
15170 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15171 [(set_attr "type" "frndint")
15172 (set_attr "i387_cw" "<rounding>")
15173 (set_attr "mode" "XF")])
15175 (define_expand "<rounding_insn>xf2"
15176 [(parallel [(set (match_operand:XF 0 "register_operand")
15177 (unspec:XF [(match_operand:XF 1 "register_operand")]
15179 (clobber (reg:CC FLAGS_REG))])]
15180 "TARGET_USE_FANCY_MATH_387
15181 && flag_unsafe_math_optimizations
15182 && !optimize_insn_for_size_p ()")
15184 (define_expand "<rounding_insn><mode>2"
15185 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15186 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15188 (clobber (reg:CC FLAGS_REG))])]
15189 "(TARGET_USE_FANCY_MATH_387
15190 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15191 || TARGET_MIX_SSE_I387)
15192 && flag_unsafe_math_optimizations)
15193 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15194 && !flag_trapping_math)"
15196 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15197 && !flag_trapping_math)
15200 emit_insn (gen_sse4_1_round<mode>2
15201 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15202 else if (optimize_insn_for_size_p ())
15204 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15206 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15207 ix86_expand_floorceil (operands[0], operands[1], true);
15208 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15209 ix86_expand_floorceil (operands[0], operands[1], false);
15210 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15211 ix86_expand_trunc (operands[0], operands[1]);
15213 gcc_unreachable ();
15217 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15218 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15219 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15220 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15221 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15222 ix86_expand_truncdf_32 (operands[0], operands[1]);
15224 gcc_unreachable ();
15231 if (optimize_insn_for_size_p ())
15234 op0 = gen_reg_rtx (XFmode);
15235 op1 = gen_reg_rtx (XFmode);
15236 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15237 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15239 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15244 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15245 (define_insn_and_split "frndintxf2_mask_pm"
15246 [(set (match_operand:XF 0 "register_operand")
15247 (unspec:XF [(match_operand:XF 1 "register_operand")]
15248 UNSPEC_FRNDINT_MASK_PM))
15249 (clobber (reg:CC FLAGS_REG))]
15250 "TARGET_USE_FANCY_MATH_387
15251 && flag_unsafe_math_optimizations
15252 && can_create_pseudo_p ()"
15257 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15259 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15260 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15262 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15263 operands[2], operands[3]));
15266 [(set_attr "type" "frndint")
15267 (set_attr "i387_cw" "mask_pm")
15268 (set_attr "mode" "XF")])
15270 (define_insn "frndintxf2_mask_pm_i387"
15271 [(set (match_operand:XF 0 "register_operand" "=f")
15272 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15273 UNSPEC_FRNDINT_MASK_PM))
15274 (use (match_operand:HI 2 "memory_operand" "m"))
15275 (use (match_operand:HI 3 "memory_operand" "m"))]
15276 "TARGET_USE_FANCY_MATH_387
15277 && flag_unsafe_math_optimizations"
15278 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15279 [(set_attr "type" "frndint")
15280 (set_attr "i387_cw" "mask_pm")
15281 (set_attr "mode" "XF")])
15283 (define_expand "nearbyintxf2"
15284 [(parallel [(set (match_operand:XF 0 "register_operand")
15285 (unspec:XF [(match_operand:XF 1 "register_operand")]
15286 UNSPEC_FRNDINT_MASK_PM))
15287 (clobber (reg:CC FLAGS_REG))])]
15288 "TARGET_USE_FANCY_MATH_387
15289 && flag_unsafe_math_optimizations")
15291 (define_expand "nearbyint<mode>2"
15292 [(use (match_operand:MODEF 0 "register_operand"))
15293 (use (match_operand:MODEF 1 "register_operand"))]
15294 "TARGET_USE_FANCY_MATH_387
15295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15296 || TARGET_MIX_SSE_I387)
15297 && flag_unsafe_math_optimizations"
15299 rtx op0 = gen_reg_rtx (XFmode);
15300 rtx op1 = gen_reg_rtx (XFmode);
15302 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15303 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15305 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15309 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15310 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15311 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15312 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15314 (clobber (reg:CC FLAGS_REG))]
15315 "TARGET_USE_FANCY_MATH_387
15316 && flag_unsafe_math_optimizations
15317 && can_create_pseudo_p ()"
15322 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15324 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15325 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15326 if (memory_operand (operands[0], VOIDmode))
15327 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15328 operands[2], operands[3]));
15331 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15332 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15333 (operands[0], operands[1], operands[2],
15334 operands[3], operands[4]));
15338 [(set_attr "type" "fistp")
15339 (set_attr "i387_cw" "<rounding>")
15340 (set_attr "mode" "<MODE>")])
15342 (define_insn "fistdi2_<rounding>"
15343 [(set (match_operand:DI 0 "memory_operand" "=m")
15344 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15346 (use (match_operand:HI 2 "memory_operand" "m"))
15347 (use (match_operand:HI 3 "memory_operand" "m"))
15348 (clobber (match_scratch:XF 4 "=&1f"))]
15349 "TARGET_USE_FANCY_MATH_387
15350 && flag_unsafe_math_optimizations"
15351 "* return output_fix_trunc (insn, operands, false);"
15352 [(set_attr "type" "fistp")
15353 (set_attr "i387_cw" "<rounding>")
15354 (set_attr "mode" "DI")])
15356 (define_insn "fistdi2_<rounding>_with_temp"
15357 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15358 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15360 (use (match_operand:HI 2 "memory_operand" "m,m"))
15361 (use (match_operand:HI 3 "memory_operand" "m,m"))
15362 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15363 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15364 "TARGET_USE_FANCY_MATH_387
15365 && flag_unsafe_math_optimizations"
15367 [(set_attr "type" "fistp")
15368 (set_attr "i387_cw" "<rounding>")
15369 (set_attr "mode" "DI")])
15372 [(set (match_operand:DI 0 "register_operand")
15373 (unspec:DI [(match_operand:XF 1 "register_operand")]
15375 (use (match_operand:HI 2 "memory_operand"))
15376 (use (match_operand:HI 3 "memory_operand"))
15377 (clobber (match_operand:DI 4 "memory_operand"))
15378 (clobber (match_scratch 5))]
15380 [(parallel [(set (match_dup 4)
15381 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15382 (use (match_dup 2))
15383 (use (match_dup 3))
15384 (clobber (match_dup 5))])
15385 (set (match_dup 0) (match_dup 4))])
15388 [(set (match_operand:DI 0 "memory_operand")
15389 (unspec:DI [(match_operand:XF 1 "register_operand")]
15391 (use (match_operand:HI 2 "memory_operand"))
15392 (use (match_operand:HI 3 "memory_operand"))
15393 (clobber (match_operand:DI 4 "memory_operand"))
15394 (clobber (match_scratch 5))]
15396 [(parallel [(set (match_dup 0)
15397 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15398 (use (match_dup 2))
15399 (use (match_dup 3))
15400 (clobber (match_dup 5))])])
15402 (define_insn "fist<mode>2_<rounding>"
15403 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15404 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15406 (use (match_operand:HI 2 "memory_operand" "m"))
15407 (use (match_operand:HI 3 "memory_operand" "m"))]
15408 "TARGET_USE_FANCY_MATH_387
15409 && flag_unsafe_math_optimizations"
15410 "* return output_fix_trunc (insn, operands, false);"
15411 [(set_attr "type" "fistp")
15412 (set_attr "i387_cw" "<rounding>")
15413 (set_attr "mode" "<MODE>")])
15415 (define_insn "fist<mode>2_<rounding>_with_temp"
15416 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15417 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15419 (use (match_operand:HI 2 "memory_operand" "m,m"))
15420 (use (match_operand:HI 3 "memory_operand" "m,m"))
15421 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15422 "TARGET_USE_FANCY_MATH_387
15423 && flag_unsafe_math_optimizations"
15425 [(set_attr "type" "fistp")
15426 (set_attr "i387_cw" "<rounding>")
15427 (set_attr "mode" "<MODE>")])
15430 [(set (match_operand:SWI24 0 "register_operand")
15431 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15433 (use (match_operand:HI 2 "memory_operand"))
15434 (use (match_operand:HI 3 "memory_operand"))
15435 (clobber (match_operand:SWI24 4 "memory_operand"))]
15437 [(parallel [(set (match_dup 4)
15438 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15439 (use (match_dup 2))
15440 (use (match_dup 3))])
15441 (set (match_dup 0) (match_dup 4))])
15444 [(set (match_operand:SWI24 0 "memory_operand")
15445 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15447 (use (match_operand:HI 2 "memory_operand"))
15448 (use (match_operand:HI 3 "memory_operand"))
15449 (clobber (match_operand:SWI24 4 "memory_operand"))]
15451 [(parallel [(set (match_dup 0)
15452 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15453 (use (match_dup 2))
15454 (use (match_dup 3))])])
15456 (define_expand "l<rounding_insn>xf<mode>2"
15457 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15458 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15460 (clobber (reg:CC FLAGS_REG))])]
15461 "TARGET_USE_FANCY_MATH_387
15462 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15463 && flag_unsafe_math_optimizations")
15465 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15466 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15467 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15469 (clobber (reg:CC FLAGS_REG))])]
15470 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15471 && !flag_trapping_math"
15473 if (TARGET_64BIT && optimize_insn_for_size_p ())
15476 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15477 ix86_expand_lfloorceil (operands[0], operands[1], true);
15478 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15479 ix86_expand_lfloorceil (operands[0], operands[1], false);
15481 gcc_unreachable ();
15486 (define_insn "fxam<mode>2_i387"
15487 [(set (match_operand:HI 0 "register_operand" "=a")
15489 [(match_operand:X87MODEF 1 "register_operand" "f")]
15491 "TARGET_USE_FANCY_MATH_387"
15492 "fxam\n\tfnstsw\t%0"
15493 [(set_attr "type" "multi")
15494 (set_attr "length" "4")
15495 (set_attr "unit" "i387")
15496 (set_attr "mode" "<MODE>")])
15498 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15499 [(set (match_operand:HI 0 "register_operand")
15501 [(match_operand:MODEF 1 "memory_operand")]
15503 "TARGET_USE_FANCY_MATH_387
15504 && can_create_pseudo_p ()"
15507 [(set (match_dup 2)(match_dup 1))
15509 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15511 operands[2] = gen_reg_rtx (<MODE>mode);
15513 MEM_VOLATILE_P (operands[1]) = 1;
15515 [(set_attr "type" "multi")
15516 (set_attr "unit" "i387")
15517 (set_attr "mode" "<MODE>")])
15519 (define_expand "isinfxf2"
15520 [(use (match_operand:SI 0 "register_operand"))
15521 (use (match_operand:XF 1 "register_operand"))]
15522 "TARGET_USE_FANCY_MATH_387
15523 && ix86_libc_has_function (function_c99_misc)"
15525 rtx mask = GEN_INT (0x45);
15526 rtx val = GEN_INT (0x05);
15530 rtx scratch = gen_reg_rtx (HImode);
15531 rtx res = gen_reg_rtx (QImode);
15533 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15535 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15536 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15537 cond = gen_rtx_fmt_ee (EQ, QImode,
15538 gen_rtx_REG (CCmode, FLAGS_REG),
15540 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15541 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15545 (define_expand "isinf<mode>2"
15546 [(use (match_operand:SI 0 "register_operand"))
15547 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15548 "TARGET_USE_FANCY_MATH_387
15549 && ix86_libc_has_function (function_c99_misc)
15550 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15552 rtx mask = GEN_INT (0x45);
15553 rtx val = GEN_INT (0x05);
15557 rtx scratch = gen_reg_rtx (HImode);
15558 rtx res = gen_reg_rtx (QImode);
15560 /* Remove excess precision by forcing value through memory. */
15561 if (memory_operand (operands[1], VOIDmode))
15562 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15565 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15567 emit_move_insn (temp, operands[1]);
15568 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15571 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15572 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15573 cond = gen_rtx_fmt_ee (EQ, QImode,
15574 gen_rtx_REG (CCmode, FLAGS_REG),
15576 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15577 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15581 (define_expand "signbitxf2"
15582 [(use (match_operand:SI 0 "register_operand"))
15583 (use (match_operand:XF 1 "register_operand"))]
15584 "TARGET_USE_FANCY_MATH_387"
15586 rtx scratch = gen_reg_rtx (HImode);
15588 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15589 emit_insn (gen_andsi3 (operands[0],
15590 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15594 (define_insn "movmsk_df"
15595 [(set (match_operand:SI 0 "register_operand" "=r")
15597 [(match_operand:DF 1 "register_operand" "x")]
15599 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15600 "%vmovmskpd\t{%1, %0|%0, %1}"
15601 [(set_attr "type" "ssemov")
15602 (set_attr "prefix" "maybe_vex")
15603 (set_attr "mode" "DF")])
15605 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15606 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15607 (define_expand "signbitdf2"
15608 [(use (match_operand:SI 0 "register_operand"))
15609 (use (match_operand:DF 1 "register_operand"))]
15610 "TARGET_USE_FANCY_MATH_387
15611 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15613 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15615 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15616 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15620 rtx scratch = gen_reg_rtx (HImode);
15622 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15623 emit_insn (gen_andsi3 (operands[0],
15624 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15629 (define_expand "signbitsf2"
15630 [(use (match_operand:SI 0 "register_operand"))
15631 (use (match_operand:SF 1 "register_operand"))]
15632 "TARGET_USE_FANCY_MATH_387
15633 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15635 rtx scratch = gen_reg_rtx (HImode);
15637 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15638 emit_insn (gen_andsi3 (operands[0],
15639 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15643 ;; Block operation instructions
15646 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15649 [(set_attr "length" "1")
15650 (set_attr "length_immediate" "0")
15651 (set_attr "modrm" "0")])
15653 (define_expand "movmem<mode>"
15654 [(use (match_operand:BLK 0 "memory_operand"))
15655 (use (match_operand:BLK 1 "memory_operand"))
15656 (use (match_operand:SWI48 2 "nonmemory_operand"))
15657 (use (match_operand:SWI48 3 "const_int_operand"))
15658 (use (match_operand:SI 4 "const_int_operand"))
15659 (use (match_operand:SI 5 "const_int_operand"))
15660 (use (match_operand:SI 6 ""))
15661 (use (match_operand:SI 7 ""))
15662 (use (match_operand:SI 8 ""))]
15665 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15666 operands[2], NULL, operands[3],
15667 operands[4], operands[5],
15668 operands[6], operands[7],
15669 operands[8], false))
15675 ;; Most CPUs don't like single string operations
15676 ;; Handle this case here to simplify previous expander.
15678 (define_expand "strmov"
15679 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15680 (set (match_operand 1 "memory_operand") (match_dup 4))
15681 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15682 (clobber (reg:CC FLAGS_REG))])
15683 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15684 (clobber (reg:CC FLAGS_REG))])]
15687 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15689 /* If .md ever supports :P for Pmode, these can be directly
15690 in the pattern above. */
15691 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15692 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15694 /* Can't use this if the user has appropriated esi or edi. */
15695 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15696 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15698 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15699 operands[2], operands[3],
15700 operands[5], operands[6]));
15704 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15707 (define_expand "strmov_singleop"
15708 [(parallel [(set (match_operand 1 "memory_operand")
15709 (match_operand 3 "memory_operand"))
15710 (set (match_operand 0 "register_operand")
15712 (set (match_operand 2 "register_operand")
15713 (match_operand 5))])]
15715 "ix86_current_function_needs_cld = 1;")
15717 (define_insn "*strmovdi_rex_1"
15718 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15719 (mem:DI (match_operand:P 3 "register_operand" "1")))
15720 (set (match_operand:P 0 "register_operand" "=D")
15721 (plus:P (match_dup 2)
15723 (set (match_operand:P 1 "register_operand" "=S")
15724 (plus:P (match_dup 3)
15727 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15729 [(set_attr "type" "str")
15730 (set_attr "memory" "both")
15731 (set_attr "mode" "DI")])
15733 (define_insn "*strmovsi_1"
15734 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15735 (mem:SI (match_operand:P 3 "register_operand" "1")))
15736 (set (match_operand:P 0 "register_operand" "=D")
15737 (plus:P (match_dup 2)
15739 (set (match_operand:P 1 "register_operand" "=S")
15740 (plus:P (match_dup 3)
15742 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15744 [(set_attr "type" "str")
15745 (set_attr "memory" "both")
15746 (set_attr "mode" "SI")])
15748 (define_insn "*strmovhi_1"
15749 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15750 (mem:HI (match_operand:P 3 "register_operand" "1")))
15751 (set (match_operand:P 0 "register_operand" "=D")
15752 (plus:P (match_dup 2)
15754 (set (match_operand:P 1 "register_operand" "=S")
15755 (plus:P (match_dup 3)
15757 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15759 [(set_attr "type" "str")
15760 (set_attr "memory" "both")
15761 (set_attr "mode" "HI")])
15763 (define_insn "*strmovqi_1"
15764 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15765 (mem:QI (match_operand:P 3 "register_operand" "1")))
15766 (set (match_operand:P 0 "register_operand" "=D")
15767 (plus:P (match_dup 2)
15769 (set (match_operand:P 1 "register_operand" "=S")
15770 (plus:P (match_dup 3)
15772 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15774 [(set_attr "type" "str")
15775 (set_attr "memory" "both")
15776 (set (attr "prefix_rex")
15778 (match_test "<P:MODE>mode == DImode")
15780 (const_string "*")))
15781 (set_attr "mode" "QI")])
15783 (define_expand "rep_mov"
15784 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15785 (set (match_operand 0 "register_operand")
15787 (set (match_operand 2 "register_operand")
15789 (set (match_operand 1 "memory_operand")
15790 (match_operand 3 "memory_operand"))
15791 (use (match_dup 4))])]
15793 "ix86_current_function_needs_cld = 1;")
15795 (define_insn "*rep_movdi_rex64"
15796 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15797 (set (match_operand:P 0 "register_operand" "=D")
15798 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15800 (match_operand:P 3 "register_operand" "0")))
15801 (set (match_operand:P 1 "register_operand" "=S")
15802 (plus:P (ashift:P (match_dup 5) (const_int 3))
15803 (match_operand:P 4 "register_operand" "1")))
15804 (set (mem:BLK (match_dup 3))
15805 (mem:BLK (match_dup 4)))
15806 (use (match_dup 5))]
15808 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15810 [(set_attr "type" "str")
15811 (set_attr "prefix_rep" "1")
15812 (set_attr "memory" "both")
15813 (set_attr "mode" "DI")])
15815 (define_insn "*rep_movsi"
15816 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15817 (set (match_operand:P 0 "register_operand" "=D")
15818 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15820 (match_operand:P 3 "register_operand" "0")))
15821 (set (match_operand:P 1 "register_operand" "=S")
15822 (plus:P (ashift:P (match_dup 5) (const_int 2))
15823 (match_operand:P 4 "register_operand" "1")))
15824 (set (mem:BLK (match_dup 3))
15825 (mem:BLK (match_dup 4)))
15826 (use (match_dup 5))]
15827 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15828 "%^rep{%;} movs{l|d}"
15829 [(set_attr "type" "str")
15830 (set_attr "prefix_rep" "1")
15831 (set_attr "memory" "both")
15832 (set_attr "mode" "SI")])
15834 (define_insn "*rep_movqi"
15835 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15836 (set (match_operand:P 0 "register_operand" "=D")
15837 (plus:P (match_operand:P 3 "register_operand" "0")
15838 (match_operand:P 5 "register_operand" "2")))
15839 (set (match_operand:P 1 "register_operand" "=S")
15840 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15841 (set (mem:BLK (match_dup 3))
15842 (mem:BLK (match_dup 4)))
15843 (use (match_dup 5))]
15844 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15846 [(set_attr "type" "str")
15847 (set_attr "prefix_rep" "1")
15848 (set_attr "memory" "both")
15849 (set_attr "mode" "QI")])
15851 (define_expand "setmem<mode>"
15852 [(use (match_operand:BLK 0 "memory_operand"))
15853 (use (match_operand:SWI48 1 "nonmemory_operand"))
15854 (use (match_operand:QI 2 "nonmemory_operand"))
15855 (use (match_operand 3 "const_int_operand"))
15856 (use (match_operand:SI 4 "const_int_operand"))
15857 (use (match_operand:SI 5 "const_int_operand"))
15858 (use (match_operand:SI 6 ""))
15859 (use (match_operand:SI 7 ""))
15860 (use (match_operand:SI 8 ""))]
15863 if (ix86_expand_set_or_movmem (operands[0], NULL,
15864 operands[1], operands[2],
15865 operands[3], operands[4],
15866 operands[5], operands[6],
15867 operands[7], operands[8], true))
15873 ;; Most CPUs don't like single string operations
15874 ;; Handle this case here to simplify previous expander.
15876 (define_expand "strset"
15877 [(set (match_operand 1 "memory_operand")
15878 (match_operand 2 "register_operand"))
15879 (parallel [(set (match_operand 0 "register_operand")
15881 (clobber (reg:CC FLAGS_REG))])]
15884 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15885 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15887 /* If .md ever supports :P for Pmode, this can be directly
15888 in the pattern above. */
15889 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15890 GEN_INT (GET_MODE_SIZE (GET_MODE
15892 /* Can't use this if the user has appropriated eax or edi. */
15893 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15894 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15896 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15902 (define_expand "strset_singleop"
15903 [(parallel [(set (match_operand 1 "memory_operand")
15904 (match_operand 2 "register_operand"))
15905 (set (match_operand 0 "register_operand")
15907 (unspec [(const_int 0)] UNSPEC_STOS)])]
15909 "ix86_current_function_needs_cld = 1;")
15911 (define_insn "*strsetdi_rex_1"
15912 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15913 (match_operand:DI 2 "register_operand" "a"))
15914 (set (match_operand:P 0 "register_operand" "=D")
15915 (plus:P (match_dup 1)
15917 (unspec [(const_int 0)] UNSPEC_STOS)]
15919 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15921 [(set_attr "type" "str")
15922 (set_attr "memory" "store")
15923 (set_attr "mode" "DI")])
15925 (define_insn "*strsetsi_1"
15926 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15927 (match_operand:SI 2 "register_operand" "a"))
15928 (set (match_operand:P 0 "register_operand" "=D")
15929 (plus:P (match_dup 1)
15931 (unspec [(const_int 0)] UNSPEC_STOS)]
15932 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15934 [(set_attr "type" "str")
15935 (set_attr "memory" "store")
15936 (set_attr "mode" "SI")])
15938 (define_insn "*strsethi_1"
15939 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15940 (match_operand:HI 2 "register_operand" "a"))
15941 (set (match_operand:P 0 "register_operand" "=D")
15942 (plus:P (match_dup 1)
15944 (unspec [(const_int 0)] UNSPEC_STOS)]
15945 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15947 [(set_attr "type" "str")
15948 (set_attr "memory" "store")
15949 (set_attr "mode" "HI")])
15951 (define_insn "*strsetqi_1"
15952 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15953 (match_operand:QI 2 "register_operand" "a"))
15954 (set (match_operand:P 0 "register_operand" "=D")
15955 (plus:P (match_dup 1)
15957 (unspec [(const_int 0)] UNSPEC_STOS)]
15958 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15960 [(set_attr "type" "str")
15961 (set_attr "memory" "store")
15962 (set (attr "prefix_rex")
15964 (match_test "<P:MODE>mode == DImode")
15966 (const_string "*")))
15967 (set_attr "mode" "QI")])
15969 (define_expand "rep_stos"
15970 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15971 (set (match_operand 0 "register_operand")
15973 (set (match_operand 2 "memory_operand") (const_int 0))
15974 (use (match_operand 3 "register_operand"))
15975 (use (match_dup 1))])]
15977 "ix86_current_function_needs_cld = 1;")
15979 (define_insn "*rep_stosdi_rex64"
15980 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15981 (set (match_operand:P 0 "register_operand" "=D")
15982 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15984 (match_operand:P 3 "register_operand" "0")))
15985 (set (mem:BLK (match_dup 3))
15987 (use (match_operand:DI 2 "register_operand" "a"))
15988 (use (match_dup 4))]
15990 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15992 [(set_attr "type" "str")
15993 (set_attr "prefix_rep" "1")
15994 (set_attr "memory" "store")
15995 (set_attr "mode" "DI")])
15997 (define_insn "*rep_stossi"
15998 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15999 (set (match_operand:P 0 "register_operand" "=D")
16000 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16002 (match_operand:P 3 "register_operand" "0")))
16003 (set (mem:BLK (match_dup 3))
16005 (use (match_operand:SI 2 "register_operand" "a"))
16006 (use (match_dup 4))]
16007 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16008 "%^rep{%;} stos{l|d}"
16009 [(set_attr "type" "str")
16010 (set_attr "prefix_rep" "1")
16011 (set_attr "memory" "store")
16012 (set_attr "mode" "SI")])
16014 (define_insn "*rep_stosqi"
16015 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16016 (set (match_operand:P 0 "register_operand" "=D")
16017 (plus:P (match_operand:P 3 "register_operand" "0")
16018 (match_operand:P 4 "register_operand" "1")))
16019 (set (mem:BLK (match_dup 3))
16021 (use (match_operand:QI 2 "register_operand" "a"))
16022 (use (match_dup 4))]
16023 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16025 [(set_attr "type" "str")
16026 (set_attr "prefix_rep" "1")
16027 (set_attr "memory" "store")
16028 (set (attr "prefix_rex")
16030 (match_test "<P:MODE>mode == DImode")
16032 (const_string "*")))
16033 (set_attr "mode" "QI")])
16035 (define_expand "cmpstrnsi"
16036 [(set (match_operand:SI 0 "register_operand")
16037 (compare:SI (match_operand:BLK 1 "general_operand")
16038 (match_operand:BLK 2 "general_operand")))
16039 (use (match_operand 3 "general_operand"))
16040 (use (match_operand 4 "immediate_operand"))]
16043 rtx addr1, addr2, out, outlow, count, countreg, align;
16045 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16048 /* Can't use this if the user has appropriated ecx, esi or edi. */
16049 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16054 out = gen_reg_rtx (SImode);
16056 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16057 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16058 if (addr1 != XEXP (operands[1], 0))
16059 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16060 if (addr2 != XEXP (operands[2], 0))
16061 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16063 count = operands[3];
16064 countreg = ix86_zero_extend_to_Pmode (count);
16066 /* %%% Iff we are testing strict equality, we can use known alignment
16067 to good advantage. This may be possible with combine, particularly
16068 once cc0 is dead. */
16069 align = operands[4];
16071 if (CONST_INT_P (count))
16073 if (INTVAL (count) == 0)
16075 emit_move_insn (operands[0], const0_rtx);
16078 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16079 operands[1], operands[2]));
16083 rtx (*gen_cmp) (rtx, rtx);
16085 gen_cmp = (TARGET_64BIT
16086 ? gen_cmpdi_1 : gen_cmpsi_1);
16088 emit_insn (gen_cmp (countreg, countreg));
16089 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16090 operands[1], operands[2]));
16093 outlow = gen_lowpart (QImode, out);
16094 emit_insn (gen_cmpintqi (outlow));
16095 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16097 if (operands[0] != out)
16098 emit_move_insn (operands[0], out);
16103 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16105 (define_expand "cmpintqi"
16106 [(set (match_dup 1)
16107 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16109 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16110 (parallel [(set (match_operand:QI 0 "register_operand")
16111 (minus:QI (match_dup 1)
16113 (clobber (reg:CC FLAGS_REG))])]
16116 operands[1] = gen_reg_rtx (QImode);
16117 operands[2] = gen_reg_rtx (QImode);
16120 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16121 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16123 (define_expand "cmpstrnqi_nz_1"
16124 [(parallel [(set (reg:CC FLAGS_REG)
16125 (compare:CC (match_operand 4 "memory_operand")
16126 (match_operand 5 "memory_operand")))
16127 (use (match_operand 2 "register_operand"))
16128 (use (match_operand:SI 3 "immediate_operand"))
16129 (clobber (match_operand 0 "register_operand"))
16130 (clobber (match_operand 1 "register_operand"))
16131 (clobber (match_dup 2))])]
16133 "ix86_current_function_needs_cld = 1;")
16135 (define_insn "*cmpstrnqi_nz_1"
16136 [(set (reg:CC FLAGS_REG)
16137 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16138 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16139 (use (match_operand:P 6 "register_operand" "2"))
16140 (use (match_operand:SI 3 "immediate_operand" "i"))
16141 (clobber (match_operand:P 0 "register_operand" "=S"))
16142 (clobber (match_operand:P 1 "register_operand" "=D"))
16143 (clobber (match_operand:P 2 "register_operand" "=c"))]
16144 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16146 [(set_attr "type" "str")
16147 (set_attr "mode" "QI")
16148 (set (attr "prefix_rex")
16150 (match_test "<P:MODE>mode == DImode")
16152 (const_string "*")))
16153 (set_attr "prefix_rep" "1")])
16155 ;; The same, but the count is not known to not be zero.
16157 (define_expand "cmpstrnqi_1"
16158 [(parallel [(set (reg:CC FLAGS_REG)
16159 (if_then_else:CC (ne (match_operand 2 "register_operand")
16161 (compare:CC (match_operand 4 "memory_operand")
16162 (match_operand 5 "memory_operand"))
16164 (use (match_operand:SI 3 "immediate_operand"))
16165 (use (reg:CC FLAGS_REG))
16166 (clobber (match_operand 0 "register_operand"))
16167 (clobber (match_operand 1 "register_operand"))
16168 (clobber (match_dup 2))])]
16170 "ix86_current_function_needs_cld = 1;")
16172 (define_insn "*cmpstrnqi_1"
16173 [(set (reg:CC FLAGS_REG)
16174 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16176 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16177 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16179 (use (match_operand:SI 3 "immediate_operand" "i"))
16180 (use (reg:CC FLAGS_REG))
16181 (clobber (match_operand:P 0 "register_operand" "=S"))
16182 (clobber (match_operand:P 1 "register_operand" "=D"))
16183 (clobber (match_operand:P 2 "register_operand" "=c"))]
16184 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16186 [(set_attr "type" "str")
16187 (set_attr "mode" "QI")
16188 (set (attr "prefix_rex")
16190 (match_test "<P:MODE>mode == DImode")
16192 (const_string "*")))
16193 (set_attr "prefix_rep" "1")])
16195 (define_expand "strlen<mode>"
16196 [(set (match_operand:P 0 "register_operand")
16197 (unspec:P [(match_operand:BLK 1 "general_operand")
16198 (match_operand:QI 2 "immediate_operand")
16199 (match_operand 3 "immediate_operand")]
16203 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16209 (define_expand "strlenqi_1"
16210 [(parallel [(set (match_operand 0 "register_operand")
16212 (clobber (match_operand 1 "register_operand"))
16213 (clobber (reg:CC FLAGS_REG))])]
16215 "ix86_current_function_needs_cld = 1;")
16217 (define_insn "*strlenqi_1"
16218 [(set (match_operand:P 0 "register_operand" "=&c")
16219 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16220 (match_operand:QI 2 "register_operand" "a")
16221 (match_operand:P 3 "immediate_operand" "i")
16222 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16223 (clobber (match_operand:P 1 "register_operand" "=D"))
16224 (clobber (reg:CC FLAGS_REG))]
16225 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16226 "%^repnz{%;} scasb"
16227 [(set_attr "type" "str")
16228 (set_attr "mode" "QI")
16229 (set (attr "prefix_rex")
16231 (match_test "<P:MODE>mode == DImode")
16233 (const_string "*")))
16234 (set_attr "prefix_rep" "1")])
16236 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16237 ;; handled in combine, but it is not currently up to the task.
16238 ;; When used for their truth value, the cmpstrn* expanders generate
16247 ;; The intermediate three instructions are unnecessary.
16249 ;; This one handles cmpstrn*_nz_1...
16252 (set (reg:CC FLAGS_REG)
16253 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16254 (mem:BLK (match_operand 5 "register_operand"))))
16255 (use (match_operand 6 "register_operand"))
16256 (use (match_operand:SI 3 "immediate_operand"))
16257 (clobber (match_operand 0 "register_operand"))
16258 (clobber (match_operand 1 "register_operand"))
16259 (clobber (match_operand 2 "register_operand"))])
16260 (set (match_operand:QI 7 "register_operand")
16261 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16262 (set (match_operand:QI 8 "register_operand")
16263 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16264 (set (reg FLAGS_REG)
16265 (compare (match_dup 7) (match_dup 8)))
16267 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16269 (set (reg:CC FLAGS_REG)
16270 (compare:CC (mem:BLK (match_dup 4))
16271 (mem:BLK (match_dup 5))))
16272 (use (match_dup 6))
16273 (use (match_dup 3))
16274 (clobber (match_dup 0))
16275 (clobber (match_dup 1))
16276 (clobber (match_dup 2))])])
16278 ;; ...and this one handles cmpstrn*_1.
16281 (set (reg:CC FLAGS_REG)
16282 (if_then_else:CC (ne (match_operand 6 "register_operand")
16284 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16285 (mem:BLK (match_operand 5 "register_operand")))
16287 (use (match_operand:SI 3 "immediate_operand"))
16288 (use (reg:CC FLAGS_REG))
16289 (clobber (match_operand 0 "register_operand"))
16290 (clobber (match_operand 1 "register_operand"))
16291 (clobber (match_operand 2 "register_operand"))])
16292 (set (match_operand:QI 7 "register_operand")
16293 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16294 (set (match_operand:QI 8 "register_operand")
16295 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16296 (set (reg FLAGS_REG)
16297 (compare (match_dup 7) (match_dup 8)))
16299 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16301 (set (reg:CC FLAGS_REG)
16302 (if_then_else:CC (ne (match_dup 6)
16304 (compare:CC (mem:BLK (match_dup 4))
16305 (mem:BLK (match_dup 5)))
16307 (use (match_dup 3))
16308 (use (reg:CC FLAGS_REG))
16309 (clobber (match_dup 0))
16310 (clobber (match_dup 1))
16311 (clobber (match_dup 2))])])
16313 ;; Conditional move instructions.
16315 (define_expand "mov<mode>cc"
16316 [(set (match_operand:SWIM 0 "register_operand")
16317 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16318 (match_operand:SWIM 2 "<general_operand>")
16319 (match_operand:SWIM 3 "<general_operand>")))]
16321 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16323 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16324 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16325 ;; So just document what we're doing explicitly.
16327 (define_expand "x86_mov<mode>cc_0_m1"
16329 [(set (match_operand:SWI48 0 "register_operand")
16330 (if_then_else:SWI48
16331 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16332 [(match_operand 1 "flags_reg_operand")
16336 (clobber (reg:CC FLAGS_REG))])])
16338 (define_insn "*x86_mov<mode>cc_0_m1"
16339 [(set (match_operand:SWI48 0 "register_operand" "=r")
16340 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16341 [(reg FLAGS_REG) (const_int 0)])
16344 (clobber (reg:CC FLAGS_REG))]
16346 "sbb{<imodesuffix>}\t%0, %0"
16347 ; Since we don't have the proper number of operands for an alu insn,
16348 ; fill in all the blanks.
16349 [(set_attr "type" "alu")
16350 (set_attr "use_carry" "1")
16351 (set_attr "pent_pair" "pu")
16352 (set_attr "memory" "none")
16353 (set_attr "imm_disp" "false")
16354 (set_attr "mode" "<MODE>")
16355 (set_attr "length_immediate" "0")])
16357 (define_insn "*x86_mov<mode>cc_0_m1_se"
16358 [(set (match_operand:SWI48 0 "register_operand" "=r")
16359 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16360 [(reg FLAGS_REG) (const_int 0)])
16363 (clobber (reg:CC FLAGS_REG))]
16365 "sbb{<imodesuffix>}\t%0, %0"
16366 [(set_attr "type" "alu")
16367 (set_attr "use_carry" "1")
16368 (set_attr "pent_pair" "pu")
16369 (set_attr "memory" "none")
16370 (set_attr "imm_disp" "false")
16371 (set_attr "mode" "<MODE>")
16372 (set_attr "length_immediate" "0")])
16374 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16375 [(set (match_operand:SWI48 0 "register_operand" "=r")
16376 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16377 [(reg FLAGS_REG) (const_int 0)])))
16378 (clobber (reg:CC FLAGS_REG))]
16380 "sbb{<imodesuffix>}\t%0, %0"
16381 [(set_attr "type" "alu")
16382 (set_attr "use_carry" "1")
16383 (set_attr "pent_pair" "pu")
16384 (set_attr "memory" "none")
16385 (set_attr "imm_disp" "false")
16386 (set_attr "mode" "<MODE>")
16387 (set_attr "length_immediate" "0")])
16389 (define_insn "*mov<mode>cc_noc"
16390 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16391 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16392 [(reg FLAGS_REG) (const_int 0)])
16393 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16394 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16395 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16397 cmov%O2%C1\t{%2, %0|%0, %2}
16398 cmov%O2%c1\t{%3, %0|%0, %3}"
16399 [(set_attr "type" "icmov")
16400 (set_attr "mode" "<MODE>")])
16402 ;; Don't do conditional moves with memory inputs. This splitter helps
16403 ;; register starved x86_32 by forcing inputs into registers before reload.
16405 [(set (match_operand:SWI248 0 "register_operand")
16406 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16407 [(reg FLAGS_REG) (const_int 0)])
16408 (match_operand:SWI248 2 "nonimmediate_operand")
16409 (match_operand:SWI248 3 "nonimmediate_operand")))]
16410 "!TARGET_64BIT && TARGET_CMOVE
16411 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16412 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16413 && can_create_pseudo_p ()
16414 && optimize_insn_for_speed_p ()"
16415 [(set (match_dup 0)
16416 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16418 if (MEM_P (operands[2]))
16419 operands[2] = force_reg (<MODE>mode, operands[2]);
16420 if (MEM_P (operands[3]))
16421 operands[3] = force_reg (<MODE>mode, operands[3]);
16424 (define_insn "*movqicc_noc"
16425 [(set (match_operand:QI 0 "register_operand" "=r,r")
16426 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16427 [(reg FLAGS_REG) (const_int 0)])
16428 (match_operand:QI 2 "register_operand" "r,0")
16429 (match_operand:QI 3 "register_operand" "0,r")))]
16430 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16432 [(set_attr "type" "icmov")
16433 (set_attr "mode" "QI")])
16436 [(set (match_operand:SWI12 0 "register_operand")
16437 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16438 [(reg FLAGS_REG) (const_int 0)])
16439 (match_operand:SWI12 2 "register_operand")
16440 (match_operand:SWI12 3 "register_operand")))]
16441 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16442 && reload_completed"
16443 [(set (match_dup 0)
16444 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16446 operands[0] = gen_lowpart (SImode, operands[0]);
16447 operands[2] = gen_lowpart (SImode, operands[2]);
16448 operands[3] = gen_lowpart (SImode, operands[3]);
16451 ;; Don't do conditional moves with memory inputs
16453 [(match_scratch:SWI248 2 "r")
16454 (set (match_operand:SWI248 0 "register_operand")
16455 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16456 [(reg FLAGS_REG) (const_int 0)])
16458 (match_operand:SWI248 3 "memory_operand")))]
16459 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16460 && optimize_insn_for_speed_p ()"
16461 [(set (match_dup 2) (match_dup 3))
16463 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16466 [(match_scratch:SWI248 2 "r")
16467 (set (match_operand:SWI248 0 "register_operand")
16468 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16469 [(reg FLAGS_REG) (const_int 0)])
16470 (match_operand:SWI248 3 "memory_operand")
16472 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16473 && optimize_insn_for_speed_p ()"
16474 [(set (match_dup 2) (match_dup 3))
16476 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16478 (define_expand "mov<mode>cc"
16479 [(set (match_operand:X87MODEF 0 "register_operand")
16480 (if_then_else:X87MODEF
16481 (match_operand 1 "comparison_operator")
16482 (match_operand:X87MODEF 2 "register_operand")
16483 (match_operand:X87MODEF 3 "register_operand")))]
16484 "(TARGET_80387 && TARGET_CMOVE)
16485 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16486 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16488 (define_insn "*movxfcc_1"
16489 [(set (match_operand:XF 0 "register_operand" "=f,f")
16490 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16491 [(reg FLAGS_REG) (const_int 0)])
16492 (match_operand:XF 2 "register_operand" "f,0")
16493 (match_operand:XF 3 "register_operand" "0,f")))]
16494 "TARGET_80387 && TARGET_CMOVE"
16496 fcmov%F1\t{%2, %0|%0, %2}
16497 fcmov%f1\t{%3, %0|%0, %3}"
16498 [(set_attr "type" "fcmov")
16499 (set_attr "mode" "XF")])
16501 (define_insn "*movdfcc_1"
16502 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16503 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16504 [(reg FLAGS_REG) (const_int 0)])
16505 (match_operand:DF 2 "nonimmediate_operand"
16507 (match_operand:DF 3 "nonimmediate_operand"
16508 "0 ,f,0 ,rm,0, rm")))]
16509 "TARGET_80387 && TARGET_CMOVE
16510 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16512 fcmov%F1\t{%2, %0|%0, %2}
16513 fcmov%f1\t{%3, %0|%0, %3}
16516 cmov%O2%C1\t{%2, %0|%0, %2}
16517 cmov%O2%c1\t{%3, %0|%0, %3}"
16518 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16519 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16520 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16523 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16524 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16525 [(reg FLAGS_REG) (const_int 0)])
16526 (match_operand:DF 2 "nonimmediate_operand")
16527 (match_operand:DF 3 "nonimmediate_operand")))]
16528 "!TARGET_64BIT && reload_completed"
16529 [(set (match_dup 2)
16530 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16532 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16534 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16535 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16538 (define_insn "*movsfcc_1_387"
16539 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16540 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16541 [(reg FLAGS_REG) (const_int 0)])
16542 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16543 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16544 "TARGET_80387 && TARGET_CMOVE
16545 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16547 fcmov%F1\t{%2, %0|%0, %2}
16548 fcmov%f1\t{%3, %0|%0, %3}
16549 cmov%O2%C1\t{%2, %0|%0, %2}
16550 cmov%O2%c1\t{%3, %0|%0, %3}"
16551 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16552 (set_attr "mode" "SF,SF,SI,SI")])
16554 ;; Don't do conditional moves with memory inputs. This splitter helps
16555 ;; register starved x86_32 by forcing inputs into registers before reload.
16557 [(set (match_operand:MODEF 0 "register_operand")
16558 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16559 [(reg FLAGS_REG) (const_int 0)])
16560 (match_operand:MODEF 2 "nonimmediate_operand")
16561 (match_operand:MODEF 3 "nonimmediate_operand")))]
16562 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16563 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16564 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16565 && can_create_pseudo_p ()
16566 && optimize_insn_for_speed_p ()"
16567 [(set (match_dup 0)
16568 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16570 if (MEM_P (operands[2]))
16571 operands[2] = force_reg (<MODE>mode, operands[2]);
16572 if (MEM_P (operands[3]))
16573 operands[3] = force_reg (<MODE>mode, operands[3]);
16576 ;; Don't do conditional moves with memory inputs
16578 [(match_scratch:MODEF 2 "r")
16579 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16580 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16581 [(reg FLAGS_REG) (const_int 0)])
16583 (match_operand:MODEF 3 "memory_operand")))]
16584 "(<MODE>mode != DFmode || TARGET_64BIT)
16585 && TARGET_80387 && TARGET_CMOVE
16586 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16587 && optimize_insn_for_speed_p ()"
16588 [(set (match_dup 2) (match_dup 3))
16590 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16593 [(match_scratch:MODEF 2 "r")
16594 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16595 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16596 [(reg FLAGS_REG) (const_int 0)])
16597 (match_operand:MODEF 3 "memory_operand")
16599 "(<MODE>mode != DFmode || TARGET_64BIT)
16600 && TARGET_80387 && TARGET_CMOVE
16601 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16602 && optimize_insn_for_speed_p ()"
16603 [(set (match_dup 2) (match_dup 3))
16605 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16607 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16608 ;; the scalar versions to have only XMM registers as operands.
16610 ;; XOP conditional move
16611 (define_insn "*xop_pcmov_<mode>"
16612 [(set (match_operand:MODEF 0 "register_operand" "=x")
16613 (if_then_else:MODEF
16614 (match_operand:MODEF 1 "register_operand" "x")
16615 (match_operand:MODEF 2 "register_operand" "x")
16616 (match_operand:MODEF 3 "register_operand" "x")))]
16618 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16619 [(set_attr "type" "sse4arg")])
16621 ;; These versions of the min/max patterns are intentionally ignorant of
16622 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16623 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16624 ;; are undefined in this condition, we're certain this is correct.
16626 (define_insn "<code><mode>3"
16627 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16629 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16630 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16631 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16633 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16634 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16635 [(set_attr "isa" "noavx,avx")
16636 (set_attr "prefix" "orig,vex")
16637 (set_attr "type" "sseadd")
16638 (set_attr "mode" "<MODE>")])
16640 ;; These versions of the min/max patterns implement exactly the operations
16641 ;; min = (op1 < op2 ? op1 : op2)
16642 ;; max = (!(op1 < op2) ? op1 : op2)
16643 ;; Their operands are not commutative, and thus they may be used in the
16644 ;; presence of -0.0 and NaN.
16646 (define_int_iterator IEEE_MAXMIN
16650 (define_int_attr ieee_maxmin
16651 [(UNSPEC_IEEE_MAX "max")
16652 (UNSPEC_IEEE_MIN "min")])
16654 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16655 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16657 [(match_operand:MODEF 1 "register_operand" "0,x")
16658 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16660 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16662 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16663 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16664 [(set_attr "isa" "noavx,avx")
16665 (set_attr "prefix" "orig,vex")
16666 (set_attr "type" "sseadd")
16667 (set_attr "mode" "<MODE>")])
16669 ;; Make two stack loads independent:
16671 ;; fld %st(0) -> fld bb
16672 ;; fmul bb fmul %st(1), %st
16674 ;; Actually we only match the last two instructions for simplicity.
16676 [(set (match_operand 0 "fp_register_operand")
16677 (match_operand 1 "fp_register_operand"))
16679 (match_operator 2 "binary_fp_operator"
16681 (match_operand 3 "memory_operand")]))]
16682 "REGNO (operands[0]) != REGNO (operands[1])"
16683 [(set (match_dup 0) (match_dup 3))
16684 (set (match_dup 0) (match_dup 4))]
16686 ;; The % modifier is not operational anymore in peephole2's, so we have to
16687 ;; swap the operands manually in the case of addition and multiplication.
16691 if (COMMUTATIVE_ARITH_P (operands[2]))
16692 op0 = operands[0], op1 = operands[1];
16694 op0 = operands[1], op1 = operands[0];
16696 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16697 GET_MODE (operands[2]),
16701 ;; Conditional addition patterns
16702 (define_expand "add<mode>cc"
16703 [(match_operand:SWI 0 "register_operand")
16704 (match_operand 1 "ordered_comparison_operator")
16705 (match_operand:SWI 2 "register_operand")
16706 (match_operand:SWI 3 "const_int_operand")]
16708 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16710 ;; Misc patterns (?)
16712 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16713 ;; Otherwise there will be nothing to keep
16715 ;; [(set (reg ebp) (reg esp))]
16716 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16717 ;; (clobber (eflags)]
16718 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16720 ;; in proper program order.
16722 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16723 [(set (match_operand:P 0 "register_operand" "=r,r")
16724 (plus:P (match_operand:P 1 "register_operand" "0,r")
16725 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16726 (clobber (reg:CC FLAGS_REG))
16727 (clobber (mem:BLK (scratch)))]
16730 switch (get_attr_type (insn))
16733 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16736 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16737 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16738 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16740 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16743 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16744 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16747 [(set (attr "type")
16748 (cond [(and (eq_attr "alternative" "0")
16749 (not (match_test "TARGET_OPT_AGU")))
16750 (const_string "alu")
16751 (match_operand:<MODE> 2 "const0_operand")
16752 (const_string "imov")
16754 (const_string "lea")))
16755 (set (attr "length_immediate")
16756 (cond [(eq_attr "type" "imov")
16758 (and (eq_attr "type" "alu")
16759 (match_operand 2 "const128_operand"))
16762 (const_string "*")))
16763 (set_attr "mode" "<MODE>")])
16765 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16766 [(set (match_operand:P 0 "register_operand" "=r")
16767 (minus:P (match_operand:P 1 "register_operand" "0")
16768 (match_operand:P 2 "register_operand" "r")))
16769 (clobber (reg:CC FLAGS_REG))
16770 (clobber (mem:BLK (scratch)))]
16772 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16773 [(set_attr "type" "alu")
16774 (set_attr "mode" "<MODE>")])
16776 (define_insn "allocate_stack_worker_probe_<mode>"
16777 [(set (match_operand:P 0 "register_operand" "=a")
16778 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16779 UNSPECV_STACK_PROBE))
16780 (clobber (reg:CC FLAGS_REG))]
16781 "ix86_target_stack_probe ()"
16782 "call\t___chkstk_ms"
16783 [(set_attr "type" "multi")
16784 (set_attr "length" "5")])
16786 (define_expand "allocate_stack"
16787 [(match_operand 0 "register_operand")
16788 (match_operand 1 "general_operand")]
16789 "ix86_target_stack_probe ()"
16793 #ifndef CHECK_STACK_LIMIT
16794 #define CHECK_STACK_LIMIT 0
16797 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16798 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16802 rtx (*insn) (rtx, rtx);
16804 x = copy_to_mode_reg (Pmode, operands[1]);
16806 insn = (TARGET_64BIT
16807 ? gen_allocate_stack_worker_probe_di
16808 : gen_allocate_stack_worker_probe_si);
16810 emit_insn (insn (x, x));
16813 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16814 stack_pointer_rtx, 0, OPTAB_DIRECT);
16816 if (x != stack_pointer_rtx)
16817 emit_move_insn (stack_pointer_rtx, x);
16819 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16823 ;; Use IOR for stack probes, this is shorter.
16824 (define_expand "probe_stack"
16825 [(match_operand 0 "memory_operand")]
16828 rtx (*gen_ior3) (rtx, rtx, rtx);
16830 gen_ior3 = (GET_MODE (operands[0]) == DImode
16831 ? gen_iordi3 : gen_iorsi3);
16833 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16837 (define_insn "adjust_stack_and_probe<mode>"
16838 [(set (match_operand:P 0 "register_operand" "=r")
16839 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16840 UNSPECV_PROBE_STACK_RANGE))
16841 (set (reg:P SP_REG)
16842 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16843 (clobber (reg:CC FLAGS_REG))
16844 (clobber (mem:BLK (scratch)))]
16846 "* return output_adjust_stack_and_probe (operands[0]);"
16847 [(set_attr "type" "multi")])
16849 (define_insn "probe_stack_range<mode>"
16850 [(set (match_operand:P 0 "register_operand" "=r")
16851 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16852 (match_operand:P 2 "const_int_operand" "n")]
16853 UNSPECV_PROBE_STACK_RANGE))
16854 (clobber (reg:CC FLAGS_REG))]
16856 "* return output_probe_stack_range (operands[0], operands[2]);"
16857 [(set_attr "type" "multi")])
16859 (define_expand "builtin_setjmp_receiver"
16860 [(label_ref (match_operand 0))]
16861 "!TARGET_64BIT && flag_pic"
16867 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16868 rtx label_rtx = gen_label_rtx ();
16869 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16870 xops[0] = xops[1] = picreg;
16871 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16872 ix86_expand_binary_operator (MINUS, SImode, xops);
16876 emit_insn (gen_set_got (pic_offset_table_rtx));
16880 (define_insn_and_split "nonlocal_goto_receiver"
16881 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16882 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16884 "&& reload_completed"
16887 if (crtl->uses_pic_offset_table)
16890 rtx label_rtx = gen_label_rtx ();
16893 /* Get a new pic base. */
16894 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16895 /* Correct this with the offset from the new to the old. */
16896 xops[0] = xops[1] = pic_offset_table_rtx;
16897 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16898 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16899 UNSPEC_MACHOPIC_OFFSET);
16900 xops[2] = gen_rtx_CONST (Pmode, tmp);
16901 ix86_expand_binary_operator (MINUS, SImode, xops);
16904 /* No pic reg restore needed. */
16905 emit_note (NOTE_INSN_DELETED);
16910 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16911 ;; Do not split instructions with mask registers.
16913 [(set (match_operand 0 "general_reg_operand")
16914 (match_operator 3 "promotable_binary_operator"
16915 [(match_operand 1 "general_reg_operand")
16916 (match_operand 2 "aligned_operand")]))
16917 (clobber (reg:CC FLAGS_REG))]
16918 "! TARGET_PARTIAL_REG_STALL && reload_completed
16919 && ((GET_MODE (operands[0]) == HImode
16920 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16921 /* ??? next two lines just !satisfies_constraint_K (...) */
16922 || !CONST_INT_P (operands[2])
16923 || satisfies_constraint_K (operands[2])))
16924 || (GET_MODE (operands[0]) == QImode
16925 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16926 [(parallel [(set (match_dup 0)
16927 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16928 (clobber (reg:CC FLAGS_REG))])]
16930 operands[0] = gen_lowpart (SImode, operands[0]);
16931 operands[1] = gen_lowpart (SImode, operands[1]);
16932 if (GET_CODE (operands[3]) != ASHIFT)
16933 operands[2] = gen_lowpart (SImode, operands[2]);
16934 PUT_MODE (operands[3], SImode);
16937 ; Promote the QImode tests, as i386 has encoding of the AND
16938 ; instruction with 32-bit sign-extended immediate and thus the
16939 ; instruction size is unchanged, except in the %eax case for
16940 ; which it is increased by one byte, hence the ! optimize_size.
16942 [(set (match_operand 0 "flags_reg_operand")
16943 (match_operator 2 "compare_operator"
16944 [(and (match_operand 3 "aligned_operand")
16945 (match_operand 4 "const_int_operand"))
16947 (set (match_operand 1 "register_operand")
16948 (and (match_dup 3) (match_dup 4)))]
16949 "! TARGET_PARTIAL_REG_STALL && reload_completed
16950 && optimize_insn_for_speed_p ()
16951 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16952 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16953 /* Ensure that the operand will remain sign-extended immediate. */
16954 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16955 [(parallel [(set (match_dup 0)
16956 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16959 (and:SI (match_dup 3) (match_dup 4)))])]
16962 = gen_int_mode (INTVAL (operands[4])
16963 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16964 operands[1] = gen_lowpart (SImode, operands[1]);
16965 operands[3] = gen_lowpart (SImode, operands[3]);
16968 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16969 ; the TEST instruction with 32-bit sign-extended immediate and thus
16970 ; the instruction size would at least double, which is not what we
16971 ; want even with ! optimize_size.
16973 [(set (match_operand 0 "flags_reg_operand")
16974 (match_operator 1 "compare_operator"
16975 [(and (match_operand:HI 2 "aligned_operand")
16976 (match_operand:HI 3 "const_int_operand"))
16978 "! TARGET_PARTIAL_REG_STALL && reload_completed
16979 && ! TARGET_FAST_PREFIX
16980 && optimize_insn_for_speed_p ()
16981 /* Ensure that the operand will remain sign-extended immediate. */
16982 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16983 [(set (match_dup 0)
16984 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16988 = gen_int_mode (INTVAL (operands[3])
16989 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16990 operands[2] = gen_lowpart (SImode, operands[2]);
16994 [(set (match_operand 0 "register_operand")
16995 (neg (match_operand 1 "register_operand")))
16996 (clobber (reg:CC FLAGS_REG))]
16997 "! TARGET_PARTIAL_REG_STALL && reload_completed
16998 && (GET_MODE (operands[0]) == HImode
16999 || (GET_MODE (operands[0]) == QImode
17000 && (TARGET_PROMOTE_QImode
17001 || optimize_insn_for_size_p ())))"
17002 [(parallel [(set (match_dup 0)
17003 (neg:SI (match_dup 1)))
17004 (clobber (reg:CC FLAGS_REG))])]
17006 operands[0] = gen_lowpart (SImode, operands[0]);
17007 operands[1] = gen_lowpart (SImode, operands[1]);
17010 ;; Do not split instructions with mask regs.
17012 [(set (match_operand 0 "general_reg_operand")
17013 (not (match_operand 1 "general_reg_operand")))]
17014 "! TARGET_PARTIAL_REG_STALL && reload_completed
17015 && (GET_MODE (operands[0]) == HImode
17016 || (GET_MODE (operands[0]) == QImode
17017 && (TARGET_PROMOTE_QImode
17018 || optimize_insn_for_size_p ())))"
17019 [(set (match_dup 0)
17020 (not:SI (match_dup 1)))]
17022 operands[0] = gen_lowpart (SImode, operands[0]);
17023 operands[1] = gen_lowpart (SImode, operands[1]);
17026 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17027 ;; transform a complex memory operation into two memory to register operations.
17029 ;; Don't push memory operands
17031 [(set (match_operand:SWI 0 "push_operand")
17032 (match_operand:SWI 1 "memory_operand"))
17033 (match_scratch:SWI 2 "<r>")]
17034 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17035 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17036 [(set (match_dup 2) (match_dup 1))
17037 (set (match_dup 0) (match_dup 2))])
17039 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17042 [(set (match_operand:SF 0 "push_operand")
17043 (match_operand:SF 1 "memory_operand"))
17044 (match_scratch:SF 2 "r")]
17045 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17046 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17047 [(set (match_dup 2) (match_dup 1))
17048 (set (match_dup 0) (match_dup 2))])
17050 ;; Don't move an immediate directly to memory when the instruction
17051 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17053 [(match_scratch:SWI124 1 "<r>")
17054 (set (match_operand:SWI124 0 "memory_operand")
17056 "optimize_insn_for_speed_p ()
17057 && ((<MODE>mode == HImode
17058 && TARGET_LCP_STALL)
17059 || (!TARGET_USE_MOV0
17060 && TARGET_SPLIT_LONG_MOVES
17061 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17062 && peep2_regno_dead_p (0, FLAGS_REG)"
17063 [(parallel [(set (match_dup 2) (const_int 0))
17064 (clobber (reg:CC FLAGS_REG))])
17065 (set (match_dup 0) (match_dup 1))]
17066 "operands[2] = gen_lowpart (SImode, operands[1]);")
17069 [(match_scratch:SWI124 2 "<r>")
17070 (set (match_operand:SWI124 0 "memory_operand")
17071 (match_operand:SWI124 1 "immediate_operand"))]
17072 "optimize_insn_for_speed_p ()
17073 && ((<MODE>mode == HImode
17074 && TARGET_LCP_STALL)
17075 || (TARGET_SPLIT_LONG_MOVES
17076 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17077 [(set (match_dup 2) (match_dup 1))
17078 (set (match_dup 0) (match_dup 2))])
17080 ;; Don't compare memory with zero, load and use a test instead.
17082 [(set (match_operand 0 "flags_reg_operand")
17083 (match_operator 1 "compare_operator"
17084 [(match_operand:SI 2 "memory_operand")
17086 (match_scratch:SI 3 "r")]
17087 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17088 [(set (match_dup 3) (match_dup 2))
17089 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17091 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17092 ;; Don't split NOTs with a displacement operand, because resulting XOR
17093 ;; will not be pairable anyway.
17095 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17096 ;; represented using a modRM byte. The XOR replacement is long decoded,
17097 ;; so this split helps here as well.
17099 ;; Note: Can't do this as a regular split because we can't get proper
17100 ;; lifetime information then.
17103 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17104 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17105 "optimize_insn_for_speed_p ()
17106 && ((TARGET_NOT_UNPAIRABLE
17107 && (!MEM_P (operands[0])
17108 || !memory_displacement_operand (operands[0], <MODE>mode)))
17109 || (TARGET_NOT_VECTORMODE
17110 && long_memory_operand (operands[0], <MODE>mode)))
17111 && peep2_regno_dead_p (0, FLAGS_REG)"
17112 [(parallel [(set (match_dup 0)
17113 (xor:SWI124 (match_dup 1) (const_int -1)))
17114 (clobber (reg:CC FLAGS_REG))])])
17116 ;; Non pairable "test imm, reg" instructions can be translated to
17117 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17118 ;; byte opcode instead of two, have a short form for byte operands),
17119 ;; so do it for other CPUs as well. Given that the value was dead,
17120 ;; this should not create any new dependencies. Pass on the sub-word
17121 ;; versions if we're concerned about partial register stalls.
17124 [(set (match_operand 0 "flags_reg_operand")
17125 (match_operator 1 "compare_operator"
17126 [(and:SI (match_operand:SI 2 "register_operand")
17127 (match_operand:SI 3 "immediate_operand"))
17129 "ix86_match_ccmode (insn, CCNOmode)
17130 && (true_regnum (operands[2]) != AX_REG
17131 || satisfies_constraint_K (operands[3]))
17132 && peep2_reg_dead_p (1, operands[2])"
17134 [(set (match_dup 0)
17135 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17138 (and:SI (match_dup 2) (match_dup 3)))])])
17140 ;; We don't need to handle HImode case, because it will be promoted to SImode
17141 ;; on ! TARGET_PARTIAL_REG_STALL
17144 [(set (match_operand 0 "flags_reg_operand")
17145 (match_operator 1 "compare_operator"
17146 [(and:QI (match_operand:QI 2 "register_operand")
17147 (match_operand:QI 3 "immediate_operand"))
17149 "! TARGET_PARTIAL_REG_STALL
17150 && ix86_match_ccmode (insn, CCNOmode)
17151 && true_regnum (operands[2]) != AX_REG
17152 && peep2_reg_dead_p (1, operands[2])"
17154 [(set (match_dup 0)
17155 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17158 (and:QI (match_dup 2) (match_dup 3)))])])
17161 [(set (match_operand 0 "flags_reg_operand")
17162 (match_operator 1 "compare_operator"
17165 (match_operand 2 "ext_register_operand")
17168 (match_operand 3 "const_int_operand"))
17170 "! TARGET_PARTIAL_REG_STALL
17171 && ix86_match_ccmode (insn, CCNOmode)
17172 && true_regnum (operands[2]) != AX_REG
17173 && peep2_reg_dead_p (1, operands[2])"
17174 [(parallel [(set (match_dup 0)
17183 (set (zero_extract:SI (match_dup 2)
17191 (match_dup 3)))])])
17193 ;; Don't do logical operations with memory inputs.
17195 [(match_scratch:SI 2 "r")
17196 (parallel [(set (match_operand:SI 0 "register_operand")
17197 (match_operator:SI 3 "arith_or_logical_operator"
17199 (match_operand:SI 1 "memory_operand")]))
17200 (clobber (reg:CC FLAGS_REG))])]
17201 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17202 [(set (match_dup 2) (match_dup 1))
17203 (parallel [(set (match_dup 0)
17204 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17205 (clobber (reg:CC FLAGS_REG))])])
17208 [(match_scratch:SI 2 "r")
17209 (parallel [(set (match_operand:SI 0 "register_operand")
17210 (match_operator:SI 3 "arith_or_logical_operator"
17211 [(match_operand:SI 1 "memory_operand")
17213 (clobber (reg:CC FLAGS_REG))])]
17214 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17215 [(set (match_dup 2) (match_dup 1))
17216 (parallel [(set (match_dup 0)
17217 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17218 (clobber (reg:CC FLAGS_REG))])])
17220 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17221 ;; refers to the destination of the load!
17224 [(set (match_operand:SI 0 "register_operand")
17225 (match_operand:SI 1 "register_operand"))
17226 (parallel [(set (match_dup 0)
17227 (match_operator:SI 3 "commutative_operator"
17229 (match_operand:SI 2 "memory_operand")]))
17230 (clobber (reg:CC FLAGS_REG))])]
17231 "REGNO (operands[0]) != REGNO (operands[1])
17232 && GENERAL_REGNO_P (REGNO (operands[0]))
17233 && GENERAL_REGNO_P (REGNO (operands[1]))"
17234 [(set (match_dup 0) (match_dup 4))
17235 (parallel [(set (match_dup 0)
17236 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17237 (clobber (reg:CC FLAGS_REG))])]
17238 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17241 [(set (match_operand 0 "register_operand")
17242 (match_operand 1 "register_operand"))
17244 (match_operator 3 "commutative_operator"
17246 (match_operand 2 "memory_operand")]))]
17247 "REGNO (operands[0]) != REGNO (operands[1])
17248 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17249 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17250 [(set (match_dup 0) (match_dup 2))
17252 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17254 ; Don't do logical operations with memory outputs
17256 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17257 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17258 ; the same decoder scheduling characteristics as the original.
17261 [(match_scratch:SI 2 "r")
17262 (parallel [(set (match_operand:SI 0 "memory_operand")
17263 (match_operator:SI 3 "arith_or_logical_operator"
17265 (match_operand:SI 1 "nonmemory_operand")]))
17266 (clobber (reg:CC FLAGS_REG))])]
17267 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17268 /* Do not split stack checking probes. */
17269 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17270 [(set (match_dup 2) (match_dup 0))
17271 (parallel [(set (match_dup 2)
17272 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17273 (clobber (reg:CC FLAGS_REG))])
17274 (set (match_dup 0) (match_dup 2))])
17277 [(match_scratch:SI 2 "r")
17278 (parallel [(set (match_operand:SI 0 "memory_operand")
17279 (match_operator:SI 3 "arith_or_logical_operator"
17280 [(match_operand:SI 1 "nonmemory_operand")
17282 (clobber (reg:CC FLAGS_REG))])]
17283 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17284 /* Do not split stack checking probes. */
17285 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17286 [(set (match_dup 2) (match_dup 0))
17287 (parallel [(set (match_dup 2)
17288 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17289 (clobber (reg:CC FLAGS_REG))])
17290 (set (match_dup 0) (match_dup 2))])
17292 ;; Attempt to use arith or logical operations with memory outputs with
17293 ;; setting of flags.
17295 [(set (match_operand:SWI 0 "register_operand")
17296 (match_operand:SWI 1 "memory_operand"))
17297 (parallel [(set (match_dup 0)
17298 (match_operator:SWI 3 "plusminuslogic_operator"
17300 (match_operand:SWI 2 "<nonmemory_operand>")]))
17301 (clobber (reg:CC FLAGS_REG))])
17302 (set (match_dup 1) (match_dup 0))
17303 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17304 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17305 && peep2_reg_dead_p (4, operands[0])
17306 && !reg_overlap_mentioned_p (operands[0], operands[1])
17307 && !reg_overlap_mentioned_p (operands[0], operands[2])
17308 && (<MODE>mode != QImode
17309 || immediate_operand (operands[2], QImode)
17310 || q_regs_operand (operands[2], QImode))
17311 && ix86_match_ccmode (peep2_next_insn (3),
17312 (GET_CODE (operands[3]) == PLUS
17313 || GET_CODE (operands[3]) == MINUS)
17314 ? CCGOCmode : CCNOmode)"
17315 [(parallel [(set (match_dup 4) (match_dup 5))
17316 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17317 (match_dup 2)]))])]
17319 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17320 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17321 copy_rtx (operands[1]),
17322 copy_rtx (operands[2]));
17323 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17324 operands[5], const0_rtx);
17328 [(parallel [(set (match_operand:SWI 0 "register_operand")
17329 (match_operator:SWI 2 "plusminuslogic_operator"
17331 (match_operand:SWI 1 "memory_operand")]))
17332 (clobber (reg:CC FLAGS_REG))])
17333 (set (match_dup 1) (match_dup 0))
17334 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17335 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17336 && GET_CODE (operands[2]) != MINUS
17337 && peep2_reg_dead_p (3, operands[0])
17338 && !reg_overlap_mentioned_p (operands[0], operands[1])
17339 && ix86_match_ccmode (peep2_next_insn (2),
17340 GET_CODE (operands[2]) == PLUS
17341 ? CCGOCmode : CCNOmode)"
17342 [(parallel [(set (match_dup 3) (match_dup 4))
17343 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17344 (match_dup 0)]))])]
17346 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17347 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17348 copy_rtx (operands[1]),
17349 copy_rtx (operands[0]));
17350 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17351 operands[4], const0_rtx);
17355 [(set (match_operand:SWI12 0 "register_operand")
17356 (match_operand:SWI12 1 "memory_operand"))
17357 (parallel [(set (match_operand:SI 4 "register_operand")
17358 (match_operator:SI 3 "plusminuslogic_operator"
17360 (match_operand:SI 2 "nonmemory_operand")]))
17361 (clobber (reg:CC FLAGS_REG))])
17362 (set (match_dup 1) (match_dup 0))
17363 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17364 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17365 && REG_P (operands[0]) && REG_P (operands[4])
17366 && REGNO (operands[0]) == REGNO (operands[4])
17367 && peep2_reg_dead_p (4, operands[0])
17368 && (<MODE>mode != QImode
17369 || immediate_operand (operands[2], SImode)
17370 || q_regs_operand (operands[2], SImode))
17371 && !reg_overlap_mentioned_p (operands[0], operands[1])
17372 && !reg_overlap_mentioned_p (operands[0], operands[2])
17373 && ix86_match_ccmode (peep2_next_insn (3),
17374 (GET_CODE (operands[3]) == PLUS
17375 || GET_CODE (operands[3]) == MINUS)
17376 ? CCGOCmode : CCNOmode)"
17377 [(parallel [(set (match_dup 4) (match_dup 5))
17378 (set (match_dup 1) (match_dup 6))])]
17380 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17381 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17382 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17383 copy_rtx (operands[1]), operands[2]);
17384 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17385 operands[5], const0_rtx);
17386 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17387 copy_rtx (operands[1]),
17388 copy_rtx (operands[2]));
17391 ;; Attempt to always use XOR for zeroing registers.
17393 [(set (match_operand 0 "register_operand")
17394 (match_operand 1 "const0_operand"))]
17395 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17396 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17397 && GENERAL_REG_P (operands[0])
17398 && peep2_regno_dead_p (0, FLAGS_REG)"
17399 [(parallel [(set (match_dup 0) (const_int 0))
17400 (clobber (reg:CC FLAGS_REG))])]
17401 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17404 [(set (strict_low_part (match_operand 0 "register_operand"))
17406 "(GET_MODE (operands[0]) == QImode
17407 || GET_MODE (operands[0]) == HImode)
17408 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17409 && peep2_regno_dead_p (0, FLAGS_REG)"
17410 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17411 (clobber (reg:CC FLAGS_REG))])])
17413 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17415 [(set (match_operand:SWI248 0 "register_operand")
17417 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17418 && peep2_regno_dead_p (0, FLAGS_REG)"
17419 [(parallel [(set (match_dup 0) (const_int -1))
17420 (clobber (reg:CC FLAGS_REG))])]
17422 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17423 operands[0] = gen_lowpart (SImode, operands[0]);
17426 ;; Attempt to convert simple lea to add/shift.
17427 ;; These can be created by move expanders.
17428 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17429 ;; relevant lea instructions were already split.
17432 [(set (match_operand:SWI48 0 "register_operand")
17433 (plus:SWI48 (match_dup 0)
17434 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17436 && peep2_regno_dead_p (0, FLAGS_REG)"
17437 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17438 (clobber (reg:CC FLAGS_REG))])])
17441 [(set (match_operand:SWI48 0 "register_operand")
17442 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17445 && peep2_regno_dead_p (0, FLAGS_REG)"
17446 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17447 (clobber (reg:CC FLAGS_REG))])])
17450 [(set (match_operand:DI 0 "register_operand")
17452 (plus:SI (match_operand:SI 1 "register_operand")
17453 (match_operand:SI 2 "nonmemory_operand"))))]
17454 "TARGET_64BIT && !TARGET_OPT_AGU
17455 && REGNO (operands[0]) == REGNO (operands[1])
17456 && peep2_regno_dead_p (0, FLAGS_REG)"
17457 [(parallel [(set (match_dup 0)
17458 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17459 (clobber (reg:CC FLAGS_REG))])])
17462 [(set (match_operand:DI 0 "register_operand")
17464 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17465 (match_operand:SI 2 "register_operand"))))]
17466 "TARGET_64BIT && !TARGET_OPT_AGU
17467 && REGNO (operands[0]) == REGNO (operands[2])
17468 && peep2_regno_dead_p (0, FLAGS_REG)"
17469 [(parallel [(set (match_dup 0)
17470 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17471 (clobber (reg:CC FLAGS_REG))])])
17474 [(set (match_operand:SWI48 0 "register_operand")
17475 (mult:SWI48 (match_dup 0)
17476 (match_operand:SWI48 1 "const_int_operand")))]
17477 "exact_log2 (INTVAL (operands[1])) >= 0
17478 && peep2_regno_dead_p (0, FLAGS_REG)"
17479 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17480 (clobber (reg:CC FLAGS_REG))])]
17481 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17484 [(set (match_operand:DI 0 "register_operand")
17486 (mult:SI (match_operand:SI 1 "register_operand")
17487 (match_operand:SI 2 "const_int_operand"))))]
17489 && exact_log2 (INTVAL (operands[2])) >= 0
17490 && REGNO (operands[0]) == REGNO (operands[1])
17491 && peep2_regno_dead_p (0, FLAGS_REG)"
17492 [(parallel [(set (match_dup 0)
17493 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17494 (clobber (reg:CC FLAGS_REG))])]
17495 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17497 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17498 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17499 ;; On many CPUs it is also faster, since special hardware to avoid esp
17500 ;; dependencies is present.
17502 ;; While some of these conversions may be done using splitters, we use
17503 ;; peepholes in order to allow combine_stack_adjustments pass to see
17504 ;; nonobfuscated RTL.
17506 ;; Convert prologue esp subtractions to push.
17507 ;; We need register to push. In order to keep verify_flow_info happy we have
17509 ;; - use scratch and clobber it in order to avoid dependencies
17510 ;; - use already live register
17511 ;; We can't use the second way right now, since there is no reliable way how to
17512 ;; verify that given register is live. First choice will also most likely in
17513 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17514 ;; call clobbered registers are dead. We may want to use base pointer as an
17515 ;; alternative when no register is available later.
17518 [(match_scratch:W 1 "r")
17519 (parallel [(set (reg:P SP_REG)
17520 (plus:P (reg:P SP_REG)
17521 (match_operand:P 0 "const_int_operand")))
17522 (clobber (reg:CC FLAGS_REG))
17523 (clobber (mem:BLK (scratch)))])]
17524 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17525 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17526 [(clobber (match_dup 1))
17527 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17528 (clobber (mem:BLK (scratch)))])])
17531 [(match_scratch:W 1 "r")
17532 (parallel [(set (reg:P SP_REG)
17533 (plus:P (reg:P SP_REG)
17534 (match_operand:P 0 "const_int_operand")))
17535 (clobber (reg:CC FLAGS_REG))
17536 (clobber (mem:BLK (scratch)))])]
17537 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17538 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17539 [(clobber (match_dup 1))
17540 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17541 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17542 (clobber (mem:BLK (scratch)))])])
17544 ;; Convert esp subtractions to push.
17546 [(match_scratch:W 1 "r")
17547 (parallel [(set (reg:P SP_REG)
17548 (plus:P (reg:P SP_REG)
17549 (match_operand:P 0 "const_int_operand")))
17550 (clobber (reg:CC FLAGS_REG))])]
17551 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17552 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17553 [(clobber (match_dup 1))
17554 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17557 [(match_scratch:W 1 "r")
17558 (parallel [(set (reg:P SP_REG)
17559 (plus:P (reg:P SP_REG)
17560 (match_operand:P 0 "const_int_operand")))
17561 (clobber (reg:CC FLAGS_REG))])]
17562 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17563 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17564 [(clobber (match_dup 1))
17565 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17566 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17568 ;; Convert epilogue deallocator to pop.
17570 [(match_scratch:W 1 "r")
17571 (parallel [(set (reg:P SP_REG)
17572 (plus:P (reg:P SP_REG)
17573 (match_operand:P 0 "const_int_operand")))
17574 (clobber (reg:CC FLAGS_REG))
17575 (clobber (mem:BLK (scratch)))])]
17576 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17577 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17578 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17579 (clobber (mem:BLK (scratch)))])])
17581 ;; Two pops case is tricky, since pop causes dependency
17582 ;; on destination register. We use two registers if available.
17584 [(match_scratch:W 1 "r")
17585 (match_scratch:W 2 "r")
17586 (parallel [(set (reg:P SP_REG)
17587 (plus:P (reg:P SP_REG)
17588 (match_operand:P 0 "const_int_operand")))
17589 (clobber (reg:CC FLAGS_REG))
17590 (clobber (mem:BLK (scratch)))])]
17591 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17592 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17593 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17594 (clobber (mem:BLK (scratch)))])
17595 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17598 [(match_scratch:W 1 "r")
17599 (parallel [(set (reg:P SP_REG)
17600 (plus:P (reg:P SP_REG)
17601 (match_operand:P 0 "const_int_operand")))
17602 (clobber (reg:CC FLAGS_REG))
17603 (clobber (mem:BLK (scratch)))])]
17604 "optimize_insn_for_size_p ()
17605 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17606 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17607 (clobber (mem:BLK (scratch)))])
17608 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17610 ;; Convert esp additions to pop.
17612 [(match_scratch:W 1 "r")
17613 (parallel [(set (reg:P SP_REG)
17614 (plus:P (reg:P SP_REG)
17615 (match_operand:P 0 "const_int_operand")))
17616 (clobber (reg:CC FLAGS_REG))])]
17617 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17618 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17620 ;; Two pops case is tricky, since pop causes dependency
17621 ;; on destination register. We use two registers if available.
17623 [(match_scratch:W 1 "r")
17624 (match_scratch:W 2 "r")
17625 (parallel [(set (reg:P SP_REG)
17626 (plus:P (reg:P SP_REG)
17627 (match_operand:P 0 "const_int_operand")))
17628 (clobber (reg:CC FLAGS_REG))])]
17629 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17630 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17631 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17634 [(match_scratch:W 1 "r")
17635 (parallel [(set (reg:P SP_REG)
17636 (plus:P (reg:P SP_REG)
17637 (match_operand:P 0 "const_int_operand")))
17638 (clobber (reg:CC FLAGS_REG))])]
17639 "optimize_insn_for_size_p ()
17640 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17641 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17642 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17644 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17645 ;; required and register dies. Similarly for 128 to -128.
17647 [(set (match_operand 0 "flags_reg_operand")
17648 (match_operator 1 "compare_operator"
17649 [(match_operand 2 "register_operand")
17650 (match_operand 3 "const_int_operand")]))]
17651 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17652 && incdec_operand (operands[3], GET_MODE (operands[3])))
17653 || (!TARGET_FUSE_CMP_AND_BRANCH
17654 && INTVAL (operands[3]) == 128))
17655 && ix86_match_ccmode (insn, CCGCmode)
17656 && peep2_reg_dead_p (1, operands[2])"
17657 [(parallel [(set (match_dup 0)
17658 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17659 (clobber (match_dup 2))])])
17661 ;; Convert imul by three, five and nine into lea
17664 [(set (match_operand:SWI48 0 "register_operand")
17665 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17666 (match_operand:SWI48 2 "const359_operand")))
17667 (clobber (reg:CC FLAGS_REG))])]
17668 "!TARGET_PARTIAL_REG_STALL
17669 || <MODE>mode == SImode
17670 || optimize_function_for_size_p (cfun)"
17671 [(set (match_dup 0)
17672 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17674 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17678 [(set (match_operand:SWI48 0 "register_operand")
17679 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17680 (match_operand:SWI48 2 "const359_operand")))
17681 (clobber (reg:CC FLAGS_REG))])]
17682 "optimize_insn_for_speed_p ()
17683 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17684 [(set (match_dup 0) (match_dup 1))
17686 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17688 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17690 ;; imul $32bit_imm, mem, reg is vector decoded, while
17691 ;; imul $32bit_imm, reg, reg is direct decoded.
17693 [(match_scratch:SWI48 3 "r")
17694 (parallel [(set (match_operand:SWI48 0 "register_operand")
17695 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17696 (match_operand:SWI48 2 "immediate_operand")))
17697 (clobber (reg:CC FLAGS_REG))])]
17698 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17699 && !satisfies_constraint_K (operands[2])"
17700 [(set (match_dup 3) (match_dup 1))
17701 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17702 (clobber (reg:CC FLAGS_REG))])])
17705 [(match_scratch:SI 3 "r")
17706 (parallel [(set (match_operand:DI 0 "register_operand")
17708 (mult:SI (match_operand:SI 1 "memory_operand")
17709 (match_operand:SI 2 "immediate_operand"))))
17710 (clobber (reg:CC FLAGS_REG))])]
17712 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17713 && !satisfies_constraint_K (operands[2])"
17714 [(set (match_dup 3) (match_dup 1))
17715 (parallel [(set (match_dup 0)
17716 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17717 (clobber (reg:CC FLAGS_REG))])])
17719 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17720 ;; Convert it into imul reg, reg
17721 ;; It would be better to force assembler to encode instruction using long
17722 ;; immediate, but there is apparently no way to do so.
17724 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17726 (match_operand:SWI248 1 "nonimmediate_operand")
17727 (match_operand:SWI248 2 "const_int_operand")))
17728 (clobber (reg:CC FLAGS_REG))])
17729 (match_scratch:SWI248 3 "r")]
17730 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17731 && satisfies_constraint_K (operands[2])"
17732 [(set (match_dup 3) (match_dup 2))
17733 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17734 (clobber (reg:CC FLAGS_REG))])]
17736 if (!rtx_equal_p (operands[0], operands[1]))
17737 emit_move_insn (operands[0], operands[1]);
17740 ;; After splitting up read-modify operations, array accesses with memory
17741 ;; operands might end up in form:
17743 ;; movl 4(%esp), %edx
17745 ;; instead of pre-splitting:
17747 ;; addl 4(%esp), %eax
17749 ;; movl 4(%esp), %edx
17750 ;; leal (%edx,%eax,4), %eax
17753 [(match_scratch:W 5 "r")
17754 (parallel [(set (match_operand 0 "register_operand")
17755 (ashift (match_operand 1 "register_operand")
17756 (match_operand 2 "const_int_operand")))
17757 (clobber (reg:CC FLAGS_REG))])
17758 (parallel [(set (match_operand 3 "register_operand")
17759 (plus (match_dup 0)
17760 (match_operand 4 "x86_64_general_operand")))
17761 (clobber (reg:CC FLAGS_REG))])]
17762 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17763 /* Validate MODE for lea. */
17764 && ((!TARGET_PARTIAL_REG_STALL
17765 && (GET_MODE (operands[0]) == QImode
17766 || GET_MODE (operands[0]) == HImode))
17767 || GET_MODE (operands[0]) == SImode
17768 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17769 && (rtx_equal_p (operands[0], operands[3])
17770 || peep2_reg_dead_p (2, operands[0]))
17771 /* We reorder load and the shift. */
17772 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17773 [(set (match_dup 5) (match_dup 4))
17774 (set (match_dup 0) (match_dup 1))]
17776 enum machine_mode op1mode = GET_MODE (operands[1]);
17777 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17778 int scale = 1 << INTVAL (operands[2]);
17779 rtx index = gen_lowpart (word_mode, operands[1]);
17780 rtx base = gen_lowpart (word_mode, operands[5]);
17781 rtx dest = gen_lowpart (mode, operands[3]);
17783 operands[1] = gen_rtx_PLUS (word_mode, base,
17784 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17785 operands[5] = base;
17786 if (mode != word_mode)
17787 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17788 if (op1mode != word_mode)
17789 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17790 operands[0] = dest;
17793 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17794 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17795 ;; caught for use by garbage collectors and the like. Using an insn that
17796 ;; maps to SIGILL makes it more likely the program will rightfully die.
17797 ;; Keeping with tradition, "6" is in honor of #UD.
17798 (define_insn "trap"
17799 [(trap_if (const_int 1) (const_int 6))]
17802 #ifdef HAVE_AS_IX86_UD2
17805 return ASM_SHORT "0x0b0f";
17808 [(set_attr "length" "2")])
17810 (define_expand "prefetch"
17811 [(prefetch (match_operand 0 "address_operand")
17812 (match_operand:SI 1 "const_int_operand")
17813 (match_operand:SI 2 "const_int_operand"))]
17814 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17816 bool write = INTVAL (operands[1]) != 0;
17817 int locality = INTVAL (operands[2]);
17819 gcc_assert (IN_RANGE (locality, 0, 3));
17821 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17822 supported by SSE counterpart or the SSE prefetch is not available
17823 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17825 if (TARGET_PREFETCHWT1 && write && locality <= 2)
17826 operands[2] = const2_rtx;
17827 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17828 operands[2] = GEN_INT (3);
17830 operands[1] = const0_rtx;
17833 (define_insn "*prefetch_sse"
17834 [(prefetch (match_operand 0 "address_operand" "p")
17836 (match_operand:SI 1 "const_int_operand"))]
17837 "TARGET_PREFETCH_SSE"
17839 static const char * const patterns[4] = {
17840 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17843 int locality = INTVAL (operands[1]);
17844 gcc_assert (IN_RANGE (locality, 0, 3));
17846 return patterns[locality];
17848 [(set_attr "type" "sse")
17849 (set_attr "atom_sse_attr" "prefetch")
17850 (set (attr "length_address")
17851 (symbol_ref "memory_address_length (operands[0], false)"))
17852 (set_attr "memory" "none")])
17854 (define_insn "*prefetch_3dnow"
17855 [(prefetch (match_operand 0 "address_operand" "p")
17856 (match_operand:SI 1 "const_int_operand" "n")
17860 if (INTVAL (operands[1]) == 0)
17861 return "prefetch\t%a0";
17863 return "prefetchw\t%a0";
17865 [(set_attr "type" "mmx")
17866 (set (attr "length_address")
17867 (symbol_ref "memory_address_length (operands[0], false)"))
17868 (set_attr "memory" "none")])
17870 (define_insn "*prefetch_prefetchwt1_<mode>"
17871 [(prefetch (match_operand:P 0 "address_operand" "p")
17874 "TARGET_PREFETCHWT1"
17875 "prefetchwt1\t%a0";
17876 [(set_attr "type" "sse")
17877 (set (attr "length_address")
17878 (symbol_ref "memory_address_length (operands[0], false)"))
17879 (set_attr "memory" "none")])
17881 (define_expand "stack_protect_set"
17882 [(match_operand 0 "memory_operand")
17883 (match_operand 1 "memory_operand")]
17884 "TARGET_SSP_TLS_GUARD"
17886 rtx (*insn)(rtx, rtx);
17888 #ifdef TARGET_THREAD_SSP_OFFSET
17889 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17890 insn = (TARGET_LP64
17891 ? gen_stack_tls_protect_set_di
17892 : gen_stack_tls_protect_set_si);
17894 insn = (TARGET_LP64
17895 ? gen_stack_protect_set_di
17896 : gen_stack_protect_set_si);
17899 emit_insn (insn (operands[0], operands[1]));
17903 (define_insn "stack_protect_set_<mode>"
17904 [(set (match_operand:PTR 0 "memory_operand" "=m")
17905 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17907 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17908 (clobber (reg:CC FLAGS_REG))]
17909 "TARGET_SSP_TLS_GUARD"
17910 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17911 [(set_attr "type" "multi")])
17913 (define_insn "stack_tls_protect_set_<mode>"
17914 [(set (match_operand:PTR 0 "memory_operand" "=m")
17915 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17916 UNSPEC_SP_TLS_SET))
17917 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17918 (clobber (reg:CC FLAGS_REG))]
17920 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17921 [(set_attr "type" "multi")])
17923 (define_expand "stack_protect_test"
17924 [(match_operand 0 "memory_operand")
17925 (match_operand 1 "memory_operand")
17927 "TARGET_SSP_TLS_GUARD"
17929 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17931 rtx (*insn)(rtx, rtx, rtx);
17933 #ifdef TARGET_THREAD_SSP_OFFSET
17934 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17935 insn = (TARGET_LP64
17936 ? gen_stack_tls_protect_test_di
17937 : gen_stack_tls_protect_test_si);
17939 insn = (TARGET_LP64
17940 ? gen_stack_protect_test_di
17941 : gen_stack_protect_test_si);
17944 emit_insn (insn (flags, operands[0], operands[1]));
17946 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17947 flags, const0_rtx, operands[2]));
17951 (define_insn "stack_protect_test_<mode>"
17952 [(set (match_operand:CCZ 0 "flags_reg_operand")
17953 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17954 (match_operand:PTR 2 "memory_operand" "m")]
17956 (clobber (match_scratch:PTR 3 "=&r"))]
17957 "TARGET_SSP_TLS_GUARD"
17958 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17959 [(set_attr "type" "multi")])
17961 (define_insn "stack_tls_protect_test_<mode>"
17962 [(set (match_operand:CCZ 0 "flags_reg_operand")
17963 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17964 (match_operand:PTR 2 "const_int_operand" "i")]
17965 UNSPEC_SP_TLS_TEST))
17966 (clobber (match_scratch:PTR 3 "=r"))]
17968 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17969 [(set_attr "type" "multi")])
17971 (define_insn "sse4_2_crc32<mode>"
17972 [(set (match_operand:SI 0 "register_operand" "=r")
17974 [(match_operand:SI 1 "register_operand" "0")
17975 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17977 "TARGET_SSE4_2 || TARGET_CRC32"
17978 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17979 [(set_attr "type" "sselog1")
17980 (set_attr "prefix_rep" "1")
17981 (set_attr "prefix_extra" "1")
17982 (set (attr "prefix_data16")
17983 (if_then_else (match_operand:HI 2)
17985 (const_string "*")))
17986 (set (attr "prefix_rex")
17987 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17989 (const_string "*")))
17990 (set_attr "mode" "SI")])
17992 (define_insn "sse4_2_crc32di"
17993 [(set (match_operand:DI 0 "register_operand" "=r")
17995 [(match_operand:DI 1 "register_operand" "0")
17996 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17998 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17999 "crc32{q}\t{%2, %0|%0, %2}"
18000 [(set_attr "type" "sselog1")
18001 (set_attr "prefix_rep" "1")
18002 (set_attr "prefix_extra" "1")
18003 (set_attr "mode" "DI")])
18005 (define_insn "rdpmc"
18006 [(set (match_operand:DI 0 "register_operand" "=A")
18007 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18011 [(set_attr "type" "other")
18012 (set_attr "length" "2")])
18014 (define_insn "rdpmc_rex64"
18015 [(set (match_operand:DI 0 "register_operand" "=a")
18016 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18018 (set (match_operand:DI 1 "register_operand" "=d")
18019 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18022 [(set_attr "type" "other")
18023 (set_attr "length" "2")])
18025 (define_insn "rdtsc"
18026 [(set (match_operand:DI 0 "register_operand" "=A")
18027 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18030 [(set_attr "type" "other")
18031 (set_attr "length" "2")])
18033 (define_insn "rdtsc_rex64"
18034 [(set (match_operand:DI 0 "register_operand" "=a")
18035 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18036 (set (match_operand:DI 1 "register_operand" "=d")
18037 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18040 [(set_attr "type" "other")
18041 (set_attr "length" "2")])
18043 (define_insn "rdtscp"
18044 [(set (match_operand:DI 0 "register_operand" "=A")
18045 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18046 (set (match_operand:SI 1 "register_operand" "=c")
18047 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18050 [(set_attr "type" "other")
18051 (set_attr "length" "3")])
18053 (define_insn "rdtscp_rex64"
18054 [(set (match_operand:DI 0 "register_operand" "=a")
18055 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18056 (set (match_operand:DI 1 "register_operand" "=d")
18057 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18058 (set (match_operand:SI 2 "register_operand" "=c")
18059 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18062 [(set_attr "type" "other")
18063 (set_attr "length" "3")])
18065 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18067 ;; FXSR, XSAVE and XSAVEOPT instructions
18069 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18071 (define_insn "fxsave"
18072 [(set (match_operand:BLK 0 "memory_operand" "=m")
18073 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18076 [(set_attr "type" "other")
18077 (set_attr "memory" "store")
18078 (set (attr "length")
18079 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18081 (define_insn "fxsave64"
18082 [(set (match_operand:BLK 0 "memory_operand" "=m")
18083 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18084 "TARGET_64BIT && TARGET_FXSR"
18086 [(set_attr "type" "other")
18087 (set_attr "memory" "store")
18088 (set (attr "length")
18089 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18091 (define_insn "fxrstor"
18092 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18096 [(set_attr "type" "other")
18097 (set_attr "memory" "load")
18098 (set (attr "length")
18099 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18101 (define_insn "fxrstor64"
18102 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18103 UNSPECV_FXRSTOR64)]
18104 "TARGET_64BIT && TARGET_FXSR"
18106 [(set_attr "type" "other")
18107 (set_attr "memory" "load")
18108 (set (attr "length")
18109 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18111 (define_int_iterator ANY_XSAVE
18113 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18114 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18115 (UNSPECV_XSAVES "TARGET_XSAVES")])
18117 (define_int_iterator ANY_XSAVE64
18119 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18120 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18121 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18123 (define_int_attr xsave
18124 [(UNSPECV_XSAVE "xsave")
18125 (UNSPECV_XSAVE64 "xsave64")
18126 (UNSPECV_XSAVEOPT "xsaveopt")
18127 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18128 (UNSPECV_XSAVEC "xsavec")
18129 (UNSPECV_XSAVEC64 "xsavec64")
18130 (UNSPECV_XSAVES "xsaves")
18131 (UNSPECV_XSAVES64 "xsaves64")])
18133 (define_int_iterator ANY_XRSTOR
18135 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18137 (define_int_iterator ANY_XRSTOR64
18139 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18141 (define_int_attr xrstor
18142 [(UNSPECV_XRSTOR "xrstor")
18143 (UNSPECV_XRSTOR64 "xrstor")
18144 (UNSPECV_XRSTORS "xrstors")
18145 (UNSPECV_XRSTORS64 "xrstors")])
18147 (define_insn "<xsave>"
18148 [(set (match_operand:BLK 0 "memory_operand" "=m")
18149 (unspec_volatile:BLK
18150 [(match_operand:DI 1 "register_operand" "A")]
18152 "!TARGET_64BIT && TARGET_XSAVE"
18154 [(set_attr "type" "other")
18155 (set_attr "memory" "store")
18156 (set (attr "length")
18157 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18159 (define_insn "<xsave>_rex64"
18160 [(set (match_operand:BLK 0 "memory_operand" "=m")
18161 (unspec_volatile:BLK
18162 [(match_operand:SI 1 "register_operand" "a")
18163 (match_operand:SI 2 "register_operand" "d")]
18165 "TARGET_64BIT && TARGET_XSAVE"
18167 [(set_attr "type" "other")
18168 (set_attr "memory" "store")
18169 (set (attr "length")
18170 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18172 (define_insn "<xsave>"
18173 [(set (match_operand:BLK 0 "memory_operand" "=m")
18174 (unspec_volatile:BLK
18175 [(match_operand:SI 1 "register_operand" "a")
18176 (match_operand:SI 2 "register_operand" "d")]
18178 "TARGET_64BIT && TARGET_XSAVE"
18180 [(set_attr "type" "other")
18181 (set_attr "memory" "store")
18182 (set (attr "length")
18183 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18185 (define_insn "<xrstor>"
18186 [(unspec_volatile:BLK
18187 [(match_operand:BLK 0 "memory_operand" "m")
18188 (match_operand:DI 1 "register_operand" "A")]
18190 "!TARGET_64BIT && TARGET_XSAVE"
18192 [(set_attr "type" "other")
18193 (set_attr "memory" "load")
18194 (set (attr "length")
18195 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18197 (define_insn "<xrstor>_rex64"
18198 [(unspec_volatile:BLK
18199 [(match_operand:BLK 0 "memory_operand" "m")
18200 (match_operand:SI 1 "register_operand" "a")
18201 (match_operand:SI 2 "register_operand" "d")]
18203 "TARGET_64BIT && TARGET_XSAVE"
18205 [(set_attr "type" "other")
18206 (set_attr "memory" "load")
18207 (set (attr "length")
18208 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18210 (define_insn "<xrstor>64"
18211 [(unspec_volatile:BLK
18212 [(match_operand:BLK 0 "memory_operand" "m")
18213 (match_operand:SI 1 "register_operand" "a")
18214 (match_operand:SI 2 "register_operand" "d")]
18216 "TARGET_64BIT && TARGET_XSAVE"
18218 [(set_attr "type" "other")
18219 (set_attr "memory" "load")
18220 (set (attr "length")
18221 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18223 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18225 ;; Floating-point instructions for atomic compound assignments
18227 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18229 ; Clobber all floating-point registers on environment save and restore
18230 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18231 (define_insn "fnstenv"
18232 [(set (match_operand:BLK 0 "memory_operand" "=m")
18233 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18234 (clobber (reg:HI FPCR_REG))
18235 (clobber (reg:XF ST0_REG))
18236 (clobber (reg:XF ST1_REG))
18237 (clobber (reg:XF ST2_REG))
18238 (clobber (reg:XF ST3_REG))
18239 (clobber (reg:XF ST4_REG))
18240 (clobber (reg:XF ST5_REG))
18241 (clobber (reg:XF ST6_REG))
18242 (clobber (reg:XF ST7_REG))]
18245 [(set_attr "type" "other")
18246 (set_attr "memory" "store")
18247 (set (attr "length")
18248 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18250 (define_insn "fldenv"
18251 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18253 (clobber (reg:CCFP FPSR_REG))
18254 (clobber (reg:HI FPCR_REG))
18255 (clobber (reg:XF ST0_REG))
18256 (clobber (reg:XF ST1_REG))
18257 (clobber (reg:XF ST2_REG))
18258 (clobber (reg:XF ST3_REG))
18259 (clobber (reg:XF ST4_REG))
18260 (clobber (reg:XF ST5_REG))
18261 (clobber (reg:XF ST6_REG))
18262 (clobber (reg:XF ST7_REG))]
18265 [(set_attr "type" "other")
18266 (set_attr "memory" "load")
18267 (set (attr "length")
18268 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18270 (define_insn "fnstsw"
18271 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18272 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18275 [(set_attr "type" "other,other")
18276 (set_attr "memory" "none,store")
18277 (set (attr "length")
18278 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18280 (define_insn "fnclex"
18281 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18284 [(set_attr "type" "other")
18285 (set_attr "memory" "none")
18286 (set_attr "length" "2")])
18288 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18290 ;; LWP instructions
18292 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18294 (define_expand "lwp_llwpcb"
18295 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18296 UNSPECV_LLWP_INTRINSIC)]
18299 (define_insn "*lwp_llwpcb<mode>1"
18300 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18301 UNSPECV_LLWP_INTRINSIC)]
18304 [(set_attr "type" "lwp")
18305 (set_attr "mode" "<MODE>")
18306 (set_attr "length" "5")])
18308 (define_expand "lwp_slwpcb"
18309 [(set (match_operand 0 "register_operand" "=r")
18310 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18315 insn = (Pmode == DImode
18317 : gen_lwp_slwpcbsi);
18319 emit_insn (insn (operands[0]));
18323 (define_insn "lwp_slwpcb<mode>"
18324 [(set (match_operand:P 0 "register_operand" "=r")
18325 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18328 [(set_attr "type" "lwp")
18329 (set_attr "mode" "<MODE>")
18330 (set_attr "length" "5")])
18332 (define_expand "lwp_lwpval<mode>3"
18333 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18334 (match_operand:SI 2 "nonimmediate_operand" "rm")
18335 (match_operand:SI 3 "const_int_operand" "i")]
18336 UNSPECV_LWPVAL_INTRINSIC)]
18338 ;; Avoid unused variable warning.
18339 "(void) operands[0];")
18341 (define_insn "*lwp_lwpval<mode>3_1"
18342 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18343 (match_operand:SI 1 "nonimmediate_operand" "rm")
18344 (match_operand:SI 2 "const_int_operand" "i")]
18345 UNSPECV_LWPVAL_INTRINSIC)]
18347 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18348 [(set_attr "type" "lwp")
18349 (set_attr "mode" "<MODE>")
18350 (set (attr "length")
18351 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18353 (define_expand "lwp_lwpins<mode>3"
18354 [(set (reg:CCC FLAGS_REG)
18355 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18356 (match_operand:SI 2 "nonimmediate_operand" "rm")
18357 (match_operand:SI 3 "const_int_operand" "i")]
18358 UNSPECV_LWPINS_INTRINSIC))
18359 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18360 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18363 (define_insn "*lwp_lwpins<mode>3_1"
18364 [(set (reg:CCC FLAGS_REG)
18365 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18366 (match_operand:SI 1 "nonimmediate_operand" "rm")
18367 (match_operand:SI 2 "const_int_operand" "i")]
18368 UNSPECV_LWPINS_INTRINSIC))]
18370 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18371 [(set_attr "type" "lwp")
18372 (set_attr "mode" "<MODE>")
18373 (set (attr "length")
18374 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18376 (define_int_iterator RDFSGSBASE
18380 (define_int_iterator WRFSGSBASE
18384 (define_int_attr fsgs
18385 [(UNSPECV_RDFSBASE "fs")
18386 (UNSPECV_RDGSBASE "gs")
18387 (UNSPECV_WRFSBASE "fs")
18388 (UNSPECV_WRGSBASE "gs")])
18390 (define_insn "rd<fsgs>base<mode>"
18391 [(set (match_operand:SWI48 0 "register_operand" "=r")
18392 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18393 "TARGET_64BIT && TARGET_FSGSBASE"
18395 [(set_attr "type" "other")
18396 (set_attr "prefix_extra" "2")])
18398 (define_insn "wr<fsgs>base<mode>"
18399 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18401 "TARGET_64BIT && TARGET_FSGSBASE"
18403 [(set_attr "type" "other")
18404 (set_attr "prefix_extra" "2")])
18406 (define_insn "rdrand<mode>_1"
18407 [(set (match_operand:SWI248 0 "register_operand" "=r")
18408 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18409 (set (reg:CCC FLAGS_REG)
18410 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18413 [(set_attr "type" "other")
18414 (set_attr "prefix_extra" "1")])
18416 (define_insn "rdseed<mode>_1"
18417 [(set (match_operand:SWI248 0 "register_operand" "=r")
18418 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18419 (set (reg:CCC FLAGS_REG)
18420 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18423 [(set_attr "type" "other")
18424 (set_attr "prefix_extra" "1")])
18426 (define_expand "pause"
18427 [(set (match_dup 0)
18428 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18431 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18432 MEM_VOLATILE_P (operands[0]) = 1;
18435 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18436 ;; They have the same encoding.
18437 (define_insn "*pause"
18438 [(set (match_operand:BLK 0)
18439 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18442 [(set_attr "length" "2")
18443 (set_attr "memory" "unknown")])
18445 (define_expand "xbegin"
18446 [(set (match_operand:SI 0 "register_operand")
18447 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18450 rtx label = gen_label_rtx ();
18452 /* xbegin is emitted as jump_insn, so reload won't be able
18453 to reload its operand. Force the value into AX hard register. */
18454 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18455 emit_move_insn (ax_reg, constm1_rtx);
18457 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18459 emit_label (label);
18460 LABEL_NUSES (label) = 1;
18462 emit_move_insn (operands[0], ax_reg);
18467 (define_insn "xbegin_1"
18469 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18471 (label_ref (match_operand 1))
18473 (set (match_operand:SI 0 "register_operand" "+a")
18474 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18477 [(set_attr "type" "other")
18478 (set_attr "length" "6")])
18480 (define_insn "xend"
18481 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18484 [(set_attr "type" "other")
18485 (set_attr "length" "3")])
18487 (define_insn "xabort"
18488 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18492 [(set_attr "type" "other")
18493 (set_attr "length" "3")])
18495 (define_expand "xtest"
18496 [(set (match_operand:QI 0 "register_operand")
18497 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18500 emit_insn (gen_xtest_1 ());
18502 ix86_expand_setcc (operands[0], NE,
18503 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18507 (define_insn "xtest_1"
18508 [(set (reg:CCZ FLAGS_REG)
18509 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18512 [(set_attr "type" "other")
18513 (set_attr "length" "3")])
18515 (define_insn "clflushopt"
18516 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18517 UNSPECV_CLFLUSHOPT)]
18518 "TARGET_CLFLUSHOPT"
18520 [(set_attr "type" "sse")
18521 (set_attr "atom_sse_attr" "fence")
18522 (set_attr "memory" "unknown")])
18526 (include "sync.md")