1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2013 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
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69 ;; Relocation specifiers
80 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
110 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
194 (define_c_enum "unspecv" [
197 UNSPECV_PROBE_STACK_RANGE
200 UNSPECV_SPLIT_STACK_RETURN
206 UNSPECV_LLWP_INTRINSIC
207 UNSPECV_SLWP_INTRINSIC
208 UNSPECV_LWPVAL_INTRINSIC
209 UNSPECV_LWPINS_INTRINSIC
225 ;; For RDRAND support
228 ;; For RDSEED support
240 ;; Constants to represent rounding modes in the ROUND instruction
249 ;; Constants to represent pcomtrue/pcomfalse variants
259 ;; Constants used in the XOP pperm instruction
261 [(PPERM_SRC 0x00) /* copy source */
262 (PPERM_INVERT 0x20) /* invert source */
263 (PPERM_REVERSE 0x40) /* bit reverse source */
264 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
265 (PPERM_ZERO 0x80) /* all 0's */
266 (PPERM_ONES 0xa0) /* all 1's */
267 (PPERM_SIGN 0xc0) /* propagate sign bit */
268 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
269 (PPERM_SRC1 0x00) /* use first source byte */
270 (PPERM_SRC2 0x10) /* use second source byte */
273 ;; Registers by name.
354 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
357 ;; In C guard expressions, put expressions which may be compile-time
358 ;; constants first. This allows for better optimization. For
359 ;; example, write "TARGET_64BIT && reload_completed", not
360 ;; "reload_completed && TARGET_64BIT".
364 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
365 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
366 (const (symbol_ref "ix86_schedule")))
368 ;; A basic instruction type. Refinements due to arguments to be
369 ;; provided in other attributes.
372 alu,alu1,negnot,imov,imovx,lea,
373 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
374 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
375 push,pop,call,callv,leave,
377 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
378 fxch,fistp,fisttp,frndint,
379 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
380 ssemul,sseimul,ssediv,sselog,sselog1,
381 sseishft,sseishft1,ssecmp,ssecomi,
382 ssecvt,ssecvt1,sseicvt,sseins,
383 sseshuf,sseshuf1,ssemuladd,sse4arg,
385 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
386 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
387 (const_string "other"))
389 ;; Main data type used by the insn
391 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
393 (const_string "unknown"))
395 ;; The CPU unit operations uses.
396 (define_attr "unit" "integer,i387,sse,mmx,unknown"
397 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
398 fxch,fistp,fisttp,frndint")
399 (const_string "i387")
400 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
401 ssemul,sseimul,ssediv,sselog,sselog1,
402 sseishft,sseishft1,ssecmp,ssecomi,
403 ssecvt,ssecvt1,sseicvt,sseins,
404 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
406 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
408 (eq_attr "type" "other")
409 (const_string "unknown")]
410 (const_string "integer")))
412 ;; The (bounding maximum) length of an instruction immediate.
413 (define_attr "length_immediate" ""
414 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
415 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
418 (eq_attr "unit" "i387,sse,mmx")
420 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
421 rotate,rotatex,rotate1,imul,icmp,push,pop")
422 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
423 (eq_attr "type" "imov,test")
424 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
425 (eq_attr "type" "call")
426 (if_then_else (match_operand 0 "constant_call_address_operand")
429 (eq_attr "type" "callv")
430 (if_then_else (match_operand 1 "constant_call_address_operand")
433 ;; We don't know the size before shorten_branches. Expect
434 ;; the instruction to fit for better scheduling.
435 (eq_attr "type" "ibr")
438 (symbol_ref "/* Update immediate_length and other attributes! */
439 gcc_unreachable (),1")))
441 ;; The (bounding maximum) length of an instruction address.
442 (define_attr "length_address" ""
443 (cond [(eq_attr "type" "str,other,multi,fxch")
445 (and (eq_attr "type" "call")
446 (match_operand 0 "constant_call_address_operand"))
448 (and (eq_attr "type" "callv")
449 (match_operand 1 "constant_call_address_operand"))
452 (symbol_ref "ix86_attr_length_address_default (insn)")))
454 ;; Set when length prefix is used.
455 (define_attr "prefix_data16" ""
456 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
458 (eq_attr "mode" "HI")
460 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
465 ;; Set when string REP prefix is used.
466 (define_attr "prefix_rep" ""
467 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
469 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
471 (and (eq_attr "type" "ibr,call,callv")
472 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
477 ;; Set when 0f opcode prefix is used.
478 (define_attr "prefix_0f" ""
480 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
481 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
482 (eq_attr "unit" "sse,mmx"))
486 ;; Set when REX opcode prefix is used.
487 (define_attr "prefix_rex" ""
488 (cond [(not (match_test "TARGET_64BIT"))
490 (and (eq_attr "mode" "DI")
491 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
492 (eq_attr "unit" "!mmx")))
494 (and (eq_attr "mode" "QI")
495 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
497 (match_test "x86_extended_reg_mentioned_p (insn)")
499 (and (eq_attr "type" "imovx")
500 (match_operand:QI 1 "ext_QIreg_operand"))
505 ;; There are also additional prefixes in 3DNOW, SSSE3.
506 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
507 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
508 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
509 (define_attr "prefix_extra" ""
510 (cond [(eq_attr "type" "ssemuladd,sse4arg")
512 (eq_attr "type" "sseiadd1,ssecvt1")
517 ;; Prefix used: original, VEX or maybe VEX.
518 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
519 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
521 (eq_attr "mode" "XI,V16SF,V8DF")
522 (const_string "evex")
524 (const_string "orig")))
526 ;; VEX W bit is used.
527 (define_attr "prefix_vex_w" "" (const_int 0))
529 ;; The length of VEX prefix
530 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
531 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
532 ;; still prefix_0f 1, with prefix_extra 1.
533 (define_attr "length_vex" ""
534 (if_then_else (and (eq_attr "prefix_0f" "1")
535 (eq_attr "prefix_extra" "0"))
536 (if_then_else (eq_attr "prefix_vex_w" "1")
537 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
538 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
539 (if_then_else (eq_attr "prefix_vex_w" "1")
540 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
541 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
543 ;; 4-bytes evex prefix and 1 byte opcode.
544 (define_attr "length_evex" "" (const_int 5))
546 ;; Set when modrm byte is used.
547 (define_attr "modrm" ""
548 (cond [(eq_attr "type" "str,leave")
550 (eq_attr "unit" "i387")
552 (and (eq_attr "type" "incdec")
553 (and (not (match_test "TARGET_64BIT"))
554 (ior (match_operand:SI 1 "register_operand")
555 (match_operand:HI 1 "register_operand"))))
557 (and (eq_attr "type" "push")
558 (not (match_operand 1 "memory_operand")))
560 (and (eq_attr "type" "pop")
561 (not (match_operand 0 "memory_operand")))
563 (and (eq_attr "type" "imov")
564 (and (not (eq_attr "mode" "DI"))
565 (ior (and (match_operand 0 "register_operand")
566 (match_operand 1 "immediate_operand"))
567 (ior (and (match_operand 0 "ax_reg_operand")
568 (match_operand 1 "memory_displacement_only_operand"))
569 (and (match_operand 0 "memory_displacement_only_operand")
570 (match_operand 1 "ax_reg_operand"))))))
572 (and (eq_attr "type" "call")
573 (match_operand 0 "constant_call_address_operand"))
575 (and (eq_attr "type" "callv")
576 (match_operand 1 "constant_call_address_operand"))
578 (and (eq_attr "type" "alu,alu1,icmp,test")
579 (match_operand 0 "ax_reg_operand"))
580 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
584 ;; When this attribute is set, calculate total insn length from
585 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
586 (define_attr "length_nobnd" "" (const_int 0))
588 ;; The (bounding maximum) length of an instruction in bytes.
589 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
590 ;; Later we may want to split them and compute proper length as for
592 (define_attr "length" ""
593 (cond [(eq_attr "length_nobnd" "!0")
594 (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
595 (attr "length_nobnd"))
596 (eq_attr "type" "other,multi,fistp,frndint")
598 (eq_attr "type" "fcmp")
600 (eq_attr "unit" "i387")
602 (plus (attr "prefix_data16")
603 (attr "length_address")))
604 (ior (eq_attr "prefix" "evex")
605 (and (ior (eq_attr "prefix" "maybe_evex")
606 (eq_attr "prefix" "maybe_vex"))
607 (match_test "TARGET_AVX512F")))
608 (plus (attr "length_evex")
609 (plus (attr "length_immediate")
611 (attr "length_address"))))
612 (ior (eq_attr "prefix" "vex")
613 (and (ior (eq_attr "prefix" "maybe_vex")
614 (eq_attr "prefix" "maybe_evex"))
615 (match_test "TARGET_AVX")))
616 (plus (attr "length_vex")
617 (plus (attr "length_immediate")
619 (attr "length_address"))))]
620 (plus (plus (attr "modrm")
621 (plus (attr "prefix_0f")
622 (plus (attr "prefix_rex")
623 (plus (attr "prefix_extra")
625 (plus (attr "prefix_rep")
626 (plus (attr "prefix_data16")
627 (plus (attr "length_immediate")
628 (attr "length_address")))))))
630 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
631 ;; `store' if there is a simple memory reference therein, or `unknown'
632 ;; if the instruction is complex.
634 (define_attr "memory" "none,load,store,both,unknown"
635 (cond [(eq_attr "type" "other,multi,str,lwp")
636 (const_string "unknown")
637 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
638 (const_string "none")
639 (eq_attr "type" "fistp,leave")
640 (const_string "both")
641 (eq_attr "type" "frndint")
642 (const_string "load")
643 (eq_attr "type" "mpxld")
644 (const_string "load")
645 (eq_attr "type" "mpxst")
646 (const_string "store")
647 (eq_attr "type" "push")
648 (if_then_else (match_operand 1 "memory_operand")
649 (const_string "both")
650 (const_string "store"))
651 (eq_attr "type" "pop")
652 (if_then_else (match_operand 0 "memory_operand")
653 (const_string "both")
654 (const_string "load"))
655 (eq_attr "type" "setcc")
656 (if_then_else (match_operand 0 "memory_operand")
657 (const_string "store")
658 (const_string "none"))
659 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
660 (if_then_else (ior (match_operand 0 "memory_operand")
661 (match_operand 1 "memory_operand"))
662 (const_string "load")
663 (const_string "none"))
664 (eq_attr "type" "ibr")
665 (if_then_else (match_operand 0 "memory_operand")
666 (const_string "load")
667 (const_string "none"))
668 (eq_attr "type" "call")
669 (if_then_else (match_operand 0 "constant_call_address_operand")
670 (const_string "none")
671 (const_string "load"))
672 (eq_attr "type" "callv")
673 (if_then_else (match_operand 1 "constant_call_address_operand")
674 (const_string "none")
675 (const_string "load"))
676 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
677 (match_operand 1 "memory_operand"))
678 (const_string "both")
679 (and (match_operand 0 "memory_operand")
680 (match_operand 1 "memory_operand"))
681 (const_string "both")
682 (match_operand 0 "memory_operand")
683 (const_string "store")
684 (match_operand 1 "memory_operand")
685 (const_string "load")
687 "!alu1,negnot,ishift1,
688 imov,imovx,icmp,test,bitmanip,
690 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
691 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
692 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
693 (match_operand 2 "memory_operand"))
694 (const_string "load")
695 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
696 (match_operand 3 "memory_operand"))
697 (const_string "load")
699 (const_string "none")))
701 ;; Indicates if an instruction has both an immediate and a displacement.
703 (define_attr "imm_disp" "false,true,unknown"
704 (cond [(eq_attr "type" "other,multi")
705 (const_string "unknown")
706 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
707 (and (match_operand 0 "memory_displacement_operand")
708 (match_operand 1 "immediate_operand")))
709 (const_string "true")
710 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
711 (and (match_operand 0 "memory_displacement_operand")
712 (match_operand 2 "immediate_operand")))
713 (const_string "true")
715 (const_string "false")))
717 ;; Indicates if an FP operation has an integer source.
719 (define_attr "fp_int_src" "false,true"
720 (const_string "false"))
722 ;; Defines rounding mode of an FP operation.
724 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
725 (const_string "any"))
727 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
728 (define_attr "use_carry" "0,1" (const_string "0"))
730 ;; Define attribute to indicate unaligned ssemov insns
731 (define_attr "movu" "0,1" (const_string "0"))
733 ;; Used to control the "enabled" attribute on a per-instruction basis.
734 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
735 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
736 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f"
737 (const_string "base"))
739 (define_attr "enabled" ""
740 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
741 (eq_attr "isa" "x64_sse4")
742 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
743 (eq_attr "isa" "x64_sse4_noavx")
744 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
745 (eq_attr "isa" "x64_avx")
746 (symbol_ref "TARGET_64BIT && TARGET_AVX")
747 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
748 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
749 (eq_attr "isa" "sse2_noavx")
750 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
751 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
752 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
753 (eq_attr "isa" "sse4_noavx")
754 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
755 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
756 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
757 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
758 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
759 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
760 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
761 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
762 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
763 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
764 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
765 (eq_attr "isa" "fma_avx512f")
766 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
770 ;; Describe a user's asm statement.
771 (define_asm_attributes
772 [(set_attr "length" "128")
773 (set_attr "type" "multi")])
775 (define_code_iterator plusminus [plus minus])
777 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
779 (define_code_iterator multdiv [mult div])
781 ;; Base name for define_insn
782 (define_code_attr plusminus_insn
783 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
784 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
786 ;; Base name for insn mnemonic.
787 (define_code_attr plusminus_mnemonic
788 [(plus "add") (ss_plus "adds") (us_plus "addus")
789 (minus "sub") (ss_minus "subs") (us_minus "subus")])
790 (define_code_attr plusminus_carry_mnemonic
791 [(plus "adc") (minus "sbb")])
792 (define_code_attr multdiv_mnemonic
793 [(mult "mul") (div "div")])
795 ;; Mark commutative operators as such in constraints.
796 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
797 (minus "") (ss_minus "") (us_minus "")])
799 ;; Mapping of max and min
800 (define_code_iterator maxmin [smax smin umax umin])
802 ;; Mapping of signed max and min
803 (define_code_iterator smaxmin [smax smin])
805 ;; Mapping of unsigned max and min
806 (define_code_iterator umaxmin [umax umin])
808 ;; Base name for integer and FP insn mnemonic
809 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
810 (umax "maxu") (umin "minu")])
811 (define_code_attr maxmin_float [(smax "max") (smin "min")])
813 ;; Mapping of logic operators
814 (define_code_iterator any_logic [and ior xor])
815 (define_code_iterator any_or [ior xor])
816 (define_code_iterator fpint_logic [and xor])
818 ;; Base name for insn mnemonic.
819 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
821 ;; Mapping of logic-shift operators
822 (define_code_iterator any_lshift [ashift lshiftrt])
824 ;; Mapping of shift-right operators
825 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
827 ;; Mapping of all shift operators
828 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
830 ;; Base name for define_insn
831 (define_code_attr shift_insn
832 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
834 ;; Base name for insn mnemonic.
835 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
836 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
838 ;; Mapping of rotate operators
839 (define_code_iterator any_rotate [rotate rotatert])
841 ;; Base name for define_insn
842 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
844 ;; Base name for insn mnemonic.
845 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
847 ;; Mapping of abs neg operators
848 (define_code_iterator absneg [abs neg])
850 ;; Base name for x87 insn mnemonic.
851 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
853 ;; Used in signed and unsigned widening multiplications.
854 (define_code_iterator any_extend [sign_extend zero_extend])
856 ;; Prefix for insn menmonic.
857 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
859 ;; Prefix for define_insn
860 (define_code_attr u [(sign_extend "") (zero_extend "u")])
861 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
862 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
864 ;; Used in signed and unsigned fix.
865 (define_code_iterator any_fix [fix unsigned_fix])
866 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
868 ;; All integer modes.
869 (define_mode_iterator SWI1248x [QI HI SI DI])
871 ;; All integer modes without QImode.
872 (define_mode_iterator SWI248x [HI SI DI])
874 ;; All integer modes without QImode and HImode.
875 (define_mode_iterator SWI48x [SI DI])
877 ;; All integer modes without SImode and DImode.
878 (define_mode_iterator SWI12 [QI HI])
880 ;; All integer modes without DImode.
881 (define_mode_iterator SWI124 [QI HI SI])
883 ;; All integer modes without QImode and DImode.
884 (define_mode_iterator SWI24 [HI SI])
886 ;; Single word integer modes.
887 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
889 ;; Single word integer modes without QImode.
890 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
892 ;; Single word integer modes without QImode and HImode.
893 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
895 ;; All math-dependant single and double word integer modes.
896 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
897 (HI "TARGET_HIMODE_MATH")
898 SI DI (TI "TARGET_64BIT")])
900 ;; Math-dependant single word integer modes.
901 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
902 (HI "TARGET_HIMODE_MATH")
903 SI (DI "TARGET_64BIT")])
905 ;; Math-dependant integer modes without DImode.
906 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
907 (HI "TARGET_HIMODE_MATH")
910 ;; Math-dependant single word integer modes without QImode.
911 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
912 SI (DI "TARGET_64BIT")])
914 ;; Double word integer modes.
915 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
916 (TI "TARGET_64BIT")])
918 ;; Double word integer modes as mode attribute.
919 (define_mode_attr DWI [(SI "DI") (DI "TI")])
920 (define_mode_attr dwi [(SI "di") (DI "ti")])
922 ;; Half mode for double word integer modes.
923 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
924 (DI "TARGET_64BIT")])
927 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
928 (BND64 "TARGET_LP64")])
930 ;; Pointer mode corresponding to bound mode.
931 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
934 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
937 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
939 (UNSPEC_BNDCN "cn")])
941 ;; Instruction suffix for integer modes.
942 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
944 ;; Pointer size prefix for integer modes (Intel asm dialect)
945 (define_mode_attr iptrsize [(QI "BYTE")
950 ;; Register class for integer modes.
951 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
953 ;; Immediate operand constraint for integer modes.
954 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
956 ;; General operand constraint for word modes.
957 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
959 ;; Immediate operand constraint for double integer modes.
960 (define_mode_attr di [(SI "nF") (DI "e")])
962 ;; Immediate operand constraint for shifts.
963 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
965 ;; General operand predicate for integer modes.
966 (define_mode_attr general_operand
967 [(QI "general_operand")
968 (HI "general_operand")
969 (SI "x86_64_general_operand")
970 (DI "x86_64_general_operand")
971 (TI "x86_64_general_operand")])
973 ;; General sign/zero extend operand predicate for integer modes.
974 (define_mode_attr general_szext_operand
975 [(QI "general_operand")
976 (HI "general_operand")
977 (SI "x86_64_szext_general_operand")
978 (DI "x86_64_szext_general_operand")])
980 ;; Immediate operand predicate for integer modes.
981 (define_mode_attr immediate_operand
982 [(QI "immediate_operand")
983 (HI "immediate_operand")
984 (SI "x86_64_immediate_operand")
985 (DI "x86_64_immediate_operand")])
987 ;; Nonmemory operand predicate for integer modes.
988 (define_mode_attr nonmemory_operand
989 [(QI "nonmemory_operand")
990 (HI "nonmemory_operand")
991 (SI "x86_64_nonmemory_operand")
992 (DI "x86_64_nonmemory_operand")])
994 ;; Operand predicate for shifts.
995 (define_mode_attr shift_operand
996 [(QI "nonimmediate_operand")
997 (HI "nonimmediate_operand")
998 (SI "nonimmediate_operand")
999 (DI "shiftdi_operand")
1000 (TI "register_operand")])
1002 ;; Operand predicate for shift argument.
1003 (define_mode_attr shift_immediate_operand
1004 [(QI "const_1_to_31_operand")
1005 (HI "const_1_to_31_operand")
1006 (SI "const_1_to_31_operand")
1007 (DI "const_1_to_63_operand")])
1009 ;; Input operand predicate for arithmetic left shifts.
1010 (define_mode_attr ashl_input_operand
1011 [(QI "nonimmediate_operand")
1012 (HI "nonimmediate_operand")
1013 (SI "nonimmediate_operand")
1014 (DI "ashldi_input_operand")
1015 (TI "reg_or_pm1_operand")])
1017 ;; SSE and x87 SFmode and DFmode floating point modes
1018 (define_mode_iterator MODEF [SF DF])
1020 ;; All x87 floating point modes
1021 (define_mode_iterator X87MODEF [SF DF XF])
1023 ;; SSE instruction suffix for various modes
1024 (define_mode_attr ssemodesuffix
1025 [(SF "ss") (DF "sd")
1026 (V16SF "ps") (V8DF "pd")
1027 (V8SF "ps") (V4DF "pd")
1028 (V4SF "ps") (V2DF "pd")
1029 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1030 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1031 (V64QI "b") (V16SI "d") (V8DI "q")])
1033 ;; SSE vector suffix for floating point modes
1034 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1036 ;; SSE vector mode corresponding to a scalar mode
1037 (define_mode_attr ssevecmode
1038 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1039 (define_mode_attr ssevecmodelower
1040 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1042 ;; Instruction suffix for REX 64bit operators.
1043 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1045 ;; This mode iterator allows :P to be used for patterns that operate on
1046 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1047 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1049 ;; This mode iterator allows :W to be used for patterns that operate on
1050 ;; word_mode sized quantities.
1051 (define_mode_iterator W
1052 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1054 ;; This mode iterator allows :PTR to be used for patterns that operate on
1055 ;; ptr_mode sized quantities.
1056 (define_mode_iterator PTR
1057 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1059 ;; Scheduling descriptions
1061 (include "pentium.md")
1064 (include "athlon.md")
1065 (include "bdver1.md")
1066 (include "bdver3.md")
1067 (include "btver2.md")
1068 (include "geode.md")
1071 (include "core2.md")
1074 ;; Operand and operator predicates and constraints
1076 (include "predicates.md")
1077 (include "constraints.md")
1080 ;; Compare and branch/compare and store instructions.
1082 (define_expand "cbranch<mode>4"
1083 [(set (reg:CC FLAGS_REG)
1084 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1085 (match_operand:SDWIM 2 "<general_operand>")))
1086 (set (pc) (if_then_else
1087 (match_operator 0 "ordered_comparison_operator"
1088 [(reg:CC FLAGS_REG) (const_int 0)])
1089 (label_ref (match_operand 3))
1093 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1094 operands[1] = force_reg (<MODE>mode, operands[1]);
1095 ix86_expand_branch (GET_CODE (operands[0]),
1096 operands[1], operands[2], operands[3]);
1100 (define_expand "cstore<mode>4"
1101 [(set (reg:CC FLAGS_REG)
1102 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1103 (match_operand:SWIM 3 "<general_operand>")))
1104 (set (match_operand:QI 0 "register_operand")
1105 (match_operator 1 "ordered_comparison_operator"
1106 [(reg:CC FLAGS_REG) (const_int 0)]))]
1109 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1110 operands[2] = force_reg (<MODE>mode, operands[2]);
1111 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1112 operands[2], operands[3]);
1116 (define_expand "cmp<mode>_1"
1117 [(set (reg:CC FLAGS_REG)
1118 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1119 (match_operand:SWI48 1 "<general_operand>")))])
1121 (define_insn "*cmp<mode>_ccno_1"
1122 [(set (reg FLAGS_REG)
1123 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1124 (match_operand:SWI 1 "const0_operand")))]
1125 "ix86_match_ccmode (insn, CCNOmode)"
1127 test{<imodesuffix>}\t%0, %0
1128 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1129 [(set_attr "type" "test,icmp")
1130 (set_attr "length_immediate" "0,1")
1131 (set_attr "mode" "<MODE>")])
1133 (define_insn "*cmp<mode>_1"
1134 [(set (reg FLAGS_REG)
1135 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1136 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1137 "ix86_match_ccmode (insn, CCmode)"
1138 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1139 [(set_attr "type" "icmp")
1140 (set_attr "mode" "<MODE>")])
1142 (define_insn "*cmp<mode>_minus_1"
1143 [(set (reg FLAGS_REG)
1145 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1146 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1148 "ix86_match_ccmode (insn, CCGOCmode)"
1149 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1150 [(set_attr "type" "icmp")
1151 (set_attr "mode" "<MODE>")])
1153 (define_insn "*cmpqi_ext_1"
1154 [(set (reg FLAGS_REG)
1156 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1159 (match_operand 1 "ext_register_operand" "Q,Q")
1161 (const_int 8)) 0)))]
1162 "ix86_match_ccmode (insn, CCmode)"
1163 "cmp{b}\t{%h1, %0|%0, %h1}"
1164 [(set_attr "isa" "*,nox64")
1165 (set_attr "type" "icmp")
1166 (set_attr "mode" "QI")])
1168 (define_insn "*cmpqi_ext_2"
1169 [(set (reg FLAGS_REG)
1173 (match_operand 0 "ext_register_operand" "Q")
1176 (match_operand:QI 1 "const0_operand")))]
1177 "ix86_match_ccmode (insn, CCNOmode)"
1179 [(set_attr "type" "test")
1180 (set_attr "length_immediate" "0")
1181 (set_attr "mode" "QI")])
1183 (define_expand "cmpqi_ext_3"
1184 [(set (reg:CC FLAGS_REG)
1188 (match_operand 0 "ext_register_operand")
1191 (match_operand:QI 1 "const_int_operand")))])
1193 (define_insn "*cmpqi_ext_3"
1194 [(set (reg FLAGS_REG)
1198 (match_operand 0 "ext_register_operand" "Q,Q")
1201 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1202 "ix86_match_ccmode (insn, CCmode)"
1203 "cmp{b}\t{%1, %h0|%h0, %1}"
1204 [(set_attr "isa" "*,nox64")
1205 (set_attr "type" "icmp")
1206 (set_attr "modrm" "1")
1207 (set_attr "mode" "QI")])
1209 (define_insn "*cmpqi_ext_4"
1210 [(set (reg FLAGS_REG)
1214 (match_operand 0 "ext_register_operand" "Q")
1219 (match_operand 1 "ext_register_operand" "Q")
1221 (const_int 8)) 0)))]
1222 "ix86_match_ccmode (insn, CCmode)"
1223 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1224 [(set_attr "type" "icmp")
1225 (set_attr "mode" "QI")])
1227 ;; These implement float point compares.
1228 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1229 ;; which would allow mix and match FP modes on the compares. Which is what
1230 ;; the old patterns did, but with many more of them.
1232 (define_expand "cbranchxf4"
1233 [(set (reg:CC FLAGS_REG)
1234 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1235 (match_operand:XF 2 "nonmemory_operand")))
1236 (set (pc) (if_then_else
1237 (match_operator 0 "ix86_fp_comparison_operator"
1240 (label_ref (match_operand 3))
1244 ix86_expand_branch (GET_CODE (operands[0]),
1245 operands[1], operands[2], operands[3]);
1249 (define_expand "cstorexf4"
1250 [(set (reg:CC FLAGS_REG)
1251 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1252 (match_operand:XF 3 "nonmemory_operand")))
1253 (set (match_operand:QI 0 "register_operand")
1254 (match_operator 1 "ix86_fp_comparison_operator"
1259 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1260 operands[2], operands[3]);
1264 (define_expand "cbranch<mode>4"
1265 [(set (reg:CC FLAGS_REG)
1266 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1267 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1268 (set (pc) (if_then_else
1269 (match_operator 0 "ix86_fp_comparison_operator"
1272 (label_ref (match_operand 3))
1274 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1276 ix86_expand_branch (GET_CODE (operands[0]),
1277 operands[1], operands[2], operands[3]);
1281 (define_expand "cstore<mode>4"
1282 [(set (reg:CC FLAGS_REG)
1283 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1284 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1285 (set (match_operand:QI 0 "register_operand")
1286 (match_operator 1 "ix86_fp_comparison_operator"
1289 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1291 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1292 operands[2], operands[3]);
1296 (define_expand "cbranchcc4"
1297 [(set (pc) (if_then_else
1298 (match_operator 0 "comparison_operator"
1299 [(match_operand 1 "flags_reg_operand")
1300 (match_operand 2 "const0_operand")])
1301 (label_ref (match_operand 3))
1305 ix86_expand_branch (GET_CODE (operands[0]),
1306 operands[1], operands[2], operands[3]);
1310 (define_expand "cstorecc4"
1311 [(set (match_operand:QI 0 "register_operand")
1312 (match_operator 1 "comparison_operator"
1313 [(match_operand 2 "flags_reg_operand")
1314 (match_operand 3 "const0_operand")]))]
1317 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1318 operands[2], operands[3]);
1323 ;; FP compares, step 1:
1324 ;; Set the FP condition codes.
1326 ;; CCFPmode compare with exceptions
1327 ;; CCFPUmode compare with no exceptions
1329 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1330 ;; used to manage the reg stack popping would not be preserved.
1332 (define_insn "*cmp<mode>_0_i387"
1333 [(set (match_operand:HI 0 "register_operand" "=a")
1336 (match_operand:X87MODEF 1 "register_operand" "f")
1337 (match_operand:X87MODEF 2 "const0_operand"))]
1340 "* return output_fp_compare (insn, operands, false, false);"
1341 [(set_attr "type" "multi")
1342 (set_attr "unit" "i387")
1343 (set_attr "mode" "<MODE>")])
1345 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1346 [(set (reg:CCFP FLAGS_REG)
1348 (match_operand:X87MODEF 1 "register_operand" "f")
1349 (match_operand:X87MODEF 2 "const0_operand")))
1350 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1351 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1353 "&& reload_completed"
1356 [(compare:CCFP (match_dup 1)(match_dup 2))]
1358 (set (reg:CC FLAGS_REG)
1359 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1361 [(set_attr "type" "multi")
1362 (set_attr "unit" "i387")
1363 (set_attr "mode" "<MODE>")])
1365 (define_insn "*cmpxf_i387"
1366 [(set (match_operand:HI 0 "register_operand" "=a")
1369 (match_operand:XF 1 "register_operand" "f")
1370 (match_operand:XF 2 "register_operand" "f"))]
1373 "* return output_fp_compare (insn, operands, false, false);"
1374 [(set_attr "type" "multi")
1375 (set_attr "unit" "i387")
1376 (set_attr "mode" "XF")])
1378 (define_insn_and_split "*cmpxf_cc_i387"
1379 [(set (reg:CCFP FLAGS_REG)
1381 (match_operand:XF 1 "register_operand" "f")
1382 (match_operand:XF 2 "register_operand" "f")))
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" "XF")])
1398 (define_insn "*cmp<mode>_i387"
1399 [(set (match_operand:HI 0 "register_operand" "=a")
1402 (match_operand:MODEF 1 "register_operand" "f")
1403 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1406 "* return output_fp_compare (insn, operands, false, false);"
1407 [(set_attr "type" "multi")
1408 (set_attr "unit" "i387")
1409 (set_attr "mode" "<MODE>")])
1411 (define_insn_and_split "*cmp<mode>_cc_i387"
1412 [(set (reg:CCFP FLAGS_REG)
1414 (match_operand:MODEF 1 "register_operand" "f")
1415 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
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" "<MODE>")])
1431 (define_insn "*cmpu<mode>_i387"
1432 [(set (match_operand:HI 0 "register_operand" "=a")
1435 (match_operand:X87MODEF 1 "register_operand" "f")
1436 (match_operand:X87MODEF 2 "register_operand" "f"))]
1439 "* return output_fp_compare (insn, operands, false, true);"
1440 [(set_attr "type" "multi")
1441 (set_attr "unit" "i387")
1442 (set_attr "mode" "<MODE>")])
1444 (define_insn_and_split "*cmpu<mode>_cc_i387"
1445 [(set (reg:CCFPU FLAGS_REG)
1447 (match_operand:X87MODEF 1 "register_operand" "f")
1448 (match_operand:X87MODEF 2 "register_operand" "f")))
1449 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1450 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1452 "&& reload_completed"
1455 [(compare:CCFPU (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 "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1465 [(set (match_operand:HI 0 "register_operand" "=a")
1468 (match_operand:X87MODEF 1 "register_operand" "f")
1469 (match_operator:X87MODEF 3 "float_operator"
1470 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1473 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1474 || optimize_function_for_size_p (cfun))"
1475 "* return output_fp_compare (insn, operands, false, false);"
1476 [(set_attr "type" "multi")
1477 (set_attr "unit" "i387")
1478 (set_attr "fp_int_src" "true")
1479 (set_attr "mode" "<SWI24:MODE>")])
1481 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1482 [(set (reg:CCFP FLAGS_REG)
1484 (match_operand:X87MODEF 1 "register_operand" "f")
1485 (match_operator:X87MODEF 3 "float_operator"
1486 [(match_operand:SWI24 2 "memory_operand" "m")])))
1487 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1488 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1489 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1490 || optimize_function_for_size_p (cfun))"
1492 "&& reload_completed"
1497 (match_op_dup 3 [(match_dup 2)]))]
1499 (set (reg:CC FLAGS_REG)
1500 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1502 [(set_attr "type" "multi")
1503 (set_attr "unit" "i387")
1504 (set_attr "fp_int_src" "true")
1505 (set_attr "mode" "<SWI24:MODE>")])
1507 ;; FP compares, step 2
1508 ;; Move the fpsw to ax.
1510 (define_insn "x86_fnstsw_1"
1511 [(set (match_operand:HI 0 "register_operand" "=a")
1512 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1515 [(set (attr "length")
1516 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1517 (set_attr "mode" "SI")
1518 (set_attr "unit" "i387")])
1520 ;; FP compares, step 3
1521 ;; Get ax into flags, general case.
1523 (define_insn "x86_sahf_1"
1524 [(set (reg:CC FLAGS_REG)
1525 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1529 #ifndef HAVE_AS_IX86_SAHF
1531 return ASM_BYTE "0x9e";
1536 [(set_attr "length" "1")
1537 (set_attr "athlon_decode" "vector")
1538 (set_attr "amdfam10_decode" "direct")
1539 (set_attr "bdver1_decode" "direct")
1540 (set_attr "mode" "SI")])
1542 ;; Pentium Pro can do steps 1 through 3 in one go.
1543 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1544 ;; (these i387 instructions set flags directly)
1546 (define_mode_iterator FPCMP [CCFP CCFPU])
1547 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1549 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1550 [(set (reg:FPCMP FLAGS_REG)
1552 (match_operand:MODEF 0 "register_operand" "f,x")
1553 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1554 "TARGET_MIX_SSE_I387
1555 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1556 "* return output_fp_compare (insn, operands, true,
1557 <FPCMP:MODE>mode == CCFPUmode);"
1558 [(set_attr "type" "fcmp,ssecomi")
1559 (set_attr "prefix" "orig,maybe_vex")
1560 (set_attr "mode" "<MODEF:MODE>")
1561 (set (attr "prefix_rep")
1562 (if_then_else (eq_attr "type" "ssecomi")
1564 (const_string "*")))
1565 (set (attr "prefix_data16")
1566 (cond [(eq_attr "type" "fcmp")
1568 (eq_attr "mode" "DF")
1571 (const_string "0")))
1572 (set_attr "athlon_decode" "vector")
1573 (set_attr "amdfam10_decode" "direct")
1574 (set_attr "bdver1_decode" "double")])
1576 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1577 [(set (reg:FPCMP FLAGS_REG)
1579 (match_operand:MODEF 0 "register_operand" "x")
1580 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1582 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1583 "* return output_fp_compare (insn, operands, true,
1584 <FPCMP:MODE>mode == CCFPUmode);"
1585 [(set_attr "type" "ssecomi")
1586 (set_attr "prefix" "maybe_vex")
1587 (set_attr "mode" "<MODEF:MODE>")
1588 (set_attr "prefix_rep" "0")
1589 (set (attr "prefix_data16")
1590 (if_then_else (eq_attr "mode" "DF")
1592 (const_string "0")))
1593 (set_attr "athlon_decode" "vector")
1594 (set_attr "amdfam10_decode" "direct")
1595 (set_attr "bdver1_decode" "double")])
1597 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1598 [(set (reg:FPCMP FLAGS_REG)
1600 (match_operand:X87MODEF 0 "register_operand" "f")
1601 (match_operand:X87MODEF 1 "register_operand" "f")))]
1602 "TARGET_80387 && TARGET_CMOVE
1603 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1604 "* return output_fp_compare (insn, operands, true,
1605 <FPCMP:MODE>mode == CCFPUmode);"
1606 [(set_attr "type" "fcmp")
1607 (set_attr "mode" "<X87MODEF:MODE>")
1608 (set_attr "athlon_decode" "vector")
1609 (set_attr "amdfam10_decode" "direct")
1610 (set_attr "bdver1_decode" "double")])
1612 ;; Push/pop instructions.
1614 (define_insn "*push<mode>2"
1615 [(set (match_operand:DWI 0 "push_operand" "=<")
1616 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1619 [(set_attr "type" "multi")
1620 (set_attr "mode" "<MODE>")])
1623 [(set (match_operand:TI 0 "push_operand")
1624 (match_operand:TI 1 "general_operand"))]
1625 "TARGET_64BIT && reload_completed
1626 && !SSE_REG_P (operands[1])"
1628 "ix86_split_long_move (operands); DONE;")
1630 (define_insn "*pushdi2_rex64"
1631 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1632 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1637 [(set_attr "type" "push,multi")
1638 (set_attr "mode" "DI")])
1640 ;; Convert impossible pushes of immediate to existing instructions.
1641 ;; First try to get scratch register and go through it. In case this
1642 ;; fails, push sign extended lower part first and then overwrite
1643 ;; upper part by 32bit move.
1645 [(match_scratch:DI 2 "r")
1646 (set (match_operand:DI 0 "push_operand")
1647 (match_operand:DI 1 "immediate_operand"))]
1648 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1649 && !x86_64_immediate_operand (operands[1], DImode)"
1650 [(set (match_dup 2) (match_dup 1))
1651 (set (match_dup 0) (match_dup 2))])
1653 ;; We need to define this as both peepholer and splitter for case
1654 ;; peephole2 pass is not run.
1655 ;; "&& 1" is needed to keep it from matching the previous pattern.
1657 [(set (match_operand:DI 0 "push_operand")
1658 (match_operand:DI 1 "immediate_operand"))]
1659 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1660 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1661 [(set (match_dup 0) (match_dup 1))
1662 (set (match_dup 2) (match_dup 3))]
1664 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1666 operands[1] = gen_lowpart (DImode, operands[2]);
1667 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1672 [(set (match_operand:DI 0 "push_operand")
1673 (match_operand:DI 1 "immediate_operand"))]
1674 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1675 ? epilogue_completed : reload_completed)
1676 && !symbolic_operand (operands[1], DImode)
1677 && !x86_64_immediate_operand (operands[1], DImode)"
1678 [(set (match_dup 0) (match_dup 1))
1679 (set (match_dup 2) (match_dup 3))]
1681 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1683 operands[1] = gen_lowpart (DImode, operands[2]);
1684 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1689 [(set (match_operand:DI 0 "push_operand")
1690 (match_operand:DI 1 "general_operand"))]
1691 "!TARGET_64BIT && reload_completed
1692 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1694 "ix86_split_long_move (operands); DONE;")
1696 (define_insn "*pushsi2"
1697 [(set (match_operand:SI 0 "push_operand" "=<")
1698 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1701 [(set_attr "type" "push")
1702 (set_attr "mode" "SI")])
1704 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1705 ;; "push a byte/word". But actually we use pushl, which has the effect
1706 ;; of rounding the amount pushed up to a word.
1708 ;; For TARGET_64BIT we always round up to 8 bytes.
1709 (define_insn "*push<mode>2_rex64"
1710 [(set (match_operand:SWI124 0 "push_operand" "=X")
1711 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1714 [(set_attr "type" "push")
1715 (set_attr "mode" "DI")])
1717 (define_insn "*push<mode>2"
1718 [(set (match_operand:SWI12 0 "push_operand" "=X")
1719 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1722 [(set_attr "type" "push")
1723 (set_attr "mode" "SI")])
1725 (define_insn "*push<mode>2_prologue"
1726 [(set (match_operand:W 0 "push_operand" "=<")
1727 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1728 (clobber (mem:BLK (scratch)))]
1730 "push{<imodesuffix>}\t%1"
1731 [(set_attr "type" "push")
1732 (set_attr "mode" "<MODE>")])
1734 (define_insn "*pop<mode>1"
1735 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1736 (match_operand:W 1 "pop_operand" ">"))]
1738 "pop{<imodesuffix>}\t%0"
1739 [(set_attr "type" "pop")
1740 (set_attr "mode" "<MODE>")])
1742 (define_insn "*pop<mode>1_epilogue"
1743 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1744 (match_operand:W 1 "pop_operand" ">"))
1745 (clobber (mem:BLK (scratch)))]
1747 "pop{<imodesuffix>}\t%0"
1748 [(set_attr "type" "pop")
1749 (set_attr "mode" "<MODE>")])
1751 ;; Move instructions.
1753 (define_expand "movxi"
1754 [(set (match_operand:XI 0 "nonimmediate_operand")
1755 (match_operand:XI 1 "general_operand"))]
1757 "ix86_expand_move (XImode, operands); DONE;")
1759 ;; Reload patterns to support multi-word load/store
1760 ;; with non-offsetable address.
1761 (define_expand "reload_noff_store"
1762 [(parallel [(match_operand 0 "memory_operand" "=m")
1763 (match_operand 1 "register_operand" "r")
1764 (match_operand:DI 2 "register_operand" "=&r")])]
1767 rtx mem = operands[0];
1768 rtx addr = XEXP (mem, 0);
1770 emit_move_insn (operands[2], addr);
1771 mem = replace_equiv_address_nv (mem, operands[2]);
1773 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1777 (define_expand "reload_noff_load"
1778 [(parallel [(match_operand 0 "register_operand" "=r")
1779 (match_operand 1 "memory_operand" "m")
1780 (match_operand:DI 2 "register_operand" "=r")])]
1783 rtx mem = operands[1];
1784 rtx addr = XEXP (mem, 0);
1786 emit_move_insn (operands[2], addr);
1787 mem = replace_equiv_address_nv (mem, operands[2]);
1789 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1793 (define_expand "movoi"
1794 [(set (match_operand:OI 0 "nonimmediate_operand")
1795 (match_operand:OI 1 "general_operand"))]
1797 "ix86_expand_move (OImode, operands); DONE;")
1799 (define_expand "movti"
1800 [(set (match_operand:TI 0 "nonimmediate_operand")
1801 (match_operand:TI 1 "nonimmediate_operand"))]
1802 "TARGET_64BIT || TARGET_SSE"
1805 ix86_expand_move (TImode, operands);
1806 else if (push_operand (operands[0], TImode))
1807 ix86_expand_push (TImode, operands[1]);
1809 ix86_expand_vector_move (TImode, operands);
1813 ;; This expands to what emit_move_complex would generate if we didn't
1814 ;; have a movti pattern. Having this avoids problems with reload on
1815 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1816 ;; to have around all the time.
1817 (define_expand "movcdi"
1818 [(set (match_operand:CDI 0 "nonimmediate_operand")
1819 (match_operand:CDI 1 "general_operand"))]
1822 if (push_operand (operands[0], CDImode))
1823 emit_move_complex_push (CDImode, operands[0], operands[1]);
1825 emit_move_complex_parts (operands[0], operands[1]);
1829 (define_expand "mov<mode>"
1830 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1831 (match_operand:SWI1248x 1 "general_operand"))]
1833 "ix86_expand_move (<MODE>mode, operands); DONE;")
1835 (define_insn "*mov<mode>_xor"
1836 [(set (match_operand:SWI48 0 "register_operand" "=r")
1837 (match_operand:SWI48 1 "const0_operand"))
1838 (clobber (reg:CC FLAGS_REG))]
1841 [(set_attr "type" "alu1")
1842 (set_attr "mode" "SI")
1843 (set_attr "length_immediate" "0")])
1845 (define_insn "*mov<mode>_or"
1846 [(set (match_operand:SWI48 0 "register_operand" "=r")
1847 (match_operand:SWI48 1 "const_int_operand"))
1848 (clobber (reg:CC FLAGS_REG))]
1850 && operands[1] == constm1_rtx"
1851 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1852 [(set_attr "type" "alu1")
1853 (set_attr "mode" "<MODE>")
1854 (set_attr "length_immediate" "1")])
1856 (define_insn "*movxi_internal_avx512f"
1857 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1858 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1859 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1861 switch (which_alternative)
1864 return standard_sse_constant_opcode (insn, operands[1]);
1867 if (misaligned_operand (operands[0], XImode)
1868 || misaligned_operand (operands[1], XImode))
1869 return "vmovdqu32\t{%1, %0|%0, %1}";
1871 return "vmovdqa32\t{%1, %0|%0, %1}";
1876 [(set_attr "type" "sselog1,ssemov,ssemov")
1877 (set_attr "prefix" "evex")
1878 (set_attr "mode" "XI")])
1880 (define_insn "*movoi_internal_avx"
1881 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1882 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1883 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1885 switch (get_attr_type (insn))
1888 return standard_sse_constant_opcode (insn, operands[1]);
1891 if (misaligned_operand (operands[0], OImode)
1892 || misaligned_operand (operands[1], OImode))
1894 if (get_attr_mode (insn) == MODE_V8SF)
1895 return "vmovups\t{%1, %0|%0, %1}";
1897 return "vmovdqu\t{%1, %0|%0, %1}";
1901 if (get_attr_mode (insn) == MODE_V8SF)
1902 return "vmovaps\t{%1, %0|%0, %1}";
1904 return "vmovdqa\t{%1, %0|%0, %1}";
1911 [(set_attr "type" "sselog1,ssemov,ssemov")
1912 (set_attr "prefix" "vex")
1914 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1915 (const_string "V8SF")
1916 (and (eq_attr "alternative" "2")
1917 (match_test "TARGET_SSE_TYPELESS_STORES"))
1918 (const_string "V8SF")
1920 (const_string "OI")))])
1922 (define_insn "*movti_internal"
1923 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1924 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1925 "(TARGET_64BIT || TARGET_SSE)
1926 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1928 switch (get_attr_type (insn))
1934 return standard_sse_constant_opcode (insn, operands[1]);
1937 /* TDmode values are passed as TImode on the stack. Moving them
1938 to stack may result in unaligned memory access. */
1939 if (misaligned_operand (operands[0], TImode)
1940 || misaligned_operand (operands[1], TImode))
1942 if (get_attr_mode (insn) == MODE_V4SF)
1943 return "%vmovups\t{%1, %0|%0, %1}";
1945 return "%vmovdqu\t{%1, %0|%0, %1}";
1949 if (get_attr_mode (insn) == MODE_V4SF)
1950 return "%vmovaps\t{%1, %0|%0, %1}";
1952 return "%vmovdqa\t{%1, %0|%0, %1}";
1959 [(set_attr "isa" "x64,x64,*,*,*")
1960 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1961 (set (attr "prefix")
1962 (if_then_else (eq_attr "type" "sselog1,ssemov")
1963 (const_string "maybe_vex")
1964 (const_string "orig")))
1966 (cond [(eq_attr "alternative" "0,1")
1968 (ior (not (match_test "TARGET_SSE2"))
1969 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1970 (const_string "V4SF")
1971 (and (eq_attr "alternative" "4")
1972 (match_test "TARGET_SSE_TYPELESS_STORES"))
1973 (const_string "V4SF")
1974 (match_test "TARGET_AVX")
1976 (match_test "optimize_function_for_size_p (cfun)")
1977 (const_string "V4SF")
1979 (const_string "TI")))])
1982 [(set (match_operand:TI 0 "nonimmediate_operand")
1983 (match_operand:TI 1 "general_operand"))]
1985 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1987 "ix86_split_long_move (operands); DONE;")
1989 (define_insn "*movdi_internal"
1990 [(set (match_operand:DI 0 "nonimmediate_operand"
1991 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1992 (match_operand:DI 1 "general_operand"
1993 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn"))]
1994 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1996 switch (get_attr_type (insn))
2002 return "pxor\t%0, %0";
2005 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2006 /* Handle broken assemblers that require movd instead of movq. */
2007 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2008 return "movd\t{%1, %0|%0, %1}";
2010 return "movq\t{%1, %0|%0, %1}";
2013 if (GENERAL_REG_P (operands[0]))
2014 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2016 return standard_sse_constant_opcode (insn, operands[1]);
2019 switch (get_attr_mode (insn))
2022 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2023 /* Handle broken assemblers that require movd instead of movq. */
2024 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2025 return "%vmovd\t{%1, %0|%0, %1}";
2027 return "%vmovq\t{%1, %0|%0, %1}";
2029 return "%vmovdqa\t{%1, %0|%0, %1}";
2031 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2034 gcc_assert (!TARGET_AVX);
2035 return "movlps\t{%1, %0|%0, %1}";
2037 return "%vmovaps\t{%1, %0|%0, %1}";
2044 if (SSE_REG_P (operands[0]))
2045 return "movq2dq\t{%1, %0|%0, %1}";
2047 return "movdq2q\t{%1, %0|%0, %1}";
2050 return "lea{q}\t{%E1, %0|%0, %E1}";
2053 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2054 if (get_attr_mode (insn) == MODE_SI)
2055 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2056 else if (which_alternative == 4)
2057 return "movabs{q}\t{%1, %0|%0, %1}";
2058 else if (ix86_use_lea_for_mov (insn, operands))
2059 return "lea{q}\t{%E1, %0|%0, %E1}";
2061 return "mov{q}\t{%1, %0|%0, %1}";
2068 (cond [(eq_attr "alternative" "0,1")
2069 (const_string "nox64")
2070 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
2071 (const_string "x64")
2072 (eq_attr "alternative" "17")
2073 (const_string "x64_sse4")
2075 (const_string "*")))
2077 (cond [(eq_attr "alternative" "0,1")
2078 (const_string "multi")
2079 (eq_attr "alternative" "6")
2080 (const_string "mmx")
2081 (eq_attr "alternative" "7,8,9,10,11")
2082 (const_string "mmxmov")
2083 (eq_attr "alternative" "12,17")
2084 (const_string "sselog1")
2085 (eq_attr "alternative" "13,14,15,16,18")
2086 (const_string "ssemov")
2087 (eq_attr "alternative" "19,20")
2088 (const_string "ssecvt")
2089 (match_operand 1 "pic_32bit_operand")
2090 (const_string "lea")
2092 (const_string "imov")))
2095 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2097 (const_string "*")))
2098 (set (attr "length_immediate")
2099 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2101 (eq_attr "alternative" "17")
2104 (const_string "*")))
2105 (set (attr "prefix_rex")
2106 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2108 (const_string "*")))
2109 (set (attr "prefix_extra")
2110 (if_then_else (eq_attr "alternative" "17")
2112 (const_string "*")))
2113 (set (attr "prefix")
2114 (if_then_else (eq_attr "type" "sselog1,ssemov")
2115 (const_string "maybe_vex")
2116 (const_string "orig")))
2117 (set (attr "prefix_data16")
2118 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2120 (const_string "*")))
2122 (cond [(eq_attr "alternative" "2")
2124 (eq_attr "alternative" "12,13")
2125 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2126 (match_operand 1 "ext_sse_reg_operand"))
2128 (ior (not (match_test "TARGET_SSE2"))
2129 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2130 (const_string "V4SF")
2131 (match_test "TARGET_AVX")
2133 (match_test "optimize_function_for_size_p (cfun)")
2134 (const_string "V4SF")
2136 (const_string "TI"))
2138 (and (eq_attr "alternative" "14,15")
2139 (not (match_test "TARGET_SSE2")))
2140 (const_string "V2SF")
2141 (eq_attr "alternative" "17")
2144 (const_string "DI")))])
2147 [(set (match_operand:DI 0 "nonimmediate_operand")
2148 (match_operand:DI 1 "general_operand"))]
2149 "!TARGET_64BIT && reload_completed
2150 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2151 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2153 "ix86_split_long_move (operands); DONE;")
2155 (define_insn "*movsi_internal"
2156 [(set (match_operand:SI 0 "nonimmediate_operand"
2157 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi")
2158 (match_operand:SI 1 "general_operand"
2159 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r"))]
2160 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2162 switch (get_attr_type (insn))
2165 if (GENERAL_REG_P (operands[0]))
2166 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2168 return standard_sse_constant_opcode (insn, operands[1]);
2171 switch (get_attr_mode (insn))
2174 return "%vmovd\t{%1, %0|%0, %1}";
2176 return "%vmovdqa\t{%1, %0|%0, %1}";
2178 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2181 return "%vmovaps\t{%1, %0|%0, %1}";
2184 gcc_assert (!TARGET_AVX);
2185 return "movss\t{%1, %0|%0, %1}";
2192 return "pxor\t%0, %0";
2195 switch (get_attr_mode (insn))
2198 return "movq\t{%1, %0|%0, %1}";
2200 return "movd\t{%1, %0|%0, %1}";
2207 return "lea{l}\t{%E1, %0|%0, %E1}";
2210 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2211 if (ix86_use_lea_for_mov (insn, operands))
2212 return "lea{l}\t{%E1, %0|%0, %E1}";
2214 return "mov{l}\t{%1, %0|%0, %1}";
2221 (if_then_else (eq_attr "alternative" "11")
2222 (const_string "sse4")
2223 (const_string "*")))
2225 (cond [(eq_attr "alternative" "2")
2226 (const_string "mmx")
2227 (eq_attr "alternative" "3,4,5")
2228 (const_string "mmxmov")
2229 (eq_attr "alternative" "6,11")
2230 (const_string "sselog1")
2231 (eq_attr "alternative" "7,8,9,10,12")
2232 (const_string "ssemov")
2233 (match_operand 1 "pic_32bit_operand")
2234 (const_string "lea")
2236 (const_string "imov")))
2237 (set (attr "length_immediate")
2238 (if_then_else (eq_attr "alternative" "11")
2240 (const_string "*")))
2241 (set (attr "prefix_extra")
2242 (if_then_else (eq_attr "alternative" "11")
2244 (const_string "*")))
2245 (set (attr "prefix")
2246 (if_then_else (eq_attr "type" "sselog1,ssemov")
2247 (const_string "maybe_vex")
2248 (const_string "orig")))
2249 (set (attr "prefix_data16")
2250 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2252 (const_string "*")))
2254 (cond [(eq_attr "alternative" "2,3")
2256 (eq_attr "alternative" "6,7")
2257 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2258 (match_operand 1 "ext_sse_reg_operand"))
2260 (ior (not (match_test "TARGET_SSE2"))
2261 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2262 (const_string "V4SF")
2263 (match_test "TARGET_AVX")
2265 (match_test "optimize_function_for_size_p (cfun)")
2266 (const_string "V4SF")
2268 (const_string "TI"))
2270 (and (eq_attr "alternative" "8,9")
2271 (not (match_test "TARGET_SSE2")))
2273 (eq_attr "alternative" "11")
2276 (const_string "SI")))])
2278 (define_insn "*movhi_internal"
2279 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,Yk,Yk,rm")
2280 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,Yk,Yk"))]
2281 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2283 switch (get_attr_type (insn))
2286 /* movzwl is faster than movw on p2 due to partial word stalls,
2287 though not as fast as an aligned movl. */
2288 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2291 switch (which_alternative)
2293 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2294 case 5: return "kmovw\t{%1, %0|%0, %1}";
2295 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2296 default: gcc_unreachable ();
2300 if (get_attr_mode (insn) == MODE_SI)
2301 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2303 return "mov{w}\t{%1, %0|%0, %1}";
2307 (cond [(match_test "optimize_function_for_size_p (cfun)")
2308 (const_string "imov")
2309 (and (eq_attr "alternative" "0")
2310 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2311 (not (match_test "TARGET_HIMODE_MATH"))))
2312 (const_string "imov")
2313 (and (eq_attr "alternative" "1,2")
2314 (match_operand:HI 1 "aligned_operand"))
2315 (const_string "imov")
2316 (eq_attr "alternative" "4,5,6")
2317 (const_string "mskmov")
2318 (and (match_test "TARGET_MOVX")
2319 (eq_attr "alternative" "0,2"))
2320 (const_string "imovx")
2322 (const_string "imov")))
2323 (set (attr "prefix")
2324 (if_then_else (eq_attr "alternative" "4,5,6")
2325 (const_string "vex")
2326 (const_string "orig")))
2328 (cond [(eq_attr "type" "imovx")
2330 (and (eq_attr "alternative" "1,2")
2331 (match_operand:HI 1 "aligned_operand"))
2333 (and (eq_attr "alternative" "0")
2334 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2335 (not (match_test "TARGET_HIMODE_MATH"))))
2338 (const_string "HI")))])
2340 ;; Situation is quite tricky about when to choose full sized (SImode) move
2341 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2342 ;; partial register dependency machines (such as AMD Athlon), where QImode
2343 ;; moves issue extra dependency and for partial register stalls machines
2344 ;; that don't use QImode patterns (and QImode move cause stall on the next
2347 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2348 ;; register stall machines with, where we use QImode instructions, since
2349 ;; partial register stall can be caused there. Then we use movzx.
2351 (define_insn "*movqi_internal"
2352 [(set (match_operand:QI 0 "nonimmediate_operand"
2353 "=q,q ,q ,r,r ,?r,m ,Yk,Yk,r")
2354 (match_operand:QI 1 "general_operand"
2355 "q ,qn,qm,q,rn,qm,qn,r ,Yk,Yk"))]
2356 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2358 switch (get_attr_type (insn))
2361 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2362 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2365 switch (which_alternative)
2367 case 7: return "kmovw\t{%k1, %0|%0, %k1}";
2368 case 8: return "kmovw\t{%1, %0|%0, %1}";
2369 case 9: return "kmovw\t{%1, %k0|%k0, %1}";
2370 default: gcc_unreachable ();
2374 if (get_attr_mode (insn) == MODE_SI)
2375 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2377 return "mov{b}\t{%1, %0|%0, %1}";
2381 (cond [(and (eq_attr "alternative" "5")
2382 (not (match_operand:QI 1 "aligned_operand")))
2383 (const_string "imovx")
2384 (match_test "optimize_function_for_size_p (cfun)")
2385 (const_string "imov")
2386 (and (eq_attr "alternative" "3")
2387 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2388 (not (match_test "TARGET_QIMODE_MATH"))))
2389 (const_string "imov")
2390 (eq_attr "alternative" "3,5")
2391 (const_string "imovx")
2392 (eq_attr "alternative" "7,8,9")
2393 (const_string "mskmov")
2394 (and (match_test "TARGET_MOVX")
2395 (eq_attr "alternative" "2"))
2396 (const_string "imovx")
2398 (const_string "imov")))
2399 (set (attr "prefix")
2400 (if_then_else (eq_attr "alternative" "7,8,9")
2401 (const_string "vex")
2402 (const_string "orig")))
2404 (cond [(eq_attr "alternative" "3,4,5")
2406 (eq_attr "alternative" "6")
2408 (eq_attr "type" "imovx")
2410 (and (eq_attr "type" "imov")
2411 (and (eq_attr "alternative" "0,1")
2412 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2413 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2414 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2416 ;; Avoid partial register stalls when not using QImode arithmetic
2417 (and (eq_attr "type" "imov")
2418 (and (eq_attr "alternative" "0,1")
2419 (and (match_test "TARGET_PARTIAL_REG_STALL")
2420 (not (match_test "TARGET_QIMODE_MATH")))))
2423 (const_string "QI")))])
2425 ;; Stores and loads of ax to arbitrary constant address.
2426 ;; We fake an second form of instruction to force reload to load address
2427 ;; into register when rax is not available
2428 (define_insn "*movabs<mode>_1"
2429 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2430 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2431 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2433 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2434 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2435 [(set_attr "type" "imov")
2436 (set_attr "modrm" "0,*")
2437 (set_attr "length_address" "8,0")
2438 (set_attr "length_immediate" "0,*")
2439 (set_attr "memory" "store")
2440 (set_attr "mode" "<MODE>")])
2442 (define_insn "*movabs<mode>_2"
2443 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2444 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2445 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2447 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2448 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2449 [(set_attr "type" "imov")
2450 (set_attr "modrm" "0,*")
2451 (set_attr "length_address" "8,0")
2452 (set_attr "length_immediate" "0")
2453 (set_attr "memory" "load")
2454 (set_attr "mode" "<MODE>")])
2456 (define_insn "swap<mode>"
2457 [(set (match_operand:SWI48 0 "register_operand" "+r")
2458 (match_operand:SWI48 1 "register_operand" "+r"))
2462 "xchg{<imodesuffix>}\t%1, %0"
2463 [(set_attr "type" "imov")
2464 (set_attr "mode" "<MODE>")
2465 (set_attr "pent_pair" "np")
2466 (set_attr "athlon_decode" "vector")
2467 (set_attr "amdfam10_decode" "double")
2468 (set_attr "bdver1_decode" "double")])
2470 (define_insn "*swap<mode>_1"
2471 [(set (match_operand:SWI12 0 "register_operand" "+r")
2472 (match_operand:SWI12 1 "register_operand" "+r"))
2475 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2477 [(set_attr "type" "imov")
2478 (set_attr "mode" "SI")
2479 (set_attr "pent_pair" "np")
2480 (set_attr "athlon_decode" "vector")
2481 (set_attr "amdfam10_decode" "double")
2482 (set_attr "bdver1_decode" "double")])
2484 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2485 ;; is disabled for AMDFAM10
2486 (define_insn "*swap<mode>_2"
2487 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2488 (match_operand:SWI12 1 "register_operand" "+<r>"))
2491 "TARGET_PARTIAL_REG_STALL"
2492 "xchg{<imodesuffix>}\t%1, %0"
2493 [(set_attr "type" "imov")
2494 (set_attr "mode" "<MODE>")
2495 (set_attr "pent_pair" "np")
2496 (set_attr "athlon_decode" "vector")])
2498 (define_expand "movstrict<mode>"
2499 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2500 (match_operand:SWI12 1 "general_operand"))]
2503 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2505 if (GET_CODE (operands[0]) == SUBREG
2506 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2508 /* Don't generate memory->memory moves, go through a register */
2509 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2510 operands[1] = force_reg (<MODE>mode, operands[1]);
2513 (define_insn "*movstrict<mode>_1"
2514 [(set (strict_low_part
2515 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2516 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2517 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2518 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2519 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2520 [(set_attr "type" "imov")
2521 (set_attr "mode" "<MODE>")])
2523 (define_insn "*movstrict<mode>_xor"
2524 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2525 (match_operand:SWI12 1 "const0_operand"))
2526 (clobber (reg:CC FLAGS_REG))]
2528 "xor{<imodesuffix>}\t%0, %0"
2529 [(set_attr "type" "alu1")
2530 (set_attr "mode" "<MODE>")
2531 (set_attr "length_immediate" "0")])
2533 (define_insn "*mov<mode>_extv_1"
2534 [(set (match_operand:SWI24 0 "register_operand" "=R")
2535 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2539 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2540 [(set_attr "type" "imovx")
2541 (set_attr "mode" "SI")])
2543 (define_insn "*movqi_extv_1"
2544 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2545 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2550 switch (get_attr_type (insn))
2553 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2555 return "mov{b}\t{%h1, %0|%0, %h1}";
2558 [(set_attr "isa" "*,*,nox64")
2560 (if_then_else (and (match_operand:QI 0 "register_operand")
2561 (ior (not (match_operand:QI 0 "QIreg_operand"))
2562 (match_test "TARGET_MOVX")))
2563 (const_string "imovx")
2564 (const_string "imov")))
2566 (if_then_else (eq_attr "type" "imovx")
2568 (const_string "QI")))])
2570 (define_insn "*mov<mode>_extzv_1"
2571 [(set (match_operand:SWI48 0 "register_operand" "=R")
2572 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2576 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2577 [(set_attr "type" "imovx")
2578 (set_attr "mode" "SI")])
2580 (define_insn "*movqi_extzv_2"
2581 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2583 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2588 switch (get_attr_type (insn))
2591 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2593 return "mov{b}\t{%h1, %0|%0, %h1}";
2596 [(set_attr "isa" "*,*,nox64")
2598 (if_then_else (and (match_operand:QI 0 "register_operand")
2599 (ior (not (match_operand:QI 0 "QIreg_operand"))
2600 (match_test "TARGET_MOVX")))
2601 (const_string "imovx")
2602 (const_string "imov")))
2604 (if_then_else (eq_attr "type" "imovx")
2606 (const_string "QI")))])
2608 (define_insn "mov<mode>_insv_1"
2609 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2612 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2615 if (CONST_INT_P (operands[1]))
2616 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2617 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2619 [(set_attr "isa" "*,nox64")
2620 (set_attr "type" "imov")
2621 (set_attr "mode" "QI")])
2623 (define_insn "*movqi_insv_2"
2624 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2627 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2630 "mov{b}\t{%h1, %h0|%h0, %h1}"
2631 [(set_attr "type" "imov")
2632 (set_attr "mode" "QI")])
2634 ;; Floating point push instructions.
2636 (define_insn "*pushtf"
2637 [(set (match_operand:TF 0 "push_operand" "=<,<")
2638 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2639 "TARGET_64BIT || TARGET_SSE"
2641 /* This insn should be already split before reg-stack. */
2644 [(set_attr "isa" "*,x64")
2645 (set_attr "type" "multi")
2646 (set_attr "unit" "sse,*")
2647 (set_attr "mode" "TF,DI")])
2649 ;; %%% Kill this when call knows how to work this out.
2651 [(set (match_operand:TF 0 "push_operand")
2652 (match_operand:TF 1 "sse_reg_operand"))]
2653 "TARGET_SSE && reload_completed"
2654 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2655 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2657 (define_insn "*pushxf"
2658 [(set (match_operand:XF 0 "push_operand" "=<,<")
2659 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2662 /* This insn should be already split before reg-stack. */
2665 [(set_attr "type" "multi")
2666 (set_attr "unit" "i387,*")
2668 (cond [(eq_attr "alternative" "1")
2669 (if_then_else (match_test "TARGET_64BIT")
2671 (const_string "SI"))
2673 (const_string "XF")))])
2675 ;; %%% Kill this when call knows how to work this out.
2677 [(set (match_operand:XF 0 "push_operand")
2678 (match_operand:XF 1 "fp_register_operand"))]
2680 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2681 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2682 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2684 (define_insn "*pushdf"
2685 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2686 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2689 /* This insn should be already split before reg-stack. */
2692 [(set_attr "isa" "*,nox64,x64,sse2")
2693 (set_attr "type" "multi")
2694 (set_attr "unit" "i387,*,*,sse")
2695 (set_attr "mode" "DF,SI,DI,DF")])
2697 ;; %%% Kill this when call knows how to work this out.
2699 [(set (match_operand:DF 0 "push_operand")
2700 (match_operand:DF 1 "any_fp_register_operand"))]
2702 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2703 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2705 (define_insn "*pushsf_rex64"
2706 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2707 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2710 /* Anything else should be already split before reg-stack. */
2711 gcc_assert (which_alternative == 1);
2712 return "push{q}\t%q1";
2714 [(set_attr "type" "multi,push,multi")
2715 (set_attr "unit" "i387,*,*")
2716 (set_attr "mode" "SF,DI,SF")])
2718 (define_insn "*pushsf"
2719 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2720 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2723 /* Anything else should be already split before reg-stack. */
2724 gcc_assert (which_alternative == 1);
2725 return "push{l}\t%1";
2727 [(set_attr "type" "multi,push,multi")
2728 (set_attr "unit" "i387,*,*")
2729 (set_attr "mode" "SF,SI,SF")])
2731 ;; %%% Kill this when call knows how to work this out.
2733 [(set (match_operand:SF 0 "push_operand")
2734 (match_operand:SF 1 "any_fp_register_operand"))]
2736 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2737 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2738 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2741 [(set (match_operand:SF 0 "push_operand")
2742 (match_operand:SF 1 "memory_operand"))]
2744 && (operands[2] = find_constant_src (insn))"
2745 [(set (match_dup 0) (match_dup 2))])
2748 [(set (match_operand 0 "push_operand")
2749 (match_operand 1 "general_operand"))]
2751 && (GET_MODE (operands[0]) == TFmode
2752 || GET_MODE (operands[0]) == XFmode
2753 || GET_MODE (operands[0]) == DFmode)
2754 && !ANY_FP_REG_P (operands[1])"
2756 "ix86_split_long_move (operands); DONE;")
2758 ;; Floating point move instructions.
2760 (define_expand "movtf"
2761 [(set (match_operand:TF 0 "nonimmediate_operand")
2762 (match_operand:TF 1 "nonimmediate_operand"))]
2763 "TARGET_64BIT || TARGET_SSE"
2764 "ix86_expand_move (TFmode, operands); DONE;")
2766 (define_expand "mov<mode>"
2767 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2768 (match_operand:X87MODEF 1 "general_operand"))]
2770 "ix86_expand_move (<MODE>mode, operands); DONE;")
2772 (define_insn "*movtf_internal"
2773 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2774 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2775 "(TARGET_64BIT || TARGET_SSE)
2776 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2777 && (!can_create_pseudo_p ()
2778 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2779 || GET_CODE (operands[1]) != CONST_DOUBLE
2780 || (optimize_function_for_size_p (cfun)
2781 && standard_sse_constant_p (operands[1])
2782 && !memory_operand (operands[0], TFmode))
2783 || (!TARGET_MEMORY_MISMATCH_STALL
2784 && memory_operand (operands[0], TFmode)))"
2786 switch (get_attr_type (insn))
2789 return standard_sse_constant_opcode (insn, operands[1]);
2792 /* Handle misaligned load/store since we
2793 don't have movmisaligntf pattern. */
2794 if (misaligned_operand (operands[0], TFmode)
2795 || misaligned_operand (operands[1], TFmode))
2797 if (get_attr_mode (insn) == MODE_V4SF)
2798 return "%vmovups\t{%1, %0|%0, %1}";
2800 return "%vmovdqu\t{%1, %0|%0, %1}";
2804 if (get_attr_mode (insn) == MODE_V4SF)
2805 return "%vmovaps\t{%1, %0|%0, %1}";
2807 return "%vmovdqa\t{%1, %0|%0, %1}";
2817 [(set_attr "isa" "*,*,*,x64,x64")
2818 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2819 (set (attr "prefix")
2820 (if_then_else (eq_attr "type" "sselog1,ssemov")
2821 (const_string "maybe_vex")
2822 (const_string "orig")))
2824 (cond [(eq_attr "alternative" "3,4")
2826 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2827 (const_string "V4SF")
2828 (and (eq_attr "alternative" "2")
2829 (match_test "TARGET_SSE_TYPELESS_STORES"))
2830 (const_string "V4SF")
2831 (match_test "TARGET_AVX")
2833 (ior (not (match_test "TARGET_SSE2"))
2834 (match_test "optimize_function_for_size_p (cfun)"))
2835 (const_string "V4SF")
2837 (const_string "TI")))])
2839 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2840 (define_insn "*movxf_internal"
2841 [(set (match_operand:XF 0 "nonimmediate_operand"
2842 "=f,m,f,?Yx*r ,!o ,!o")
2843 (match_operand:XF 1 "general_operand"
2844 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2845 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2846 && (!can_create_pseudo_p ()
2847 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2848 || GET_CODE (operands[1]) != CONST_DOUBLE
2849 || (optimize_function_for_size_p (cfun)
2850 && standard_80387_constant_p (operands[1]) > 0
2851 && !memory_operand (operands[0], XFmode))
2852 || (!TARGET_MEMORY_MISMATCH_STALL
2853 && memory_operand (operands[0], XFmode)))"
2855 switch (get_attr_type (insn))
2858 if (which_alternative == 2)
2859 return standard_80387_constant_opcode (operands[1]);
2860 return output_387_reg_move (insn, operands);
2869 [(set_attr "isa" "*,*,*,*,nox64,x64")
2870 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2872 (cond [(eq_attr "alternative" "3,4,5")
2873 (if_then_else (match_test "TARGET_64BIT")
2875 (const_string "SI"))
2877 (const_string "XF")))])
2879 ;; Possible store forwarding (partial memory) stall in alternative 4.
2880 (define_insn "*movdf_internal"
2881 [(set (match_operand:DF 0 "nonimmediate_operand"
2882 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2883 (match_operand:DF 1 "general_operand"
2884 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2885 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2886 && (!can_create_pseudo_p ()
2887 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2888 || GET_CODE (operands[1]) != CONST_DOUBLE
2889 || (optimize_function_for_size_p (cfun)
2890 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2891 && standard_80387_constant_p (operands[1]) > 0)
2892 || (TARGET_SSE2 && TARGET_SSE_MATH
2893 && standard_sse_constant_p (operands[1])))
2894 && !memory_operand (operands[0], DFmode))
2895 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2896 && memory_operand (operands[0], DFmode)))"
2898 switch (get_attr_type (insn))
2901 if (which_alternative == 2)
2902 return standard_80387_constant_opcode (operands[1]);
2903 return output_387_reg_move (insn, operands);
2909 if (get_attr_mode (insn) == MODE_SI)
2910 return "mov{l}\t{%1, %k0|%k0, %1}";
2911 else if (which_alternative == 8)
2912 return "movabs{q}\t{%1, %0|%0, %1}";
2914 return "mov{q}\t{%1, %0|%0, %1}";
2917 return standard_sse_constant_opcode (insn, operands[1]);
2920 switch (get_attr_mode (insn))
2923 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2924 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2925 return "%vmovsd\t{%1, %0|%0, %1}";
2928 return "%vmovaps\t{%1, %0|%0, %1}";
2930 return "vmovapd\t{%g1, %g0|%g0, %g1}";
2932 return "%vmovapd\t{%1, %0|%0, %1}";
2935 gcc_assert (!TARGET_AVX);
2936 return "movlps\t{%1, %0|%0, %1}";
2938 gcc_assert (!TARGET_AVX);
2939 return "movlpd\t{%1, %0|%0, %1}";
2942 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2943 /* Handle broken assemblers that require movd instead of movq. */
2944 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2945 return "%vmovd\t{%1, %0|%0, %1}";
2947 return "%vmovq\t{%1, %0|%0, %1}";
2958 (cond [(eq_attr "alternative" "3,4")
2959 (const_string "nox64")
2960 (eq_attr "alternative" "5,6,7,8,17,18")
2961 (const_string "x64")
2962 (eq_attr "alternative" "9,10,11,12")
2963 (const_string "sse2")
2965 (const_string "*")))
2967 (cond [(eq_attr "alternative" "0,1,2")
2968 (const_string "fmov")
2969 (eq_attr "alternative" "3,4")
2970 (const_string "multi")
2971 (eq_attr "alternative" "5,6,7,8")
2972 (const_string "imov")
2973 (eq_attr "alternative" "9,13")
2974 (const_string "sselog1")
2976 (const_string "ssemov")))
2978 (if_then_else (eq_attr "alternative" "8")
2980 (const_string "*")))
2981 (set (attr "length_immediate")
2982 (if_then_else (eq_attr "alternative" "8")
2984 (const_string "*")))
2985 (set (attr "prefix")
2986 (if_then_else (eq_attr "type" "sselog1,ssemov")
2987 (const_string "maybe_vex")
2988 (const_string "orig")))
2989 (set (attr "prefix_data16")
2991 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2992 (eq_attr "mode" "V1DF"))
2994 (const_string "*")))
2996 (cond [(eq_attr "alternative" "3,4,7")
2998 (eq_attr "alternative" "5,6,8,17,18")
3001 /* xorps is one byte shorter for non-AVX targets. */
3002 (eq_attr "alternative" "9,13")
3003 (cond [(not (match_test "TARGET_SSE2"))
3004 (const_string "V4SF")
3005 (match_test "TARGET_AVX512F")
3007 (match_test "TARGET_AVX")
3008 (const_string "V2DF")
3009 (match_test "optimize_function_for_size_p (cfun)")
3010 (const_string "V4SF")
3011 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3014 (const_string "V2DF"))
3016 /* For architectures resolving dependencies on
3017 whole SSE registers use movapd to break dependency
3018 chains, otherwise use short move to avoid extra work. */
3020 /* movaps is one byte shorter for non-AVX targets. */
3021 (eq_attr "alternative" "10,14")
3022 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3023 (match_operand 1 "ext_sse_reg_operand"))
3024 (const_string "V8DF")
3025 (ior (not (match_test "TARGET_SSE2"))
3026 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3027 (const_string "V4SF")
3028 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3029 (const_string "V2DF")
3030 (match_test "TARGET_AVX")
3032 (match_test "optimize_function_for_size_p (cfun)")
3033 (const_string "V4SF")
3035 (const_string "DF"))
3037 /* For architectures resolving dependencies on register
3038 parts we may avoid extra work to zero out upper part
3040 (eq_attr "alternative" "11,15")
3041 (cond [(not (match_test "TARGET_SSE2"))
3042 (const_string "V2SF")
3043 (match_test "TARGET_AVX")
3045 (match_test "TARGET_SSE_SPLIT_REGS")
3046 (const_string "V1DF")
3048 (const_string "DF"))
3050 (and (eq_attr "alternative" "12,16")
3051 (not (match_test "TARGET_SSE2")))
3052 (const_string "V2SF")
3054 (const_string "DF")))])
3056 (define_insn "*movsf_internal"
3057 [(set (match_operand:SF 0 "nonimmediate_operand"
3058 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3059 (match_operand:SF 1 "general_operand"
3060 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3061 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3062 && (!can_create_pseudo_p ()
3063 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3064 || GET_CODE (operands[1]) != CONST_DOUBLE
3065 || (optimize_function_for_size_p (cfun)
3066 && ((!TARGET_SSE_MATH
3067 && standard_80387_constant_p (operands[1]) > 0)
3069 && standard_sse_constant_p (operands[1]))))
3070 || memory_operand (operands[0], SFmode))"
3072 switch (get_attr_type (insn))
3075 if (which_alternative == 2)
3076 return standard_80387_constant_opcode (operands[1]);
3077 return output_387_reg_move (insn, operands);
3080 return "mov{l}\t{%1, %0|%0, %1}";
3083 return standard_sse_constant_opcode (insn, operands[1]);
3086 switch (get_attr_mode (insn))
3089 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3090 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3091 return "%vmovss\t{%1, %0|%0, %1}";
3094 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3096 return "%vmovaps\t{%1, %0|%0, %1}";
3099 return "%vmovd\t{%1, %0|%0, %1}";
3106 switch (get_attr_mode (insn))
3109 return "movq\t{%1, %0|%0, %1}";
3111 return "movd\t{%1, %0|%0, %1}";
3122 (cond [(eq_attr "alternative" "0,1,2")
3123 (const_string "fmov")
3124 (eq_attr "alternative" "3,4")
3125 (const_string "imov")
3126 (eq_attr "alternative" "5")
3127 (const_string "sselog1")
3128 (eq_attr "alternative" "11,12,13,14,15")
3129 (const_string "mmxmov")
3131 (const_string "ssemov")))
3132 (set (attr "prefix")
3133 (if_then_else (eq_attr "type" "sselog1,ssemov")
3134 (const_string "maybe_vex")
3135 (const_string "orig")))
3136 (set (attr "prefix_data16")
3137 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3139 (const_string "*")))
3141 (cond [(eq_attr "alternative" "3,4,9,10,14,15")
3143 (eq_attr "alternative" "11")
3145 (eq_attr "alternative" "5")
3146 (cond [(not (match_test "TARGET_SSE2"))
3147 (const_string "V4SF")
3148 (match_test "TARGET_AVX512F")
3149 (const_string "V16SF")
3150 (match_test "TARGET_AVX")
3151 (const_string "V4SF")
3152 (match_test "optimize_function_for_size_p (cfun)")
3153 (const_string "V4SF")
3154 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3157 (const_string "V4SF"))
3159 /* For architectures resolving dependencies on
3160 whole SSE registers use APS move to break dependency
3161 chains, otherwise use short move to avoid extra work.
3163 Do the same for architectures resolving dependencies on
3164 the parts. While in DF mode it is better to always handle
3165 just register parts, the SF mode is different due to lack
3166 of instructions to load just part of the register. It is
3167 better to maintain the whole registers in single format
3168 to avoid problems on using packed logical operations. */
3169 (eq_attr "alternative" "6")
3170 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3171 (match_operand 1 "ext_sse_reg_operand"))
3172 (const_string "V16SF")
3173 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3174 (match_test "TARGET_SSE_SPLIT_REGS"))
3175 (const_string "V4SF")
3177 (const_string "SF"))
3179 (const_string "SF")))])
3182 [(set (match_operand 0 "any_fp_register_operand")
3183 (match_operand 1 "memory_operand"))]
3185 && (GET_MODE (operands[0]) == TFmode
3186 || GET_MODE (operands[0]) == XFmode
3187 || GET_MODE (operands[0]) == DFmode
3188 || GET_MODE (operands[0]) == SFmode)
3189 && (operands[2] = find_constant_src (insn))"
3190 [(set (match_dup 0) (match_dup 2))]
3192 rtx c = operands[2];
3193 int r = REGNO (operands[0]);
3195 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3196 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3201 [(set (match_operand 0 "any_fp_register_operand")
3202 (float_extend (match_operand 1 "memory_operand")))]
3204 && (GET_MODE (operands[0]) == TFmode
3205 || GET_MODE (operands[0]) == XFmode
3206 || GET_MODE (operands[0]) == DFmode)
3207 && (operands[2] = find_constant_src (insn))"
3208 [(set (match_dup 0) (match_dup 2))]
3210 rtx c = operands[2];
3211 int r = REGNO (operands[0]);
3213 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3214 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3218 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3220 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3221 (match_operand:X87MODEF 1 "immediate_operand"))]
3223 && (standard_80387_constant_p (operands[1]) == 8
3224 || standard_80387_constant_p (operands[1]) == 9)"
3225 [(set (match_dup 0)(match_dup 1))
3227 (neg:X87MODEF (match_dup 0)))]
3231 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3232 if (real_isnegzero (&r))
3233 operands[1] = CONST0_RTX (<MODE>mode);
3235 operands[1] = CONST1_RTX (<MODE>mode);
3239 [(set (match_operand 0 "nonimmediate_operand")
3240 (match_operand 1 "general_operand"))]
3242 && (GET_MODE (operands[0]) == TFmode
3243 || GET_MODE (operands[0]) == XFmode
3244 || GET_MODE (operands[0]) == DFmode)
3245 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3247 "ix86_split_long_move (operands); DONE;")
3249 (define_insn "swapxf"
3250 [(set (match_operand:XF 0 "register_operand" "+f")
3251 (match_operand:XF 1 "register_operand" "+f"))
3256 if (STACK_TOP_P (operands[0]))
3261 [(set_attr "type" "fxch")
3262 (set_attr "mode" "XF")])
3264 (define_insn "*swap<mode>"
3265 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3266 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3269 "TARGET_80387 || reload_completed"
3271 if (STACK_TOP_P (operands[0]))
3276 [(set_attr "type" "fxch")
3277 (set_attr "mode" "<MODE>")])
3279 ;; Zero extension instructions
3281 (define_expand "zero_extendsidi2"
3282 [(set (match_operand:DI 0 "nonimmediate_operand")
3283 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3285 (define_insn "*zero_extendsidi2"
3286 [(set (match_operand:DI 0 "nonimmediate_operand"
3287 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3289 (match_operand:SI 1 "x86_64_zext_operand"
3290 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3293 switch (get_attr_type (insn))
3296 if (ix86_use_lea_for_mov (insn, operands))
3297 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3299 return "mov{l}\t{%1, %k0|%k0, %1}";
3305 return "movd\t{%1, %0|%0, %1}";
3308 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3311 if (GENERAL_REG_P (operands[0]))
3312 return "%vmovd\t{%1, %k0|%k0, %1}";
3314 return "%vmovd\t{%1, %0|%0, %1}";
3321 (cond [(eq_attr "alternative" "0,1,2")
3322 (const_string "nox64")
3323 (eq_attr "alternative" "3,7")
3324 (const_string "x64")
3325 (eq_attr "alternative" "8")
3326 (const_string "x64_sse4")
3327 (eq_attr "alternative" "10")
3328 (const_string "sse2")
3330 (const_string "*")))
3332 (cond [(eq_attr "alternative" "0,1,2,4")
3333 (const_string "multi")
3334 (eq_attr "alternative" "5,6")
3335 (const_string "mmxmov")
3336 (eq_attr "alternative" "7,9,10")
3337 (const_string "ssemov")
3338 (eq_attr "alternative" "8")
3339 (const_string "sselog1")
3341 (const_string "imovx")))
3342 (set (attr "prefix_extra")
3343 (if_then_else (eq_attr "alternative" "8")
3345 (const_string "*")))
3346 (set (attr "length_immediate")
3347 (if_then_else (eq_attr "alternative" "8")
3349 (const_string "*")))
3350 (set (attr "prefix")
3351 (if_then_else (eq_attr "type" "ssemov,sselog1")
3352 (const_string "maybe_vex")
3353 (const_string "orig")))
3354 (set (attr "prefix_0f")
3355 (if_then_else (eq_attr "type" "imovx")
3357 (const_string "*")))
3359 (cond [(eq_attr "alternative" "5,6")
3361 (eq_attr "alternative" "7,8,9")
3364 (const_string "SI")))])
3367 [(set (match_operand:DI 0 "memory_operand")
3368 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3370 [(set (match_dup 4) (const_int 0))]
3371 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3374 [(set (match_operand:DI 0 "register_operand")
3375 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3376 "!TARGET_64BIT && reload_completed
3377 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3378 && true_regnum (operands[0]) == true_regnum (operands[1])"
3379 [(set (match_dup 4) (const_int 0))]
3380 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3383 [(set (match_operand:DI 0 "nonimmediate_operand")
3384 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3385 "!TARGET_64BIT && reload_completed
3386 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3387 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3388 [(set (match_dup 3) (match_dup 1))
3389 (set (match_dup 4) (const_int 0))]
3390 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3392 (define_insn "zero_extend<mode>di2"
3393 [(set (match_operand:DI 0 "register_operand" "=r")
3395 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3397 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3398 [(set_attr "type" "imovx")
3399 (set_attr "mode" "SI")])
3401 (define_expand "zero_extend<mode>si2"
3402 [(set (match_operand:SI 0 "register_operand")
3403 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3406 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3408 operands[1] = force_reg (<MODE>mode, operands[1]);
3409 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3414 (define_insn_and_split "zero_extend<mode>si2_and"
3415 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3417 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3418 (clobber (reg:CC FLAGS_REG))]
3419 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3421 "&& reload_completed"
3422 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3423 (clobber (reg:CC FLAGS_REG))])]
3425 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3427 ix86_expand_clear (operands[0]);
3429 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3430 emit_insn (gen_movstrict<mode>
3431 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3435 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3437 [(set_attr "type" "alu1")
3438 (set_attr "mode" "SI")])
3440 (define_insn "*zero_extend<mode>si2"
3441 [(set (match_operand:SI 0 "register_operand" "=r")
3443 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3444 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3445 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3446 [(set_attr "type" "imovx")
3447 (set_attr "mode" "SI")])
3449 (define_expand "zero_extendqihi2"
3450 [(set (match_operand:HI 0 "register_operand")
3451 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3454 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3456 operands[1] = force_reg (QImode, operands[1]);
3457 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3462 (define_insn_and_split "zero_extendqihi2_and"
3463 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3464 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3465 (clobber (reg:CC FLAGS_REG))]
3466 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3468 "&& reload_completed"
3469 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3470 (clobber (reg:CC FLAGS_REG))])]
3472 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3474 ix86_expand_clear (operands[0]);
3476 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3477 emit_insn (gen_movstrictqi
3478 (gen_lowpart (QImode, operands[0]), operands[1]));
3482 operands[0] = gen_lowpart (SImode, operands[0]);
3484 [(set_attr "type" "alu1")
3485 (set_attr "mode" "SI")])
3487 ; zero extend to SImode to avoid partial register stalls
3488 (define_insn "*zero_extendqihi2"
3489 [(set (match_operand:HI 0 "register_operand" "=r")
3490 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3491 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3492 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3493 [(set_attr "type" "imovx")
3494 (set_attr "mode" "SI")])
3496 ;; Sign extension instructions
3498 (define_expand "extendsidi2"
3499 [(set (match_operand:DI 0 "register_operand")
3500 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3505 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3510 (define_insn "*extendsidi2_rex64"
3511 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3512 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3516 movs{lq|x}\t{%1, %0|%0, %1}"
3517 [(set_attr "type" "imovx")
3518 (set_attr "mode" "DI")
3519 (set_attr "prefix_0f" "0")
3520 (set_attr "modrm" "0,1")])
3522 (define_insn "extendsidi2_1"
3523 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3524 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3525 (clobber (reg:CC FLAGS_REG))
3526 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3530 ;; Split the memory case. If the source register doesn't die, it will stay
3531 ;; this way, if it does die, following peephole2s take care of it.
3533 [(set (match_operand:DI 0 "memory_operand")
3534 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3535 (clobber (reg:CC FLAGS_REG))
3536 (clobber (match_operand:SI 2 "register_operand"))]
3540 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3542 emit_move_insn (operands[3], operands[1]);
3544 /* Generate a cltd if possible and doing so it profitable. */
3545 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3546 && true_regnum (operands[1]) == AX_REG
3547 && true_regnum (operands[2]) == DX_REG)
3549 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3553 emit_move_insn (operands[2], operands[1]);
3554 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3556 emit_move_insn (operands[4], operands[2]);
3560 ;; Peepholes for the case where the source register does die, after
3561 ;; being split with the above splitter.
3563 [(set (match_operand:SI 0 "memory_operand")
3564 (match_operand:SI 1 "register_operand"))
3565 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3566 (parallel [(set (match_dup 2)
3567 (ashiftrt:SI (match_dup 2) (const_int 31)))
3568 (clobber (reg:CC FLAGS_REG))])
3569 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3570 "REGNO (operands[1]) != REGNO (operands[2])
3571 && peep2_reg_dead_p (2, operands[1])
3572 && peep2_reg_dead_p (4, operands[2])
3573 && !reg_mentioned_p (operands[2], operands[3])"
3574 [(set (match_dup 0) (match_dup 1))
3575 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3576 (clobber (reg:CC FLAGS_REG))])
3577 (set (match_dup 3) (match_dup 1))])
3580 [(set (match_operand:SI 0 "memory_operand")
3581 (match_operand:SI 1 "register_operand"))
3582 (parallel [(set (match_operand:SI 2 "register_operand")
3583 (ashiftrt:SI (match_dup 1) (const_int 31)))
3584 (clobber (reg:CC FLAGS_REG))])
3585 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3586 "/* cltd is shorter than sarl $31, %eax */
3587 !optimize_function_for_size_p (cfun)
3588 && true_regnum (operands[1]) == AX_REG
3589 && true_regnum (operands[2]) == DX_REG
3590 && peep2_reg_dead_p (2, operands[1])
3591 && peep2_reg_dead_p (3, operands[2])
3592 && !reg_mentioned_p (operands[2], operands[3])"
3593 [(set (match_dup 0) (match_dup 1))
3594 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3595 (clobber (reg:CC FLAGS_REG))])
3596 (set (match_dup 3) (match_dup 1))])
3598 ;; Extend to register case. Optimize case where source and destination
3599 ;; registers match and cases where we can use cltd.
3601 [(set (match_operand:DI 0 "register_operand")
3602 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3603 (clobber (reg:CC FLAGS_REG))
3604 (clobber (match_scratch:SI 2))]
3608 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3610 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3611 emit_move_insn (operands[3], operands[1]);
3613 /* Generate a cltd if possible and doing so it profitable. */
3614 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3615 && true_regnum (operands[3]) == AX_REG
3616 && true_regnum (operands[4]) == DX_REG)
3618 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3622 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3623 emit_move_insn (operands[4], operands[1]);
3625 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3629 (define_insn "extend<mode>di2"
3630 [(set (match_operand:DI 0 "register_operand" "=r")
3632 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3634 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3635 [(set_attr "type" "imovx")
3636 (set_attr "mode" "DI")])
3638 (define_insn "extendhisi2"
3639 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3640 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3643 switch (get_attr_prefix_0f (insn))
3646 return "{cwtl|cwde}";
3648 return "movs{wl|x}\t{%1, %0|%0, %1}";
3651 [(set_attr "type" "imovx")
3652 (set_attr "mode" "SI")
3653 (set (attr "prefix_0f")
3654 ;; movsx is short decodable while cwtl is vector decoded.
3655 (if_then_else (and (eq_attr "cpu" "!k6")
3656 (eq_attr "alternative" "0"))
3658 (const_string "1")))
3660 (if_then_else (eq_attr "prefix_0f" "0")
3662 (const_string "1")))])
3664 (define_insn "*extendhisi2_zext"
3665 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3668 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3671 switch (get_attr_prefix_0f (insn))
3674 return "{cwtl|cwde}";
3676 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3679 [(set_attr "type" "imovx")
3680 (set_attr "mode" "SI")
3681 (set (attr "prefix_0f")
3682 ;; movsx is short decodable while cwtl is vector decoded.
3683 (if_then_else (and (eq_attr "cpu" "!k6")
3684 (eq_attr "alternative" "0"))
3686 (const_string "1")))
3688 (if_then_else (eq_attr "prefix_0f" "0")
3690 (const_string "1")))])
3692 (define_insn "extendqisi2"
3693 [(set (match_operand:SI 0 "register_operand" "=r")
3694 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3696 "movs{bl|x}\t{%1, %0|%0, %1}"
3697 [(set_attr "type" "imovx")
3698 (set_attr "mode" "SI")])
3700 (define_insn "*extendqisi2_zext"
3701 [(set (match_operand:DI 0 "register_operand" "=r")
3703 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3705 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3706 [(set_attr "type" "imovx")
3707 (set_attr "mode" "SI")])
3709 (define_insn "extendqihi2"
3710 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3711 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3714 switch (get_attr_prefix_0f (insn))
3717 return "{cbtw|cbw}";
3719 return "movs{bw|x}\t{%1, %0|%0, %1}";
3722 [(set_attr "type" "imovx")
3723 (set_attr "mode" "HI")
3724 (set (attr "prefix_0f")
3725 ;; movsx is short decodable while cwtl is vector decoded.
3726 (if_then_else (and (eq_attr "cpu" "!k6")
3727 (eq_attr "alternative" "0"))
3729 (const_string "1")))
3731 (if_then_else (eq_attr "prefix_0f" "0")
3733 (const_string "1")))])
3735 ;; Conversions between float and double.
3737 ;; These are all no-ops in the model used for the 80387.
3738 ;; So just emit moves.
3740 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3742 [(set (match_operand:DF 0 "push_operand")
3743 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3745 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3746 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3749 [(set (match_operand:XF 0 "push_operand")
3750 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3752 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3753 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3754 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3756 (define_expand "extendsfdf2"
3757 [(set (match_operand:DF 0 "nonimmediate_operand")
3758 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3759 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3761 /* ??? Needed for compress_float_constant since all fp constants
3762 are TARGET_LEGITIMATE_CONSTANT_P. */
3763 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3765 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3766 && standard_80387_constant_p (operands[1]) > 0)
3768 operands[1] = simplify_const_unary_operation
3769 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3770 emit_move_insn_1 (operands[0], operands[1]);
3773 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3777 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3779 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3781 We do the conversion post reload to avoid producing of 128bit spills
3782 that might lead to ICE on 32bit target. The sequence unlikely combine
3785 [(set (match_operand:DF 0 "register_operand")
3787 (match_operand:SF 1 "nonimmediate_operand")))]
3788 "TARGET_USE_VECTOR_FP_CONVERTS
3789 && optimize_insn_for_speed_p ()
3790 && reload_completed && SSE_REG_P (operands[0])"
3795 (parallel [(const_int 0) (const_int 1)]))))]
3797 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3798 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3799 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3800 Try to avoid move when unpacking can be done in source. */
3801 if (REG_P (operands[1]))
3803 /* If it is unsafe to overwrite upper half of source, we need
3804 to move to destination and unpack there. */
3805 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3806 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3807 && true_regnum (operands[0]) != true_regnum (operands[1]))
3809 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3810 emit_move_insn (tmp, operands[1]);
3813 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3814 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3818 emit_insn (gen_vec_setv4sf_0 (operands[3],
3819 CONST0_RTX (V4SFmode), operands[1]));
3822 ;; It's more profitable to split and then extend in the same register.
3824 [(set (match_operand:DF 0 "register_operand")
3826 (match_operand:SF 1 "memory_operand")))]
3827 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3828 && optimize_insn_for_speed_p ()
3829 && SSE_REG_P (operands[0])"
3830 [(set (match_dup 2) (match_dup 1))
3831 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3832 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3834 (define_insn "*extendsfdf2_mixed"
3835 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3837 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3838 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3840 switch (which_alternative)
3844 return output_387_reg_move (insn, operands);
3847 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3853 [(set_attr "type" "fmov,fmov,ssecvt")
3854 (set_attr "prefix" "orig,orig,maybe_vex")
3855 (set_attr "mode" "SF,XF,DF")])
3857 (define_insn "*extendsfdf2_sse"
3858 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3859 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3860 "TARGET_SSE2 && TARGET_SSE_MATH"
3861 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3862 [(set_attr "type" "ssecvt")
3863 (set_attr "prefix" "maybe_vex")
3864 (set_attr "mode" "DF")])
3866 (define_insn "*extendsfdf2_i387"
3867 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3868 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3870 "* return output_387_reg_move (insn, operands);"
3871 [(set_attr "type" "fmov")
3872 (set_attr "mode" "SF,XF")])
3874 (define_expand "extend<mode>xf2"
3875 [(set (match_operand:XF 0 "nonimmediate_operand")
3876 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3879 /* ??? Needed for compress_float_constant since all fp constants
3880 are TARGET_LEGITIMATE_CONSTANT_P. */
3881 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3883 if (standard_80387_constant_p (operands[1]) > 0)
3885 operands[1] = simplify_const_unary_operation
3886 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3887 emit_move_insn_1 (operands[0], operands[1]);
3890 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3894 (define_insn "*extend<mode>xf2_i387"
3895 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3897 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3899 "* return output_387_reg_move (insn, operands);"
3900 [(set_attr "type" "fmov")
3901 (set_attr "mode" "<MODE>,XF")])
3903 ;; %%% This seems bad bad news.
3904 ;; This cannot output into an f-reg because there is no way to be sure
3905 ;; of truncating in that case. Otherwise this is just like a simple move
3906 ;; insn. So we pretend we can output to a reg in order to get better
3907 ;; register preferencing, but we really use a stack slot.
3909 ;; Conversion from DFmode to SFmode.
3911 (define_expand "truncdfsf2"
3912 [(set (match_operand:SF 0 "nonimmediate_operand")
3914 (match_operand:DF 1 "nonimmediate_operand")))]
3915 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3917 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3919 else if (flag_unsafe_math_optimizations)
3923 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3924 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3929 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3931 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3933 We do the conversion post reload to avoid producing of 128bit spills
3934 that might lead to ICE on 32bit target. The sequence unlikely combine
3937 [(set (match_operand:SF 0 "register_operand")
3939 (match_operand:DF 1 "nonimmediate_operand")))]
3940 "TARGET_USE_VECTOR_FP_CONVERTS
3941 && optimize_insn_for_speed_p ()
3942 && reload_completed && SSE_REG_P (operands[0])"
3945 (float_truncate:V2SF
3949 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3950 operands[3] = CONST0_RTX (V2SFmode);
3951 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3952 /* Use movsd for loading from memory, unpcklpd for registers.
3953 Try to avoid move when unpacking can be done in source, or SSE3
3954 movddup is available. */
3955 if (REG_P (operands[1]))
3958 && true_regnum (operands[0]) != true_regnum (operands[1])
3959 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3960 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3962 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3963 emit_move_insn (tmp, operands[1]);
3966 else if (!TARGET_SSE3)
3967 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3968 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3971 emit_insn (gen_sse2_loadlpd (operands[4],
3972 CONST0_RTX (V2DFmode), operands[1]));
3975 ;; It's more profitable to split and then extend in the same register.
3977 [(set (match_operand:SF 0 "register_operand")
3979 (match_operand:DF 1 "memory_operand")))]
3980 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3981 && optimize_insn_for_speed_p ()
3982 && SSE_REG_P (operands[0])"
3983 [(set (match_dup 2) (match_dup 1))
3984 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
3985 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
3987 (define_expand "truncdfsf2_with_temp"
3988 [(parallel [(set (match_operand:SF 0)
3989 (float_truncate:SF (match_operand:DF 1)))
3990 (clobber (match_operand:SF 2))])])
3992 (define_insn "*truncdfsf_fast_mixed"
3993 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
3995 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
3996 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3998 switch (which_alternative)
4001 return output_387_reg_move (insn, operands);
4003 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4008 [(set_attr "type" "fmov,ssecvt")
4009 (set_attr "prefix" "orig,maybe_vex")
4010 (set_attr "mode" "SF")])
4012 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4013 ;; because nothing we do here is unsafe.
4014 (define_insn "*truncdfsf_fast_sse"
4015 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4017 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4018 "TARGET_SSE2 && TARGET_SSE_MATH"
4019 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4020 [(set_attr "type" "ssecvt")
4021 (set_attr "prefix" "maybe_vex")
4022 (set_attr "mode" "SF")])
4024 (define_insn "*truncdfsf_fast_i387"
4025 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4027 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4028 "TARGET_80387 && flag_unsafe_math_optimizations"
4029 "* return output_387_reg_move (insn, operands);"
4030 [(set_attr "type" "fmov")
4031 (set_attr "mode" "SF")])
4033 (define_insn "*truncdfsf_mixed"
4034 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4036 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4037 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4038 "TARGET_MIX_SSE_I387"
4040 switch (which_alternative)
4043 return output_387_reg_move (insn, operands);
4045 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4051 [(set_attr "isa" "*,sse2,*,*,*")
4052 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4053 (set_attr "unit" "*,*,i387,i387,i387")
4054 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4055 (set_attr "mode" "SF")])
4057 (define_insn "*truncdfsf_i387"
4058 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4060 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4061 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4064 switch (which_alternative)
4067 return output_387_reg_move (insn, operands);
4073 [(set_attr "type" "fmov,multi,multi,multi")
4074 (set_attr "unit" "*,i387,i387,i387")
4075 (set_attr "mode" "SF")])
4077 (define_insn "*truncdfsf2_i387_1"
4078 [(set (match_operand:SF 0 "memory_operand" "=m")
4080 (match_operand:DF 1 "register_operand" "f")))]
4082 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4083 && !TARGET_MIX_SSE_I387"
4084 "* return output_387_reg_move (insn, operands);"
4085 [(set_attr "type" "fmov")
4086 (set_attr "mode" "SF")])
4089 [(set (match_operand:SF 0 "register_operand")
4091 (match_operand:DF 1 "fp_register_operand")))
4092 (clobber (match_operand 2))]
4094 [(set (match_dup 2) (match_dup 1))
4095 (set (match_dup 0) (match_dup 2))]
4096 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4098 ;; Conversion from XFmode to {SF,DF}mode
4100 (define_expand "truncxf<mode>2"
4101 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4102 (float_truncate:MODEF
4103 (match_operand:XF 1 "register_operand")))
4104 (clobber (match_dup 2))])]
4107 if (flag_unsafe_math_optimizations)
4109 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4110 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4111 if (reg != operands[0])
4112 emit_move_insn (operands[0], reg);
4116 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4119 (define_insn "*truncxfsf2_mixed"
4120 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4122 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4123 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4126 gcc_assert (!which_alternative);
4127 return output_387_reg_move (insn, operands);
4129 [(set_attr "type" "fmov,multi,multi,multi")
4130 (set_attr "unit" "*,i387,i387,i387")
4131 (set_attr "mode" "SF")])
4133 (define_insn "*truncxfdf2_mixed"
4134 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4136 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4137 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4140 gcc_assert (!which_alternative);
4141 return output_387_reg_move (insn, operands);
4143 [(set_attr "isa" "*,*,sse2,*")
4144 (set_attr "type" "fmov,multi,multi,multi")
4145 (set_attr "unit" "*,i387,i387,i387")
4146 (set_attr "mode" "DF")])
4148 (define_insn "truncxf<mode>2_i387_noop"
4149 [(set (match_operand:MODEF 0 "register_operand" "=f")
4150 (float_truncate:MODEF
4151 (match_operand:XF 1 "register_operand" "f")))]
4152 "TARGET_80387 && flag_unsafe_math_optimizations"
4153 "* return output_387_reg_move (insn, operands);"
4154 [(set_attr "type" "fmov")
4155 (set_attr "mode" "<MODE>")])
4157 (define_insn "*truncxf<mode>2_i387"
4158 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4159 (float_truncate:MODEF
4160 (match_operand:XF 1 "register_operand" "f")))]
4162 "* return output_387_reg_move (insn, operands);"
4163 [(set_attr "type" "fmov")
4164 (set_attr "mode" "<MODE>")])
4167 [(set (match_operand:MODEF 0 "register_operand")
4168 (float_truncate:MODEF
4169 (match_operand:XF 1 "register_operand")))
4170 (clobber (match_operand:MODEF 2 "memory_operand"))]
4171 "TARGET_80387 && reload_completed"
4172 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4173 (set (match_dup 0) (match_dup 2))])
4176 [(set (match_operand:MODEF 0 "memory_operand")
4177 (float_truncate:MODEF
4178 (match_operand:XF 1 "register_operand")))
4179 (clobber (match_operand:MODEF 2 "memory_operand"))]
4181 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4183 ;; Signed conversion to DImode.
4185 (define_expand "fix_truncxfdi2"
4186 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4187 (fix:DI (match_operand:XF 1 "register_operand")))
4188 (clobber (reg:CC FLAGS_REG))])]
4193 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4198 (define_expand "fix_trunc<mode>di2"
4199 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4200 (fix:DI (match_operand:MODEF 1 "register_operand")))
4201 (clobber (reg:CC FLAGS_REG))])]
4202 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4205 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4207 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4210 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4212 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4213 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4214 if (out != operands[0])
4215 emit_move_insn (operands[0], out);
4220 ;; Signed conversion to SImode.
4222 (define_expand "fix_truncxfsi2"
4223 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4224 (fix:SI (match_operand:XF 1 "register_operand")))
4225 (clobber (reg:CC FLAGS_REG))])]
4230 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4235 (define_expand "fix_trunc<mode>si2"
4236 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4237 (fix:SI (match_operand:MODEF 1 "register_operand")))
4238 (clobber (reg:CC FLAGS_REG))])]
4239 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4242 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4244 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4247 if (SSE_FLOAT_MODE_P (<MODE>mode))
4249 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4250 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4251 if (out != operands[0])
4252 emit_move_insn (operands[0], out);
4257 ;; Signed conversion to HImode.
4259 (define_expand "fix_trunc<mode>hi2"
4260 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4261 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4262 (clobber (reg:CC FLAGS_REG))])]
4264 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4268 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4273 ;; Unsigned conversion to SImode.
4275 (define_expand "fixuns_trunc<mode>si2"
4277 [(set (match_operand:SI 0 "register_operand")
4279 (match_operand:MODEF 1 "nonimmediate_operand")))
4281 (clobber (match_scratch:<ssevecmode> 3))
4282 (clobber (match_scratch:<ssevecmode> 4))])]
4283 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4285 enum machine_mode mode = <MODE>mode;
4286 enum machine_mode vecmode = <ssevecmode>mode;
4287 REAL_VALUE_TYPE TWO31r;
4290 if (optimize_insn_for_size_p ())
4293 real_ldexp (&TWO31r, &dconst1, 31);
4294 two31 = const_double_from_real_value (TWO31r, mode);
4295 two31 = ix86_build_const_vector (vecmode, true, two31);
4296 operands[2] = force_reg (vecmode, two31);
4299 (define_insn_and_split "*fixuns_trunc<mode>_1"
4300 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4302 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4303 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4304 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4305 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4306 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4307 && optimize_function_for_speed_p (cfun)"
4309 "&& reload_completed"
4312 ix86_split_convert_uns_si_sse (operands);
4316 ;; Unsigned conversion to HImode.
4317 ;; Without these patterns, we'll try the unsigned SI conversion which
4318 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4320 (define_expand "fixuns_trunc<mode>hi2"
4322 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4323 (set (match_operand:HI 0 "nonimmediate_operand")
4324 (subreg:HI (match_dup 2) 0))]
4325 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4326 "operands[2] = gen_reg_rtx (SImode);")
4328 ;; When SSE is available, it is always faster to use it!
4329 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4330 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4331 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4332 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4333 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4334 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4335 [(set_attr "type" "sseicvt")
4336 (set_attr "prefix" "maybe_vex")
4337 (set (attr "prefix_rex")
4339 (match_test "<SWI48:MODE>mode == DImode")
4341 (const_string "*")))
4342 (set_attr "mode" "<MODEF:MODE>")
4343 (set_attr "athlon_decode" "double,vector")
4344 (set_attr "amdfam10_decode" "double,double")
4345 (set_attr "bdver1_decode" "double,double")])
4347 ;; Avoid vector decoded forms of the instruction.
4349 [(match_scratch:MODEF 2 "x")
4350 (set (match_operand:SWI48 0 "register_operand")
4351 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4352 "TARGET_AVOID_VECTOR_DECODE
4353 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4354 && optimize_insn_for_speed_p ()"
4355 [(set (match_dup 2) (match_dup 1))
4356 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4358 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4359 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4360 (fix:SWI248x (match_operand 1 "register_operand")))]
4361 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4363 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4364 && (TARGET_64BIT || <MODE>mode != DImode))
4366 && can_create_pseudo_p ()"
4371 if (memory_operand (operands[0], VOIDmode))
4372 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4375 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4376 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4382 [(set_attr "type" "fisttp")
4383 (set_attr "mode" "<MODE>")])
4385 (define_insn "fix_trunc<mode>_i387_fisttp"
4386 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4387 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4388 (clobber (match_scratch:XF 2 "=&1f"))]
4389 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4391 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4392 && (TARGET_64BIT || <MODE>mode != DImode))
4393 && TARGET_SSE_MATH)"
4394 "* return output_fix_trunc (insn, operands, true);"
4395 [(set_attr "type" "fisttp")
4396 (set_attr "mode" "<MODE>")])
4398 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4399 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4400 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4401 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4402 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4403 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4405 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4406 && (TARGET_64BIT || <MODE>mode != DImode))
4407 && TARGET_SSE_MATH)"
4409 [(set_attr "type" "fisttp")
4410 (set_attr "mode" "<MODE>")])
4413 [(set (match_operand:SWI248x 0 "register_operand")
4414 (fix:SWI248x (match_operand 1 "register_operand")))
4415 (clobber (match_operand:SWI248x 2 "memory_operand"))
4416 (clobber (match_scratch 3))]
4418 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4419 (clobber (match_dup 3))])
4420 (set (match_dup 0) (match_dup 2))])
4423 [(set (match_operand:SWI248x 0 "memory_operand")
4424 (fix:SWI248x (match_operand 1 "register_operand")))
4425 (clobber (match_operand:SWI248x 2 "memory_operand"))
4426 (clobber (match_scratch 3))]
4428 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4429 (clobber (match_dup 3))])])
4431 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4432 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4433 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4434 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4435 ;; function in i386.c.
4436 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4437 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4438 (fix:SWI248x (match_operand 1 "register_operand")))
4439 (clobber (reg:CC FLAGS_REG))]
4440 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4442 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4443 && (TARGET_64BIT || <MODE>mode != DImode))
4444 && can_create_pseudo_p ()"
4449 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4451 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4452 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4453 if (memory_operand (operands[0], VOIDmode))
4454 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4455 operands[2], operands[3]));
4458 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4459 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4460 operands[2], operands[3],
4465 [(set_attr "type" "fistp")
4466 (set_attr "i387_cw" "trunc")
4467 (set_attr "mode" "<MODE>")])
4469 (define_insn "fix_truncdi_i387"
4470 [(set (match_operand:DI 0 "memory_operand" "=m")
4471 (fix:DI (match_operand 1 "register_operand" "f")))
4472 (use (match_operand:HI 2 "memory_operand" "m"))
4473 (use (match_operand:HI 3 "memory_operand" "m"))
4474 (clobber (match_scratch:XF 4 "=&1f"))]
4475 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4477 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4478 "* return output_fix_trunc (insn, operands, false);"
4479 [(set_attr "type" "fistp")
4480 (set_attr "i387_cw" "trunc")
4481 (set_attr "mode" "DI")])
4483 (define_insn "fix_truncdi_i387_with_temp"
4484 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4485 (fix:DI (match_operand 1 "register_operand" "f,f")))
4486 (use (match_operand:HI 2 "memory_operand" "m,m"))
4487 (use (match_operand:HI 3 "memory_operand" "m,m"))
4488 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4489 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4490 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4492 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4494 [(set_attr "type" "fistp")
4495 (set_attr "i387_cw" "trunc")
4496 (set_attr "mode" "DI")])
4499 [(set (match_operand:DI 0 "register_operand")
4500 (fix:DI (match_operand 1 "register_operand")))
4501 (use (match_operand:HI 2 "memory_operand"))
4502 (use (match_operand:HI 3 "memory_operand"))
4503 (clobber (match_operand:DI 4 "memory_operand"))
4504 (clobber (match_scratch 5))]
4506 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4509 (clobber (match_dup 5))])
4510 (set (match_dup 0) (match_dup 4))])
4513 [(set (match_operand:DI 0 "memory_operand")
4514 (fix:DI (match_operand 1 "register_operand")))
4515 (use (match_operand:HI 2 "memory_operand"))
4516 (use (match_operand:HI 3 "memory_operand"))
4517 (clobber (match_operand:DI 4 "memory_operand"))
4518 (clobber (match_scratch 5))]
4520 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4523 (clobber (match_dup 5))])])
4525 (define_insn "fix_trunc<mode>_i387"
4526 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4527 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4528 (use (match_operand:HI 2 "memory_operand" "m"))
4529 (use (match_operand:HI 3 "memory_operand" "m"))]
4530 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4532 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4533 "* return output_fix_trunc (insn, operands, false);"
4534 [(set_attr "type" "fistp")
4535 (set_attr "i387_cw" "trunc")
4536 (set_attr "mode" "<MODE>")])
4538 (define_insn "fix_trunc<mode>_i387_with_temp"
4539 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4540 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4541 (use (match_operand:HI 2 "memory_operand" "m,m"))
4542 (use (match_operand:HI 3 "memory_operand" "m,m"))
4543 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4544 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4546 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4548 [(set_attr "type" "fistp")
4549 (set_attr "i387_cw" "trunc")
4550 (set_attr "mode" "<MODE>")])
4553 [(set (match_operand:SWI24 0 "register_operand")
4554 (fix:SWI24 (match_operand 1 "register_operand")))
4555 (use (match_operand:HI 2 "memory_operand"))
4556 (use (match_operand:HI 3 "memory_operand"))
4557 (clobber (match_operand:SWI24 4 "memory_operand"))]
4559 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4561 (use (match_dup 3))])
4562 (set (match_dup 0) (match_dup 4))])
4565 [(set (match_operand:SWI24 0 "memory_operand")
4566 (fix:SWI24 (match_operand 1 "register_operand")))
4567 (use (match_operand:HI 2 "memory_operand"))
4568 (use (match_operand:HI 3 "memory_operand"))
4569 (clobber (match_operand:SWI24 4 "memory_operand"))]
4571 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4573 (use (match_dup 3))])])
4575 (define_insn "x86_fnstcw_1"
4576 [(set (match_operand:HI 0 "memory_operand" "=m")
4577 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4580 [(set (attr "length")
4581 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4582 (set_attr "mode" "HI")
4583 (set_attr "unit" "i387")
4584 (set_attr "bdver1_decode" "vector")])
4586 (define_insn "x86_fldcw_1"
4587 [(set (reg:HI FPCR_REG)
4588 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4591 [(set (attr "length")
4592 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4593 (set_attr "mode" "HI")
4594 (set_attr "unit" "i387")
4595 (set_attr "athlon_decode" "vector")
4596 (set_attr "amdfam10_decode" "vector")
4597 (set_attr "bdver1_decode" "vector")])
4599 ;; Conversion between fixed point and floating point.
4601 ;; Even though we only accept memory inputs, the backend _really_
4602 ;; wants to be able to do this between registers.
4604 (define_expand "floathi<mode>2"
4605 [(set (match_operand:X87MODEF 0 "register_operand")
4606 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4608 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4609 || TARGET_MIX_SSE_I387)")
4611 ;; Pre-reload splitter to add memory clobber to the pattern.
4612 (define_insn_and_split "*floathi<mode>2_1"
4613 [(set (match_operand:X87MODEF 0 "register_operand")
4614 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4616 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4617 || TARGET_MIX_SSE_I387)
4618 && can_create_pseudo_p ()"
4621 [(parallel [(set (match_dup 0)
4622 (float:X87MODEF (match_dup 1)))
4623 (clobber (match_dup 2))])]
4624 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4626 (define_insn "*floathi<mode>2_i387_with_temp"
4627 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4628 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4629 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4631 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4632 || TARGET_MIX_SSE_I387)"
4634 [(set_attr "type" "fmov,multi")
4635 (set_attr "mode" "<MODE>")
4636 (set_attr "unit" "*,i387")
4637 (set_attr "fp_int_src" "true")])
4639 (define_insn "*floathi<mode>2_i387"
4640 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4641 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4643 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4644 || TARGET_MIX_SSE_I387)"
4646 [(set_attr "type" "fmov")
4647 (set_attr "mode" "<MODE>")
4648 (set_attr "fp_int_src" "true")])
4651 [(set (match_operand:X87MODEF 0 "register_operand")
4652 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4653 (clobber (match_operand:HI 2 "memory_operand"))]
4655 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4656 || TARGET_MIX_SSE_I387)
4657 && reload_completed"
4658 [(set (match_dup 2) (match_dup 1))
4659 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4662 [(set (match_operand:X87MODEF 0 "register_operand")
4663 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4664 (clobber (match_operand:HI 2 "memory_operand"))]
4666 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4667 || TARGET_MIX_SSE_I387)
4668 && reload_completed"
4669 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4671 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4672 [(set (match_operand:X87MODEF 0 "register_operand")
4674 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4676 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4677 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4679 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4680 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4681 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4683 rtx reg = gen_reg_rtx (XFmode);
4684 rtx (*insn)(rtx, rtx);
4686 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4688 if (<X87MODEF:MODE>mode == SFmode)
4689 insn = gen_truncxfsf2;
4690 else if (<X87MODEF:MODE>mode == DFmode)
4691 insn = gen_truncxfdf2;
4695 emit_insn (insn (operands[0], reg));
4700 ;; Pre-reload splitter to add memory clobber to the pattern.
4701 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4702 [(set (match_operand:X87MODEF 0 "register_operand")
4703 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4705 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4706 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4707 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4708 || TARGET_MIX_SSE_I387))
4709 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4710 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4711 && ((<SWI48x:MODE>mode == SImode
4712 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4713 && optimize_function_for_speed_p (cfun)
4714 && flag_trapping_math)
4715 || !(TARGET_INTER_UNIT_CONVERSIONS
4716 || optimize_function_for_size_p (cfun)))))
4717 && can_create_pseudo_p ()"
4720 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4721 (clobber (match_dup 2))])]
4723 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4725 /* Avoid store forwarding (partial memory) stall penalty
4726 by passing DImode value through XMM registers. */
4727 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4728 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4729 && optimize_function_for_speed_p (cfun))
4731 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4738 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4739 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4741 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4742 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4743 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4744 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4746 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4747 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4748 (set_attr "unit" "*,i387,*,*,*")
4749 (set_attr "athlon_decode" "*,*,double,direct,double")
4750 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4751 (set_attr "bdver1_decode" "*,*,double,direct,double")
4752 (set_attr "fp_int_src" "true")])
4754 (define_insn "*floatsi<mode>2_vector_mixed"
4755 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4756 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4757 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4758 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4762 [(set_attr "type" "fmov,sseicvt")
4763 (set_attr "mode" "<MODE>,<ssevecmode>")
4764 (set_attr "unit" "i387,*")
4765 (set_attr "athlon_decode" "*,direct")
4766 (set_attr "amdfam10_decode" "*,double")
4767 (set_attr "bdver1_decode" "*,direct")
4768 (set_attr "fp_int_src" "true")])
4770 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4771 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4773 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4774 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4775 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4777 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4778 (set_attr "mode" "<MODEF:MODE>")
4779 (set_attr "unit" "*,i387,*,*")
4780 (set_attr "athlon_decode" "*,*,double,direct")
4781 (set_attr "amdfam10_decode" "*,*,vector,double")
4782 (set_attr "bdver1_decode" "*,*,double,direct")
4783 (set_attr "fp_int_src" "true")])
4786 [(set (match_operand:MODEF 0 "register_operand")
4787 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4788 (clobber (match_operand:SWI48 2 "memory_operand"))]
4789 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4790 && TARGET_INTER_UNIT_CONVERSIONS
4791 && reload_completed && SSE_REG_P (operands[0])"
4792 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4795 [(set (match_operand:MODEF 0 "register_operand")
4796 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4797 (clobber (match_operand:SWI48 2 "memory_operand"))]
4798 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4799 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4800 && reload_completed && SSE_REG_P (operands[0])"
4801 [(set (match_dup 2) (match_dup 1))
4802 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4804 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4805 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4807 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4808 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4809 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4812 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4813 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4814 [(set_attr "type" "fmov,sseicvt,sseicvt")
4815 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4816 (set_attr "mode" "<MODEF:MODE>")
4817 (set (attr "prefix_rex")
4819 (and (eq_attr "prefix" "maybe_vex")
4820 (match_test "<SWI48:MODE>mode == DImode"))
4822 (const_string "*")))
4823 (set_attr "unit" "i387,*,*")
4824 (set_attr "athlon_decode" "*,double,direct")
4825 (set_attr "amdfam10_decode" "*,vector,double")
4826 (set_attr "bdver1_decode" "*,double,direct")
4827 (set_attr "fp_int_src" "true")])
4829 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4830 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4832 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4833 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4834 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4837 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4838 [(set_attr "type" "fmov,sseicvt")
4839 (set_attr "prefix" "orig,maybe_vex")
4840 (set_attr "mode" "<MODEF:MODE>")
4841 (set (attr "prefix_rex")
4843 (and (eq_attr "prefix" "maybe_vex")
4844 (match_test "<SWI48:MODE>mode == DImode"))
4846 (const_string "*")))
4847 (set_attr "athlon_decode" "*,direct")
4848 (set_attr "amdfam10_decode" "*,double")
4849 (set_attr "bdver1_decode" "*,direct")
4850 (set_attr "fp_int_src" "true")])
4852 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4853 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4855 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4856 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4857 "TARGET_SSE2 && TARGET_SSE_MATH
4858 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4860 [(set_attr "type" "sseicvt")
4861 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4862 (set_attr "athlon_decode" "double,direct,double")
4863 (set_attr "amdfam10_decode" "vector,double,double")
4864 (set_attr "bdver1_decode" "double,direct,double")
4865 (set_attr "fp_int_src" "true")])
4867 (define_insn "*floatsi<mode>2_vector_sse"
4868 [(set (match_operand:MODEF 0 "register_operand" "=x")
4869 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4870 "TARGET_SSE2 && TARGET_SSE_MATH
4871 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4873 [(set_attr "type" "sseicvt")
4874 (set_attr "mode" "<MODE>")
4875 (set_attr "athlon_decode" "direct")
4876 (set_attr "amdfam10_decode" "double")
4877 (set_attr "bdver1_decode" "direct")
4878 (set_attr "fp_int_src" "true")])
4881 [(set (match_operand:MODEF 0 "register_operand")
4882 (float:MODEF (match_operand:SI 1 "register_operand")))
4883 (clobber (match_operand:SI 2 "memory_operand"))]
4884 "TARGET_SSE2 && TARGET_SSE_MATH
4885 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4886 && reload_completed && SSE_REG_P (operands[0])"
4889 rtx op1 = operands[1];
4891 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4893 if (GET_CODE (op1) == SUBREG)
4894 op1 = SUBREG_REG (op1);
4896 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4898 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4899 emit_insn (gen_sse2_loadld (operands[4],
4900 CONST0_RTX (V4SImode), operands[1]));
4902 /* We can ignore possible trapping value in the
4903 high part of SSE register for non-trapping math. */
4904 else if (SSE_REG_P (op1) && !flag_trapping_math)
4905 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4908 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4909 emit_move_insn (operands[2], operands[1]);
4910 emit_insn (gen_sse2_loadld (operands[4],
4911 CONST0_RTX (V4SImode), operands[2]));
4913 if (<ssevecmode>mode == V4SFmode)
4914 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4916 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4921 [(set (match_operand:MODEF 0 "register_operand")
4922 (float:MODEF (match_operand:SI 1 "memory_operand")))
4923 (clobber (match_operand:SI 2 "memory_operand"))]
4924 "TARGET_SSE2 && TARGET_SSE_MATH
4925 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4926 && reload_completed && SSE_REG_P (operands[0])"
4929 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4931 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4933 emit_insn (gen_sse2_loadld (operands[4],
4934 CONST0_RTX (V4SImode), operands[1]));
4935 if (<ssevecmode>mode == V4SFmode)
4936 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4938 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4943 [(set (match_operand:MODEF 0 "register_operand")
4944 (float:MODEF (match_operand:SI 1 "register_operand")))]
4945 "TARGET_SSE2 && TARGET_SSE_MATH
4946 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4947 && reload_completed && SSE_REG_P (operands[0])"
4950 rtx op1 = operands[1];
4952 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4954 if (GET_CODE (op1) == SUBREG)
4955 op1 = SUBREG_REG (op1);
4957 if (GENERAL_REG_P (op1))
4959 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4960 if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4961 emit_insn (gen_sse2_loadld (operands[4],
4962 CONST0_RTX (V4SImode), operands[1]));
4965 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4967 emit_insn (gen_sse2_loadld (operands[4],
4968 CONST0_RTX (V4SImode), operands[5]));
4969 ix86_free_from_memory (GET_MODE (operands[1]));
4972 /* We can ignore possible trapping value in the
4973 high part of SSE register for non-trapping math. */
4974 else if (SSE_REG_P (op1) && !flag_trapping_math)
4975 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4978 if (<ssevecmode>mode == V4SFmode)
4979 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4981 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4986 [(set (match_operand:MODEF 0 "register_operand")
4987 (float:MODEF (match_operand:SI 1 "memory_operand")))]
4988 "TARGET_SSE2 && TARGET_SSE_MATH
4989 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4990 && reload_completed && SSE_REG_P (operands[0])"
4993 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4995 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4997 emit_insn (gen_sse2_loadld (operands[4],
4998 CONST0_RTX (V4SImode), operands[1]));
4999 if (<ssevecmode>mode == V4SFmode)
5000 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5002 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5006 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
5007 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5009 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
5010 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
5011 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5013 [(set_attr "type" "sseicvt")
5014 (set_attr "mode" "<MODEF:MODE>")
5015 (set_attr "athlon_decode" "double,direct")
5016 (set_attr "amdfam10_decode" "vector,double")
5017 (set_attr "bdver1_decode" "double,direct")
5018 (set_attr "btver2_decode" "double,double")
5019 (set_attr "fp_int_src" "true")])
5021 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
5022 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5024 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
5025 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5026 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5027 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5028 [(set_attr "type" "sseicvt")
5029 (set_attr "prefix" "maybe_vex")
5030 (set_attr "mode" "<MODEF:MODE>")
5031 (set (attr "prefix_rex")
5033 (and (eq_attr "prefix" "maybe_vex")
5034 (match_test "<SWI48:MODE>mode == DImode"))
5036 (const_string "*")))
5037 (set_attr "athlon_decode" "double,direct")
5038 (set_attr "amdfam10_decode" "vector,double")
5039 (set_attr "bdver1_decode" "double,direct")
5040 (set_attr "btver2_decode" "double,double")
5041 (set_attr "fp_int_src" "true")])
5044 [(set (match_operand:MODEF 0 "register_operand")
5045 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
5046 (clobber (match_operand:SWI48 2 "memory_operand"))]
5047 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5048 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5049 && reload_completed && SSE_REG_P (operands[0])"
5050 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5052 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
5053 [(set (match_operand:MODEF 0 "register_operand" "=x")
5055 (match_operand:SWI48 1 "memory_operand" "m")))]
5056 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5057 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5058 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5059 [(set_attr "type" "sseicvt")
5060 (set_attr "prefix" "maybe_vex")
5061 (set_attr "mode" "<MODEF:MODE>")
5062 (set (attr "prefix_rex")
5064 (and (eq_attr "prefix" "maybe_vex")
5065 (match_test "<SWI48:MODE>mode == DImode"))
5067 (const_string "*")))
5068 (set_attr "athlon_decode" "direct")
5069 (set_attr "amdfam10_decode" "double")
5070 (set_attr "bdver1_decode" "direct")
5071 (set_attr "fp_int_src" "true")])
5074 [(set (match_operand:MODEF 0 "register_operand")
5075 (float:MODEF (match_operand:SWI48 1 "register_operand")))
5076 (clobber (match_operand:SWI48 2 "memory_operand"))]
5077 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5078 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5079 && reload_completed && SSE_REG_P (operands[0])"
5080 [(set (match_dup 2) (match_dup 1))
5081 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5084 [(set (match_operand:MODEF 0 "register_operand")
5085 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
5086 (clobber (match_operand:SWI48 2 "memory_operand"))]
5087 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5088 && reload_completed && SSE_REG_P (operands[0])"
5089 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5091 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5092 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5094 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5095 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5097 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5101 [(set_attr "type" "fmov,multi")
5102 (set_attr "mode" "<X87MODEF:MODE>")
5103 (set_attr "unit" "*,i387")
5104 (set_attr "fp_int_src" "true")])
5106 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5107 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5109 (match_operand:SWI48x 1 "memory_operand" "m")))]
5111 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5113 [(set_attr "type" "fmov")
5114 (set_attr "mode" "<X87MODEF:MODE>")
5115 (set_attr "fp_int_src" "true")])
5118 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5119 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5120 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5122 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5123 && reload_completed"
5124 [(set (match_dup 2) (match_dup 1))
5125 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5128 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5129 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5130 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5132 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5133 && reload_completed"
5134 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5136 ;; Avoid partial SSE register dependency stalls
5139 [(set (match_operand:MODEF 0 "register_operand")
5140 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5141 "TARGET_SSE2 && TARGET_SSE_MATH
5142 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5143 && optimize_function_for_speed_p (cfun)
5144 && reload_completed && SSE_REG_P (operands[0])"
5146 (vec_merge:<ssevecmode>
5147 (vec_duplicate:<ssevecmode>
5148 (float:MODEF (match_dup 1)))
5152 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5154 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5158 [(set (match_operand:MODEF 0 "register_operand")
5159 (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
5160 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5161 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5162 && optimize_function_for_speed_p (cfun)
5163 && reload_completed && SSE_REG_P (operands[0])"
5165 (vec_merge:<ssevecmode>
5166 (vec_duplicate:<ssevecmode>
5167 (float:MODEF (match_dup 1)))
5171 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5173 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5176 ;; Break partial reg stall for cvtsd2ss.
5179 [(set (match_operand:SF 0 "register_operand")
5181 (match_operand:DF 1 "nonimmediate_operand")))]
5182 "TARGET_SSE2 && TARGET_SSE_MATH
5183 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5184 && optimize_function_for_speed_p (cfun)
5185 && SSE_REG_P (operands[0])
5186 && (!SSE_REG_P (operands[1])
5187 || REGNO (operands[0]) != REGNO (operands[1]))"
5191 (float_truncate:V2SF
5196 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5198 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5200 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5203 ;; Break partial reg stall for cvtss2sd.
5206 [(set (match_operand:DF 0 "register_operand")
5208 (match_operand:SF 1 "nonimmediate_operand")))]
5209 "TARGET_SSE2 && TARGET_SSE_MATH
5210 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5211 && optimize_function_for_speed_p (cfun)
5212 && SSE_REG_P (operands[0])
5213 && (!SSE_REG_P (operands[1])
5214 || REGNO (operands[0]) != REGNO (operands[1]))"
5220 (parallel [(const_int 0) (const_int 1)])))
5224 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5226 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5228 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5231 ;; Avoid store forwarding (partial memory) stall penalty
5232 ;; by passing DImode value through XMM registers. */
5234 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5235 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5237 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5238 (clobber (match_scratch:V4SI 3 "=X,x"))
5239 (clobber (match_scratch:V4SI 4 "=X,x"))
5240 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5241 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5242 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5243 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5245 [(set_attr "type" "multi")
5246 (set_attr "mode" "<X87MODEF:MODE>")
5247 (set_attr "unit" "i387")
5248 (set_attr "fp_int_src" "true")])
5251 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5252 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5253 (clobber (match_scratch:V4SI 3))
5254 (clobber (match_scratch:V4SI 4))
5255 (clobber (match_operand:DI 2 "memory_operand"))]
5256 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5257 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5258 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5259 && reload_completed"
5260 [(set (match_dup 2) (match_dup 3))
5261 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5263 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5264 Assemble the 64-bit DImode value in an xmm register. */
5265 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5266 gen_rtx_SUBREG (SImode, operands[1], 0)));
5267 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5268 gen_rtx_SUBREG (SImode, operands[1], 4)));
5269 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5272 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5276 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5277 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5278 (clobber (match_scratch:V4SI 3))
5279 (clobber (match_scratch:V4SI 4))
5280 (clobber (match_operand:DI 2 "memory_operand"))]
5281 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5282 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5283 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5284 && reload_completed"
5285 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5287 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5288 [(set (match_operand:MODEF 0 "register_operand")
5289 (unsigned_float:MODEF
5290 (match_operand:SWI12 1 "nonimmediate_operand")))]
5292 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5294 operands[1] = convert_to_mode (SImode, operands[1], 1);
5295 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5299 ;; Avoid store forwarding (partial memory) stall penalty by extending
5300 ;; SImode value to DImode through XMM register instead of pushing two
5301 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5302 ;; targets benefit from this optimization. Also note that fild
5303 ;; loads from memory only.
5305 (define_insn "*floatunssi<mode>2_1"
5306 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5307 (unsigned_float:X87MODEF
5308 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5309 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5310 (clobber (match_scratch:SI 3 "=X,x"))]
5312 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5315 [(set_attr "type" "multi")
5316 (set_attr "mode" "<MODE>")])
5319 [(set (match_operand:X87MODEF 0 "register_operand")
5320 (unsigned_float:X87MODEF
5321 (match_operand:SI 1 "register_operand")))
5322 (clobber (match_operand:DI 2 "memory_operand"))
5323 (clobber (match_scratch:SI 3))]
5325 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5327 && reload_completed"
5328 [(set (match_dup 2) (match_dup 1))
5330 (float:X87MODEF (match_dup 2)))]
5331 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5334 [(set (match_operand:X87MODEF 0 "register_operand")
5335 (unsigned_float:X87MODEF
5336 (match_operand:SI 1 "memory_operand")))
5337 (clobber (match_operand:DI 2 "memory_operand"))
5338 (clobber (match_scratch:SI 3))]
5340 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5342 && reload_completed"
5343 [(set (match_dup 2) (match_dup 3))
5345 (float:X87MODEF (match_dup 2)))]
5347 emit_move_insn (operands[3], operands[1]);
5348 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5351 (define_expand "floatunssi<mode>2"
5353 [(set (match_operand:X87MODEF 0 "register_operand")
5354 (unsigned_float:X87MODEF
5355 (match_operand:SI 1 "nonimmediate_operand")))
5356 (clobber (match_dup 2))
5357 (clobber (match_scratch:SI 3))])]
5359 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5361 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5363 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5365 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5369 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5372 (define_expand "floatunsdisf2"
5373 [(use (match_operand:SF 0 "register_operand"))
5374 (use (match_operand:DI 1 "nonimmediate_operand"))]
5375 "TARGET_64BIT && TARGET_SSE_MATH"
5376 "x86_emit_floatuns (operands); DONE;")
5378 (define_expand "floatunsdidf2"
5379 [(use (match_operand:DF 0 "register_operand"))
5380 (use (match_operand:DI 1 "nonimmediate_operand"))]
5381 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5382 && TARGET_SSE2 && TARGET_SSE_MATH"
5385 x86_emit_floatuns (operands);
5387 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5391 ;; Load effective address instructions
5393 (define_insn_and_split "*lea<mode>"
5394 [(set (match_operand:SWI48 0 "register_operand" "=r")
5395 (match_operand:SWI48 1 "address_no_seg_operand" "p"))]
5398 if (SImode_address_operand (operands[1], VOIDmode))
5400 gcc_assert (TARGET_64BIT);
5401 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5404 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5406 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5409 enum machine_mode mode = <MODE>mode;
5412 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5413 change operands[] array behind our back. */
5414 pat = PATTERN (curr_insn);
5416 operands[0] = SET_DEST (pat);
5417 operands[1] = SET_SRC (pat);
5419 /* Emit all operations in SImode for zero-extended addresses. Recall
5420 that x86_64 inheretly zero-extends SImode operations to DImode. */
5421 if (SImode_address_operand (operands[1], VOIDmode))
5424 ix86_split_lea_for_addr (curr_insn, operands, mode);
5427 [(set_attr "type" "lea")
5430 (match_operand 1 "SImode_address_operand")
5432 (const_string "<MODE>")))])
5436 (define_expand "add<mode>3"
5437 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5438 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5439 (match_operand:SDWIM 2 "<general_operand>")))]
5441 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5443 (define_insn_and_split "*add<dwi>3_doubleword"
5444 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5446 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5447 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5448 (clobber (reg:CC FLAGS_REG))]
5449 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5452 [(parallel [(set (reg:CC FLAGS_REG)
5453 (unspec:CC [(match_dup 1) (match_dup 2)]
5456 (plus:DWIH (match_dup 1) (match_dup 2)))])
5457 (parallel [(set (match_dup 3)
5461 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5463 (clobber (reg:CC FLAGS_REG))])]
5464 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5466 (define_insn "*add<mode>3_cc"
5467 [(set (reg:CC FLAGS_REG)
5469 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5470 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5472 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5473 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5474 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5475 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5476 [(set_attr "type" "alu")
5477 (set_attr "mode" "<MODE>")])
5479 (define_insn "addqi3_cc"
5480 [(set (reg:CC FLAGS_REG)
5482 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5483 (match_operand:QI 2 "general_operand" "qn,qm")]
5485 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5486 (plus:QI (match_dup 1) (match_dup 2)))]
5487 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5488 "add{b}\t{%2, %0|%0, %2}"
5489 [(set_attr "type" "alu")
5490 (set_attr "mode" "QI")])
5492 (define_insn "*add<mode>_1"
5493 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5495 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5496 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5497 (clobber (reg:CC FLAGS_REG))]
5498 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5500 switch (get_attr_type (insn))
5506 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5507 if (operands[2] == const1_rtx)
5508 return "inc{<imodesuffix>}\t%0";
5511 gcc_assert (operands[2] == constm1_rtx);
5512 return "dec{<imodesuffix>}\t%0";
5516 /* For most processors, ADD is faster than LEA. This alternative
5517 was added to use ADD as much as possible. */
5518 if (which_alternative == 2)
5521 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5524 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5525 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5526 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5528 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5532 (cond [(eq_attr "alternative" "3")
5533 (const_string "lea")
5534 (match_operand:SWI48 2 "incdec_operand")
5535 (const_string "incdec")
5537 (const_string "alu")))
5538 (set (attr "length_immediate")
5540 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5542 (const_string "*")))
5543 (set_attr "mode" "<MODE>")])
5545 ;; It may seem that nonimmediate operand is proper one for operand 1.
5546 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5547 ;; we take care in ix86_binary_operator_ok to not allow two memory
5548 ;; operands so proper swapping will be done in reload. This allow
5549 ;; patterns constructed from addsi_1 to match.
5551 (define_insn "addsi_1_zext"
5552 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5554 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5555 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5556 (clobber (reg:CC FLAGS_REG))]
5557 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5559 switch (get_attr_type (insn))
5565 if (operands[2] == const1_rtx)
5566 return "inc{l}\t%k0";
5569 gcc_assert (operands[2] == constm1_rtx);
5570 return "dec{l}\t%k0";
5574 /* For most processors, ADD is faster than LEA. This alternative
5575 was added to use ADD as much as possible. */
5576 if (which_alternative == 1)
5579 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5582 if (x86_maybe_negate_const_int (&operands[2], SImode))
5583 return "sub{l}\t{%2, %k0|%k0, %2}";
5585 return "add{l}\t{%2, %k0|%k0, %2}";
5589 (cond [(eq_attr "alternative" "2")
5590 (const_string "lea")
5591 (match_operand:SI 2 "incdec_operand")
5592 (const_string "incdec")
5594 (const_string "alu")))
5595 (set (attr "length_immediate")
5597 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5599 (const_string "*")))
5600 (set_attr "mode" "SI")])
5602 (define_insn "*addhi_1"
5603 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5604 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5605 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5606 (clobber (reg:CC FLAGS_REG))]
5607 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5609 switch (get_attr_type (insn))
5615 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5616 if (operands[2] == const1_rtx)
5617 return "inc{w}\t%0";
5620 gcc_assert (operands[2] == constm1_rtx);
5621 return "dec{w}\t%0";
5625 /* For most processors, ADD is faster than LEA. This alternative
5626 was added to use ADD as much as possible. */
5627 if (which_alternative == 2)
5630 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5633 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634 if (x86_maybe_negate_const_int (&operands[2], HImode))
5635 return "sub{w}\t{%2, %0|%0, %2}";
5637 return "add{w}\t{%2, %0|%0, %2}";
5641 (cond [(eq_attr "alternative" "3")
5642 (const_string "lea")
5643 (match_operand:HI 2 "incdec_operand")
5644 (const_string "incdec")
5646 (const_string "alu")))
5647 (set (attr "length_immediate")
5649 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5651 (const_string "*")))
5652 (set_attr "mode" "HI,HI,HI,SI")])
5654 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5655 (define_insn "*addqi_1"
5656 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5657 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5658 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5659 (clobber (reg:CC FLAGS_REG))]
5660 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5662 bool widen = (which_alternative == 3 || which_alternative == 4);
5664 switch (get_attr_type (insn))
5670 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5671 if (operands[2] == const1_rtx)
5672 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5675 gcc_assert (operands[2] == constm1_rtx);
5676 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5680 /* For most processors, ADD is faster than LEA. These alternatives
5681 were added to use ADD as much as possible. */
5682 if (which_alternative == 2 || which_alternative == 4)
5685 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689 if (x86_maybe_negate_const_int (&operands[2], QImode))
5692 return "sub{l}\t{%2, %k0|%k0, %2}";
5694 return "sub{b}\t{%2, %0|%0, %2}";
5697 return "add{l}\t{%k2, %k0|%k0, %k2}";
5699 return "add{b}\t{%2, %0|%0, %2}";
5703 (cond [(eq_attr "alternative" "5")
5704 (const_string "lea")
5705 (match_operand:QI 2 "incdec_operand")
5706 (const_string "incdec")
5708 (const_string "alu")))
5709 (set (attr "length_immediate")
5711 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5713 (const_string "*")))
5714 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5716 (define_insn "*addqi_1_slp"
5717 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5718 (plus:QI (match_dup 0)
5719 (match_operand:QI 1 "general_operand" "qn,qm")))
5720 (clobber (reg:CC FLAGS_REG))]
5721 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5722 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5724 switch (get_attr_type (insn))
5727 if (operands[1] == const1_rtx)
5728 return "inc{b}\t%0";
5731 gcc_assert (operands[1] == constm1_rtx);
5732 return "dec{b}\t%0";
5736 if (x86_maybe_negate_const_int (&operands[1], QImode))
5737 return "sub{b}\t{%1, %0|%0, %1}";
5739 return "add{b}\t{%1, %0|%0, %1}";
5743 (if_then_else (match_operand:QI 1 "incdec_operand")
5744 (const_string "incdec")
5745 (const_string "alu1")))
5746 (set (attr "memory")
5747 (if_then_else (match_operand 1 "memory_operand")
5748 (const_string "load")
5749 (const_string "none")))
5750 (set_attr "mode" "QI")])
5752 ;; Split non destructive adds if we cannot use lea.
5754 [(set (match_operand:SWI48 0 "register_operand")
5755 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5756 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5757 (clobber (reg:CC FLAGS_REG))]
5758 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5759 [(set (match_dup 0) (match_dup 1))
5760 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5761 (clobber (reg:CC FLAGS_REG))])])
5763 ;; Convert add to the lea pattern to avoid flags dependency.
5765 [(set (match_operand:SWI 0 "register_operand")
5766 (plus:SWI (match_operand:SWI 1 "register_operand")
5767 (match_operand:SWI 2 "<nonmemory_operand>")))
5768 (clobber (reg:CC FLAGS_REG))]
5769 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5772 enum machine_mode mode = <MODE>mode;
5775 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5778 operands[0] = gen_lowpart (mode, operands[0]);
5779 operands[1] = gen_lowpart (mode, operands[1]);
5780 operands[2] = gen_lowpart (mode, operands[2]);
5783 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5785 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5789 ;; Split non destructive adds if we cannot use lea.
5791 [(set (match_operand:DI 0 "register_operand")
5793 (plus:SI (match_operand:SI 1 "register_operand")
5794 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5795 (clobber (reg:CC FLAGS_REG))]
5797 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5798 [(set (match_dup 3) (match_dup 1))
5799 (parallel [(set (match_dup 0)
5800 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5801 (clobber (reg:CC FLAGS_REG))])]
5802 "operands[3] = gen_lowpart (SImode, operands[0]);")
5804 ;; Convert add to the lea pattern to avoid flags dependency.
5806 [(set (match_operand:DI 0 "register_operand")
5808 (plus:SI (match_operand:SI 1 "register_operand")
5809 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5810 (clobber (reg:CC FLAGS_REG))]
5811 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5813 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5815 (define_insn "*add<mode>_2"
5816 [(set (reg FLAGS_REG)
5819 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5820 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5822 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5823 (plus:SWI (match_dup 1) (match_dup 2)))]
5824 "ix86_match_ccmode (insn, CCGOCmode)
5825 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5827 switch (get_attr_type (insn))
5830 if (operands[2] == const1_rtx)
5831 return "inc{<imodesuffix>}\t%0";
5834 gcc_assert (operands[2] == constm1_rtx);
5835 return "dec{<imodesuffix>}\t%0";
5839 if (which_alternative == 2)
5842 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5845 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5846 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5847 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5849 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5853 (if_then_else (match_operand:SWI 2 "incdec_operand")
5854 (const_string "incdec")
5855 (const_string "alu")))
5856 (set (attr "length_immediate")
5858 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5860 (const_string "*")))
5861 (set_attr "mode" "<MODE>")])
5863 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5864 (define_insn "*addsi_2_zext"
5865 [(set (reg FLAGS_REG)
5867 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5868 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5870 (set (match_operand:DI 0 "register_operand" "=r,r")
5871 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5872 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5873 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5875 switch (get_attr_type (insn))
5878 if (operands[2] == const1_rtx)
5879 return "inc{l}\t%k0";
5882 gcc_assert (operands[2] == constm1_rtx);
5883 return "dec{l}\t%k0";
5887 if (which_alternative == 1)
5890 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5893 if (x86_maybe_negate_const_int (&operands[2], SImode))
5894 return "sub{l}\t{%2, %k0|%k0, %2}";
5896 return "add{l}\t{%2, %k0|%k0, %2}";
5900 (if_then_else (match_operand:SI 2 "incdec_operand")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set (attr "length_immediate")
5905 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5907 (const_string "*")))
5908 (set_attr "mode" "SI")])
5910 (define_insn "*add<mode>_3"
5911 [(set (reg FLAGS_REG)
5913 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5914 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5915 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5916 "ix86_match_ccmode (insn, CCZmode)
5917 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5919 switch (get_attr_type (insn))
5922 if (operands[2] == const1_rtx)
5923 return "inc{<imodesuffix>}\t%0";
5926 gcc_assert (operands[2] == constm1_rtx);
5927 return "dec{<imodesuffix>}\t%0";
5931 if (which_alternative == 1)
5934 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5937 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5938 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5939 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5941 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5945 (if_then_else (match_operand:SWI 2 "incdec_operand")
5946 (const_string "incdec")
5947 (const_string "alu")))
5948 (set (attr "length_immediate")
5950 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5952 (const_string "*")))
5953 (set_attr "mode" "<MODE>")])
5955 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5956 (define_insn "*addsi_3_zext"
5957 [(set (reg FLAGS_REG)
5959 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5960 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5961 (set (match_operand:DI 0 "register_operand" "=r,r")
5962 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5963 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5964 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5966 switch (get_attr_type (insn))
5969 if (operands[2] == const1_rtx)
5970 return "inc{l}\t%k0";
5973 gcc_assert (operands[2] == constm1_rtx);
5974 return "dec{l}\t%k0";
5978 if (which_alternative == 1)
5981 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5984 if (x86_maybe_negate_const_int (&operands[2], SImode))
5985 return "sub{l}\t{%2, %k0|%k0, %2}";
5987 return "add{l}\t{%2, %k0|%k0, %2}";
5991 (if_then_else (match_operand:SI 2 "incdec_operand")
5992 (const_string "incdec")
5993 (const_string "alu")))
5994 (set (attr "length_immediate")
5996 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5998 (const_string "*")))
5999 (set_attr "mode" "SI")])
6001 ; For comparisons against 1, -1 and 128, we may generate better code
6002 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6003 ; is matched then. We can't accept general immediate, because for
6004 ; case of overflows, the result is messed up.
6005 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6006 ; only for comparisons not depending on it.
6008 (define_insn "*adddi_4"
6009 [(set (reg FLAGS_REG)
6011 (match_operand:DI 1 "nonimmediate_operand" "0")
6012 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6013 (clobber (match_scratch:DI 0 "=rm"))]
6015 && ix86_match_ccmode (insn, CCGCmode)"
6017 switch (get_attr_type (insn))
6020 if (operands[2] == constm1_rtx)
6021 return "inc{q}\t%0";
6024 gcc_assert (operands[2] == const1_rtx);
6025 return "dec{q}\t%0";
6029 if (x86_maybe_negate_const_int (&operands[2], DImode))
6030 return "add{q}\t{%2, %0|%0, %2}";
6032 return "sub{q}\t{%2, %0|%0, %2}";
6036 (if_then_else (match_operand:DI 2 "incdec_operand")
6037 (const_string "incdec")
6038 (const_string "alu")))
6039 (set (attr "length_immediate")
6041 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6043 (const_string "*")))
6044 (set_attr "mode" "DI")])
6046 ; For comparisons against 1, -1 and 128, we may generate better code
6047 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6048 ; is matched then. We can't accept general immediate, because for
6049 ; case of overflows, the result is messed up.
6050 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6051 ; only for comparisons not depending on it.
6053 (define_insn "*add<mode>_4"
6054 [(set (reg FLAGS_REG)
6056 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6057 (match_operand:SWI124 2 "const_int_operand" "n")))
6058 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6059 "ix86_match_ccmode (insn, CCGCmode)"
6061 switch (get_attr_type (insn))
6064 if (operands[2] == constm1_rtx)
6065 return "inc{<imodesuffix>}\t%0";
6068 gcc_assert (operands[2] == const1_rtx);
6069 return "dec{<imodesuffix>}\t%0";
6073 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6074 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6076 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6080 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6081 (const_string "incdec")
6082 (const_string "alu")))
6083 (set (attr "length_immediate")
6085 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6087 (const_string "*")))
6088 (set_attr "mode" "<MODE>")])
6090 (define_insn "*add<mode>_5"
6091 [(set (reg FLAGS_REG)
6094 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6095 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6097 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6098 "ix86_match_ccmode (insn, CCGOCmode)
6099 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6101 switch (get_attr_type (insn))
6104 if (operands[2] == const1_rtx)
6105 return "inc{<imodesuffix>}\t%0";
6108 gcc_assert (operands[2] == constm1_rtx);
6109 return "dec{<imodesuffix>}\t%0";
6113 if (which_alternative == 1)
6116 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6119 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6120 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6121 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6123 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6127 (if_then_else (match_operand:SWI 2 "incdec_operand")
6128 (const_string "incdec")
6129 (const_string "alu")))
6130 (set (attr "length_immediate")
6132 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6134 (const_string "*")))
6135 (set_attr "mode" "<MODE>")])
6137 (define_insn "addqi_ext_1"
6138 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6143 (match_operand 1 "ext_register_operand" "0,0")
6146 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6147 (clobber (reg:CC FLAGS_REG))]
6150 switch (get_attr_type (insn))
6153 if (operands[2] == const1_rtx)
6154 return "inc{b}\t%h0";
6157 gcc_assert (operands[2] == constm1_rtx);
6158 return "dec{b}\t%h0";
6162 return "add{b}\t{%2, %h0|%h0, %2}";
6165 [(set_attr "isa" "*,nox64")
6167 (if_then_else (match_operand:QI 2 "incdec_operand")
6168 (const_string "incdec")
6169 (const_string "alu")))
6170 (set_attr "modrm" "1")
6171 (set_attr "mode" "QI")])
6173 (define_insn "*addqi_ext_2"
6174 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6179 (match_operand 1 "ext_register_operand" "%0")
6183 (match_operand 2 "ext_register_operand" "Q")
6186 (clobber (reg:CC FLAGS_REG))]
6188 "add{b}\t{%h2, %h0|%h0, %h2}"
6189 [(set_attr "type" "alu")
6190 (set_attr "mode" "QI")])
6192 ;; The lea patterns for modes less than 32 bits need to be matched by
6193 ;; several insns converted to real lea by splitters.
6195 (define_insn_and_split "*lea_general_1"
6196 [(set (match_operand 0 "register_operand" "=r")
6197 (plus (plus (match_operand 1 "index_register_operand" "l")
6198 (match_operand 2 "register_operand" "r"))
6199 (match_operand 3 "immediate_operand" "i")))]
6200 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6201 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6202 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6203 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6204 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6205 || GET_MODE (operands[3]) == VOIDmode)"
6207 "&& reload_completed"
6210 enum machine_mode mode = SImode;
6213 operands[0] = gen_lowpart (mode, operands[0]);
6214 operands[1] = gen_lowpart (mode, operands[1]);
6215 operands[2] = gen_lowpart (mode, operands[2]);
6216 operands[3] = gen_lowpart (mode, operands[3]);
6218 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6221 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6224 [(set_attr "type" "lea")
6225 (set_attr "mode" "SI")])
6227 (define_insn_and_split "*lea_general_2"
6228 [(set (match_operand 0 "register_operand" "=r")
6229 (plus (mult (match_operand 1 "index_register_operand" "l")
6230 (match_operand 2 "const248_operand" "n"))
6231 (match_operand 3 "nonmemory_operand" "ri")))]
6232 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6233 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6234 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6235 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6236 || GET_MODE (operands[3]) == VOIDmode)"
6238 "&& reload_completed"
6241 enum machine_mode mode = SImode;
6244 operands[0] = gen_lowpart (mode, operands[0]);
6245 operands[1] = gen_lowpart (mode, operands[1]);
6246 operands[3] = gen_lowpart (mode, operands[3]);
6248 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6251 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6254 [(set_attr "type" "lea")
6255 (set_attr "mode" "SI")])
6257 (define_insn_and_split "*lea_general_3"
6258 [(set (match_operand 0 "register_operand" "=r")
6259 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6260 (match_operand 2 "const248_operand" "n"))
6261 (match_operand 3 "register_operand" "r"))
6262 (match_operand 4 "immediate_operand" "i")))]
6263 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6264 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6265 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6266 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6268 "&& reload_completed"
6271 enum machine_mode mode = SImode;
6274 operands[0] = gen_lowpart (mode, operands[0]);
6275 operands[1] = gen_lowpart (mode, operands[1]);
6276 operands[3] = gen_lowpart (mode, operands[3]);
6277 operands[4] = gen_lowpart (mode, operands[4]);
6279 pat = gen_rtx_PLUS (mode,
6281 gen_rtx_MULT (mode, operands[1],
6286 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6289 [(set_attr "type" "lea")
6290 (set_attr "mode" "SI")])
6292 (define_insn_and_split "*lea_general_4"
6293 [(set (match_operand 0 "register_operand" "=r")
6295 (match_operand 1 "index_register_operand" "l")
6296 (match_operand 2 "const_int_operand" "n"))
6297 (match_operand 3 "const_int_operand" "n")))]
6298 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6299 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6300 || GET_MODE (operands[0]) == SImode
6301 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6302 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6303 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6304 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6305 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6307 "&& reload_completed"
6310 enum machine_mode mode = GET_MODE (operands[0]);
6313 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6316 operands[0] = gen_lowpart (mode, operands[0]);
6317 operands[1] = gen_lowpart (mode, operands[1]);
6320 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6322 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6323 INTVAL (operands[3]));
6325 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6328 [(set_attr "type" "lea")
6330 (if_then_else (match_operand:DI 0)
6332 (const_string "SI")))])
6334 ;; Subtract instructions
6336 (define_expand "sub<mode>3"
6337 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6338 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6339 (match_operand:SDWIM 2 "<general_operand>")))]
6341 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6343 (define_insn_and_split "*sub<dwi>3_doubleword"
6344 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6346 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6347 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6348 (clobber (reg:CC FLAGS_REG))]
6349 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6352 [(parallel [(set (reg:CC FLAGS_REG)
6353 (compare:CC (match_dup 1) (match_dup 2)))
6355 (minus:DWIH (match_dup 1) (match_dup 2)))])
6356 (parallel [(set (match_dup 3)
6360 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6362 (clobber (reg:CC FLAGS_REG))])]
6363 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6365 (define_insn "*sub<mode>_1"
6366 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6368 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6369 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6370 (clobber (reg:CC FLAGS_REG))]
6371 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6372 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6373 [(set_attr "type" "alu")
6374 (set_attr "mode" "<MODE>")])
6376 (define_insn "*subsi_1_zext"
6377 [(set (match_operand:DI 0 "register_operand" "=r")
6379 (minus:SI (match_operand:SI 1 "register_operand" "0")
6380 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6381 (clobber (reg:CC FLAGS_REG))]
6382 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6383 "sub{l}\t{%2, %k0|%k0, %2}"
6384 [(set_attr "type" "alu")
6385 (set_attr "mode" "SI")])
6387 (define_insn "*subqi_1_slp"
6388 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6389 (minus:QI (match_dup 0)
6390 (match_operand:QI 1 "general_operand" "qn,qm")))
6391 (clobber (reg:CC FLAGS_REG))]
6392 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6393 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6394 "sub{b}\t{%1, %0|%0, %1}"
6395 [(set_attr "type" "alu1")
6396 (set_attr "mode" "QI")])
6398 (define_insn "*sub<mode>_2"
6399 [(set (reg FLAGS_REG)
6402 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6403 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6405 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6406 (minus:SWI (match_dup 1) (match_dup 2)))]
6407 "ix86_match_ccmode (insn, CCGOCmode)
6408 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6409 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6410 [(set_attr "type" "alu")
6411 (set_attr "mode" "<MODE>")])
6413 (define_insn "*subsi_2_zext"
6414 [(set (reg FLAGS_REG)
6416 (minus:SI (match_operand:SI 1 "register_operand" "0")
6417 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6419 (set (match_operand:DI 0 "register_operand" "=r")
6421 (minus:SI (match_dup 1)
6423 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6424 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6425 "sub{l}\t{%2, %k0|%k0, %2}"
6426 [(set_attr "type" "alu")
6427 (set_attr "mode" "SI")])
6429 (define_insn "*sub<mode>_3"
6430 [(set (reg FLAGS_REG)
6431 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6432 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6433 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6434 (minus:SWI (match_dup 1) (match_dup 2)))]
6435 "ix86_match_ccmode (insn, CCmode)
6436 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6437 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6438 [(set_attr "type" "alu")
6439 (set_attr "mode" "<MODE>")])
6441 (define_insn "*subsi_3_zext"
6442 [(set (reg FLAGS_REG)
6443 (compare (match_operand:SI 1 "register_operand" "0")
6444 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6445 (set (match_operand:DI 0 "register_operand" "=r")
6447 (minus:SI (match_dup 1)
6449 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6450 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6451 "sub{l}\t{%2, %1|%1, %2}"
6452 [(set_attr "type" "alu")
6453 (set_attr "mode" "SI")])
6455 ;; Add with carry and subtract with borrow
6457 (define_expand "<plusminus_insn><mode>3_carry"
6459 [(set (match_operand:SWI 0 "nonimmediate_operand")
6461 (match_operand:SWI 1 "nonimmediate_operand")
6462 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6463 [(match_operand 3 "flags_reg_operand")
6465 (match_operand:SWI 2 "<general_operand>"))))
6466 (clobber (reg:CC FLAGS_REG))])]
6467 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6469 (define_insn "*<plusminus_insn><mode>3_carry"
6470 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6472 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6474 (match_operator 3 "ix86_carry_flag_operator"
6475 [(reg FLAGS_REG) (const_int 0)])
6476 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6477 (clobber (reg:CC FLAGS_REG))]
6478 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6479 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6480 [(set_attr "type" "alu")
6481 (set_attr "use_carry" "1")
6482 (set_attr "pent_pair" "pu")
6483 (set_attr "mode" "<MODE>")])
6485 (define_insn "*addsi3_carry_zext"
6486 [(set (match_operand:DI 0 "register_operand" "=r")
6488 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6489 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6490 [(reg FLAGS_REG) (const_int 0)])
6491 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6492 (clobber (reg:CC FLAGS_REG))]
6493 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6494 "adc{l}\t{%2, %k0|%k0, %2}"
6495 [(set_attr "type" "alu")
6496 (set_attr "use_carry" "1")
6497 (set_attr "pent_pair" "pu")
6498 (set_attr "mode" "SI")])
6500 (define_insn "*subsi3_carry_zext"
6501 [(set (match_operand:DI 0 "register_operand" "=r")
6503 (minus:SI (match_operand:SI 1 "register_operand" "0")
6504 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6505 [(reg FLAGS_REG) (const_int 0)])
6506 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6507 (clobber (reg:CC FLAGS_REG))]
6508 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6509 "sbb{l}\t{%2, %k0|%k0, %2}"
6510 [(set_attr "type" "alu")
6511 (set_attr "pent_pair" "pu")
6512 (set_attr "mode" "SI")])
6516 (define_insn "adcx<mode>3"
6517 [(set (reg:CCC FLAGS_REG)
6520 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6522 (match_operator 4 "ix86_carry_flag_operator"
6523 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6524 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6526 (set (match_operand:SWI48 0 "register_operand" "=r")
6527 (plus:SWI48 (match_dup 1)
6528 (plus:SWI48 (match_op_dup 4
6529 [(match_dup 3) (const_int 0)])
6531 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6532 "adcx\t{%2, %0|%0, %2}"
6533 [(set_attr "type" "alu")
6534 (set_attr "use_carry" "1")
6535 (set_attr "mode" "<MODE>")])
6537 ;; Overflow setting add instructions
6539 (define_insn "*add<mode>3_cconly_overflow"
6540 [(set (reg:CCC FLAGS_REG)
6543 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6544 (match_operand:SWI 2 "<general_operand>" "<g>"))
6546 (clobber (match_scratch:SWI 0 "=<r>"))]
6547 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6548 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6549 [(set_attr "type" "alu")
6550 (set_attr "mode" "<MODE>")])
6552 (define_insn "*add<mode>3_cc_overflow"
6553 [(set (reg:CCC FLAGS_REG)
6556 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6557 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6559 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6560 (plus:SWI (match_dup 1) (match_dup 2)))]
6561 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6562 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6563 [(set_attr "type" "alu")
6564 (set_attr "mode" "<MODE>")])
6566 (define_insn "*addsi3_zext_cc_overflow"
6567 [(set (reg:CCC FLAGS_REG)
6570 (match_operand:SI 1 "nonimmediate_operand" "%0")
6571 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6573 (set (match_operand:DI 0 "register_operand" "=r")
6574 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6575 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6576 "add{l}\t{%2, %k0|%k0, %2}"
6577 [(set_attr "type" "alu")
6578 (set_attr "mode" "SI")])
6580 ;; The patterns that match these are at the end of this file.
6582 (define_expand "<plusminus_insn>xf3"
6583 [(set (match_operand:XF 0 "register_operand")
6585 (match_operand:XF 1 "register_operand")
6586 (match_operand:XF 2 "register_operand")))]
6589 (define_expand "<plusminus_insn><mode>3"
6590 [(set (match_operand:MODEF 0 "register_operand")
6592 (match_operand:MODEF 1 "register_operand")
6593 (match_operand:MODEF 2 "nonimmediate_operand")))]
6594 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6595 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6597 ;; Multiply instructions
6599 (define_expand "mul<mode>3"
6600 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6602 (match_operand:SWIM248 1 "register_operand")
6603 (match_operand:SWIM248 2 "<general_operand>")))
6604 (clobber (reg:CC FLAGS_REG))])])
6606 (define_expand "mulqi3"
6607 [(parallel [(set (match_operand:QI 0 "register_operand")
6609 (match_operand:QI 1 "register_operand")
6610 (match_operand:QI 2 "nonimmediate_operand")))
6611 (clobber (reg:CC FLAGS_REG))])]
6612 "TARGET_QIMODE_MATH")
6615 ;; IMUL reg32/64, reg32/64, imm8 Direct
6616 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6617 ;; IMUL reg32/64, reg32/64, imm32 Direct
6618 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6619 ;; IMUL reg32/64, reg32/64 Direct
6620 ;; IMUL reg32/64, mem32/64 Direct
6622 ;; On BDVER1, all above IMULs use DirectPath
6624 (define_insn "*mul<mode>3_1"
6625 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6627 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6628 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6629 (clobber (reg:CC FLAGS_REG))]
6630 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6632 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6633 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6634 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6635 [(set_attr "type" "imul")
6636 (set_attr "prefix_0f" "0,0,1")
6637 (set (attr "athlon_decode")
6638 (cond [(eq_attr "cpu" "athlon")
6639 (const_string "vector")
6640 (eq_attr "alternative" "1")
6641 (const_string "vector")
6642 (and (eq_attr "alternative" "2")
6643 (match_operand 1 "memory_operand"))
6644 (const_string "vector")]
6645 (const_string "direct")))
6646 (set (attr "amdfam10_decode")
6647 (cond [(and (eq_attr "alternative" "0,1")
6648 (match_operand 1 "memory_operand"))
6649 (const_string "vector")]
6650 (const_string "direct")))
6651 (set_attr "bdver1_decode" "direct")
6652 (set_attr "mode" "<MODE>")])
6654 (define_insn "*mulsi3_1_zext"
6655 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6657 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6658 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6659 (clobber (reg:CC FLAGS_REG))]
6661 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6663 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6664 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6665 imul{l}\t{%2, %k0|%k0, %2}"
6666 [(set_attr "type" "imul")
6667 (set_attr "prefix_0f" "0,0,1")
6668 (set (attr "athlon_decode")
6669 (cond [(eq_attr "cpu" "athlon")
6670 (const_string "vector")
6671 (eq_attr "alternative" "1")
6672 (const_string "vector")
6673 (and (eq_attr "alternative" "2")
6674 (match_operand 1 "memory_operand"))
6675 (const_string "vector")]
6676 (const_string "direct")))
6677 (set (attr "amdfam10_decode")
6678 (cond [(and (eq_attr "alternative" "0,1")
6679 (match_operand 1 "memory_operand"))
6680 (const_string "vector")]
6681 (const_string "direct")))
6682 (set_attr "bdver1_decode" "direct")
6683 (set_attr "mode" "SI")])
6686 ;; IMUL reg16, reg16, imm8 VectorPath
6687 ;; IMUL reg16, mem16, imm8 VectorPath
6688 ;; IMUL reg16, reg16, imm16 VectorPath
6689 ;; IMUL reg16, mem16, imm16 VectorPath
6690 ;; IMUL reg16, reg16 Direct
6691 ;; IMUL reg16, mem16 Direct
6693 ;; On BDVER1, all HI MULs use DoublePath
6695 (define_insn "*mulhi3_1"
6696 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6697 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6698 (match_operand:HI 2 "general_operand" "K,n,mr")))
6699 (clobber (reg:CC FLAGS_REG))]
6701 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6703 imul{w}\t{%2, %1, %0|%0, %1, %2}
6704 imul{w}\t{%2, %1, %0|%0, %1, %2}
6705 imul{w}\t{%2, %0|%0, %2}"
6706 [(set_attr "type" "imul")
6707 (set_attr "prefix_0f" "0,0,1")
6708 (set (attr "athlon_decode")
6709 (cond [(eq_attr "cpu" "athlon")
6710 (const_string "vector")
6711 (eq_attr "alternative" "1,2")
6712 (const_string "vector")]
6713 (const_string "direct")))
6714 (set (attr "amdfam10_decode")
6715 (cond [(eq_attr "alternative" "0,1")
6716 (const_string "vector")]
6717 (const_string "direct")))
6718 (set_attr "bdver1_decode" "double")
6719 (set_attr "mode" "HI")])
6721 ;;On AMDFAM10 and BDVER1
6725 (define_insn "*mulqi3_1"
6726 [(set (match_operand:QI 0 "register_operand" "=a")
6727 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6728 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6729 (clobber (reg:CC FLAGS_REG))]
6731 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6733 [(set_attr "type" "imul")
6734 (set_attr "length_immediate" "0")
6735 (set (attr "athlon_decode")
6736 (if_then_else (eq_attr "cpu" "athlon")
6737 (const_string "vector")
6738 (const_string "direct")))
6739 (set_attr "amdfam10_decode" "direct")
6740 (set_attr "bdver1_decode" "direct")
6741 (set_attr "mode" "QI")])
6743 (define_expand "<u>mul<mode><dwi>3"
6744 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6747 (match_operand:DWIH 1 "nonimmediate_operand"))
6749 (match_operand:DWIH 2 "register_operand"))))
6750 (clobber (reg:CC FLAGS_REG))])])
6752 (define_expand "<u>mulqihi3"
6753 [(parallel [(set (match_operand:HI 0 "register_operand")
6756 (match_operand:QI 1 "nonimmediate_operand"))
6758 (match_operand:QI 2 "register_operand"))))
6759 (clobber (reg:CC FLAGS_REG))])]
6760 "TARGET_QIMODE_MATH")
6762 (define_insn "*bmi2_umulditi3_1"
6763 [(set (match_operand:DI 0 "register_operand" "=r")
6765 (match_operand:DI 2 "nonimmediate_operand" "%d")
6766 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6767 (set (match_operand:DI 1 "register_operand" "=r")
6770 (mult:TI (zero_extend:TI (match_dup 2))
6771 (zero_extend:TI (match_dup 3)))
6773 "TARGET_64BIT && TARGET_BMI2
6774 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6775 "mulx\t{%3, %0, %1|%1, %0, %3}"
6776 [(set_attr "type" "imulx")
6777 (set_attr "prefix" "vex")
6778 (set_attr "mode" "DI")])
6780 (define_insn "*bmi2_umulsidi3_1"
6781 [(set (match_operand:SI 0 "register_operand" "=r")
6783 (match_operand:SI 2 "nonimmediate_operand" "%d")
6784 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6785 (set (match_operand:SI 1 "register_operand" "=r")
6788 (mult:DI (zero_extend:DI (match_dup 2))
6789 (zero_extend:DI (match_dup 3)))
6791 "!TARGET_64BIT && TARGET_BMI2
6792 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6793 "mulx\t{%3, %0, %1|%1, %0, %3}"
6794 [(set_attr "type" "imulx")
6795 (set_attr "prefix" "vex")
6796 (set_attr "mode" "SI")])
6798 (define_insn "*umul<mode><dwi>3_1"
6799 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6802 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6804 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6805 (clobber (reg:CC FLAGS_REG))]
6806 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6809 mul{<imodesuffix>}\t%2"
6810 [(set_attr "isa" "bmi2,*")
6811 (set_attr "type" "imulx,imul")
6812 (set_attr "length_immediate" "*,0")
6813 (set (attr "athlon_decode")
6814 (cond [(eq_attr "alternative" "1")
6815 (if_then_else (eq_attr "cpu" "athlon")
6816 (const_string "vector")
6817 (const_string "double"))]
6818 (const_string "*")))
6819 (set_attr "amdfam10_decode" "*,double")
6820 (set_attr "bdver1_decode" "*,direct")
6821 (set_attr "prefix" "vex,orig")
6822 (set_attr "mode" "<MODE>")])
6824 ;; Convert mul to the mulx pattern to avoid flags dependency.
6826 [(set (match_operand:<DWI> 0 "register_operand")
6829 (match_operand:DWIH 1 "register_operand"))
6831 (match_operand:DWIH 2 "nonimmediate_operand"))))
6832 (clobber (reg:CC FLAGS_REG))]
6833 "TARGET_BMI2 && reload_completed
6834 && true_regnum (operands[1]) == DX_REG"
6835 [(parallel [(set (match_dup 3)
6836 (mult:DWIH (match_dup 1) (match_dup 2)))
6840 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6841 (zero_extend:<DWI> (match_dup 2)))
6844 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6846 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6849 (define_insn "*mul<mode><dwi>3_1"
6850 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6853 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6855 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6856 (clobber (reg:CC FLAGS_REG))]
6857 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6858 "imul{<imodesuffix>}\t%2"
6859 [(set_attr "type" "imul")
6860 (set_attr "length_immediate" "0")
6861 (set (attr "athlon_decode")
6862 (if_then_else (eq_attr "cpu" "athlon")
6863 (const_string "vector")
6864 (const_string "double")))
6865 (set_attr "amdfam10_decode" "double")
6866 (set_attr "bdver1_decode" "direct")
6867 (set_attr "mode" "<MODE>")])
6869 (define_insn "*<u>mulqihi3_1"
6870 [(set (match_operand:HI 0 "register_operand" "=a")
6873 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6875 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6876 (clobber (reg:CC FLAGS_REG))]
6878 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6879 "<sgnprefix>mul{b}\t%2"
6880 [(set_attr "type" "imul")
6881 (set_attr "length_immediate" "0")
6882 (set (attr "athlon_decode")
6883 (if_then_else (eq_attr "cpu" "athlon")
6884 (const_string "vector")
6885 (const_string "direct")))
6886 (set_attr "amdfam10_decode" "direct")
6887 (set_attr "bdver1_decode" "direct")
6888 (set_attr "mode" "QI")])
6890 (define_expand "<s>mul<mode>3_highpart"
6891 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6896 (match_operand:SWI48 1 "nonimmediate_operand"))
6898 (match_operand:SWI48 2 "register_operand")))
6900 (clobber (match_scratch:SWI48 3))
6901 (clobber (reg:CC FLAGS_REG))])]
6903 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6905 (define_insn "*<s>muldi3_highpart_1"
6906 [(set (match_operand:DI 0 "register_operand" "=d")
6911 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6913 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6915 (clobber (match_scratch:DI 3 "=1"))
6916 (clobber (reg:CC FLAGS_REG))]
6918 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6919 "<sgnprefix>mul{q}\t%2"
6920 [(set_attr "type" "imul")
6921 (set_attr "length_immediate" "0")
6922 (set (attr "athlon_decode")
6923 (if_then_else (eq_attr "cpu" "athlon")
6924 (const_string "vector")
6925 (const_string "double")))
6926 (set_attr "amdfam10_decode" "double")
6927 (set_attr "bdver1_decode" "direct")
6928 (set_attr "mode" "DI")])
6930 (define_insn "*<s>mulsi3_highpart_1"
6931 [(set (match_operand:SI 0 "register_operand" "=d")
6936 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6938 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6940 (clobber (match_scratch:SI 3 "=1"))
6941 (clobber (reg:CC FLAGS_REG))]
6942 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6943 "<sgnprefix>mul{l}\t%2"
6944 [(set_attr "type" "imul")
6945 (set_attr "length_immediate" "0")
6946 (set (attr "athlon_decode")
6947 (if_then_else (eq_attr "cpu" "athlon")
6948 (const_string "vector")
6949 (const_string "double")))
6950 (set_attr "amdfam10_decode" "double")
6951 (set_attr "bdver1_decode" "direct")
6952 (set_attr "mode" "SI")])
6954 (define_insn "*<s>mulsi3_highpart_zext"
6955 [(set (match_operand:DI 0 "register_operand" "=d")
6956 (zero_extend:DI (truncate:SI
6958 (mult:DI (any_extend:DI
6959 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6961 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6963 (clobber (match_scratch:SI 3 "=1"))
6964 (clobber (reg:CC FLAGS_REG))]
6966 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6967 "<sgnprefix>mul{l}\t%2"
6968 [(set_attr "type" "imul")
6969 (set_attr "length_immediate" "0")
6970 (set (attr "athlon_decode")
6971 (if_then_else (eq_attr "cpu" "athlon")
6972 (const_string "vector")
6973 (const_string "double")))
6974 (set_attr "amdfam10_decode" "double")
6975 (set_attr "bdver1_decode" "direct")
6976 (set_attr "mode" "SI")])
6978 ;; The patterns that match these are at the end of this file.
6980 (define_expand "mulxf3"
6981 [(set (match_operand:XF 0 "register_operand")
6982 (mult:XF (match_operand:XF 1 "register_operand")
6983 (match_operand:XF 2 "register_operand")))]
6986 (define_expand "mul<mode>3"
6987 [(set (match_operand:MODEF 0 "register_operand")
6988 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6989 (match_operand:MODEF 2 "nonimmediate_operand")))]
6990 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6991 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6993 ;; Divide instructions
6995 ;; The patterns that match these are at the end of this file.
6997 (define_expand "divxf3"
6998 [(set (match_operand:XF 0 "register_operand")
6999 (div:XF (match_operand:XF 1 "register_operand")
7000 (match_operand:XF 2 "register_operand")))]
7003 (define_expand "divdf3"
7004 [(set (match_operand:DF 0 "register_operand")
7005 (div:DF (match_operand:DF 1 "register_operand")
7006 (match_operand:DF 2 "nonimmediate_operand")))]
7007 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7008 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7010 (define_expand "divsf3"
7011 [(set (match_operand:SF 0 "register_operand")
7012 (div:SF (match_operand:SF 1 "register_operand")
7013 (match_operand:SF 2 "nonimmediate_operand")))]
7014 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7019 && optimize_insn_for_speed_p ()
7020 && flag_finite_math_only && !flag_trapping_math
7021 && flag_unsafe_math_optimizations)
7023 ix86_emit_swdivsf (operands[0], operands[1],
7024 operands[2], SFmode);
7029 ;; Divmod instructions.
7031 (define_expand "divmod<mode>4"
7032 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7034 (match_operand:SWIM248 1 "register_operand")
7035 (match_operand:SWIM248 2 "nonimmediate_operand")))
7036 (set (match_operand:SWIM248 3 "register_operand")
7037 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7038 (clobber (reg:CC FLAGS_REG))])])
7040 ;; Split with 8bit unsigned divide:
7041 ;; if (dividend an divisor are in [0-255])
7042 ;; use 8bit unsigned integer divide
7044 ;; use original integer divide
7046 [(set (match_operand:SWI48 0 "register_operand")
7047 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7048 (match_operand:SWI48 3 "nonimmediate_operand")))
7049 (set (match_operand:SWI48 1 "register_operand")
7050 (mod:SWI48 (match_dup 2) (match_dup 3)))
7051 (clobber (reg:CC FLAGS_REG))]
7052 "TARGET_USE_8BIT_IDIV
7053 && TARGET_QIMODE_MATH
7054 && can_create_pseudo_p ()
7055 && !optimize_insn_for_size_p ()"
7057 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7059 (define_insn_and_split "divmod<mode>4_1"
7060 [(set (match_operand:SWI48 0 "register_operand" "=a")
7061 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7062 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7063 (set (match_operand:SWI48 1 "register_operand" "=&d")
7064 (mod:SWI48 (match_dup 2) (match_dup 3)))
7065 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7066 (clobber (reg:CC FLAGS_REG))]
7070 [(parallel [(set (match_dup 1)
7071 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7072 (clobber (reg:CC FLAGS_REG))])
7073 (parallel [(set (match_dup 0)
7074 (div:SWI48 (match_dup 2) (match_dup 3)))
7076 (mod:SWI48 (match_dup 2) (match_dup 3)))
7078 (clobber (reg:CC FLAGS_REG))])]
7080 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7082 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7083 operands[4] = operands[2];
7086 /* Avoid use of cltd in favor of a mov+shift. */
7087 emit_move_insn (operands[1], operands[2]);
7088 operands[4] = operands[1];
7091 [(set_attr "type" "multi")
7092 (set_attr "mode" "<MODE>")])
7094 (define_insn_and_split "*divmod<mode>4"
7095 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7096 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7097 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7098 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7099 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7100 (clobber (reg:CC FLAGS_REG))]
7104 [(parallel [(set (match_dup 1)
7105 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7106 (clobber (reg:CC FLAGS_REG))])
7107 (parallel [(set (match_dup 0)
7108 (div:SWIM248 (match_dup 2) (match_dup 3)))
7110 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7112 (clobber (reg:CC FLAGS_REG))])]
7114 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7116 if (<MODE>mode != HImode
7117 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7118 operands[4] = operands[2];
7121 /* Avoid use of cltd in favor of a mov+shift. */
7122 emit_move_insn (operands[1], operands[2]);
7123 operands[4] = operands[1];
7126 [(set_attr "type" "multi")
7127 (set_attr "mode" "<MODE>")])
7129 (define_insn "*divmod<mode>4_noext"
7130 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7131 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7132 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7133 (set (match_operand:SWIM248 1 "register_operand" "=d")
7134 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7135 (use (match_operand:SWIM248 4 "register_operand" "1"))
7136 (clobber (reg:CC FLAGS_REG))]
7138 "idiv{<imodesuffix>}\t%3"
7139 [(set_attr "type" "idiv")
7140 (set_attr "mode" "<MODE>")])
7142 (define_expand "divmodqi4"
7143 [(parallel [(set (match_operand:QI 0 "register_operand")
7145 (match_operand:QI 1 "register_operand")
7146 (match_operand:QI 2 "nonimmediate_operand")))
7147 (set (match_operand:QI 3 "register_operand")
7148 (mod:QI (match_dup 1) (match_dup 2)))
7149 (clobber (reg:CC FLAGS_REG))])]
7150 "TARGET_QIMODE_MATH"
7155 tmp0 = gen_reg_rtx (HImode);
7156 tmp1 = gen_reg_rtx (HImode);
7158 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7160 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7161 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7163 /* Extract remainder from AH. */
7164 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7165 insn = emit_move_insn (operands[3], tmp1);
7167 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7168 set_unique_reg_note (insn, REG_EQUAL, mod);
7170 /* Extract quotient from AL. */
7171 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7173 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7174 set_unique_reg_note (insn, REG_EQUAL, div);
7179 ;; Divide AX by r/m8, with result stored in
7182 ;; Change div/mod to HImode and extend the second argument to HImode
7183 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7184 ;; combine may fail.
7185 (define_insn "divmodhiqi3"
7186 [(set (match_operand:HI 0 "register_operand" "=a")
7191 (mod:HI (match_operand:HI 1 "register_operand" "0")
7193 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7197 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7198 (clobber (reg:CC FLAGS_REG))]
7199 "TARGET_QIMODE_MATH"
7201 [(set_attr "type" "idiv")
7202 (set_attr "mode" "QI")])
7204 (define_expand "udivmod<mode>4"
7205 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7207 (match_operand:SWIM248 1 "register_operand")
7208 (match_operand:SWIM248 2 "nonimmediate_operand")))
7209 (set (match_operand:SWIM248 3 "register_operand")
7210 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7211 (clobber (reg:CC FLAGS_REG))])])
7213 ;; Split with 8bit unsigned divide:
7214 ;; if (dividend an divisor are in [0-255])
7215 ;; use 8bit unsigned integer divide
7217 ;; use original integer divide
7219 [(set (match_operand:SWI48 0 "register_operand")
7220 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7221 (match_operand:SWI48 3 "nonimmediate_operand")))
7222 (set (match_operand:SWI48 1 "register_operand")
7223 (umod:SWI48 (match_dup 2) (match_dup 3)))
7224 (clobber (reg:CC FLAGS_REG))]
7225 "TARGET_USE_8BIT_IDIV
7226 && TARGET_QIMODE_MATH
7227 && can_create_pseudo_p ()
7228 && !optimize_insn_for_size_p ()"
7230 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7232 (define_insn_and_split "udivmod<mode>4_1"
7233 [(set (match_operand:SWI48 0 "register_operand" "=a")
7234 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7235 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7236 (set (match_operand:SWI48 1 "register_operand" "=&d")
7237 (umod:SWI48 (match_dup 2) (match_dup 3)))
7238 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7239 (clobber (reg:CC FLAGS_REG))]
7243 [(set (match_dup 1) (const_int 0))
7244 (parallel [(set (match_dup 0)
7245 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7247 (umod:SWI48 (match_dup 2) (match_dup 3)))
7249 (clobber (reg:CC FLAGS_REG))])]
7251 [(set_attr "type" "multi")
7252 (set_attr "mode" "<MODE>")])
7254 (define_insn_and_split "*udivmod<mode>4"
7255 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7256 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7257 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7258 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7259 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7260 (clobber (reg:CC FLAGS_REG))]
7264 [(set (match_dup 1) (const_int 0))
7265 (parallel [(set (match_dup 0)
7266 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7268 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7270 (clobber (reg:CC FLAGS_REG))])]
7272 [(set_attr "type" "multi")
7273 (set_attr "mode" "<MODE>")])
7275 (define_insn "*udivmod<mode>4_noext"
7276 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7277 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7278 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7279 (set (match_operand:SWIM248 1 "register_operand" "=d")
7280 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7281 (use (match_operand:SWIM248 4 "register_operand" "1"))
7282 (clobber (reg:CC FLAGS_REG))]
7284 "div{<imodesuffix>}\t%3"
7285 [(set_attr "type" "idiv")
7286 (set_attr "mode" "<MODE>")])
7288 (define_expand "udivmodqi4"
7289 [(parallel [(set (match_operand:QI 0 "register_operand")
7291 (match_operand:QI 1 "register_operand")
7292 (match_operand:QI 2 "nonimmediate_operand")))
7293 (set (match_operand:QI 3 "register_operand")
7294 (umod:QI (match_dup 1) (match_dup 2)))
7295 (clobber (reg:CC FLAGS_REG))])]
7296 "TARGET_QIMODE_MATH"
7301 tmp0 = gen_reg_rtx (HImode);
7302 tmp1 = gen_reg_rtx (HImode);
7304 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7306 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7307 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7309 /* Extract remainder from AH. */
7310 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7311 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7312 insn = emit_move_insn (operands[3], tmp1);
7314 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7315 set_unique_reg_note (insn, REG_EQUAL, mod);
7317 /* Extract quotient from AL. */
7318 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7320 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7321 set_unique_reg_note (insn, REG_EQUAL, div);
7326 (define_insn "udivmodhiqi3"
7327 [(set (match_operand:HI 0 "register_operand" "=a")
7332 (mod:HI (match_operand:HI 1 "register_operand" "0")
7334 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7338 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7339 (clobber (reg:CC FLAGS_REG))]
7340 "TARGET_QIMODE_MATH"
7342 [(set_attr "type" "idiv")
7343 (set_attr "mode" "QI")])
7345 ;; We cannot use div/idiv for double division, because it causes
7346 ;; "division by zero" on the overflow and that's not what we expect
7347 ;; from truncate. Because true (non truncating) double division is
7348 ;; never generated, we can't create this insn anyway.
7351 ; [(set (match_operand:SI 0 "register_operand" "=a")
7353 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7355 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7356 ; (set (match_operand:SI 3 "register_operand" "=d")
7358 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7359 ; (clobber (reg:CC FLAGS_REG))]
7361 ; "div{l}\t{%2, %0|%0, %2}"
7362 ; [(set_attr "type" "idiv")])
7364 ;;- Logical AND instructions
7366 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7367 ;; Note that this excludes ah.
7369 (define_expand "testsi_ccno_1"
7370 [(set (reg:CCNO FLAGS_REG)
7372 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7373 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7376 (define_expand "testqi_ccz_1"
7377 [(set (reg:CCZ FLAGS_REG)
7378 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7379 (match_operand:QI 1 "nonmemory_operand"))
7382 (define_expand "testdi_ccno_1"
7383 [(set (reg:CCNO FLAGS_REG)
7385 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7386 (match_operand:DI 1 "x86_64_szext_general_operand"))
7388 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7390 (define_insn "*testdi_1"
7391 [(set (reg FLAGS_REG)
7394 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7395 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7397 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7398 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7400 test{l}\t{%k1, %k0|%k0, %k1}
7401 test{l}\t{%k1, %k0|%k0, %k1}
7402 test{q}\t{%1, %0|%0, %1}
7403 test{q}\t{%1, %0|%0, %1}
7404 test{q}\t{%1, %0|%0, %1}"
7405 [(set_attr "type" "test")
7406 (set_attr "modrm" "0,1,0,1,1")
7407 (set_attr "mode" "SI,SI,DI,DI,DI")])
7409 (define_insn "*testqi_1_maybe_si"
7410 [(set (reg FLAGS_REG)
7413 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7414 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7416 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7417 && ix86_match_ccmode (insn,
7418 CONST_INT_P (operands[1])
7419 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7421 if (which_alternative == 3)
7423 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7424 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7425 return "test{l}\t{%1, %k0|%k0, %1}";
7427 return "test{b}\t{%1, %0|%0, %1}";
7429 [(set_attr "type" "test")
7430 (set_attr "modrm" "0,1,1,1")
7431 (set_attr "mode" "QI,QI,QI,SI")
7432 (set_attr "pent_pair" "uv,np,uv,np")])
7434 (define_insn "*test<mode>_1"
7435 [(set (reg FLAGS_REG)
7438 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7439 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7441 "ix86_match_ccmode (insn, CCNOmode)
7442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7443 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7444 [(set_attr "type" "test")
7445 (set_attr "modrm" "0,1,1")
7446 (set_attr "mode" "<MODE>")
7447 (set_attr "pent_pair" "uv,np,uv")])
7449 (define_expand "testqi_ext_ccno_0"
7450 [(set (reg:CCNO FLAGS_REG)
7454 (match_operand 0 "ext_register_operand")
7457 (match_operand 1 "const_int_operand"))
7460 (define_insn "*testqi_ext_0"
7461 [(set (reg FLAGS_REG)
7465 (match_operand 0 "ext_register_operand" "Q")
7468 (match_operand 1 "const_int_operand" "n"))
7470 "ix86_match_ccmode (insn, CCNOmode)"
7471 "test{b}\t{%1, %h0|%h0, %1}"
7472 [(set_attr "type" "test")
7473 (set_attr "mode" "QI")
7474 (set_attr "length_immediate" "1")
7475 (set_attr "modrm" "1")
7476 (set_attr "pent_pair" "np")])
7478 (define_insn "*testqi_ext_1"
7479 [(set (reg FLAGS_REG)
7483 (match_operand 0 "ext_register_operand" "Q,Q")
7487 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7489 "ix86_match_ccmode (insn, CCNOmode)"
7490 "test{b}\t{%1, %h0|%h0, %1}"
7491 [(set_attr "isa" "*,nox64")
7492 (set_attr "type" "test")
7493 (set_attr "mode" "QI")])
7495 (define_insn "*testqi_ext_2"
7496 [(set (reg FLAGS_REG)
7500 (match_operand 0 "ext_register_operand" "Q")
7504 (match_operand 1 "ext_register_operand" "Q")
7508 "ix86_match_ccmode (insn, CCNOmode)"
7509 "test{b}\t{%h1, %h0|%h0, %h1}"
7510 [(set_attr "type" "test")
7511 (set_attr "mode" "QI")])
7513 ;; Combine likes to form bit extractions for some tests. Humor it.
7514 (define_insn "*testqi_ext_3"
7515 [(set (reg FLAGS_REG)
7516 (compare (zero_extract:SWI48
7517 (match_operand 0 "nonimmediate_operand" "rm")
7518 (match_operand:SWI48 1 "const_int_operand")
7519 (match_operand:SWI48 2 "const_int_operand"))
7521 "ix86_match_ccmode (insn, CCNOmode)
7522 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7523 || GET_MODE (operands[0]) == SImode
7524 || GET_MODE (operands[0]) == HImode
7525 || GET_MODE (operands[0]) == QImode)
7526 /* Ensure that resulting mask is zero or sign extended operand. */
7527 && INTVAL (operands[2]) >= 0
7528 && ((INTVAL (operands[1]) > 0
7529 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7530 || (<MODE>mode == DImode
7531 && INTVAL (operands[1]) > 32
7532 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7536 [(set (match_operand 0 "flags_reg_operand")
7537 (match_operator 1 "compare_operator"
7539 (match_operand 2 "nonimmediate_operand")
7540 (match_operand 3 "const_int_operand")
7541 (match_operand 4 "const_int_operand"))
7543 "ix86_match_ccmode (insn, CCNOmode)"
7544 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7546 rtx val = operands[2];
7547 HOST_WIDE_INT len = INTVAL (operands[3]);
7548 HOST_WIDE_INT pos = INTVAL (operands[4]);
7550 enum machine_mode mode, submode;
7552 mode = GET_MODE (val);
7555 /* ??? Combine likes to put non-volatile mem extractions in QImode
7556 no matter the size of the test. So find a mode that works. */
7557 if (! MEM_VOLATILE_P (val))
7559 mode = smallest_mode_for_size (pos + len, MODE_INT);
7560 val = adjust_address (val, mode, 0);
7563 else if (GET_CODE (val) == SUBREG
7564 && (submode = GET_MODE (SUBREG_REG (val)),
7565 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7566 && pos + len <= GET_MODE_BITSIZE (submode)
7567 && GET_MODE_CLASS (submode) == MODE_INT)
7569 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7571 val = SUBREG_REG (val);
7573 else if (mode == HImode && pos + len <= 8)
7575 /* Small HImode tests can be converted to QImode. */
7577 val = gen_lowpart (QImode, val);
7580 if (len == HOST_BITS_PER_WIDE_INT)
7583 mask = ((HOST_WIDE_INT)1 << len) - 1;
7586 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7589 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7590 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7591 ;; this is relatively important trick.
7592 ;; Do the conversion only post-reload to avoid limiting of the register class
7595 [(set (match_operand 0 "flags_reg_operand")
7596 (match_operator 1 "compare_operator"
7597 [(and (match_operand 2 "register_operand")
7598 (match_operand 3 "const_int_operand"))
7601 && QI_REG_P (operands[2])
7602 && GET_MODE (operands[2]) != QImode
7603 && ((ix86_match_ccmode (insn, CCZmode)
7604 && !(INTVAL (operands[3]) & ~(255 << 8)))
7605 || (ix86_match_ccmode (insn, CCNOmode)
7606 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7609 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7613 operands[2] = gen_lowpart (SImode, operands[2]);
7614 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7618 [(set (match_operand 0 "flags_reg_operand")
7619 (match_operator 1 "compare_operator"
7620 [(and (match_operand 2 "nonimmediate_operand")
7621 (match_operand 3 "const_int_operand"))
7624 && GET_MODE (operands[2]) != QImode
7625 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7626 && ((ix86_match_ccmode (insn, CCZmode)
7627 && !(INTVAL (operands[3]) & ~255))
7628 || (ix86_match_ccmode (insn, CCNOmode)
7629 && !(INTVAL (operands[3]) & ~127)))"
7631 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7634 operands[2] = gen_lowpart (QImode, operands[2]);
7635 operands[3] = gen_lowpart (QImode, operands[3]);
7639 [(set (match_operand:SWI12 0 "mask_reg_operand")
7640 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand")
7641 (match_operand:SWI12 2 "mask_reg_operand")))
7642 (clobber (reg:CC FLAGS_REG))]
7643 "TARGET_AVX512F && reload_completed"
7645 (any_logic:SWI12 (match_dup 1)
7648 (define_insn "*k<logic><mode>"
7649 [(set (match_operand:SWI12 0 "mask_reg_operand" "=Yk")
7650 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "Yk")
7651 (match_operand:SWI12 2 "mask_reg_operand" "Yk")))]
7653 "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7654 [(set_attr "mode" "<MODE>")
7655 (set_attr "type" "msklog")
7656 (set_attr "prefix" "vex")])
7658 ;; %%% This used to optimize known byte-wide and operations to memory,
7659 ;; and sometimes to QImode registers. If this is considered useful,
7660 ;; it should be done with splitters.
7662 (define_expand "and<mode>3"
7663 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7664 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7665 (match_operand:SWIM 2 "<general_szext_operand>")))]
7668 enum machine_mode mode = <MODE>mode;
7669 rtx (*insn) (rtx, rtx);
7671 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7673 HOST_WIDE_INT ival = INTVAL (operands[2]);
7675 if (ival == (HOST_WIDE_INT) 0xffffffff)
7677 else if (ival == 0xffff)
7679 else if (ival == 0xff)
7683 if (mode == <MODE>mode)
7685 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7689 if (<MODE>mode == DImode)
7690 insn = (mode == SImode)
7691 ? gen_zero_extendsidi2
7693 ? gen_zero_extendhidi2
7694 : gen_zero_extendqidi2;
7695 else if (<MODE>mode == SImode)
7696 insn = (mode == HImode)
7697 ? gen_zero_extendhisi2
7698 : gen_zero_extendqisi2;
7699 else if (<MODE>mode == HImode)
7700 insn = gen_zero_extendqihi2;
7704 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7708 (define_insn "*anddi_1"
7709 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7711 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7712 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7713 (clobber (reg:CC FLAGS_REG))]
7714 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7716 switch (get_attr_type (insn))
7722 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7723 if (get_attr_mode (insn) == MODE_SI)
7724 return "and{l}\t{%k2, %k0|%k0, %k2}";
7726 return "and{q}\t{%2, %0|%0, %2}";
7729 [(set_attr "type" "alu,alu,alu,imovx")
7730 (set_attr "length_immediate" "*,*,*,0")
7731 (set (attr "prefix_rex")
7733 (and (eq_attr "type" "imovx")
7734 (and (match_test "INTVAL (operands[2]) == 0xff")
7735 (match_operand 1 "ext_QIreg_operand")))
7737 (const_string "*")))
7738 (set_attr "mode" "SI,DI,DI,SI")])
7740 (define_insn "*andsi_1"
7741 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7742 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7743 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7744 (clobber (reg:CC FLAGS_REG))]
7745 "ix86_binary_operator_ok (AND, SImode, operands)"
7747 switch (get_attr_type (insn))
7753 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7754 return "and{l}\t{%2, %0|%0, %2}";
7757 [(set_attr "type" "alu,alu,imovx")
7758 (set (attr "prefix_rex")
7760 (and (eq_attr "type" "imovx")
7761 (and (match_test "INTVAL (operands[2]) == 0xff")
7762 (match_operand 1 "ext_QIreg_operand")))
7764 (const_string "*")))
7765 (set_attr "length_immediate" "*,*,0")
7766 (set_attr "mode" "SI")])
7768 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7769 (define_insn "*andsi_1_zext"
7770 [(set (match_operand:DI 0 "register_operand" "=r")
7772 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7773 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7774 (clobber (reg:CC FLAGS_REG))]
7775 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7776 "and{l}\t{%2, %k0|%k0, %2}"
7777 [(set_attr "type" "alu")
7778 (set_attr "mode" "SI")])
7780 (define_insn "*andhi_1"
7781 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!Yk")
7782 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,Yk")
7783 (match_operand:HI 2 "general_operand" "rn,rm,L,Yk")))
7784 (clobber (reg:CC FLAGS_REG))]
7785 "ix86_binary_operator_ok (AND, HImode, operands)"
7787 switch (get_attr_type (insn))
7793 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7796 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7797 return "and{w}\t{%2, %0|%0, %2}";
7800 [(set_attr "type" "alu,alu,imovx,msklog")
7801 (set_attr "length_immediate" "*,*,0,*")
7802 (set (attr "prefix_rex")
7804 (and (eq_attr "type" "imovx")
7805 (match_operand 1 "ext_QIreg_operand"))
7807 (const_string "*")))
7808 (set_attr "mode" "HI,HI,SI,HI")])
7810 ;; %%% Potential partial reg stall on alternative 2. What to do?
7811 (define_insn "*andqi_1"
7812 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!Yk")
7813 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
7814 (match_operand:QI 2 "general_operand" "qn,qmn,rn,Yk")))
7815 (clobber (reg:CC FLAGS_REG))]
7816 "ix86_binary_operator_ok (AND, QImode, operands)"
7818 and{b}\t{%2, %0|%0, %2}
7819 and{b}\t{%2, %0|%0, %2}
7820 and{l}\t{%k2, %k0|%k0, %k2}
7821 kandw\t{%2, %1, %0|%0, %1, %2}"
7822 [(set_attr "type" "alu,alu,alu,msklog")
7823 (set_attr "mode" "QI,QI,SI,HI")])
7825 (define_insn "*andqi_1_slp"
7826 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7827 (and:QI (match_dup 0)
7828 (match_operand:QI 1 "general_operand" "qn,qmn")))
7829 (clobber (reg:CC FLAGS_REG))]
7830 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7831 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7832 "and{b}\t{%1, %0|%0, %1}"
7833 [(set_attr "type" "alu1")
7834 (set_attr "mode" "QI")])
7836 (define_insn "kandn<mode>"
7837 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!Yk")
7840 (match_operand:SWI12 1 "register_operand" "r,0,Yk"))
7841 (match_operand:SWI12 2 "register_operand" "r,r,Yk")))
7842 (clobber (reg:CC FLAGS_REG))]
7845 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
7847 kandnw\t{%2, %1, %0|%0, %1, %2}"
7848 [(set_attr "isa" "bmi,*,avx512f")
7849 (set_attr "type" "bitmanip,*,msklog")
7850 (set_attr "prefix" "*,*,vex")
7851 (set_attr "btver2_decode" "direct,*,*")
7852 (set_attr "mode" "<MODE>")])
7855 [(set (match_operand:SWI12 0 "general_reg_operand")
7859 (match_operand:SWI12 1 "general_reg_operand")))
7860 (clobber (reg:CC FLAGS_REG))]
7861 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7863 (not:HI (match_dup 0)))
7864 (parallel [(set (match_dup 0)
7865 (and:HI (match_dup 0)
7867 (clobber (reg:CC FLAGS_REG))])])
7869 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7871 [(set (match_operand:DI 0 "register_operand")
7872 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7873 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7874 (clobber (reg:CC FLAGS_REG))]
7876 [(parallel [(set (match_dup 0)
7877 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7878 (clobber (reg:CC FLAGS_REG))])]
7879 "operands[2] = gen_lowpart (SImode, operands[2]);")
7882 [(set (match_operand:SWI248 0 "register_operand")
7883 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7884 (match_operand:SWI248 2 "const_int_operand")))
7885 (clobber (reg:CC FLAGS_REG))]
7887 && true_regnum (operands[0]) != true_regnum (operands[1])"
7890 HOST_WIDE_INT ival = INTVAL (operands[2]);
7891 enum machine_mode mode;
7892 rtx (*insn) (rtx, rtx);
7894 if (ival == (HOST_WIDE_INT) 0xffffffff)
7896 else if (ival == 0xffff)
7900 gcc_assert (ival == 0xff);
7904 if (<MODE>mode == DImode)
7905 insn = (mode == SImode)
7906 ? gen_zero_extendsidi2
7908 ? gen_zero_extendhidi2
7909 : gen_zero_extendqidi2;
7912 if (<MODE>mode != SImode)
7913 /* Zero extend to SImode to avoid partial register stalls. */
7914 operands[0] = gen_lowpart (SImode, operands[0]);
7916 insn = (mode == HImode)
7917 ? gen_zero_extendhisi2
7918 : gen_zero_extendqisi2;
7920 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7925 [(set (match_operand 0 "register_operand")
7927 (const_int -65536)))
7928 (clobber (reg:CC FLAGS_REG))]
7929 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7930 || optimize_function_for_size_p (cfun)"
7931 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7932 "operands[1] = gen_lowpart (HImode, operands[0]);")
7935 [(set (match_operand 0 "ext_register_operand")
7938 (clobber (reg:CC FLAGS_REG))]
7939 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7940 && reload_completed"
7941 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7942 "operands[1] = gen_lowpart (QImode, operands[0]);")
7945 [(set (match_operand 0 "ext_register_operand")
7947 (const_int -65281)))
7948 (clobber (reg:CC FLAGS_REG))]
7949 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7950 && reload_completed"
7951 [(parallel [(set (zero_extract:SI (match_dup 0)
7955 (zero_extract:SI (match_dup 0)
7958 (zero_extract:SI (match_dup 0)
7961 (clobber (reg:CC FLAGS_REG))])]
7962 "operands[0] = gen_lowpart (SImode, operands[0]);")
7964 (define_insn "*anddi_2"
7965 [(set (reg FLAGS_REG)
7968 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7969 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7971 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7972 (and:DI (match_dup 1) (match_dup 2)))]
7973 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7974 && ix86_binary_operator_ok (AND, DImode, operands)"
7976 and{l}\t{%k2, %k0|%k0, %k2}
7977 and{q}\t{%2, %0|%0, %2}
7978 and{q}\t{%2, %0|%0, %2}"
7979 [(set_attr "type" "alu")
7980 (set_attr "mode" "SI,DI,DI")])
7982 (define_insn "*andqi_2_maybe_si"
7983 [(set (reg FLAGS_REG)
7985 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7986 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7988 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7989 (and:QI (match_dup 1) (match_dup 2)))]
7990 "ix86_binary_operator_ok (AND, QImode, operands)
7991 && ix86_match_ccmode (insn,
7992 CONST_INT_P (operands[2])
7993 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7995 if (which_alternative == 2)
7997 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7998 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7999 return "and{l}\t{%2, %k0|%k0, %2}";
8001 return "and{b}\t{%2, %0|%0, %2}";
8003 [(set_attr "type" "alu")
8004 (set_attr "mode" "QI,QI,SI")])
8006 (define_insn "*and<mode>_2"
8007 [(set (reg FLAGS_REG)
8008 (compare (and:SWI124
8009 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8010 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8012 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8013 (and:SWI124 (match_dup 1) (match_dup 2)))]
8014 "ix86_match_ccmode (insn, CCNOmode)
8015 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8016 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8017 [(set_attr "type" "alu")
8018 (set_attr "mode" "<MODE>")])
8020 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8021 (define_insn "*andsi_2_zext"
8022 [(set (reg FLAGS_REG)
8024 (match_operand:SI 1 "nonimmediate_operand" "%0")
8025 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8027 (set (match_operand:DI 0 "register_operand" "=r")
8028 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8029 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8030 && ix86_binary_operator_ok (AND, SImode, operands)"
8031 "and{l}\t{%2, %k0|%k0, %2}"
8032 [(set_attr "type" "alu")
8033 (set_attr "mode" "SI")])
8035 (define_insn "*andqi_2_slp"
8036 [(set (reg FLAGS_REG)
8038 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8039 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8041 (set (strict_low_part (match_dup 0))
8042 (and:QI (match_dup 0) (match_dup 1)))]
8043 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8044 && ix86_match_ccmode (insn, CCNOmode)
8045 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8046 "and{b}\t{%1, %0|%0, %1}"
8047 [(set_attr "type" "alu1")
8048 (set_attr "mode" "QI")])
8050 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8051 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8052 ;; for a QImode operand, which of course failed.
8053 (define_insn "andqi_ext_0"
8054 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8059 (match_operand 1 "ext_register_operand" "0")
8062 (match_operand 2 "const_int_operand" "n")))
8063 (clobber (reg:CC FLAGS_REG))]
8065 "and{b}\t{%2, %h0|%h0, %2}"
8066 [(set_attr "type" "alu")
8067 (set_attr "length_immediate" "1")
8068 (set_attr "modrm" "1")
8069 (set_attr "mode" "QI")])
8071 ;; Generated by peephole translating test to and. This shows up
8072 ;; often in fp comparisons.
8073 (define_insn "*andqi_ext_0_cc"
8074 [(set (reg FLAGS_REG)
8078 (match_operand 1 "ext_register_operand" "0")
8081 (match_operand 2 "const_int_operand" "n"))
8083 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8092 "ix86_match_ccmode (insn, CCNOmode)"
8093 "and{b}\t{%2, %h0|%h0, %2}"
8094 [(set_attr "type" "alu")
8095 (set_attr "length_immediate" "1")
8096 (set_attr "modrm" "1")
8097 (set_attr "mode" "QI")])
8099 (define_insn "*andqi_ext_1"
8100 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8105 (match_operand 1 "ext_register_operand" "0,0")
8109 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8110 (clobber (reg:CC FLAGS_REG))]
8112 "and{b}\t{%2, %h0|%h0, %2}"
8113 [(set_attr "isa" "*,nox64")
8114 (set_attr "type" "alu")
8115 (set_attr "length_immediate" "0")
8116 (set_attr "mode" "QI")])
8118 (define_insn "*andqi_ext_2"
8119 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8124 (match_operand 1 "ext_register_operand" "%0")
8128 (match_operand 2 "ext_register_operand" "Q")
8131 (clobber (reg:CC FLAGS_REG))]
8133 "and{b}\t{%h2, %h0|%h0, %h2}"
8134 [(set_attr "type" "alu")
8135 (set_attr "length_immediate" "0")
8136 (set_attr "mode" "QI")])
8138 ;; Convert wide AND instructions with immediate operand to shorter QImode
8139 ;; equivalents when possible.
8140 ;; Don't do the splitting with memory operands, since it introduces risk
8141 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8142 ;; for size, but that can (should?) be handled by generic code instead.
8144 [(set (match_operand 0 "register_operand")
8145 (and (match_operand 1 "register_operand")
8146 (match_operand 2 "const_int_operand")))
8147 (clobber (reg:CC FLAGS_REG))]
8149 && QI_REG_P (operands[0])
8150 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8151 && !(~INTVAL (operands[2]) & ~(255 << 8))
8152 && GET_MODE (operands[0]) != QImode"
8153 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8154 (and:SI (zero_extract:SI (match_dup 1)
8155 (const_int 8) (const_int 8))
8157 (clobber (reg:CC FLAGS_REG))])]
8159 operands[0] = gen_lowpart (SImode, operands[0]);
8160 operands[1] = gen_lowpart (SImode, operands[1]);
8161 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8164 ;; Since AND can be encoded with sign extended immediate, this is only
8165 ;; profitable when 7th bit is not set.
8167 [(set (match_operand 0 "register_operand")
8168 (and (match_operand 1 "general_operand")
8169 (match_operand 2 "const_int_operand")))
8170 (clobber (reg:CC FLAGS_REG))]
8172 && ANY_QI_REG_P (operands[0])
8173 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8174 && !(~INTVAL (operands[2]) & ~255)
8175 && !(INTVAL (operands[2]) & 128)
8176 && GET_MODE (operands[0]) != QImode"
8177 [(parallel [(set (strict_low_part (match_dup 0))
8178 (and:QI (match_dup 1)
8180 (clobber (reg:CC FLAGS_REG))])]
8182 operands[0] = gen_lowpart (QImode, operands[0]);
8183 operands[1] = gen_lowpart (QImode, operands[1]);
8184 operands[2] = gen_lowpart (QImode, operands[2]);
8187 ;; Logical inclusive and exclusive OR instructions
8189 ;; %%% This used to optimize known byte-wide and operations to memory.
8190 ;; If this is considered useful, it should be done with splitters.
8192 (define_expand "<code><mode>3"
8193 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8194 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8195 (match_operand:SWIM 2 "<general_operand>")))]
8197 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8199 (define_insn "*<code><mode>_1"
8200 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
8202 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
8203 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>")))
8204 (clobber (reg:CC FLAGS_REG))]
8205 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8206 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8207 [(set_attr "type" "alu")
8208 (set_attr "mode" "<MODE>")])
8210 (define_insn "*<code>hi_1"
8211 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!Yk")
8213 (match_operand:HI 1 "nonimmediate_operand" "%0,0,Yk")
8214 (match_operand:HI 2 "general_operand" "<g>,r<i>,Yk")))
8215 (clobber (reg:CC FLAGS_REG))]
8216 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8218 <logic>{w}\t{%2, %0|%0, %2}
8219 <logic>{w}\t{%2, %0|%0, %2}
8220 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8221 [(set_attr "type" "alu,alu,msklog")
8222 (set_attr "mode" "HI")])
8224 ;; %%% Potential partial reg stall on alternative 2. What to do?
8225 (define_insn "*<code>qi_1"
8226 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!Yk")
8227 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
8228 (match_operand:QI 2 "general_operand" "qmn,qn,rn,Yk")))
8229 (clobber (reg:CC FLAGS_REG))]
8230 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8232 <logic>{b}\t{%2, %0|%0, %2}
8233 <logic>{b}\t{%2, %0|%0, %2}
8234 <logic>{l}\t{%k2, %k0|%k0, %k2}
8235 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8236 [(set_attr "type" "alu,alu,alu,msklog")
8237 (set_attr "mode" "QI,QI,SI,HI")])
8239 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8240 (define_insn "*<code>si_1_zext"
8241 [(set (match_operand:DI 0 "register_operand" "=r")
8243 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8244 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8245 (clobber (reg:CC FLAGS_REG))]
8246 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8247 "<logic>{l}\t{%2, %k0|%k0, %2}"
8248 [(set_attr "type" "alu")
8249 (set_attr "mode" "SI")])
8251 (define_insn "*<code>si_1_zext_imm"
8252 [(set (match_operand:DI 0 "register_operand" "=r")
8254 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8255 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8256 (clobber (reg:CC FLAGS_REG))]
8257 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8258 "<logic>{l}\t{%2, %k0|%k0, %2}"
8259 [(set_attr "type" "alu")
8260 (set_attr "mode" "SI")])
8262 (define_insn "*<code>qi_1_slp"
8263 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8264 (any_or:QI (match_dup 0)
8265 (match_operand:QI 1 "general_operand" "qmn,qn")))
8266 (clobber (reg:CC FLAGS_REG))]
8267 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8268 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8269 "<logic>{b}\t{%1, %0|%0, %1}"
8270 [(set_attr "type" "alu1")
8271 (set_attr "mode" "QI")])
8273 (define_insn "*<code><mode>_2"
8274 [(set (reg FLAGS_REG)
8275 (compare (any_or:SWI
8276 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8277 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8279 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8280 (any_or:SWI (match_dup 1) (match_dup 2)))]
8281 "ix86_match_ccmode (insn, CCNOmode)
8282 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8283 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8284 [(set_attr "type" "alu")
8285 (set_attr "mode" "<MODE>")])
8287 (define_insn "kxnor<mode>"
8288 [(set (match_operand:SWI12 0 "register_operand" "=r,!Yk")
8291 (match_operand:SWI12 1 "register_operand" "0,Yk")
8292 (match_operand:SWI12 2 "register_operand" "r,Yk"))))
8293 (clobber (reg:CC FLAGS_REG))]
8297 kxnorw\t{%2, %1, %0|%0, %1, %2}"
8298 [(set_attr "type" "*,msklog")
8299 (set_attr "prefix" "*,vex")
8300 (set_attr "mode" "<MODE>")])
8303 [(set (match_operand:SWI12 0 "general_reg_operand")
8307 (match_operand:SWI12 1 "general_reg_operand"))))
8308 (clobber (reg:CC FLAGS_REG))]
8309 "TARGET_AVX512F && reload_completed"
8310 [(parallel [(set (match_dup 0)
8311 (xor:HI (match_dup 0)
8313 (clobber (reg:CC FLAGS_REG))])
8315 (not:HI (match_dup 0)))])
8317 (define_insn "kortestzhi"
8318 [(set (reg:CCZ FLAGS_REG)
8321 (match_operand:HI 0 "register_operand" "Yk")
8322 (match_operand:HI 1 "register_operand" "Yk"))
8324 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8325 "kortestw\t{%1, %0|%0, %1}"
8326 [(set_attr "mode" "HI")
8327 (set_attr "type" "msklog")
8328 (set_attr "prefix" "vex")])
8330 (define_insn "kortestchi"
8331 [(set (reg:CCC FLAGS_REG)
8334 (match_operand:HI 0 "register_operand" "Yk")
8335 (match_operand:HI 1 "register_operand" "Yk"))
8337 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8338 "kortestw\t{%1, %0|%0, %1}"
8339 [(set_attr "mode" "HI")
8340 (set_attr "type" "msklog")
8341 (set_attr "prefix" "vex")])
8343 (define_insn "kunpckhi"
8344 [(set (match_operand:HI 0 "register_operand" "=Yk")
8347 (match_operand:HI 1 "register_operand" "Yk")
8349 (zero_extend:HI (match_operand:QI 2 "register_operand" "Yk"))))]
8351 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8352 [(set_attr "mode" "HI")
8353 (set_attr "type" "msklog")
8354 (set_attr "prefix" "vex")])
8356 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8357 ;; ??? Special case for immediate operand is missing - it is tricky.
8358 (define_insn "*<code>si_2_zext"
8359 [(set (reg FLAGS_REG)
8360 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8361 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8363 (set (match_operand:DI 0 "register_operand" "=r")
8364 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8365 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8366 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8367 "<logic>{l}\t{%2, %k0|%k0, %2}"
8368 [(set_attr "type" "alu")
8369 (set_attr "mode" "SI")])
8371 (define_insn "*<code>si_2_zext_imm"
8372 [(set (reg FLAGS_REG)
8374 (match_operand:SI 1 "nonimmediate_operand" "%0")
8375 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8377 (set (match_operand:DI 0 "register_operand" "=r")
8378 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8379 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8380 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8381 "<logic>{l}\t{%2, %k0|%k0, %2}"
8382 [(set_attr "type" "alu")
8383 (set_attr "mode" "SI")])
8385 (define_insn "*<code>qi_2_slp"
8386 [(set (reg FLAGS_REG)
8387 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8388 (match_operand:QI 1 "general_operand" "qmn,qn"))
8390 (set (strict_low_part (match_dup 0))
8391 (any_or:QI (match_dup 0) (match_dup 1)))]
8392 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8393 && ix86_match_ccmode (insn, CCNOmode)
8394 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8395 "<logic>{b}\t{%1, %0|%0, %1}"
8396 [(set_attr "type" "alu1")
8397 (set_attr "mode" "QI")])
8399 (define_insn "*<code><mode>_3"
8400 [(set (reg FLAGS_REG)
8401 (compare (any_or:SWI
8402 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8403 (match_operand:SWI 2 "<general_operand>" "<g>"))
8405 (clobber (match_scratch:SWI 0 "=<r>"))]
8406 "ix86_match_ccmode (insn, CCNOmode)
8407 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8408 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8409 [(set_attr "type" "alu")
8410 (set_attr "mode" "<MODE>")])
8412 (define_insn "*<code>qi_ext_0"
8413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8418 (match_operand 1 "ext_register_operand" "0")
8421 (match_operand 2 "const_int_operand" "n")))
8422 (clobber (reg:CC FLAGS_REG))]
8423 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8424 "<logic>{b}\t{%2, %h0|%h0, %2}"
8425 [(set_attr "type" "alu")
8426 (set_attr "length_immediate" "1")
8427 (set_attr "modrm" "1")
8428 (set_attr "mode" "QI")])
8430 (define_insn "*<code>qi_ext_1"
8431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8436 (match_operand 1 "ext_register_operand" "0,0")
8440 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8441 (clobber (reg:CC FLAGS_REG))]
8442 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8443 "<logic>{b}\t{%2, %h0|%h0, %2}"
8444 [(set_attr "isa" "*,nox64")
8445 (set_attr "type" "alu")
8446 (set_attr "length_immediate" "0")
8447 (set_attr "mode" "QI")])
8449 (define_insn "*<code>qi_ext_2"
8450 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8454 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8457 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8460 (clobber (reg:CC FLAGS_REG))]
8461 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8462 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8463 [(set_attr "type" "alu")
8464 (set_attr "length_immediate" "0")
8465 (set_attr "mode" "QI")])
8468 [(set (match_operand 0 "register_operand")
8469 (any_or (match_operand 1 "register_operand")
8470 (match_operand 2 "const_int_operand")))
8471 (clobber (reg:CC FLAGS_REG))]
8473 && QI_REG_P (operands[0])
8474 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8475 && !(INTVAL (operands[2]) & ~(255 << 8))
8476 && GET_MODE (operands[0]) != QImode"
8477 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8478 (any_or:SI (zero_extract:SI (match_dup 1)
8479 (const_int 8) (const_int 8))
8481 (clobber (reg:CC FLAGS_REG))])]
8483 operands[0] = gen_lowpart (SImode, operands[0]);
8484 operands[1] = gen_lowpart (SImode, operands[1]);
8485 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8488 ;; Since OR can be encoded with sign extended immediate, this is only
8489 ;; profitable when 7th bit is set.
8491 [(set (match_operand 0 "register_operand")
8492 (any_or (match_operand 1 "general_operand")
8493 (match_operand 2 "const_int_operand")))
8494 (clobber (reg:CC FLAGS_REG))]
8496 && ANY_QI_REG_P (operands[0])
8497 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8498 && !(INTVAL (operands[2]) & ~255)
8499 && (INTVAL (operands[2]) & 128)
8500 && GET_MODE (operands[0]) != QImode"
8501 [(parallel [(set (strict_low_part (match_dup 0))
8502 (any_or:QI (match_dup 1)
8504 (clobber (reg:CC FLAGS_REG))])]
8506 operands[0] = gen_lowpart (QImode, operands[0]);
8507 operands[1] = gen_lowpart (QImode, operands[1]);
8508 operands[2] = gen_lowpart (QImode, operands[2]);
8511 (define_expand "xorqi_cc_ext_1"
8513 (set (reg:CCNO FLAGS_REG)
8517 (match_operand 1 "ext_register_operand")
8520 (match_operand:QI 2 "const_int_operand"))
8522 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8532 (define_insn "*xorqi_cc_ext_1"
8533 [(set (reg FLAGS_REG)
8537 (match_operand 1 "ext_register_operand" "0,0")
8540 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8542 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8551 "ix86_match_ccmode (insn, CCNOmode)"
8552 "xor{b}\t{%2, %h0|%h0, %2}"
8553 [(set_attr "isa" "*,nox64")
8554 (set_attr "type" "alu")
8555 (set_attr "modrm" "1")
8556 (set_attr "mode" "QI")])
8558 ;; Negation instructions
8560 (define_expand "neg<mode>2"
8561 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8562 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8564 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8566 (define_insn_and_split "*neg<dwi>2_doubleword"
8567 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8568 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8569 (clobber (reg:CC FLAGS_REG))]
8570 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8574 [(set (reg:CCZ FLAGS_REG)
8575 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8576 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8579 (plus:DWIH (match_dup 3)
8580 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8582 (clobber (reg:CC FLAGS_REG))])
8585 (neg:DWIH (match_dup 2)))
8586 (clobber (reg:CC FLAGS_REG))])]
8587 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8589 (define_insn "*neg<mode>2_1"
8590 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8591 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8592 (clobber (reg:CC FLAGS_REG))]
8593 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8594 "neg{<imodesuffix>}\t%0"
8595 [(set_attr "type" "negnot")
8596 (set_attr "mode" "<MODE>")])
8598 ;; Combine is quite creative about this pattern.
8599 (define_insn "*negsi2_1_zext"
8600 [(set (match_operand:DI 0 "register_operand" "=r")
8602 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8605 (clobber (reg:CC FLAGS_REG))]
8606 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8608 [(set_attr "type" "negnot")
8609 (set_attr "mode" "SI")])
8611 ;; The problem with neg is that it does not perform (compare x 0),
8612 ;; it really performs (compare 0 x), which leaves us with the zero
8613 ;; flag being the only useful item.
8615 (define_insn "*neg<mode>2_cmpz"
8616 [(set (reg:CCZ FLAGS_REG)
8618 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8620 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8621 (neg:SWI (match_dup 1)))]
8622 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8623 "neg{<imodesuffix>}\t%0"
8624 [(set_attr "type" "negnot")
8625 (set_attr "mode" "<MODE>")])
8627 (define_insn "*negsi2_cmpz_zext"
8628 [(set (reg:CCZ FLAGS_REG)
8632 (match_operand:DI 1 "register_operand" "0")
8636 (set (match_operand:DI 0 "register_operand" "=r")
8637 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8640 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8642 [(set_attr "type" "negnot")
8643 (set_attr "mode" "SI")])
8645 ;; Changing of sign for FP values is doable using integer unit too.
8647 (define_expand "<code><mode>2"
8648 [(set (match_operand:X87MODEF 0 "register_operand")
8649 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8650 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8651 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8653 (define_insn "*absneg<mode>2_mixed"
8654 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8655 (match_operator:MODEF 3 "absneg_operator"
8656 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8657 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8658 (clobber (reg:CC FLAGS_REG))]
8659 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8662 (define_insn "*absneg<mode>2_sse"
8663 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8664 (match_operator:MODEF 3 "absneg_operator"
8665 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8666 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8667 (clobber (reg:CC FLAGS_REG))]
8668 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8671 (define_insn "*absneg<mode>2_i387"
8672 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8673 (match_operator:X87MODEF 3 "absneg_operator"
8674 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8675 (use (match_operand 2))
8676 (clobber (reg:CC FLAGS_REG))]
8677 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8680 (define_expand "<code>tf2"
8681 [(set (match_operand:TF 0 "register_operand")
8682 (absneg:TF (match_operand:TF 1 "register_operand")))]
8684 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8686 (define_insn "*absnegtf2_sse"
8687 [(set (match_operand:TF 0 "register_operand" "=x,x")
8688 (match_operator:TF 3 "absneg_operator"
8689 [(match_operand:TF 1 "register_operand" "0,x")]))
8690 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8691 (clobber (reg:CC FLAGS_REG))]
8695 ;; Splitters for fp abs and neg.
8698 [(set (match_operand 0 "fp_register_operand")
8699 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8700 (use (match_operand 2))
8701 (clobber (reg:CC FLAGS_REG))]
8703 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8706 [(set (match_operand 0 "register_operand")
8707 (match_operator 3 "absneg_operator"
8708 [(match_operand 1 "register_operand")]))
8709 (use (match_operand 2 "nonimmediate_operand"))
8710 (clobber (reg:CC FLAGS_REG))]
8711 "reload_completed && SSE_REG_P (operands[0])"
8712 [(set (match_dup 0) (match_dup 3))]
8714 enum machine_mode mode = GET_MODE (operands[0]);
8715 enum machine_mode vmode = GET_MODE (operands[2]);
8718 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8719 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8720 if (operands_match_p (operands[0], operands[2]))
8723 operands[1] = operands[2];
8726 if (GET_CODE (operands[3]) == ABS)
8727 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8729 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8734 [(set (match_operand:SF 0 "register_operand")
8735 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8736 (use (match_operand:V4SF 2))
8737 (clobber (reg:CC FLAGS_REG))]
8739 [(parallel [(set (match_dup 0) (match_dup 1))
8740 (clobber (reg:CC FLAGS_REG))])]
8743 operands[0] = gen_lowpart (SImode, operands[0]);
8744 if (GET_CODE (operands[1]) == ABS)
8746 tmp = gen_int_mode (0x7fffffff, SImode);
8747 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8751 tmp = gen_int_mode (0x80000000, SImode);
8752 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8758 [(set (match_operand:DF 0 "register_operand")
8759 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8760 (use (match_operand 2))
8761 (clobber (reg:CC FLAGS_REG))]
8763 [(parallel [(set (match_dup 0) (match_dup 1))
8764 (clobber (reg:CC FLAGS_REG))])]
8769 tmp = gen_lowpart (DImode, operands[0]);
8770 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8773 if (GET_CODE (operands[1]) == ABS)
8776 tmp = gen_rtx_NOT (DImode, tmp);
8780 operands[0] = gen_highpart (SImode, operands[0]);
8781 if (GET_CODE (operands[1]) == ABS)
8783 tmp = gen_int_mode (0x7fffffff, SImode);
8784 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8788 tmp = gen_int_mode (0x80000000, SImode);
8789 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8796 [(set (match_operand:XF 0 "register_operand")
8797 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8798 (use (match_operand 2))
8799 (clobber (reg:CC FLAGS_REG))]
8801 [(parallel [(set (match_dup 0) (match_dup 1))
8802 (clobber (reg:CC FLAGS_REG))])]
8805 operands[0] = gen_rtx_REG (SImode,
8806 true_regnum (operands[0])
8807 + (TARGET_64BIT ? 1 : 2));
8808 if (GET_CODE (operands[1]) == ABS)
8810 tmp = GEN_INT (0x7fff);
8811 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8815 tmp = GEN_INT (0x8000);
8816 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8821 ;; Conditionalize these after reload. If they match before reload, we
8822 ;; lose the clobber and ability to use integer instructions.
8824 (define_insn "*<code><mode>2_1"
8825 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8826 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8828 && (reload_completed
8829 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8830 "f<absneg_mnemonic>"
8831 [(set_attr "type" "fsgn")
8832 (set_attr "mode" "<MODE>")])
8834 (define_insn "*<code>extendsfdf2"
8835 [(set (match_operand:DF 0 "register_operand" "=f")
8836 (absneg:DF (float_extend:DF
8837 (match_operand:SF 1 "register_operand" "0"))))]
8838 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8839 "f<absneg_mnemonic>"
8840 [(set_attr "type" "fsgn")
8841 (set_attr "mode" "DF")])
8843 (define_insn "*<code>extendsfxf2"
8844 [(set (match_operand:XF 0 "register_operand" "=f")
8845 (absneg:XF (float_extend:XF
8846 (match_operand:SF 1 "register_operand" "0"))))]
8848 "f<absneg_mnemonic>"
8849 [(set_attr "type" "fsgn")
8850 (set_attr "mode" "XF")])
8852 (define_insn "*<code>extenddfxf2"
8853 [(set (match_operand:XF 0 "register_operand" "=f")
8854 (absneg:XF (float_extend:XF
8855 (match_operand:DF 1 "register_operand" "0"))))]
8857 "f<absneg_mnemonic>"
8858 [(set_attr "type" "fsgn")
8859 (set_attr "mode" "XF")])
8861 ;; Copysign instructions
8863 (define_mode_iterator CSGNMODE [SF DF TF])
8864 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8866 (define_expand "copysign<mode>3"
8867 [(match_operand:CSGNMODE 0 "register_operand")
8868 (match_operand:CSGNMODE 1 "nonmemory_operand")
8869 (match_operand:CSGNMODE 2 "register_operand")]
8870 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8871 || (TARGET_SSE && (<MODE>mode == TFmode))"
8872 "ix86_expand_copysign (operands); DONE;")
8874 (define_insn_and_split "copysign<mode>3_const"
8875 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8877 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8878 (match_operand:CSGNMODE 2 "register_operand" "0")
8879 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8881 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8882 || (TARGET_SSE && (<MODE>mode == TFmode))"
8884 "&& reload_completed"
8886 "ix86_split_copysign_const (operands); DONE;")
8888 (define_insn "copysign<mode>3_var"
8889 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8891 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8892 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8893 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8894 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8896 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8897 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8898 || (TARGET_SSE && (<MODE>mode == TFmode))"
8902 [(set (match_operand:CSGNMODE 0 "register_operand")
8904 [(match_operand:CSGNMODE 2 "register_operand")
8905 (match_operand:CSGNMODE 3 "register_operand")
8906 (match_operand:<CSGNVMODE> 4)
8907 (match_operand:<CSGNVMODE> 5)]
8909 (clobber (match_scratch:<CSGNVMODE> 1))]
8910 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8911 || (TARGET_SSE && (<MODE>mode == TFmode)))
8912 && reload_completed"
8914 "ix86_split_copysign_var (operands); DONE;")
8916 ;; One complement instructions
8918 (define_expand "one_cmpl<mode>2"
8919 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8920 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8922 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8924 (define_insn "*one_cmpl<mode>2_1"
8925 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8926 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))]
8927 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8928 "not{<imodesuffix>}\t%0"
8929 [(set_attr "type" "negnot")
8930 (set_attr "mode" "<MODE>")])
8932 (define_insn "*one_cmplhi2_1"
8933 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!Yk")
8934 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,Yk")))]
8935 "ix86_unary_operator_ok (NOT, HImode, operands)"
8938 knotw\t{%1, %0|%0, %1}"
8939 [(set_attr "isa" "*,avx512f")
8940 (set_attr "type" "negnot,msklog")
8941 (set_attr "prefix" "*,vex")
8942 (set_attr "mode" "HI")])
8944 ;; %%% Potential partial reg stall on alternative 1. What to do?
8945 (define_insn "*one_cmplqi2_1"
8946 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!Yk")
8947 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,Yk")))]
8948 "ix86_unary_operator_ok (NOT, QImode, operands)"
8952 knotw\t{%1, %0|%0, %1}"
8953 [(set_attr "isa" "*,*,avx512f")
8954 (set_attr "type" "negnot,negnot,msklog")
8955 (set_attr "prefix" "*,*,vex")
8956 (set_attr "mode" "QI,SI,QI")])
8958 ;; ??? Currently never generated - xor is used instead.
8959 (define_insn "*one_cmplsi2_1_zext"
8960 [(set (match_operand:DI 0 "register_operand" "=r")
8962 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8963 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8965 [(set_attr "type" "negnot")
8966 (set_attr "mode" "SI")])
8968 (define_insn "*one_cmpl<mode>2_2"
8969 [(set (reg FLAGS_REG)
8970 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8972 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8973 (not:SWI (match_dup 1)))]
8974 "ix86_match_ccmode (insn, CCNOmode)
8975 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8977 [(set_attr "type" "alu1")
8978 (set_attr "mode" "<MODE>")])
8981 [(set (match_operand 0 "flags_reg_operand")
8982 (match_operator 2 "compare_operator"
8983 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8985 (set (match_operand:SWI 1 "nonimmediate_operand")
8986 (not:SWI (match_dup 3)))]
8987 "ix86_match_ccmode (insn, CCNOmode)"
8988 [(parallel [(set (match_dup 0)
8989 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8992 (xor:SWI (match_dup 3) (const_int -1)))])])
8994 ;; ??? Currently never generated - xor is used instead.
8995 (define_insn "*one_cmplsi2_2_zext"
8996 [(set (reg FLAGS_REG)
8997 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8999 (set (match_operand:DI 0 "register_operand" "=r")
9000 (zero_extend:DI (not:SI (match_dup 1))))]
9001 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9002 && ix86_unary_operator_ok (NOT, SImode, operands)"
9004 [(set_attr "type" "alu1")
9005 (set_attr "mode" "SI")])
9008 [(set (match_operand 0 "flags_reg_operand")
9009 (match_operator 2 "compare_operator"
9010 [(not:SI (match_operand:SI 3 "register_operand"))
9012 (set (match_operand:DI 1 "register_operand")
9013 (zero_extend:DI (not:SI (match_dup 3))))]
9014 "ix86_match_ccmode (insn, CCNOmode)"
9015 [(parallel [(set (match_dup 0)
9016 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9019 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9021 ;; Shift instructions
9023 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9024 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9025 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9026 ;; from the assembler input.
9028 ;; This instruction shifts the target reg/mem as usual, but instead of
9029 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9030 ;; is a left shift double, bits are taken from the high order bits of
9031 ;; reg, else if the insn is a shift right double, bits are taken from the
9032 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9033 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9035 ;; Since sh[lr]d does not change the `reg' operand, that is done
9036 ;; separately, making all shifts emit pairs of shift double and normal
9037 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9038 ;; support a 63 bit shift, each shift where the count is in a reg expands
9039 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9041 ;; If the shift count is a constant, we need never emit more than one
9042 ;; shift pair, instead using moves and sign extension for counts greater
9045 (define_expand "ashl<mode>3"
9046 [(set (match_operand:SDWIM 0 "<shift_operand>")
9047 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9048 (match_operand:QI 2 "nonmemory_operand")))]
9050 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9052 (define_insn "*ashl<mode>3_doubleword"
9053 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9054 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9055 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9056 (clobber (reg:CC FLAGS_REG))]
9059 [(set_attr "type" "multi")])
9062 [(set (match_operand:DWI 0 "register_operand")
9063 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9064 (match_operand:QI 2 "nonmemory_operand")))
9065 (clobber (reg:CC FLAGS_REG))]
9066 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9068 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9070 ;; By default we don't ask for a scratch register, because when DWImode
9071 ;; values are manipulated, registers are already at a premium. But if
9072 ;; we have one handy, we won't turn it away.
9075 [(match_scratch:DWIH 3 "r")
9076 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9078 (match_operand:<DWI> 1 "nonmemory_operand")
9079 (match_operand:QI 2 "nonmemory_operand")))
9080 (clobber (reg:CC FLAGS_REG))])
9084 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9086 (define_insn "x86_64_shld"
9087 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9088 (ior:DI (ashift:DI (match_dup 0)
9089 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9090 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9091 (minus:QI (const_int 64) (match_dup 2)))))
9092 (clobber (reg:CC FLAGS_REG))]
9094 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9095 [(set_attr "type" "ishift")
9096 (set_attr "prefix_0f" "1")
9097 (set_attr "mode" "DI")
9098 (set_attr "athlon_decode" "vector")
9099 (set_attr "amdfam10_decode" "vector")
9100 (set_attr "bdver1_decode" "vector")])
9102 (define_insn "x86_shld"
9103 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9104 (ior:SI (ashift:SI (match_dup 0)
9105 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9106 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9107 (minus:QI (const_int 32) (match_dup 2)))))
9108 (clobber (reg:CC FLAGS_REG))]
9110 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9111 [(set_attr "type" "ishift")
9112 (set_attr "prefix_0f" "1")
9113 (set_attr "mode" "SI")
9114 (set_attr "pent_pair" "np")
9115 (set_attr "athlon_decode" "vector")
9116 (set_attr "amdfam10_decode" "vector")
9117 (set_attr "bdver1_decode" "vector")])
9119 (define_expand "x86_shift<mode>_adj_1"
9120 [(set (reg:CCZ FLAGS_REG)
9121 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9124 (set (match_operand:SWI48 0 "register_operand")
9125 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9126 (match_operand:SWI48 1 "register_operand")
9129 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9130 (match_operand:SWI48 3 "register_operand")
9133 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9135 (define_expand "x86_shift<mode>_adj_2"
9136 [(use (match_operand:SWI48 0 "register_operand"))
9137 (use (match_operand:SWI48 1 "register_operand"))
9138 (use (match_operand:QI 2 "register_operand"))]
9141 rtx label = gen_label_rtx ();
9144 emit_insn (gen_testqi_ccz_1 (operands[2],
9145 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9147 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9148 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9149 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9150 gen_rtx_LABEL_REF (VOIDmode, label),
9152 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9153 JUMP_LABEL (tmp) = label;
9155 emit_move_insn (operands[0], operands[1]);
9156 ix86_expand_clear (operands[1]);
9159 LABEL_NUSES (label) = 1;
9164 ;; Avoid useless masking of count operand.
9165 (define_insn "*ashl<mode>3_mask"
9166 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9168 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9171 (match_operand:SI 2 "register_operand" "c")
9172 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9173 (clobber (reg:CC FLAGS_REG))]
9174 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9175 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9176 == GET_MODE_BITSIZE (<MODE>mode)-1"
9178 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9180 [(set_attr "type" "ishift")
9181 (set_attr "mode" "<MODE>")])
9183 (define_insn "*bmi2_ashl<mode>3_1"
9184 [(set (match_operand:SWI48 0 "register_operand" "=r")
9185 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9186 (match_operand:SWI48 2 "register_operand" "r")))]
9188 "shlx\t{%2, %1, %0|%0, %1, %2}"
9189 [(set_attr "type" "ishiftx")
9190 (set_attr "mode" "<MODE>")])
9192 (define_insn "*ashl<mode>3_1"
9193 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9194 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9195 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9196 (clobber (reg:CC FLAGS_REG))]
9197 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9199 switch (get_attr_type (insn))
9206 gcc_assert (operands[2] == const1_rtx);
9207 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9208 return "add{<imodesuffix>}\t%0, %0";
9211 if (operands[2] == const1_rtx
9212 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9213 return "sal{<imodesuffix>}\t%0";
9215 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9218 [(set_attr "isa" "*,*,bmi2")
9220 (cond [(eq_attr "alternative" "1")
9221 (const_string "lea")
9222 (eq_attr "alternative" "2")
9223 (const_string "ishiftx")
9224 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9225 (match_operand 0 "register_operand"))
9226 (match_operand 2 "const1_operand"))
9227 (const_string "alu")
9229 (const_string "ishift")))
9230 (set (attr "length_immediate")
9232 (ior (eq_attr "type" "alu")
9233 (and (eq_attr "type" "ishift")
9234 (and (match_operand 2 "const1_operand")
9235 (ior (match_test "TARGET_SHIFT1")
9236 (match_test "optimize_function_for_size_p (cfun)")))))
9238 (const_string "*")))
9239 (set_attr "mode" "<MODE>")])
9241 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9243 [(set (match_operand:SWI48 0 "register_operand")
9244 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9245 (match_operand:QI 2 "register_operand")))
9246 (clobber (reg:CC FLAGS_REG))]
9247 "TARGET_BMI2 && reload_completed"
9249 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9250 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9252 (define_insn "*bmi2_ashlsi3_1_zext"
9253 [(set (match_operand:DI 0 "register_operand" "=r")
9255 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9256 (match_operand:SI 2 "register_operand" "r"))))]
9257 "TARGET_64BIT && TARGET_BMI2"
9258 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9259 [(set_attr "type" "ishiftx")
9260 (set_attr "mode" "SI")])
9262 (define_insn "*ashlsi3_1_zext"
9263 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9265 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9266 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9267 (clobber (reg:CC FLAGS_REG))]
9268 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9270 switch (get_attr_type (insn))
9277 gcc_assert (operands[2] == const1_rtx);
9278 return "add{l}\t%k0, %k0";
9281 if (operands[2] == const1_rtx
9282 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9283 return "sal{l}\t%k0";
9285 return "sal{l}\t{%2, %k0|%k0, %2}";
9288 [(set_attr "isa" "*,*,bmi2")
9290 (cond [(eq_attr "alternative" "1")
9291 (const_string "lea")
9292 (eq_attr "alternative" "2")
9293 (const_string "ishiftx")
9294 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9295 (match_operand 2 "const1_operand"))
9296 (const_string "alu")
9298 (const_string "ishift")))
9299 (set (attr "length_immediate")
9301 (ior (eq_attr "type" "alu")
9302 (and (eq_attr "type" "ishift")
9303 (and (match_operand 2 "const1_operand")
9304 (ior (match_test "TARGET_SHIFT1")
9305 (match_test "optimize_function_for_size_p (cfun)")))))
9307 (const_string "*")))
9308 (set_attr "mode" "SI")])
9310 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9312 [(set (match_operand:DI 0 "register_operand")
9314 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9315 (match_operand:QI 2 "register_operand"))))
9316 (clobber (reg:CC FLAGS_REG))]
9317 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9319 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9320 "operands[2] = gen_lowpart (SImode, operands[2]);")
9322 (define_insn "*ashlhi3_1"
9323 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9324 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9325 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9326 (clobber (reg:CC FLAGS_REG))]
9327 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9329 switch (get_attr_type (insn))
9335 gcc_assert (operands[2] == const1_rtx);
9336 return "add{w}\t%0, %0";
9339 if (operands[2] == const1_rtx
9340 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9341 return "sal{w}\t%0";
9343 return "sal{w}\t{%2, %0|%0, %2}";
9347 (cond [(eq_attr "alternative" "1")
9348 (const_string "lea")
9349 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9350 (match_operand 0 "register_operand"))
9351 (match_operand 2 "const1_operand"))
9352 (const_string "alu")
9354 (const_string "ishift")))
9355 (set (attr "length_immediate")
9357 (ior (eq_attr "type" "alu")
9358 (and (eq_attr "type" "ishift")
9359 (and (match_operand 2 "const1_operand")
9360 (ior (match_test "TARGET_SHIFT1")
9361 (match_test "optimize_function_for_size_p (cfun)")))))
9363 (const_string "*")))
9364 (set_attr "mode" "HI,SI")])
9366 ;; %%% Potential partial reg stall on alternative 1. What to do?
9367 (define_insn "*ashlqi3_1"
9368 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9369 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9370 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9371 (clobber (reg:CC FLAGS_REG))]
9372 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9374 switch (get_attr_type (insn))
9380 gcc_assert (operands[2] == const1_rtx);
9381 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9382 return "add{l}\t%k0, %k0";
9384 return "add{b}\t%0, %0";
9387 if (operands[2] == const1_rtx
9388 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9390 if (get_attr_mode (insn) == MODE_SI)
9391 return "sal{l}\t%k0";
9393 return "sal{b}\t%0";
9397 if (get_attr_mode (insn) == MODE_SI)
9398 return "sal{l}\t{%2, %k0|%k0, %2}";
9400 return "sal{b}\t{%2, %0|%0, %2}";
9405 (cond [(eq_attr "alternative" "2")
9406 (const_string "lea")
9407 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9408 (match_operand 0 "register_operand"))
9409 (match_operand 2 "const1_operand"))
9410 (const_string "alu")
9412 (const_string "ishift")))
9413 (set (attr "length_immediate")
9415 (ior (eq_attr "type" "alu")
9416 (and (eq_attr "type" "ishift")
9417 (and (match_operand 2 "const1_operand")
9418 (ior (match_test "TARGET_SHIFT1")
9419 (match_test "optimize_function_for_size_p (cfun)")))))
9421 (const_string "*")))
9422 (set_attr "mode" "QI,SI,SI")])
9424 (define_insn "*ashlqi3_1_slp"
9425 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9426 (ashift:QI (match_dup 0)
9427 (match_operand:QI 1 "nonmemory_operand" "cI")))
9428 (clobber (reg:CC FLAGS_REG))]
9429 "(optimize_function_for_size_p (cfun)
9430 || !TARGET_PARTIAL_FLAG_REG_STALL
9431 || (operands[1] == const1_rtx
9433 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9435 switch (get_attr_type (insn))
9438 gcc_assert (operands[1] == const1_rtx);
9439 return "add{b}\t%0, %0";
9442 if (operands[1] == const1_rtx
9443 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9444 return "sal{b}\t%0";
9446 return "sal{b}\t{%1, %0|%0, %1}";
9450 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9451 (match_operand 0 "register_operand"))
9452 (match_operand 1 "const1_operand"))
9453 (const_string "alu")
9455 (const_string "ishift1")))
9456 (set (attr "length_immediate")
9458 (ior (eq_attr "type" "alu")
9459 (and (eq_attr "type" "ishift1")
9460 (and (match_operand 1 "const1_operand")
9461 (ior (match_test "TARGET_SHIFT1")
9462 (match_test "optimize_function_for_size_p (cfun)")))))
9464 (const_string "*")))
9465 (set_attr "mode" "QI")])
9467 ;; Convert ashift to the lea pattern to avoid flags dependency.
9469 [(set (match_operand 0 "register_operand")
9470 (ashift (match_operand 1 "index_register_operand")
9471 (match_operand:QI 2 "const_int_operand")))
9472 (clobber (reg:CC FLAGS_REG))]
9473 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9475 && true_regnum (operands[0]) != true_regnum (operands[1])"
9478 enum machine_mode mode = GET_MODE (operands[0]);
9481 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9484 operands[0] = gen_lowpart (mode, operands[0]);
9485 operands[1] = gen_lowpart (mode, operands[1]);
9488 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9490 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9492 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9496 ;; Convert ashift to the lea pattern to avoid flags dependency.
9498 [(set (match_operand:DI 0 "register_operand")
9500 (ashift:SI (match_operand:SI 1 "index_register_operand")
9501 (match_operand:QI 2 "const_int_operand"))))
9502 (clobber (reg:CC FLAGS_REG))]
9503 "TARGET_64BIT && reload_completed
9504 && true_regnum (operands[0]) != true_regnum (operands[1])"
9506 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9508 operands[1] = gen_lowpart (SImode, operands[1]);
9509 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9512 ;; This pattern can't accept a variable shift count, since shifts by
9513 ;; zero don't affect the flags. We assume that shifts by constant
9514 ;; zero are optimized away.
9515 (define_insn "*ashl<mode>3_cmp"
9516 [(set (reg FLAGS_REG)
9518 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9519 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9521 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9522 (ashift:SWI (match_dup 1) (match_dup 2)))]
9523 "(optimize_function_for_size_p (cfun)
9524 || !TARGET_PARTIAL_FLAG_REG_STALL
9525 || (operands[2] == const1_rtx
9527 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9528 && ix86_match_ccmode (insn, CCGOCmode)
9529 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9531 switch (get_attr_type (insn))
9534 gcc_assert (operands[2] == const1_rtx);
9535 return "add{<imodesuffix>}\t%0, %0";
9538 if (operands[2] == const1_rtx
9539 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9540 return "sal{<imodesuffix>}\t%0";
9542 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9546 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9547 (match_operand 0 "register_operand"))
9548 (match_operand 2 "const1_operand"))
9549 (const_string "alu")
9551 (const_string "ishift")))
9552 (set (attr "length_immediate")
9554 (ior (eq_attr "type" "alu")
9555 (and (eq_attr "type" "ishift")
9556 (and (match_operand 2 "const1_operand")
9557 (ior (match_test "TARGET_SHIFT1")
9558 (match_test "optimize_function_for_size_p (cfun)")))))
9560 (const_string "*")))
9561 (set_attr "mode" "<MODE>")])
9563 (define_insn "*ashlsi3_cmp_zext"
9564 [(set (reg FLAGS_REG)
9566 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9567 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9569 (set (match_operand:DI 0 "register_operand" "=r")
9570 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9572 && (optimize_function_for_size_p (cfun)
9573 || !TARGET_PARTIAL_FLAG_REG_STALL
9574 || (operands[2] == const1_rtx
9576 || TARGET_DOUBLE_WITH_ADD)))
9577 && ix86_match_ccmode (insn, CCGOCmode)
9578 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9580 switch (get_attr_type (insn))
9583 gcc_assert (operands[2] == const1_rtx);
9584 return "add{l}\t%k0, %k0";
9587 if (operands[2] == const1_rtx
9588 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9589 return "sal{l}\t%k0";
9591 return "sal{l}\t{%2, %k0|%k0, %2}";
9595 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9596 (match_operand 2 "const1_operand"))
9597 (const_string "alu")
9599 (const_string "ishift")))
9600 (set (attr "length_immediate")
9602 (ior (eq_attr "type" "alu")
9603 (and (eq_attr "type" "ishift")
9604 (and (match_operand 2 "const1_operand")
9605 (ior (match_test "TARGET_SHIFT1")
9606 (match_test "optimize_function_for_size_p (cfun)")))))
9608 (const_string "*")))
9609 (set_attr "mode" "SI")])
9611 (define_insn "*ashl<mode>3_cconly"
9612 [(set (reg FLAGS_REG)
9614 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9615 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9617 (clobber (match_scratch:SWI 0 "=<r>"))]
9618 "(optimize_function_for_size_p (cfun)
9619 || !TARGET_PARTIAL_FLAG_REG_STALL
9620 || (operands[2] == const1_rtx
9622 || TARGET_DOUBLE_WITH_ADD)))
9623 && ix86_match_ccmode (insn, CCGOCmode)"
9625 switch (get_attr_type (insn))
9628 gcc_assert (operands[2] == const1_rtx);
9629 return "add{<imodesuffix>}\t%0, %0";
9632 if (operands[2] == const1_rtx
9633 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9634 return "sal{<imodesuffix>}\t%0";
9636 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9640 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9641 (match_operand 0 "register_operand"))
9642 (match_operand 2 "const1_operand"))
9643 (const_string "alu")
9645 (const_string "ishift")))
9646 (set (attr "length_immediate")
9648 (ior (eq_attr "type" "alu")
9649 (and (eq_attr "type" "ishift")
9650 (and (match_operand 2 "const1_operand")
9651 (ior (match_test "TARGET_SHIFT1")
9652 (match_test "optimize_function_for_size_p (cfun)")))))
9654 (const_string "*")))
9655 (set_attr "mode" "<MODE>")])
9657 ;; See comment above `ashl<mode>3' about how this works.
9659 (define_expand "<shift_insn><mode>3"
9660 [(set (match_operand:SDWIM 0 "<shift_operand>")
9661 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9662 (match_operand:QI 2 "nonmemory_operand")))]
9664 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9666 ;; Avoid useless masking of count operand.
9667 (define_insn "*<shift_insn><mode>3_mask"
9668 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9670 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9673 (match_operand:SI 2 "register_operand" "c")
9674 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9675 (clobber (reg:CC FLAGS_REG))]
9676 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9677 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9678 == GET_MODE_BITSIZE (<MODE>mode)-1"
9680 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9682 [(set_attr "type" "ishift")
9683 (set_attr "mode" "<MODE>")])
9685 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9686 [(set (match_operand:DWI 0 "register_operand" "=r")
9687 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9688 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9689 (clobber (reg:CC FLAGS_REG))]
9692 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9694 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9695 [(set_attr "type" "multi")])
9697 ;; By default we don't ask for a scratch register, because when DWImode
9698 ;; values are manipulated, registers are already at a premium. But if
9699 ;; we have one handy, we won't turn it away.
9702 [(match_scratch:DWIH 3 "r")
9703 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9705 (match_operand:<DWI> 1 "register_operand")
9706 (match_operand:QI 2 "nonmemory_operand")))
9707 (clobber (reg:CC FLAGS_REG))])
9711 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9713 (define_insn "x86_64_shrd"
9714 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9715 (ior:DI (ashiftrt:DI (match_dup 0)
9716 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9717 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9718 (minus:QI (const_int 64) (match_dup 2)))))
9719 (clobber (reg:CC FLAGS_REG))]
9721 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9722 [(set_attr "type" "ishift")
9723 (set_attr "prefix_0f" "1")
9724 (set_attr "mode" "DI")
9725 (set_attr "athlon_decode" "vector")
9726 (set_attr "amdfam10_decode" "vector")
9727 (set_attr "bdver1_decode" "vector")])
9729 (define_insn "x86_shrd"
9730 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9731 (ior:SI (ashiftrt:SI (match_dup 0)
9732 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9733 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9734 (minus:QI (const_int 32) (match_dup 2)))))
9735 (clobber (reg:CC FLAGS_REG))]
9737 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9738 [(set_attr "type" "ishift")
9739 (set_attr "prefix_0f" "1")
9740 (set_attr "mode" "SI")
9741 (set_attr "pent_pair" "np")
9742 (set_attr "athlon_decode" "vector")
9743 (set_attr "amdfam10_decode" "vector")
9744 (set_attr "bdver1_decode" "vector")])
9746 (define_insn "ashrdi3_cvt"
9747 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9748 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9749 (match_operand:QI 2 "const_int_operand")))
9750 (clobber (reg:CC FLAGS_REG))]
9751 "TARGET_64BIT && INTVAL (operands[2]) == 63
9752 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9753 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9756 sar{q}\t{%2, %0|%0, %2}"
9757 [(set_attr "type" "imovx,ishift")
9758 (set_attr "prefix_0f" "0,*")
9759 (set_attr "length_immediate" "0,*")
9760 (set_attr "modrm" "0,1")
9761 (set_attr "mode" "DI")])
9763 (define_insn "ashrsi3_cvt"
9764 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9765 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9766 (match_operand:QI 2 "const_int_operand")))
9767 (clobber (reg:CC FLAGS_REG))]
9768 "INTVAL (operands[2]) == 31
9769 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9770 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9773 sar{l}\t{%2, %0|%0, %2}"
9774 [(set_attr "type" "imovx,ishift")
9775 (set_attr "prefix_0f" "0,*")
9776 (set_attr "length_immediate" "0,*")
9777 (set_attr "modrm" "0,1")
9778 (set_attr "mode" "SI")])
9780 (define_insn "*ashrsi3_cvt_zext"
9781 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9783 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9784 (match_operand:QI 2 "const_int_operand"))))
9785 (clobber (reg:CC FLAGS_REG))]
9786 "TARGET_64BIT && INTVAL (operands[2]) == 31
9787 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9788 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9791 sar{l}\t{%2, %k0|%k0, %2}"
9792 [(set_attr "type" "imovx,ishift")
9793 (set_attr "prefix_0f" "0,*")
9794 (set_attr "length_immediate" "0,*")
9795 (set_attr "modrm" "0,1")
9796 (set_attr "mode" "SI")])
9798 (define_expand "x86_shift<mode>_adj_3"
9799 [(use (match_operand:SWI48 0 "register_operand"))
9800 (use (match_operand:SWI48 1 "register_operand"))
9801 (use (match_operand:QI 2 "register_operand"))]
9804 rtx label = gen_label_rtx ();
9807 emit_insn (gen_testqi_ccz_1 (operands[2],
9808 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9810 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9811 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9812 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9813 gen_rtx_LABEL_REF (VOIDmode, label),
9815 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9816 JUMP_LABEL (tmp) = label;
9818 emit_move_insn (operands[0], operands[1]);
9819 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9820 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9822 LABEL_NUSES (label) = 1;
9827 (define_insn "*bmi2_<shift_insn><mode>3_1"
9828 [(set (match_operand:SWI48 0 "register_operand" "=r")
9829 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9830 (match_operand:SWI48 2 "register_operand" "r")))]
9832 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9833 [(set_attr "type" "ishiftx")
9834 (set_attr "mode" "<MODE>")])
9836 (define_insn "*<shift_insn><mode>3_1"
9837 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9839 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9840 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9841 (clobber (reg:CC FLAGS_REG))]
9842 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9844 switch (get_attr_type (insn))
9850 if (operands[2] == const1_rtx
9851 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9852 return "<shift>{<imodesuffix>}\t%0";
9854 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9857 [(set_attr "isa" "*,bmi2")
9858 (set_attr "type" "ishift,ishiftx")
9859 (set (attr "length_immediate")
9861 (and (match_operand 2 "const1_operand")
9862 (ior (match_test "TARGET_SHIFT1")
9863 (match_test "optimize_function_for_size_p (cfun)")))
9865 (const_string "*")))
9866 (set_attr "mode" "<MODE>")])
9868 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9870 [(set (match_operand:SWI48 0 "register_operand")
9871 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9872 (match_operand:QI 2 "register_operand")))
9873 (clobber (reg:CC FLAGS_REG))]
9874 "TARGET_BMI2 && reload_completed"
9876 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9877 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9879 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9880 [(set (match_operand:DI 0 "register_operand" "=r")
9882 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9883 (match_operand:SI 2 "register_operand" "r"))))]
9884 "TARGET_64BIT && TARGET_BMI2"
9885 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9886 [(set_attr "type" "ishiftx")
9887 (set_attr "mode" "SI")])
9889 (define_insn "*<shift_insn>si3_1_zext"
9890 [(set (match_operand:DI 0 "register_operand" "=r,r")
9892 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9893 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9894 (clobber (reg:CC FLAGS_REG))]
9895 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9897 switch (get_attr_type (insn))
9903 if (operands[2] == const1_rtx
9904 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9905 return "<shift>{l}\t%k0";
9907 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9910 [(set_attr "isa" "*,bmi2")
9911 (set_attr "type" "ishift,ishiftx")
9912 (set (attr "length_immediate")
9914 (and (match_operand 2 "const1_operand")
9915 (ior (match_test "TARGET_SHIFT1")
9916 (match_test "optimize_function_for_size_p (cfun)")))
9918 (const_string "*")))
9919 (set_attr "mode" "SI")])
9921 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9923 [(set (match_operand:DI 0 "register_operand")
9925 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9926 (match_operand:QI 2 "register_operand"))))
9927 (clobber (reg:CC FLAGS_REG))]
9928 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9930 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9931 "operands[2] = gen_lowpart (SImode, operands[2]);")
9933 (define_insn "*<shift_insn><mode>3_1"
9934 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9936 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9937 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9938 (clobber (reg:CC FLAGS_REG))]
9939 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9941 if (operands[2] == const1_rtx
9942 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9943 return "<shift>{<imodesuffix>}\t%0";
9945 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9947 [(set_attr "type" "ishift")
9948 (set (attr "length_immediate")
9950 (and (match_operand 2 "const1_operand")
9951 (ior (match_test "TARGET_SHIFT1")
9952 (match_test "optimize_function_for_size_p (cfun)")))
9954 (const_string "*")))
9955 (set_attr "mode" "<MODE>")])
9957 (define_insn "*<shift_insn>qi3_1_slp"
9958 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9959 (any_shiftrt:QI (match_dup 0)
9960 (match_operand:QI 1 "nonmemory_operand" "cI")))
9961 (clobber (reg:CC FLAGS_REG))]
9962 "(optimize_function_for_size_p (cfun)
9963 || !TARGET_PARTIAL_REG_STALL
9964 || (operands[1] == const1_rtx
9967 if (operands[1] == const1_rtx
9968 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9969 return "<shift>{b}\t%0";
9971 return "<shift>{b}\t{%1, %0|%0, %1}";
9973 [(set_attr "type" "ishift1")
9974 (set (attr "length_immediate")
9976 (and (match_operand 1 "const1_operand")
9977 (ior (match_test "TARGET_SHIFT1")
9978 (match_test "optimize_function_for_size_p (cfun)")))
9980 (const_string "*")))
9981 (set_attr "mode" "QI")])
9983 ;; This pattern can't accept a variable shift count, since shifts by
9984 ;; zero don't affect the flags. We assume that shifts by constant
9985 ;; zero are optimized away.
9986 (define_insn "*<shift_insn><mode>3_cmp"
9987 [(set (reg FLAGS_REG)
9990 (match_operand:SWI 1 "nonimmediate_operand" "0")
9991 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9993 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9994 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9995 "(optimize_function_for_size_p (cfun)
9996 || !TARGET_PARTIAL_FLAG_REG_STALL
9997 || (operands[2] == const1_rtx
9999 && ix86_match_ccmode (insn, CCGOCmode)
10000 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10002 if (operands[2] == const1_rtx
10003 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10004 return "<shift>{<imodesuffix>}\t%0";
10006 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10008 [(set_attr "type" "ishift")
10009 (set (attr "length_immediate")
10011 (and (match_operand 2 "const1_operand")
10012 (ior (match_test "TARGET_SHIFT1")
10013 (match_test "optimize_function_for_size_p (cfun)")))
10015 (const_string "*")))
10016 (set_attr "mode" "<MODE>")])
10018 (define_insn "*<shift_insn>si3_cmp_zext"
10019 [(set (reg FLAGS_REG)
10021 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10022 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10024 (set (match_operand:DI 0 "register_operand" "=r")
10025 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10027 && (optimize_function_for_size_p (cfun)
10028 || !TARGET_PARTIAL_FLAG_REG_STALL
10029 || (operands[2] == const1_rtx
10031 && ix86_match_ccmode (insn, CCGOCmode)
10032 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10034 if (operands[2] == const1_rtx
10035 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10036 return "<shift>{l}\t%k0";
10038 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10040 [(set_attr "type" "ishift")
10041 (set (attr "length_immediate")
10043 (and (match_operand 2 "const1_operand")
10044 (ior (match_test "TARGET_SHIFT1")
10045 (match_test "optimize_function_for_size_p (cfun)")))
10047 (const_string "*")))
10048 (set_attr "mode" "SI")])
10050 (define_insn "*<shift_insn><mode>3_cconly"
10051 [(set (reg FLAGS_REG)
10054 (match_operand:SWI 1 "register_operand" "0")
10055 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10057 (clobber (match_scratch:SWI 0 "=<r>"))]
10058 "(optimize_function_for_size_p (cfun)
10059 || !TARGET_PARTIAL_FLAG_REG_STALL
10060 || (operands[2] == const1_rtx
10062 && ix86_match_ccmode (insn, CCGOCmode)"
10064 if (operands[2] == const1_rtx
10065 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10066 return "<shift>{<imodesuffix>}\t%0";
10068 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10070 [(set_attr "type" "ishift")
10071 (set (attr "length_immediate")
10073 (and (match_operand 2 "const1_operand")
10074 (ior (match_test "TARGET_SHIFT1")
10075 (match_test "optimize_function_for_size_p (cfun)")))
10077 (const_string "*")))
10078 (set_attr "mode" "<MODE>")])
10080 ;; Rotate instructions
10082 (define_expand "<rotate_insn>ti3"
10083 [(set (match_operand:TI 0 "register_operand")
10084 (any_rotate:TI (match_operand:TI 1 "register_operand")
10085 (match_operand:QI 2 "nonmemory_operand")))]
10088 if (const_1_to_63_operand (operands[2], VOIDmode))
10089 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10090 (operands[0], operands[1], operands[2]));
10097 (define_expand "<rotate_insn>di3"
10098 [(set (match_operand:DI 0 "shiftdi_operand")
10099 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10100 (match_operand:QI 2 "nonmemory_operand")))]
10104 ix86_expand_binary_operator (<CODE>, DImode, operands);
10105 else if (const_1_to_31_operand (operands[2], VOIDmode))
10106 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10107 (operands[0], operands[1], operands[2]));
10114 (define_expand "<rotate_insn><mode>3"
10115 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10116 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10117 (match_operand:QI 2 "nonmemory_operand")))]
10119 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10121 ;; Avoid useless masking of count operand.
10122 (define_insn "*<rotate_insn><mode>3_mask"
10123 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10125 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10128 (match_operand:SI 2 "register_operand" "c")
10129 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10130 (clobber (reg:CC FLAGS_REG))]
10131 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10132 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10133 == GET_MODE_BITSIZE (<MODE>mode)-1"
10135 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10137 [(set_attr "type" "rotate")
10138 (set_attr "mode" "<MODE>")])
10140 ;; Implement rotation using two double-precision
10141 ;; shift instructions and a scratch register.
10143 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10144 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10145 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10146 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10147 (clobber (reg:CC FLAGS_REG))
10148 (clobber (match_scratch:DWIH 3 "=&r"))]
10152 [(set (match_dup 3) (match_dup 4))
10154 [(set (match_dup 4)
10155 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10156 (lshiftrt:DWIH (match_dup 5)
10157 (minus:QI (match_dup 6) (match_dup 2)))))
10158 (clobber (reg:CC FLAGS_REG))])
10160 [(set (match_dup 5)
10161 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10162 (lshiftrt:DWIH (match_dup 3)
10163 (minus:QI (match_dup 6) (match_dup 2)))))
10164 (clobber (reg:CC FLAGS_REG))])]
10166 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10168 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10171 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10172 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10173 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10174 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10175 (clobber (reg:CC FLAGS_REG))
10176 (clobber (match_scratch:DWIH 3 "=&r"))]
10180 [(set (match_dup 3) (match_dup 4))
10182 [(set (match_dup 4)
10183 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10184 (ashift:DWIH (match_dup 5)
10185 (minus:QI (match_dup 6) (match_dup 2)))))
10186 (clobber (reg:CC FLAGS_REG))])
10188 [(set (match_dup 5)
10189 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10190 (ashift:DWIH (match_dup 3)
10191 (minus:QI (match_dup 6) (match_dup 2)))))
10192 (clobber (reg:CC FLAGS_REG))])]
10194 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10196 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10199 (define_insn "*bmi2_rorx<mode>3_1"
10200 [(set (match_operand:SWI48 0 "register_operand" "=r")
10201 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10202 (match_operand:QI 2 "immediate_operand" "<S>")))]
10204 "rorx\t{%2, %1, %0|%0, %1, %2}"
10205 [(set_attr "type" "rotatex")
10206 (set_attr "mode" "<MODE>")])
10208 (define_insn "*<rotate_insn><mode>3_1"
10209 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10211 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10212 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10213 (clobber (reg:CC FLAGS_REG))]
10214 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10216 switch (get_attr_type (insn))
10222 if (operands[2] == const1_rtx
10223 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10224 return "<rotate>{<imodesuffix>}\t%0";
10226 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10229 [(set_attr "isa" "*,bmi2")
10230 (set_attr "type" "rotate,rotatex")
10231 (set (attr "length_immediate")
10233 (and (eq_attr "type" "rotate")
10234 (and (match_operand 2 "const1_operand")
10235 (ior (match_test "TARGET_SHIFT1")
10236 (match_test "optimize_function_for_size_p (cfun)"))))
10238 (const_string "*")))
10239 (set_attr "mode" "<MODE>")])
10241 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10243 [(set (match_operand:SWI48 0 "register_operand")
10244 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10245 (match_operand:QI 2 "immediate_operand")))
10246 (clobber (reg:CC FLAGS_REG))]
10247 "TARGET_BMI2 && reload_completed"
10248 [(set (match_dup 0)
10249 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10252 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10256 [(set (match_operand:SWI48 0 "register_operand")
10257 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10258 (match_operand:QI 2 "immediate_operand")))
10259 (clobber (reg:CC FLAGS_REG))]
10260 "TARGET_BMI2 && reload_completed"
10261 [(set (match_dup 0)
10262 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10264 (define_insn "*bmi2_rorxsi3_1_zext"
10265 [(set (match_operand:DI 0 "register_operand" "=r")
10267 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10268 (match_operand:QI 2 "immediate_operand" "I"))))]
10269 "TARGET_64BIT && TARGET_BMI2"
10270 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10271 [(set_attr "type" "rotatex")
10272 (set_attr "mode" "SI")])
10274 (define_insn "*<rotate_insn>si3_1_zext"
10275 [(set (match_operand:DI 0 "register_operand" "=r,r")
10277 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10278 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10279 (clobber (reg:CC FLAGS_REG))]
10280 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10282 switch (get_attr_type (insn))
10288 if (operands[2] == const1_rtx
10289 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10290 return "<rotate>{l}\t%k0";
10292 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10295 [(set_attr "isa" "*,bmi2")
10296 (set_attr "type" "rotate,rotatex")
10297 (set (attr "length_immediate")
10299 (and (eq_attr "type" "rotate")
10300 (and (match_operand 2 "const1_operand")
10301 (ior (match_test "TARGET_SHIFT1")
10302 (match_test "optimize_function_for_size_p (cfun)"))))
10304 (const_string "*")))
10305 (set_attr "mode" "SI")])
10307 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10309 [(set (match_operand:DI 0 "register_operand")
10311 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10312 (match_operand:QI 2 "immediate_operand"))))
10313 (clobber (reg:CC FLAGS_REG))]
10314 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10315 [(set (match_dup 0)
10316 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10319 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10323 [(set (match_operand:DI 0 "register_operand")
10325 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10326 (match_operand:QI 2 "immediate_operand"))))
10327 (clobber (reg:CC FLAGS_REG))]
10328 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10329 [(set (match_dup 0)
10330 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10332 (define_insn "*<rotate_insn><mode>3_1"
10333 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10334 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10335 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10336 (clobber (reg:CC FLAGS_REG))]
10337 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10339 if (operands[2] == const1_rtx
10340 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10341 return "<rotate>{<imodesuffix>}\t%0";
10343 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10345 [(set_attr "type" "rotate")
10346 (set (attr "length_immediate")
10348 (and (match_operand 2 "const1_operand")
10349 (ior (match_test "TARGET_SHIFT1")
10350 (match_test "optimize_function_for_size_p (cfun)")))
10352 (const_string "*")))
10353 (set_attr "mode" "<MODE>")])
10355 (define_insn "*<rotate_insn>qi3_1_slp"
10356 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10357 (any_rotate:QI (match_dup 0)
10358 (match_operand:QI 1 "nonmemory_operand" "cI")))
10359 (clobber (reg:CC FLAGS_REG))]
10360 "(optimize_function_for_size_p (cfun)
10361 || !TARGET_PARTIAL_REG_STALL
10362 || (operands[1] == const1_rtx
10363 && TARGET_SHIFT1))"
10365 if (operands[1] == const1_rtx
10366 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10367 return "<rotate>{b}\t%0";
10369 return "<rotate>{b}\t{%1, %0|%0, %1}";
10371 [(set_attr "type" "rotate1")
10372 (set (attr "length_immediate")
10374 (and (match_operand 1 "const1_operand")
10375 (ior (match_test "TARGET_SHIFT1")
10376 (match_test "optimize_function_for_size_p (cfun)")))
10378 (const_string "*")))
10379 (set_attr "mode" "QI")])
10382 [(set (match_operand:HI 0 "register_operand")
10383 (any_rotate:HI (match_dup 0) (const_int 8)))
10384 (clobber (reg:CC FLAGS_REG))]
10386 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10387 [(parallel [(set (strict_low_part (match_dup 0))
10388 (bswap:HI (match_dup 0)))
10389 (clobber (reg:CC FLAGS_REG))])])
10391 ;; Bit set / bit test instructions
10393 (define_expand "extv"
10394 [(set (match_operand:SI 0 "register_operand")
10395 (sign_extract:SI (match_operand:SI 1 "register_operand")
10396 (match_operand:SI 2 "const8_operand")
10397 (match_operand:SI 3 "const8_operand")))]
10400 /* Handle extractions from %ah et al. */
10401 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10404 /* From mips.md: extract_bit_field doesn't verify that our source
10405 matches the predicate, so check it again here. */
10406 if (! ext_register_operand (operands[1], VOIDmode))
10410 (define_expand "extzv"
10411 [(set (match_operand:SI 0 "register_operand")
10412 (zero_extract:SI (match_operand 1 "ext_register_operand")
10413 (match_operand:SI 2 "const8_operand")
10414 (match_operand:SI 3 "const8_operand")))]
10417 /* Handle extractions from %ah et al. */
10418 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10421 /* From mips.md: extract_bit_field doesn't verify that our source
10422 matches the predicate, so check it again here. */
10423 if (! ext_register_operand (operands[1], VOIDmode))
10427 (define_expand "insv"
10428 [(set (zero_extract (match_operand 0 "register_operand")
10429 (match_operand 1 "const_int_operand")
10430 (match_operand 2 "const_int_operand"))
10431 (match_operand 3 "register_operand"))]
10434 rtx (*gen_mov_insv_1) (rtx, rtx);
10436 if (ix86_expand_pinsr (operands))
10439 /* Handle insertions to %ah et al. */
10440 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10443 /* From mips.md: insert_bit_field doesn't verify that our source
10444 matches the predicate, so check it again here. */
10445 if (! ext_register_operand (operands[0], VOIDmode))
10448 gen_mov_insv_1 = (TARGET_64BIT
10449 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10451 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10455 ;; %%% bts, btr, btc, bt.
10456 ;; In general these instructions are *slow* when applied to memory,
10457 ;; since they enforce atomic operation. When applied to registers,
10458 ;; it depends on the cpu implementation. They're never faster than
10459 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10460 ;; no point. But in 64-bit, we can't hold the relevant immediates
10461 ;; within the instruction itself, so operating on bits in the high
10462 ;; 32-bits of a register becomes easier.
10464 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10465 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10466 ;; negdf respectively, so they can never be disabled entirely.
10468 (define_insn "*btsq"
10469 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10471 (match_operand:DI 1 "const_0_to_63_operand"))
10473 (clobber (reg:CC FLAGS_REG))]
10474 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10475 "bts{q}\t{%1, %0|%0, %1}"
10476 [(set_attr "type" "alu1")
10477 (set_attr "prefix_0f" "1")
10478 (set_attr "mode" "DI")])
10480 (define_insn "*btrq"
10481 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10483 (match_operand:DI 1 "const_0_to_63_operand"))
10485 (clobber (reg:CC FLAGS_REG))]
10486 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10487 "btr{q}\t{%1, %0|%0, %1}"
10488 [(set_attr "type" "alu1")
10489 (set_attr "prefix_0f" "1")
10490 (set_attr "mode" "DI")])
10492 (define_insn "*btcq"
10493 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10495 (match_operand:DI 1 "const_0_to_63_operand"))
10496 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10497 (clobber (reg:CC FLAGS_REG))]
10498 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10499 "btc{q}\t{%1, %0|%0, %1}"
10500 [(set_attr "type" "alu1")
10501 (set_attr "prefix_0f" "1")
10502 (set_attr "mode" "DI")])
10504 ;; Allow Nocona to avoid these instructions if a register is available.
10507 [(match_scratch:DI 2 "r")
10508 (parallel [(set (zero_extract:DI
10509 (match_operand:DI 0 "register_operand")
10511 (match_operand:DI 1 "const_0_to_63_operand"))
10513 (clobber (reg:CC FLAGS_REG))])]
10514 "TARGET_64BIT && !TARGET_USE_BT"
10517 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10520 if (HOST_BITS_PER_WIDE_INT >= 64)
10521 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10522 else if (i < HOST_BITS_PER_WIDE_INT)
10523 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10525 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10527 op1 = immed_double_const (lo, hi, DImode);
10530 emit_move_insn (operands[2], op1);
10534 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10539 [(match_scratch:DI 2 "r")
10540 (parallel [(set (zero_extract:DI
10541 (match_operand:DI 0 "register_operand")
10543 (match_operand:DI 1 "const_0_to_63_operand"))
10545 (clobber (reg:CC FLAGS_REG))])]
10546 "TARGET_64BIT && !TARGET_USE_BT"
10549 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10552 if (HOST_BITS_PER_WIDE_INT >= 64)
10553 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10554 else if (i < HOST_BITS_PER_WIDE_INT)
10555 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10557 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10559 op1 = immed_double_const (~lo, ~hi, DImode);
10562 emit_move_insn (operands[2], op1);
10566 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10571 [(match_scratch:DI 2 "r")
10572 (parallel [(set (zero_extract:DI
10573 (match_operand:DI 0 "register_operand")
10575 (match_operand:DI 1 "const_0_to_63_operand"))
10576 (not:DI (zero_extract:DI
10577 (match_dup 0) (const_int 1) (match_dup 1))))
10578 (clobber (reg:CC FLAGS_REG))])]
10579 "TARGET_64BIT && !TARGET_USE_BT"
10582 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10585 if (HOST_BITS_PER_WIDE_INT >= 64)
10586 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10587 else if (i < HOST_BITS_PER_WIDE_INT)
10588 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10590 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10592 op1 = immed_double_const (lo, hi, DImode);
10595 emit_move_insn (operands[2], op1);
10599 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10603 (define_insn "*bt<mode>"
10604 [(set (reg:CCC FLAGS_REG)
10606 (zero_extract:SWI48
10607 (match_operand:SWI48 0 "register_operand" "r")
10609 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10611 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10612 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10613 [(set_attr "type" "alu1")
10614 (set_attr "prefix_0f" "1")
10615 (set_attr "mode" "<MODE>")])
10617 ;; Store-flag instructions.
10619 ;; For all sCOND expanders, also expand the compare or test insn that
10620 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10622 (define_insn_and_split "*setcc_di_1"
10623 [(set (match_operand:DI 0 "register_operand" "=q")
10624 (match_operator:DI 1 "ix86_comparison_operator"
10625 [(reg FLAGS_REG) (const_int 0)]))]
10626 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10628 "&& reload_completed"
10629 [(set (match_dup 2) (match_dup 1))
10630 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10632 PUT_MODE (operands[1], QImode);
10633 operands[2] = gen_lowpart (QImode, operands[0]);
10636 (define_insn_and_split "*setcc_si_1_and"
10637 [(set (match_operand:SI 0 "register_operand" "=q")
10638 (match_operator:SI 1 "ix86_comparison_operator"
10639 [(reg FLAGS_REG) (const_int 0)]))
10640 (clobber (reg:CC FLAGS_REG))]
10641 "!TARGET_PARTIAL_REG_STALL
10642 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10644 "&& reload_completed"
10645 [(set (match_dup 2) (match_dup 1))
10646 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10647 (clobber (reg:CC FLAGS_REG))])]
10649 PUT_MODE (operands[1], QImode);
10650 operands[2] = gen_lowpart (QImode, operands[0]);
10653 (define_insn_and_split "*setcc_si_1_movzbl"
10654 [(set (match_operand:SI 0 "register_operand" "=q")
10655 (match_operator:SI 1 "ix86_comparison_operator"
10656 [(reg FLAGS_REG) (const_int 0)]))]
10657 "!TARGET_PARTIAL_REG_STALL
10658 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10660 "&& reload_completed"
10661 [(set (match_dup 2) (match_dup 1))
10662 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10664 PUT_MODE (operands[1], QImode);
10665 operands[2] = gen_lowpart (QImode, operands[0]);
10668 (define_insn "*setcc_qi"
10669 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10670 (match_operator:QI 1 "ix86_comparison_operator"
10671 [(reg FLAGS_REG) (const_int 0)]))]
10674 [(set_attr "type" "setcc")
10675 (set_attr "mode" "QI")])
10677 (define_insn "*setcc_qi_slp"
10678 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10679 (match_operator:QI 1 "ix86_comparison_operator"
10680 [(reg FLAGS_REG) (const_int 0)]))]
10683 [(set_attr "type" "setcc")
10684 (set_attr "mode" "QI")])
10686 ;; In general it is not safe to assume too much about CCmode registers,
10687 ;; so simplify-rtx stops when it sees a second one. Under certain
10688 ;; conditions this is safe on x86, so help combine not create
10695 [(set (match_operand:QI 0 "nonimmediate_operand")
10696 (ne:QI (match_operator 1 "ix86_comparison_operator"
10697 [(reg FLAGS_REG) (const_int 0)])
10700 [(set (match_dup 0) (match_dup 1))]
10701 "PUT_MODE (operands[1], QImode);")
10704 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10705 (ne:QI (match_operator 1 "ix86_comparison_operator"
10706 [(reg FLAGS_REG) (const_int 0)])
10709 [(set (match_dup 0) (match_dup 1))]
10710 "PUT_MODE (operands[1], QImode);")
10713 [(set (match_operand:QI 0 "nonimmediate_operand")
10714 (eq:QI (match_operator 1 "ix86_comparison_operator"
10715 [(reg FLAGS_REG) (const_int 0)])
10718 [(set (match_dup 0) (match_dup 1))]
10720 rtx new_op1 = copy_rtx (operands[1]);
10721 operands[1] = new_op1;
10722 PUT_MODE (new_op1, QImode);
10723 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10724 GET_MODE (XEXP (new_op1, 0))));
10726 /* Make sure that (a) the CCmode we have for the flags is strong
10727 enough for the reversed compare or (b) we have a valid FP compare. */
10728 if (! ix86_comparison_operator (new_op1, VOIDmode))
10733 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10734 (eq:QI (match_operator 1 "ix86_comparison_operator"
10735 [(reg FLAGS_REG) (const_int 0)])
10738 [(set (match_dup 0) (match_dup 1))]
10740 rtx new_op1 = copy_rtx (operands[1]);
10741 operands[1] = new_op1;
10742 PUT_MODE (new_op1, QImode);
10743 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10744 GET_MODE (XEXP (new_op1, 0))));
10746 /* Make sure that (a) the CCmode we have for the flags is strong
10747 enough for the reversed compare or (b) we have a valid FP compare. */
10748 if (! ix86_comparison_operator (new_op1, VOIDmode))
10752 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10753 ;; subsequent logical operations are used to imitate conditional moves.
10754 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10757 (define_insn "setcc_<mode>_sse"
10758 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10759 (match_operator:MODEF 3 "sse_comparison_operator"
10760 [(match_operand:MODEF 1 "register_operand" "0,x")
10761 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10762 "SSE_FLOAT_MODE_P (<MODE>mode)"
10764 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10765 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10766 [(set_attr "isa" "noavx,avx")
10767 (set_attr "type" "ssecmp")
10768 (set_attr "length_immediate" "1")
10769 (set_attr "prefix" "orig,vex")
10770 (set_attr "mode" "<MODE>")])
10772 ;; Basic conditional jump instructions.
10773 ;; We ignore the overflow flag for signed branch instructions.
10775 (define_insn "*jcc_1"
10777 (if_then_else (match_operator 1 "ix86_comparison_operator"
10778 [(reg FLAGS_REG) (const_int 0)])
10779 (label_ref (match_operand 0))
10783 [(set_attr "type" "ibr")
10784 (set_attr "modrm" "0")
10785 (set (attr "length_nobnd")
10786 (if_then_else (and (ge (minus (match_dup 0) (pc))
10788 (lt (minus (match_dup 0) (pc))
10793 (define_insn "*jcc_2"
10795 (if_then_else (match_operator 1 "ix86_comparison_operator"
10796 [(reg FLAGS_REG) (const_int 0)])
10798 (label_ref (match_operand 0))))]
10801 [(set_attr "type" "ibr")
10802 (set_attr "modrm" "0")
10803 (set (attr "length_nobnd")
10804 (if_then_else (and (ge (minus (match_dup 0) (pc))
10806 (lt (minus (match_dup 0) (pc))
10811 ;; In general it is not safe to assume too much about CCmode registers,
10812 ;; so simplify-rtx stops when it sees a second one. Under certain
10813 ;; conditions this is safe on x86, so help combine not create
10821 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10822 [(reg FLAGS_REG) (const_int 0)])
10824 (label_ref (match_operand 1))
10828 (if_then_else (match_dup 0)
10829 (label_ref (match_dup 1))
10831 "PUT_MODE (operands[0], VOIDmode);")
10835 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10836 [(reg FLAGS_REG) (const_int 0)])
10838 (label_ref (match_operand 1))
10842 (if_then_else (match_dup 0)
10843 (label_ref (match_dup 1))
10846 rtx new_op0 = copy_rtx (operands[0]);
10847 operands[0] = new_op0;
10848 PUT_MODE (new_op0, VOIDmode);
10849 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10850 GET_MODE (XEXP (new_op0, 0))));
10852 /* Make sure that (a) the CCmode we have for the flags is strong
10853 enough for the reversed compare or (b) we have a valid FP compare. */
10854 if (! ix86_comparison_operator (new_op0, VOIDmode))
10858 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10859 ;; pass generates from shift insn with QImode operand. Actually, the mode
10860 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10861 ;; appropriate modulo of the bit offset value.
10863 (define_insn_and_split "*jcc_bt<mode>"
10865 (if_then_else (match_operator 0 "bt_comparison_operator"
10866 [(zero_extract:SWI48
10867 (match_operand:SWI48 1 "register_operand" "r")
10870 (match_operand:QI 2 "register_operand" "r")))
10872 (label_ref (match_operand 3))
10874 (clobber (reg:CC FLAGS_REG))]
10875 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10878 [(set (reg:CCC FLAGS_REG)
10880 (zero_extract:SWI48
10886 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10887 (label_ref (match_dup 3))
10890 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10892 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10895 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10896 ;; zero extended to SImode.
10897 (define_insn_and_split "*jcc_bt<mode>_1"
10899 (if_then_else (match_operator 0 "bt_comparison_operator"
10900 [(zero_extract:SWI48
10901 (match_operand:SWI48 1 "register_operand" "r")
10903 (match_operand:SI 2 "register_operand" "r"))
10905 (label_ref (match_operand 3))
10907 (clobber (reg:CC FLAGS_REG))]
10908 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10911 [(set (reg:CCC FLAGS_REG)
10913 (zero_extract:SWI48
10919 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10920 (label_ref (match_dup 3))
10923 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10925 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10928 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10929 ;; also for DImode, this is what combine produces.
10930 (define_insn_and_split "*jcc_bt<mode>_mask"
10932 (if_then_else (match_operator 0 "bt_comparison_operator"
10933 [(zero_extract:SWI48
10934 (match_operand:SWI48 1 "register_operand" "r")
10937 (match_operand:SI 2 "register_operand" "r")
10938 (match_operand:SI 3 "const_int_operand" "n")))])
10939 (label_ref (match_operand 4))
10941 (clobber (reg:CC FLAGS_REG))]
10942 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10943 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10944 == GET_MODE_BITSIZE (<MODE>mode)-1"
10947 [(set (reg:CCC FLAGS_REG)
10949 (zero_extract:SWI48
10955 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10956 (label_ref (match_dup 4))
10959 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10961 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10964 (define_insn_and_split "*jcc_btsi_1"
10966 (if_then_else (match_operator 0 "bt_comparison_operator"
10969 (match_operand:SI 1 "register_operand" "r")
10970 (match_operand:QI 2 "register_operand" "r"))
10973 (label_ref (match_operand 3))
10975 (clobber (reg:CC FLAGS_REG))]
10976 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10979 [(set (reg:CCC FLAGS_REG)
10987 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10988 (label_ref (match_dup 3))
10991 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10993 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10996 ;; avoid useless masking of bit offset operand
10997 (define_insn_and_split "*jcc_btsi_mask_1"
11000 (match_operator 0 "bt_comparison_operator"
11003 (match_operand:SI 1 "register_operand" "r")
11006 (match_operand:SI 2 "register_operand" "r")
11007 (match_operand:SI 3 "const_int_operand" "n")) 0))
11010 (label_ref (match_operand 4))
11012 (clobber (reg:CC FLAGS_REG))]
11013 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11014 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11017 [(set (reg:CCC FLAGS_REG)
11025 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11026 (label_ref (match_dup 4))
11028 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11030 ;; Define combination compare-and-branch fp compare instructions to help
11033 (define_insn "*jcc<mode>_0_i387"
11035 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11036 [(match_operand:X87MODEF 1 "register_operand" "f")
11037 (match_operand:X87MODEF 2 "const0_operand")])
11038 (label_ref (match_operand 3))
11040 (clobber (reg:CCFP FPSR_REG))
11041 (clobber (reg:CCFP FLAGS_REG))
11042 (clobber (match_scratch:HI 4 "=a"))]
11043 "TARGET_80387 && !TARGET_CMOVE"
11046 (define_insn "*jcc<mode>_0_r_i387"
11048 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11049 [(match_operand:X87MODEF 1 "register_operand" "f")
11050 (match_operand:X87MODEF 2 "const0_operand")])
11052 (label_ref (match_operand 3))))
11053 (clobber (reg:CCFP FPSR_REG))
11054 (clobber (reg:CCFP FLAGS_REG))
11055 (clobber (match_scratch:HI 4 "=a"))]
11056 "TARGET_80387 && !TARGET_CMOVE"
11059 (define_insn "*jccxf_i387"
11061 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11062 [(match_operand:XF 1 "register_operand" "f")
11063 (match_operand:XF 2 "register_operand" "f")])
11064 (label_ref (match_operand 3))
11066 (clobber (reg:CCFP FPSR_REG))
11067 (clobber (reg:CCFP FLAGS_REG))
11068 (clobber (match_scratch:HI 4 "=a"))]
11069 "TARGET_80387 && !TARGET_CMOVE"
11072 (define_insn "*jccxf_r_i387"
11074 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11075 [(match_operand:XF 1 "register_operand" "f")
11076 (match_operand:XF 2 "register_operand" "f")])
11078 (label_ref (match_operand 3))))
11079 (clobber (reg:CCFP FPSR_REG))
11080 (clobber (reg:CCFP FLAGS_REG))
11081 (clobber (match_scratch:HI 4 "=a"))]
11082 "TARGET_80387 && !TARGET_CMOVE"
11085 (define_insn "*jcc<mode>_i387"
11087 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11088 [(match_operand:MODEF 1 "register_operand" "f")
11089 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11090 (label_ref (match_operand 3))
11092 (clobber (reg:CCFP FPSR_REG))
11093 (clobber (reg:CCFP FLAGS_REG))
11094 (clobber (match_scratch:HI 4 "=a"))]
11095 "TARGET_80387 && !TARGET_CMOVE"
11098 (define_insn "*jcc<mode>_r_i387"
11100 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11101 [(match_operand:MODEF 1 "register_operand" "f")
11102 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11104 (label_ref (match_operand 3))))
11105 (clobber (reg:CCFP FPSR_REG))
11106 (clobber (reg:CCFP FLAGS_REG))
11107 (clobber (match_scratch:HI 4 "=a"))]
11108 "TARGET_80387 && !TARGET_CMOVE"
11111 (define_insn "*jccu<mode>_i387"
11113 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11114 [(match_operand:X87MODEF 1 "register_operand" "f")
11115 (match_operand:X87MODEF 2 "register_operand" "f")])
11116 (label_ref (match_operand 3))
11118 (clobber (reg:CCFP FPSR_REG))
11119 (clobber (reg:CCFP FLAGS_REG))
11120 (clobber (match_scratch:HI 4 "=a"))]
11121 "TARGET_80387 && !TARGET_CMOVE"
11124 (define_insn "*jccu<mode>_r_i387"
11126 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11127 [(match_operand:X87MODEF 1 "register_operand" "f")
11128 (match_operand:X87MODEF 2 "register_operand" "f")])
11130 (label_ref (match_operand 3))))
11131 (clobber (reg:CCFP FPSR_REG))
11132 (clobber (reg:CCFP FLAGS_REG))
11133 (clobber (match_scratch:HI 4 "=a"))]
11134 "TARGET_80387 && !TARGET_CMOVE"
11139 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11140 [(match_operand:X87MODEF 1 "register_operand")
11141 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11143 (match_operand 4)))
11144 (clobber (reg:CCFP FPSR_REG))
11145 (clobber (reg:CCFP FLAGS_REG))]
11146 "TARGET_80387 && !TARGET_CMOVE
11147 && reload_completed"
11150 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11151 operands[3], operands[4], NULL_RTX, NULL_RTX);
11157 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11158 [(match_operand:X87MODEF 1 "register_operand")
11159 (match_operand:X87MODEF 2 "general_operand")])
11161 (match_operand 4)))
11162 (clobber (reg:CCFP FPSR_REG))
11163 (clobber (reg:CCFP FLAGS_REG))
11164 (clobber (match_scratch:HI 5))]
11165 "TARGET_80387 && !TARGET_CMOVE
11166 && reload_completed"
11169 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11170 operands[3], operands[4], operands[5], NULL_RTX);
11174 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11175 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11176 ;; with a precedence over other operators and is always put in the first
11177 ;; place. Swap condition and operands to match ficom instruction.
11179 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11182 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11183 [(match_operator:X87MODEF 1 "float_operator"
11184 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11185 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11186 (label_ref (match_operand 4))
11188 (clobber (reg:CCFP FPSR_REG))
11189 (clobber (reg:CCFP FLAGS_REG))
11190 (clobber (match_scratch:HI 5 "=a,a"))]
11191 "TARGET_80387 && !TARGET_CMOVE
11192 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11193 || optimize_function_for_size_p (cfun))"
11196 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11199 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11200 [(match_operator:X87MODEF 1 "float_operator"
11201 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11202 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11204 (label_ref (match_operand 4))))
11205 (clobber (reg:CCFP FPSR_REG))
11206 (clobber (reg:CCFP FLAGS_REG))
11207 (clobber (match_scratch:HI 5 "=a,a"))]
11208 "TARGET_80387 && !TARGET_CMOVE
11209 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11210 || optimize_function_for_size_p (cfun))"
11216 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11217 [(match_operator:X87MODEF 1 "float_operator"
11218 [(match_operand:SWI24 2 "memory_operand")])
11219 (match_operand:X87MODEF 3 "register_operand")])
11221 (match_operand 5)))
11222 (clobber (reg:CCFP FPSR_REG))
11223 (clobber (reg:CCFP FLAGS_REG))
11224 (clobber (match_scratch:HI 6))]
11225 "TARGET_80387 && !TARGET_CMOVE
11226 && reload_completed"
11229 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11230 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11231 operands[4], operands[5], operands[6], NULL_RTX);
11235 ;; %%% Kill this when reload knows how to do it.
11239 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11240 [(match_operator:X87MODEF 1 "float_operator"
11241 [(match_operand:SWI24 2 "register_operand")])
11242 (match_operand:X87MODEF 3 "register_operand")])
11244 (match_operand 5)))
11245 (clobber (reg:CCFP FPSR_REG))
11246 (clobber (reg:CCFP FLAGS_REG))
11247 (clobber (match_scratch:HI 6))]
11248 "TARGET_80387 && !TARGET_CMOVE
11249 && reload_completed"
11252 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11254 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11255 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
11256 operands[4], operands[5], operands[6], operands[2]);
11260 ;; Unconditional and other jump instructions
11262 (define_insn "jump"
11264 (label_ref (match_operand 0)))]
11267 [(set_attr "type" "ibr")
11268 (set (attr "length_nobnd")
11269 (if_then_else (and (ge (minus (match_dup 0) (pc))
11271 (lt (minus (match_dup 0) (pc))
11275 (set_attr "modrm" "0")])
11277 (define_expand "indirect_jump"
11278 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11282 operands[0] = convert_memory_address (word_mode, operands[0]);
11285 (define_insn "*indirect_jump"
11286 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11289 [(set_attr "type" "ibr")
11290 (set_attr "length_immediate" "0")])
11292 (define_expand "tablejump"
11293 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11294 (use (label_ref (match_operand 1)))])]
11297 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11298 relative. Convert the relative address to an absolute address. */
11302 enum rtx_code code;
11304 /* We can't use @GOTOFF for text labels on VxWorks;
11305 see gotoff_operand. */
11306 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11310 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11312 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11316 op1 = pic_offset_table_rtx;
11321 op0 = pic_offset_table_rtx;
11325 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11330 operands[0] = convert_memory_address (word_mode, operands[0]);
11333 (define_insn "*tablejump_1"
11334 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11335 (use (label_ref (match_operand 1)))]
11338 [(set_attr "type" "ibr")
11339 (set_attr "length_immediate" "0")])
11341 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11344 [(set (reg FLAGS_REG) (match_operand 0))
11345 (set (match_operand:QI 1 "register_operand")
11346 (match_operator:QI 2 "ix86_comparison_operator"
11347 [(reg FLAGS_REG) (const_int 0)]))
11348 (set (match_operand 3 "q_regs_operand")
11349 (zero_extend (match_dup 1)))]
11350 "(peep2_reg_dead_p (3, operands[1])
11351 || operands_match_p (operands[1], operands[3]))
11352 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11353 [(set (match_dup 4) (match_dup 0))
11354 (set (strict_low_part (match_dup 5))
11357 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11358 operands[5] = gen_lowpart (QImode, operands[3]);
11359 ix86_expand_clear (operands[3]);
11363 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11364 (match_operand 4)])
11365 (set (match_operand:QI 1 "register_operand")
11366 (match_operator:QI 2 "ix86_comparison_operator"
11367 [(reg FLAGS_REG) (const_int 0)]))
11368 (set (match_operand 3 "q_regs_operand")
11369 (zero_extend (match_dup 1)))]
11370 "(peep2_reg_dead_p (3, operands[1])
11371 || operands_match_p (operands[1], operands[3]))
11372 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11373 [(parallel [(set (match_dup 5) (match_dup 0))
11375 (set (strict_low_part (match_dup 6))
11378 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11379 operands[6] = gen_lowpart (QImode, operands[3]);
11380 ix86_expand_clear (operands[3]);
11383 ;; Similar, but match zero extend with andsi3.
11386 [(set (reg FLAGS_REG) (match_operand 0))
11387 (set (match_operand:QI 1 "register_operand")
11388 (match_operator:QI 2 "ix86_comparison_operator"
11389 [(reg FLAGS_REG) (const_int 0)]))
11390 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11391 (and:SI (match_dup 3) (const_int 255)))
11392 (clobber (reg:CC FLAGS_REG))])]
11393 "REGNO (operands[1]) == REGNO (operands[3])
11394 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11395 [(set (match_dup 4) (match_dup 0))
11396 (set (strict_low_part (match_dup 5))
11399 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11400 operands[5] = gen_lowpart (QImode, operands[3]);
11401 ix86_expand_clear (operands[3]);
11405 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11406 (match_operand 4)])
11407 (set (match_operand:QI 1 "register_operand")
11408 (match_operator:QI 2 "ix86_comparison_operator"
11409 [(reg FLAGS_REG) (const_int 0)]))
11410 (parallel [(set (match_operand 3 "q_regs_operand")
11411 (zero_extend (match_dup 1)))
11412 (clobber (reg:CC FLAGS_REG))])]
11413 "(peep2_reg_dead_p (3, operands[1])
11414 || operands_match_p (operands[1], operands[3]))
11415 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11416 [(parallel [(set (match_dup 5) (match_dup 0))
11418 (set (strict_low_part (match_dup 6))
11421 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11422 operands[6] = gen_lowpart (QImode, operands[3]);
11423 ix86_expand_clear (operands[3]);
11426 ;; Call instructions.
11428 ;; The predicates normally associated with named expanders are not properly
11429 ;; checked for calls. This is a bug in the generic code, but it isn't that
11430 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11432 ;; P6 processors will jump to the address after the decrement when %esp
11433 ;; is used as a call operand, so they will execute return address as a code.
11434 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11436 ;; Register constraint for call instruction.
11437 (define_mode_attr c [(SI "l") (DI "r")])
11439 ;; Call subroutine returning no value.
11441 (define_expand "call"
11442 [(call (match_operand:QI 0)
11444 (use (match_operand 2))]
11447 ix86_expand_call (NULL, operands[0], operands[1],
11448 operands[2], NULL, false);
11452 (define_expand "sibcall"
11453 [(call (match_operand:QI 0)
11455 (use (match_operand 2))]
11458 ix86_expand_call (NULL, operands[0], operands[1],
11459 operands[2], NULL, true);
11463 (define_insn "*call"
11464 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11465 (match_operand 1))]
11466 "!SIBLING_CALL_P (insn)"
11467 "* return ix86_output_call_insn (insn, operands[0]);"
11468 [(set_attr "type" "call")])
11470 (define_insn "*call_rex64_ms_sysv"
11471 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11472 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11474 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11475 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11476 "* return ix86_output_call_insn (insn, operands[0]);"
11477 [(set_attr "type" "call")])
11479 (define_insn "*sibcall"
11480 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11481 (match_operand 1))]
11482 "SIBLING_CALL_P (insn)"
11483 "* return ix86_output_call_insn (insn, operands[0]);"
11484 [(set_attr "type" "call")])
11486 (define_expand "call_pop"
11487 [(parallel [(call (match_operand:QI 0)
11488 (match_operand:SI 1))
11489 (set (reg:SI SP_REG)
11490 (plus:SI (reg:SI SP_REG)
11491 (match_operand:SI 3)))])]
11494 ix86_expand_call (NULL, operands[0], operands[1],
11495 operands[2], operands[3], false);
11499 (define_insn "*call_pop"
11500 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11502 (set (reg:SI SP_REG)
11503 (plus:SI (reg:SI SP_REG)
11504 (match_operand:SI 2 "immediate_operand" "i")))]
11505 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11506 "* return ix86_output_call_insn (insn, operands[0]);"
11507 [(set_attr "type" "call")])
11509 (define_insn "*sibcall_pop"
11510 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11512 (set (reg:SI SP_REG)
11513 (plus:SI (reg:SI SP_REG)
11514 (match_operand:SI 2 "immediate_operand" "i")))]
11515 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11516 "* return ix86_output_call_insn (insn, operands[0]);"
11517 [(set_attr "type" "call")])
11519 ;; Call subroutine, returning value in operand 0
11521 (define_expand "call_value"
11522 [(set (match_operand 0)
11523 (call (match_operand:QI 1)
11524 (match_operand 2)))
11525 (use (match_operand 3))]
11528 ix86_expand_call (operands[0], operands[1], operands[2],
11529 operands[3], NULL, false);
11533 (define_expand "sibcall_value"
11534 [(set (match_operand 0)
11535 (call (match_operand:QI 1)
11536 (match_operand 2)))
11537 (use (match_operand 3))]
11540 ix86_expand_call (operands[0], operands[1], operands[2],
11541 operands[3], NULL, true);
11545 (define_insn "*call_value"
11546 [(set (match_operand 0)
11547 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11548 (match_operand 2)))]
11549 "!SIBLING_CALL_P (insn)"
11550 "* return ix86_output_call_insn (insn, operands[1]);"
11551 [(set_attr "type" "callv")])
11553 (define_insn "*sibcall_value"
11554 [(set (match_operand 0)
11555 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11556 (match_operand 2)))]
11557 "SIBLING_CALL_P (insn)"
11558 "* return ix86_output_call_insn (insn, operands[1]);"
11559 [(set_attr "type" "callv")])
11561 (define_insn "*call_value_rex64_ms_sysv"
11562 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11563 [(set (match_operand 0)
11564 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11565 (match_operand 2)))
11566 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11567 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11568 "* return ix86_output_call_insn (insn, operands[1]);"
11569 [(set_attr "type" "callv")])
11571 (define_expand "call_value_pop"
11572 [(parallel [(set (match_operand 0)
11573 (call (match_operand:QI 1)
11574 (match_operand:SI 2)))
11575 (set (reg:SI SP_REG)
11576 (plus:SI (reg:SI SP_REG)
11577 (match_operand:SI 4)))])]
11580 ix86_expand_call (operands[0], operands[1], operands[2],
11581 operands[3], operands[4], false);
11585 (define_insn "*call_value_pop"
11586 [(set (match_operand 0)
11587 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11588 (match_operand 2)))
11589 (set (reg:SI SP_REG)
11590 (plus:SI (reg:SI SP_REG)
11591 (match_operand:SI 3 "immediate_operand" "i")))]
11592 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11593 "* return ix86_output_call_insn (insn, operands[1]);"
11594 [(set_attr "type" "callv")])
11596 (define_insn "*sibcall_value_pop"
11597 [(set (match_operand 0)
11598 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11599 (match_operand 2)))
11600 (set (reg:SI SP_REG)
11601 (plus:SI (reg:SI SP_REG)
11602 (match_operand:SI 3 "immediate_operand" "i")))]
11603 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11604 "* return ix86_output_call_insn (insn, operands[1]);"
11605 [(set_attr "type" "callv")])
11607 ;; Call subroutine returning any type.
11609 (define_expand "untyped_call"
11610 [(parallel [(call (match_operand 0)
11613 (match_operand 2)])]
11618 /* In order to give reg-stack an easier job in validating two
11619 coprocessor registers as containing a possible return value,
11620 simply pretend the untyped call returns a complex long double
11623 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11624 and should have the default ABI. */
11626 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11627 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11628 operands[0], const0_rtx,
11629 GEN_INT ((TARGET_64BIT
11630 ? (ix86_abi == SYSV_ABI
11631 ? X86_64_SSE_REGPARM_MAX
11632 : X86_64_MS_SSE_REGPARM_MAX)
11633 : X86_32_SSE_REGPARM_MAX)
11637 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11639 rtx set = XVECEXP (operands[2], 0, i);
11640 emit_move_insn (SET_DEST (set), SET_SRC (set));
11643 /* The optimizer does not know that the call sets the function value
11644 registers we stored in the result block. We avoid problems by
11645 claiming that all hard registers are used and clobbered at this
11647 emit_insn (gen_blockage ());
11652 ;; Prologue and epilogue instructions
11654 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11655 ;; all of memory. This blocks insns from being moved across this point.
11657 (define_insn "blockage"
11658 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11661 [(set_attr "length" "0")])
11663 ;; Do not schedule instructions accessing memory across this point.
11665 (define_expand "memory_blockage"
11666 [(set (match_dup 0)
11667 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11670 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11671 MEM_VOLATILE_P (operands[0]) = 1;
11674 (define_insn "*memory_blockage"
11675 [(set (match_operand:BLK 0)
11676 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11679 [(set_attr "length" "0")])
11681 ;; As USE insns aren't meaningful after reload, this is used instead
11682 ;; to prevent deleting instructions setting registers for PIC code
11683 (define_insn "prologue_use"
11684 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11687 [(set_attr "length" "0")])
11689 ;; Insn emitted into the body of a function to return from a function.
11690 ;; This is only done if the function's epilogue is known to be simple.
11691 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11693 (define_expand "return"
11695 "ix86_can_use_return_insn_p ()"
11697 if (crtl->args.pops_args)
11699 rtx popc = GEN_INT (crtl->args.pops_args);
11700 emit_jump_insn (gen_simple_return_pop_internal (popc));
11705 ;; We need to disable this for TARGET_SEH, as otherwise
11706 ;; shrink-wrapped prologue gets enabled too. This might exceed
11707 ;; the maximum size of prologue in unwind information.
11709 (define_expand "simple_return"
11713 if (crtl->args.pops_args)
11715 rtx popc = GEN_INT (crtl->args.pops_args);
11716 emit_jump_insn (gen_simple_return_pop_internal (popc));
11721 (define_insn "simple_return_internal"
11725 [(set_attr "length_nobnd" "1")
11726 (set_attr "atom_unit" "jeu")
11727 (set_attr "length_immediate" "0")
11728 (set_attr "modrm" "0")])
11730 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11731 ;; instruction Athlon and K8 have.
11733 (define_insn "simple_return_internal_long"
11735 (unspec [(const_int 0)] UNSPEC_REP)]
11738 if (ix86_bnd_prefixed_insn_p (insn))
11741 return "rep%; ret";
11743 [(set_attr "length" "2")
11744 (set_attr "atom_unit" "jeu")
11745 (set_attr "length_immediate" "0")
11746 (set_attr "prefix_rep" "1")
11747 (set_attr "modrm" "0")])
11749 (define_insn "simple_return_pop_internal"
11751 (use (match_operand:SI 0 "const_int_operand"))]
11754 [(set_attr "length_nobnd" "3")
11755 (set_attr "atom_unit" "jeu")
11756 (set_attr "length_immediate" "2")
11757 (set_attr "modrm" "0")])
11759 (define_insn "simple_return_indirect_internal"
11761 (use (match_operand:SI 0 "register_operand" "r"))]
11764 [(set_attr "type" "ibr")
11765 (set_attr "length_immediate" "0")])
11771 [(set_attr "length" "1")
11772 (set_attr "length_immediate" "0")
11773 (set_attr "modrm" "0")])
11775 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11776 (define_insn "nops"
11777 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11781 int num = INTVAL (operands[0]);
11783 gcc_assert (IN_RANGE (num, 1, 8));
11786 fputs ("\tnop\n", asm_out_file);
11790 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11791 (set_attr "length_immediate" "0")
11792 (set_attr "modrm" "0")])
11794 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11795 ;; branch prediction penalty for the third jump in a 16-byte
11799 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11802 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11803 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11805 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11806 The align insn is used to avoid 3 jump instructions in the row to improve
11807 branch prediction and the benefits hardly outweigh the cost of extra 8
11808 nops on the average inserted by full alignment pseudo operation. */
11812 [(set_attr "length" "16")])
11814 (define_expand "prologue"
11817 "ix86_expand_prologue (); DONE;")
11819 (define_insn "set_got"
11820 [(set (match_operand:SI 0 "register_operand" "=r")
11821 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11822 (clobber (reg:CC FLAGS_REG))]
11824 "* return output_set_got (operands[0], NULL_RTX);"
11825 [(set_attr "type" "multi")
11826 (set_attr "length" "12")])
11828 (define_insn "set_got_labelled"
11829 [(set (match_operand:SI 0 "register_operand" "=r")
11830 (unspec:SI [(label_ref (match_operand 1))]
11832 (clobber (reg:CC FLAGS_REG))]
11834 "* return output_set_got (operands[0], operands[1]);"
11835 [(set_attr "type" "multi")
11836 (set_attr "length" "12")])
11838 (define_insn "set_got_rex64"
11839 [(set (match_operand:DI 0 "register_operand" "=r")
11840 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11842 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11843 [(set_attr "type" "lea")
11844 (set_attr "length_address" "4")
11845 (set_attr "mode" "DI")])
11847 (define_insn "set_rip_rex64"
11848 [(set (match_operand:DI 0 "register_operand" "=r")
11849 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11851 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11852 [(set_attr "type" "lea")
11853 (set_attr "length_address" "4")
11854 (set_attr "mode" "DI")])
11856 (define_insn "set_got_offset_rex64"
11857 [(set (match_operand:DI 0 "register_operand" "=r")
11859 [(label_ref (match_operand 1))]
11860 UNSPEC_SET_GOT_OFFSET))]
11862 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11863 [(set_attr "type" "imov")
11864 (set_attr "length_immediate" "0")
11865 (set_attr "length_address" "8")
11866 (set_attr "mode" "DI")])
11868 (define_expand "epilogue"
11871 "ix86_expand_epilogue (1); DONE;")
11873 (define_expand "sibcall_epilogue"
11876 "ix86_expand_epilogue (0); DONE;")
11878 (define_expand "eh_return"
11879 [(use (match_operand 0 "register_operand"))]
11882 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11884 /* Tricky bit: we write the address of the handler to which we will
11885 be returning into someone else's stack frame, one word below the
11886 stack address we wish to restore. */
11887 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11888 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11889 tmp = gen_rtx_MEM (Pmode, tmp);
11890 emit_move_insn (tmp, ra);
11892 emit_jump_insn (gen_eh_return_internal ());
11897 (define_insn_and_split "eh_return_internal"
11901 "epilogue_completed"
11903 "ix86_expand_epilogue (2); DONE;")
11905 (define_insn "leave"
11906 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11907 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11908 (clobber (mem:BLK (scratch)))]
11911 [(set_attr "type" "leave")])
11913 (define_insn "leave_rex64"
11914 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11915 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11916 (clobber (mem:BLK (scratch)))]
11919 [(set_attr "type" "leave")])
11921 ;; Handle -fsplit-stack.
11923 (define_expand "split_stack_prologue"
11927 ix86_expand_split_stack_prologue ();
11931 ;; In order to support the call/return predictor, we use a return
11932 ;; instruction which the middle-end doesn't see.
11933 (define_insn "split_stack_return"
11934 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11935 UNSPECV_SPLIT_STACK_RETURN)]
11938 if (operands[0] == const0_rtx)
11943 [(set_attr "atom_unit" "jeu")
11944 (set_attr "modrm" "0")
11945 (set (attr "length")
11946 (if_then_else (match_operand:SI 0 "const0_operand")
11949 (set (attr "length_immediate")
11950 (if_then_else (match_operand:SI 0 "const0_operand")
11954 ;; If there are operand 0 bytes available on the stack, jump to
11957 (define_expand "split_stack_space_check"
11958 [(set (pc) (if_then_else
11959 (ltu (minus (reg SP_REG)
11960 (match_operand 0 "register_operand"))
11961 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11962 (label_ref (match_operand 1))
11966 rtx reg, size, limit;
11968 reg = gen_reg_rtx (Pmode);
11969 size = force_reg (Pmode, operands[0]);
11970 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11971 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11972 UNSPEC_STACK_CHECK);
11973 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11974 ix86_expand_branch (GEU, reg, limit, operands[1]);
11979 ;; Bit manipulation instructions.
11981 (define_expand "ffs<mode>2"
11982 [(set (match_dup 2) (const_int -1))
11983 (parallel [(set (match_dup 3) (match_dup 4))
11984 (set (match_operand:SWI48 0 "register_operand")
11986 (match_operand:SWI48 1 "nonimmediate_operand")))])
11987 (set (match_dup 0) (if_then_else:SWI48
11988 (eq (match_dup 3) (const_int 0))
11991 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11992 (clobber (reg:CC FLAGS_REG))])]
11995 enum machine_mode flags_mode;
11997 if (<MODE>mode == SImode && !TARGET_CMOVE)
11999 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12003 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12005 operands[2] = gen_reg_rtx (<MODE>mode);
12006 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12007 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12010 (define_insn_and_split "ffssi2_no_cmove"
12011 [(set (match_operand:SI 0 "register_operand" "=r")
12012 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12013 (clobber (match_scratch:SI 2 "=&q"))
12014 (clobber (reg:CC FLAGS_REG))]
12017 "&& reload_completed"
12018 [(parallel [(set (match_dup 4) (match_dup 5))
12019 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12020 (set (strict_low_part (match_dup 3))
12021 (eq:QI (match_dup 4) (const_int 0)))
12022 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12023 (clobber (reg:CC FLAGS_REG))])
12024 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12025 (clobber (reg:CC FLAGS_REG))])
12026 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12027 (clobber (reg:CC FLAGS_REG))])]
12029 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12031 operands[3] = gen_lowpart (QImode, operands[2]);
12032 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12033 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12035 ix86_expand_clear (operands[2]);
12038 (define_insn "*tzcnt<mode>_1"
12039 [(set (reg:CCC FLAGS_REG)
12040 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12042 (set (match_operand:SWI48 0 "register_operand" "=r")
12043 (ctz:SWI48 (match_dup 1)))]
12045 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12046 [(set_attr "type" "alu1")
12047 (set_attr "prefix_0f" "1")
12048 (set_attr "prefix_rep" "1")
12049 (set_attr "btver2_decode" "double")
12050 (set_attr "mode" "<MODE>")])
12052 (define_insn "*bsf<mode>_1"
12053 [(set (reg:CCZ FLAGS_REG)
12054 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12056 (set (match_operand:SWI48 0 "register_operand" "=r")
12057 (ctz:SWI48 (match_dup 1)))]
12059 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12060 [(set_attr "type" "alu1")
12061 (set_attr "prefix_0f" "1")
12062 (set_attr "btver2_decode" "double")
12063 (set_attr "mode" "<MODE>")])
12065 (define_insn "ctz<mode>2"
12066 [(set (match_operand:SWI248 0 "register_operand" "=r")
12067 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12068 (clobber (reg:CC FLAGS_REG))]
12072 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12073 else if (optimize_function_for_size_p (cfun))
12075 else if (TARGET_GENERIC)
12076 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12077 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12079 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12081 [(set_attr "type" "alu1")
12082 (set_attr "prefix_0f" "1")
12083 (set (attr "prefix_rep")
12085 (ior (match_test "TARGET_BMI")
12086 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12087 (match_test "TARGET_GENERIC")))
12089 (const_string "0")))
12090 (set_attr "mode" "<MODE>")])
12092 (define_expand "clz<mode>2"
12094 [(set (match_operand:SWI248 0 "register_operand")
12097 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12098 (clobber (reg:CC FLAGS_REG))])
12100 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12101 (clobber (reg:CC FLAGS_REG))])]
12106 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12109 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12112 (define_insn "clz<mode>2_lzcnt"
12113 [(set (match_operand:SWI248 0 "register_operand" "=r")
12114 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12115 (clobber (reg:CC FLAGS_REG))]
12117 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12118 [(set_attr "prefix_rep" "1")
12119 (set_attr "type" "bitmanip")
12120 (set_attr "mode" "<MODE>")])
12122 ;; BMI instructions.
12123 (define_insn "*bmi_andn_<mode>"
12124 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12127 (match_operand:SWI48 1 "register_operand" "r,r"))
12128 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12129 (clobber (reg:CC FLAGS_REG))]
12131 "andn\t{%2, %1, %0|%0, %1, %2}"
12132 [(set_attr "type" "bitmanip")
12133 (set_attr "btver2_decode" "direct, double")
12134 (set_attr "mode" "<MODE>")])
12136 (define_insn "bmi_bextr_<mode>"
12137 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12138 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12139 (match_operand:SWI48 2 "register_operand" "r,r")]
12141 (clobber (reg:CC FLAGS_REG))]
12143 "bextr\t{%2, %1, %0|%0, %1, %2}"
12144 [(set_attr "type" "bitmanip")
12145 (set_attr "btver2_decode" "direct, double")
12146 (set_attr "mode" "<MODE>")])
12148 (define_insn "*bmi_blsi_<mode>"
12149 [(set (match_operand:SWI48 0 "register_operand" "=r")
12152 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12154 (clobber (reg:CC FLAGS_REG))]
12156 "blsi\t{%1, %0|%0, %1}"
12157 [(set_attr "type" "bitmanip")
12158 (set_attr "btver2_decode" "double")
12159 (set_attr "mode" "<MODE>")])
12161 (define_insn "*bmi_blsmsk_<mode>"
12162 [(set (match_operand:SWI48 0 "register_operand" "=r")
12165 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12168 (clobber (reg:CC FLAGS_REG))]
12170 "blsmsk\t{%1, %0|%0, %1}"
12171 [(set_attr "type" "bitmanip")
12172 (set_attr "btver2_decode" "double")
12173 (set_attr "mode" "<MODE>")])
12175 (define_insn "*bmi_blsr_<mode>"
12176 [(set (match_operand:SWI48 0 "register_operand" "=r")
12179 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12182 (clobber (reg:CC FLAGS_REG))]
12184 "blsr\t{%1, %0|%0, %1}"
12185 [(set_attr "type" "bitmanip")
12186 (set_attr "btver2_decode" "double")
12187 (set_attr "mode" "<MODE>")])
12189 ;; BMI2 instructions.
12190 (define_insn "bmi2_bzhi_<mode>3"
12191 [(set (match_operand:SWI48 0 "register_operand" "=r")
12192 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12193 (match_operand:SWI48 2 "register_operand" "r"))
12194 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12195 (clobber (reg:CC FLAGS_REG))]
12197 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12198 [(set_attr "type" "bitmanip")
12199 (set_attr "prefix" "vex")
12200 (set_attr "mode" "<MODE>")])
12202 (define_insn "bmi2_pdep_<mode>3"
12203 [(set (match_operand:SWI48 0 "register_operand" "=r")
12204 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12205 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12208 "pdep\t{%2, %1, %0|%0, %1, %2}"
12209 [(set_attr "type" "bitmanip")
12210 (set_attr "prefix" "vex")
12211 (set_attr "mode" "<MODE>")])
12213 (define_insn "bmi2_pext_<mode>3"
12214 [(set (match_operand:SWI48 0 "register_operand" "=r")
12215 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12216 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12219 "pext\t{%2, %1, %0|%0, %1, %2}"
12220 [(set_attr "type" "bitmanip")
12221 (set_attr "prefix" "vex")
12222 (set_attr "mode" "<MODE>")])
12224 ;; TBM instructions.
12225 (define_insn "tbm_bextri_<mode>"
12226 [(set (match_operand:SWI48 0 "register_operand" "=r")
12227 (zero_extract:SWI48
12228 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12229 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12230 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12231 (clobber (reg:CC FLAGS_REG))]
12234 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12235 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12237 [(set_attr "type" "bitmanip")
12238 (set_attr "mode" "<MODE>")])
12240 (define_insn "*tbm_blcfill_<mode>"
12241 [(set (match_operand:SWI48 0 "register_operand" "=r")
12244 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12247 (clobber (reg:CC FLAGS_REG))]
12249 "blcfill\t{%1, %0|%0, %1}"
12250 [(set_attr "type" "bitmanip")
12251 (set_attr "mode" "<MODE>")])
12253 (define_insn "*tbm_blci_<mode>"
12254 [(set (match_operand:SWI48 0 "register_operand" "=r")
12258 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12261 (clobber (reg:CC FLAGS_REG))]
12263 "blci\t{%1, %0|%0, %1}"
12264 [(set_attr "type" "bitmanip")
12265 (set_attr "mode" "<MODE>")])
12267 (define_insn "*tbm_blcic_<mode>"
12268 [(set (match_operand:SWI48 0 "register_operand" "=r")
12271 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12275 (clobber (reg:CC FLAGS_REG))]
12277 "blcic\t{%1, %0|%0, %1}"
12278 [(set_attr "type" "bitmanip")
12279 (set_attr "mode" "<MODE>")])
12281 (define_insn "*tbm_blcmsk_<mode>"
12282 [(set (match_operand:SWI48 0 "register_operand" "=r")
12285 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12288 (clobber (reg:CC FLAGS_REG))]
12290 "blcmsk\t{%1, %0|%0, %1}"
12291 [(set_attr "type" "bitmanip")
12292 (set_attr "mode" "<MODE>")])
12294 (define_insn "*tbm_blcs_<mode>"
12295 [(set (match_operand:SWI48 0 "register_operand" "=r")
12298 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12301 (clobber (reg:CC FLAGS_REG))]
12303 "blcs\t{%1, %0|%0, %1}"
12304 [(set_attr "type" "bitmanip")
12305 (set_attr "mode" "<MODE>")])
12307 (define_insn "*tbm_blsfill_<mode>"
12308 [(set (match_operand:SWI48 0 "register_operand" "=r")
12311 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12314 (clobber (reg:CC FLAGS_REG))]
12316 "blsfill\t{%1, %0|%0, %1}"
12317 [(set_attr "type" "bitmanip")
12318 (set_attr "mode" "<MODE>")])
12320 (define_insn "*tbm_blsic_<mode>"
12321 [(set (match_operand:SWI48 0 "register_operand" "=r")
12324 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12328 (clobber (reg:CC FLAGS_REG))]
12330 "blsic\t{%1, %0|%0, %1}"
12331 [(set_attr "type" "bitmanip")
12332 (set_attr "mode" "<MODE>")])
12334 (define_insn "*tbm_t1mskc_<mode>"
12335 [(set (match_operand:SWI48 0 "register_operand" "=r")
12338 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12342 (clobber (reg:CC FLAGS_REG))]
12344 "t1mskc\t{%1, %0|%0, %1}"
12345 [(set_attr "type" "bitmanip")
12346 (set_attr "mode" "<MODE>")])
12348 (define_insn "*tbm_tzmsk_<mode>"
12349 [(set (match_operand:SWI48 0 "register_operand" "=r")
12352 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12356 (clobber (reg:CC FLAGS_REG))]
12358 "tzmsk\t{%1, %0|%0, %1}"
12359 [(set_attr "type" "bitmanip")
12360 (set_attr "mode" "<MODE>")])
12362 (define_insn "bsr_rex64"
12363 [(set (match_operand:DI 0 "register_operand" "=r")
12364 (minus:DI (const_int 63)
12365 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12366 (clobber (reg:CC FLAGS_REG))]
12368 "bsr{q}\t{%1, %0|%0, %1}"
12369 [(set_attr "type" "alu1")
12370 (set_attr "prefix_0f" "1")
12371 (set_attr "mode" "DI")])
12374 [(set (match_operand:SI 0 "register_operand" "=r")
12375 (minus:SI (const_int 31)
12376 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12377 (clobber (reg:CC FLAGS_REG))]
12379 "bsr{l}\t{%1, %0|%0, %1}"
12380 [(set_attr "type" "alu1")
12381 (set_attr "prefix_0f" "1")
12382 (set_attr "mode" "SI")])
12384 (define_insn "*bsrhi"
12385 [(set (match_operand:HI 0 "register_operand" "=r")
12386 (minus:HI (const_int 15)
12387 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12388 (clobber (reg:CC FLAGS_REG))]
12390 "bsr{w}\t{%1, %0|%0, %1}"
12391 [(set_attr "type" "alu1")
12392 (set_attr "prefix_0f" "1")
12393 (set_attr "mode" "HI")])
12395 (define_insn "popcount<mode>2"
12396 [(set (match_operand:SWI248 0 "register_operand" "=r")
12398 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12399 (clobber (reg:CC FLAGS_REG))]
12403 return "popcnt\t{%1, %0|%0, %1}";
12405 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12408 [(set_attr "prefix_rep" "1")
12409 (set_attr "type" "bitmanip")
12410 (set_attr "mode" "<MODE>")])
12412 (define_insn "*popcount<mode>2_cmp"
12413 [(set (reg FLAGS_REG)
12416 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12418 (set (match_operand:SWI248 0 "register_operand" "=r")
12419 (popcount:SWI248 (match_dup 1)))]
12420 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12423 return "popcnt\t{%1, %0|%0, %1}";
12425 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12428 [(set_attr "prefix_rep" "1")
12429 (set_attr "type" "bitmanip")
12430 (set_attr "mode" "<MODE>")])
12432 (define_insn "*popcountsi2_cmp_zext"
12433 [(set (reg FLAGS_REG)
12435 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12437 (set (match_operand:DI 0 "register_operand" "=r")
12438 (zero_extend:DI(popcount:SI (match_dup 1))))]
12439 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12442 return "popcnt\t{%1, %0|%0, %1}";
12444 return "popcnt{l}\t{%1, %0|%0, %1}";
12447 [(set_attr "prefix_rep" "1")
12448 (set_attr "type" "bitmanip")
12449 (set_attr "mode" "SI")])
12451 (define_expand "bswapdi2"
12452 [(set (match_operand:DI 0 "register_operand")
12453 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12457 operands[1] = force_reg (DImode, operands[1]);
12460 (define_expand "bswapsi2"
12461 [(set (match_operand:SI 0 "register_operand")
12462 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12467 else if (TARGET_BSWAP)
12468 operands[1] = force_reg (SImode, operands[1]);
12471 rtx x = operands[0];
12473 emit_move_insn (x, operands[1]);
12474 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12475 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12476 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12481 (define_insn "*bswap<mode>2_movbe"
12482 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12483 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12485 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12488 movbe\t{%1, %0|%0, %1}
12489 movbe\t{%1, %0|%0, %1}"
12490 [(set_attr "type" "bitmanip,imov,imov")
12491 (set_attr "modrm" "0,1,1")
12492 (set_attr "prefix_0f" "*,1,1")
12493 (set_attr "prefix_extra" "*,1,1")
12494 (set_attr "mode" "<MODE>")])
12496 (define_insn "*bswap<mode>2"
12497 [(set (match_operand:SWI48 0 "register_operand" "=r")
12498 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12501 [(set_attr "type" "bitmanip")
12502 (set_attr "modrm" "0")
12503 (set_attr "mode" "<MODE>")])
12505 (define_insn "*bswaphi_lowpart_1"
12506 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12507 (bswap:HI (match_dup 0)))
12508 (clobber (reg:CC FLAGS_REG))]
12509 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12511 xchg{b}\t{%h0, %b0|%b0, %h0}
12512 rol{w}\t{$8, %0|%0, 8}"
12513 [(set_attr "length" "2,4")
12514 (set_attr "mode" "QI,HI")])
12516 (define_insn "bswaphi_lowpart"
12517 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12518 (bswap:HI (match_dup 0)))
12519 (clobber (reg:CC FLAGS_REG))]
12521 "rol{w}\t{$8, %0|%0, 8}"
12522 [(set_attr "length" "4")
12523 (set_attr "mode" "HI")])
12525 (define_expand "paritydi2"
12526 [(set (match_operand:DI 0 "register_operand")
12527 (parity:DI (match_operand:DI 1 "register_operand")))]
12530 rtx scratch = gen_reg_rtx (QImode);
12533 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12534 NULL_RTX, operands[1]));
12536 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12537 gen_rtx_REG (CCmode, FLAGS_REG),
12539 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12542 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12545 rtx tmp = gen_reg_rtx (SImode);
12547 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12548 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12553 (define_expand "paritysi2"
12554 [(set (match_operand:SI 0 "register_operand")
12555 (parity:SI (match_operand:SI 1 "register_operand")))]
12558 rtx scratch = gen_reg_rtx (QImode);
12561 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12563 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12564 gen_rtx_REG (CCmode, FLAGS_REG),
12566 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12568 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12572 (define_insn_and_split "paritydi2_cmp"
12573 [(set (reg:CC FLAGS_REG)
12574 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12576 (clobber (match_scratch:DI 0 "=r"))
12577 (clobber (match_scratch:SI 1 "=&r"))
12578 (clobber (match_scratch:HI 2 "=Q"))]
12581 "&& reload_completed"
12583 [(set (match_dup 1)
12584 (xor:SI (match_dup 1) (match_dup 4)))
12585 (clobber (reg:CC FLAGS_REG))])
12587 [(set (reg:CC FLAGS_REG)
12588 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12589 (clobber (match_dup 1))
12590 (clobber (match_dup 2))])]
12592 operands[4] = gen_lowpart (SImode, operands[3]);
12596 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12597 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12600 operands[1] = gen_highpart (SImode, operands[3]);
12603 (define_insn_and_split "paritysi2_cmp"
12604 [(set (reg:CC FLAGS_REG)
12605 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12607 (clobber (match_scratch:SI 0 "=r"))
12608 (clobber (match_scratch:HI 1 "=&Q"))]
12611 "&& reload_completed"
12613 [(set (match_dup 1)
12614 (xor:HI (match_dup 1) (match_dup 3)))
12615 (clobber (reg:CC FLAGS_REG))])
12617 [(set (reg:CC FLAGS_REG)
12618 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12619 (clobber (match_dup 1))])]
12621 operands[3] = gen_lowpart (HImode, operands[2]);
12623 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12624 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12627 (define_insn "*parityhi2_cmp"
12628 [(set (reg:CC FLAGS_REG)
12629 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12631 (clobber (match_scratch:HI 0 "=Q"))]
12633 "xor{b}\t{%h0, %b0|%b0, %h0}"
12634 [(set_attr "length" "2")
12635 (set_attr "mode" "HI")])
12638 ;; Thread-local storage patterns for ELF.
12640 ;; Note that these code sequences must appear exactly as shown
12641 ;; in order to allow linker relaxation.
12643 (define_insn "*tls_global_dynamic_32_gnu"
12644 [(set (match_operand:SI 0 "register_operand" "=a")
12646 [(match_operand:SI 1 "register_operand" "b")
12647 (match_operand 2 "tls_symbolic_operand")
12648 (match_operand 3 "constant_call_address_operand" "z")]
12650 (clobber (match_scratch:SI 4 "=d"))
12651 (clobber (match_scratch:SI 5 "=c"))
12652 (clobber (reg:CC FLAGS_REG))]
12653 "!TARGET_64BIT && TARGET_GNU_TLS"
12656 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12657 if (TARGET_SUN_TLS)
12658 #ifdef HAVE_AS_IX86_TLSGDPLT
12659 return "call\t%a2@tlsgdplt";
12661 return "call\t%p3@plt";
12663 return "call\t%P3";
12665 [(set_attr "type" "multi")
12666 (set_attr "length" "12")])
12668 (define_expand "tls_global_dynamic_32"
12670 [(set (match_operand:SI 0 "register_operand")
12671 (unspec:SI [(match_operand:SI 2 "register_operand")
12672 (match_operand 1 "tls_symbolic_operand")
12673 (match_operand 3 "constant_call_address_operand")]
12675 (clobber (match_scratch:SI 4))
12676 (clobber (match_scratch:SI 5))
12677 (clobber (reg:CC FLAGS_REG))])])
12679 (define_insn "*tls_global_dynamic_64_<mode>"
12680 [(set (match_operand:P 0 "register_operand" "=a")
12682 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12683 (match_operand 3)))
12684 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12689 fputs (ASM_BYTE "0x66\n", asm_out_file);
12691 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12692 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12693 fputs ("\trex64\n", asm_out_file);
12694 if (TARGET_SUN_TLS)
12695 return "call\t%p2@plt";
12696 return "call\t%P2";
12698 [(set_attr "type" "multi")
12699 (set (attr "length")
12700 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12702 (define_insn "*tls_global_dynamic_64_largepic"
12703 [(set (match_operand:DI 0 "register_operand" "=a")
12705 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12706 (match_operand:DI 3 "immediate_operand" "i")))
12707 (match_operand 4)))
12708 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12710 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12711 && GET_CODE (operands[3]) == CONST
12712 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12713 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12716 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12717 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12718 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12719 return "call\t{*%%rax|rax}";
12721 [(set_attr "type" "multi")
12722 (set_attr "length" "22")])
12724 (define_expand "tls_global_dynamic_64_<mode>"
12726 [(set (match_operand:P 0 "register_operand")
12728 (mem:QI (match_operand 2))
12730 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12734 (define_insn "*tls_local_dynamic_base_32_gnu"
12735 [(set (match_operand:SI 0 "register_operand" "=a")
12737 [(match_operand:SI 1 "register_operand" "b")
12738 (match_operand 2 "constant_call_address_operand" "z")]
12739 UNSPEC_TLS_LD_BASE))
12740 (clobber (match_scratch:SI 3 "=d"))
12741 (clobber (match_scratch:SI 4 "=c"))
12742 (clobber (reg:CC FLAGS_REG))]
12743 "!TARGET_64BIT && TARGET_GNU_TLS"
12746 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12747 if (TARGET_SUN_TLS)
12748 #ifdef HAVE_AS_IX86_TLSLDMPLT
12749 return "call\t%&@tlsldmplt";
12751 return "call\t%p2@plt";
12753 return "call\t%P2";
12755 [(set_attr "type" "multi")
12756 (set_attr "length" "11")])
12758 (define_expand "tls_local_dynamic_base_32"
12760 [(set (match_operand:SI 0 "register_operand")
12762 [(match_operand:SI 1 "register_operand")
12763 (match_operand 2 "constant_call_address_operand")]
12764 UNSPEC_TLS_LD_BASE))
12765 (clobber (match_scratch:SI 3))
12766 (clobber (match_scratch:SI 4))
12767 (clobber (reg:CC FLAGS_REG))])])
12769 (define_insn "*tls_local_dynamic_base_64_<mode>"
12770 [(set (match_operand:P 0 "register_operand" "=a")
12772 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12773 (match_operand 2)))
12774 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12778 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12779 if (TARGET_SUN_TLS)
12780 return "call\t%p1@plt";
12781 return "call\t%P1";
12783 [(set_attr "type" "multi")
12784 (set_attr "length" "12")])
12786 (define_insn "*tls_local_dynamic_base_64_largepic"
12787 [(set (match_operand:DI 0 "register_operand" "=a")
12789 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12790 (match_operand:DI 2 "immediate_operand" "i")))
12791 (match_operand 3)))
12792 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12793 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12794 && GET_CODE (operands[2]) == CONST
12795 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
12796 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
12799 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12800 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
12801 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
12802 return "call\t{*%%rax|rax}";
12804 [(set_attr "type" "multi")
12805 (set_attr "length" "22")])
12807 (define_expand "tls_local_dynamic_base_64_<mode>"
12809 [(set (match_operand:P 0 "register_operand")
12811 (mem:QI (match_operand 1))
12813 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12816 ;; Local dynamic of a single variable is a lose. Show combine how
12817 ;; to convert that back to global dynamic.
12819 (define_insn_and_split "*tls_local_dynamic_32_once"
12820 [(set (match_operand:SI 0 "register_operand" "=a")
12822 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12823 (match_operand 2 "constant_call_address_operand" "z")]
12824 UNSPEC_TLS_LD_BASE)
12825 (const:SI (unspec:SI
12826 [(match_operand 3 "tls_symbolic_operand")]
12828 (clobber (match_scratch:SI 4 "=d"))
12829 (clobber (match_scratch:SI 5 "=c"))
12830 (clobber (reg:CC FLAGS_REG))]
12835 [(set (match_dup 0)
12836 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12838 (clobber (match_dup 4))
12839 (clobber (match_dup 5))
12840 (clobber (reg:CC FLAGS_REG))])])
12842 ;; Segment register for the thread base ptr load
12843 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12845 ;; Load and add the thread base pointer from %<tp_seg>:0.
12846 (define_insn "*load_tp_x32"
12847 [(set (match_operand:SI 0 "register_operand" "=r")
12848 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12850 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12851 [(set_attr "type" "imov")
12852 (set_attr "modrm" "0")
12853 (set_attr "length" "7")
12854 (set_attr "memory" "load")
12855 (set_attr "imm_disp" "false")])
12857 (define_insn "*load_tp_x32_zext"
12858 [(set (match_operand:DI 0 "register_operand" "=r")
12859 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12861 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12862 [(set_attr "type" "imov")
12863 (set_attr "modrm" "0")
12864 (set_attr "length" "7")
12865 (set_attr "memory" "load")
12866 (set_attr "imm_disp" "false")])
12868 (define_insn "*load_tp_<mode>"
12869 [(set (match_operand:P 0 "register_operand" "=r")
12870 (unspec:P [(const_int 0)] UNSPEC_TP))]
12872 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12873 [(set_attr "type" "imov")
12874 (set_attr "modrm" "0")
12875 (set_attr "length" "7")
12876 (set_attr "memory" "load")
12877 (set_attr "imm_disp" "false")])
12879 (define_insn "*add_tp_x32"
12880 [(set (match_operand:SI 0 "register_operand" "=r")
12881 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12882 (match_operand:SI 1 "register_operand" "0")))
12883 (clobber (reg:CC FLAGS_REG))]
12885 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12886 [(set_attr "type" "alu")
12887 (set_attr "modrm" "0")
12888 (set_attr "length" "7")
12889 (set_attr "memory" "load")
12890 (set_attr "imm_disp" "false")])
12892 (define_insn "*add_tp_x32_zext"
12893 [(set (match_operand:DI 0 "register_operand" "=r")
12895 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12896 (match_operand:SI 1 "register_operand" "0"))))
12897 (clobber (reg:CC FLAGS_REG))]
12899 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12900 [(set_attr "type" "alu")
12901 (set_attr "modrm" "0")
12902 (set_attr "length" "7")
12903 (set_attr "memory" "load")
12904 (set_attr "imm_disp" "false")])
12906 (define_insn "*add_tp_<mode>"
12907 [(set (match_operand:P 0 "register_operand" "=r")
12908 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12909 (match_operand:P 1 "register_operand" "0")))
12910 (clobber (reg:CC FLAGS_REG))]
12912 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12913 [(set_attr "type" "alu")
12914 (set_attr "modrm" "0")
12915 (set_attr "length" "7")
12916 (set_attr "memory" "load")
12917 (set_attr "imm_disp" "false")])
12919 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12920 ;; %rax as destination of the initial executable code sequence.
12921 (define_insn "tls_initial_exec_64_sun"
12922 [(set (match_operand:DI 0 "register_operand" "=a")
12924 [(match_operand 1 "tls_symbolic_operand")]
12925 UNSPEC_TLS_IE_SUN))
12926 (clobber (reg:CC FLAGS_REG))]
12927 "TARGET_64BIT && TARGET_SUN_TLS"
12930 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12931 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12933 [(set_attr "type" "multi")])
12935 ;; GNU2 TLS patterns can be split.
12937 (define_expand "tls_dynamic_gnu2_32"
12938 [(set (match_dup 3)
12939 (plus:SI (match_operand:SI 2 "register_operand")
12941 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12944 [(set (match_operand:SI 0 "register_operand")
12945 (unspec:SI [(match_dup 1) (match_dup 3)
12946 (match_dup 2) (reg:SI SP_REG)]
12948 (clobber (reg:CC FLAGS_REG))])]
12949 "!TARGET_64BIT && TARGET_GNU2_TLS"
12951 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12952 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12955 (define_insn "*tls_dynamic_gnu2_lea_32"
12956 [(set (match_operand:SI 0 "register_operand" "=r")
12957 (plus:SI (match_operand:SI 1 "register_operand" "b")
12959 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12960 UNSPEC_TLSDESC))))]
12961 "!TARGET_64BIT && TARGET_GNU2_TLS"
12962 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12963 [(set_attr "type" "lea")
12964 (set_attr "mode" "SI")
12965 (set_attr "length" "6")
12966 (set_attr "length_address" "4")])
12968 (define_insn "*tls_dynamic_gnu2_call_32"
12969 [(set (match_operand:SI 0 "register_operand" "=a")
12970 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12971 (match_operand:SI 2 "register_operand" "0")
12972 ;; we have to make sure %ebx still points to the GOT
12973 (match_operand:SI 3 "register_operand" "b")
12976 (clobber (reg:CC FLAGS_REG))]
12977 "!TARGET_64BIT && TARGET_GNU2_TLS"
12978 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12979 [(set_attr "type" "call")
12980 (set_attr "length" "2")
12981 (set_attr "length_address" "0")])
12983 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12984 [(set (match_operand:SI 0 "register_operand" "=&a")
12986 (unspec:SI [(match_operand 3 "tls_modbase_operand")
12987 (match_operand:SI 4)
12988 (match_operand:SI 2 "register_operand" "b")
12991 (const:SI (unspec:SI
12992 [(match_operand 1 "tls_symbolic_operand")]
12994 (clobber (reg:CC FLAGS_REG))]
12995 "!TARGET_64BIT && TARGET_GNU2_TLS"
12998 [(set (match_dup 0) (match_dup 5))]
13000 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13001 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13004 (define_expand "tls_dynamic_gnu2_64"
13005 [(set (match_dup 2)
13006 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13009 [(set (match_operand:DI 0 "register_operand")
13010 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13012 (clobber (reg:CC FLAGS_REG))])]
13013 "TARGET_64BIT && TARGET_GNU2_TLS"
13015 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13016 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13019 (define_insn "*tls_dynamic_gnu2_lea_64"
13020 [(set (match_operand:DI 0 "register_operand" "=r")
13021 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13023 "TARGET_64BIT && TARGET_GNU2_TLS"
13024 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13025 [(set_attr "type" "lea")
13026 (set_attr "mode" "DI")
13027 (set_attr "length" "7")
13028 (set_attr "length_address" "4")])
13030 (define_insn "*tls_dynamic_gnu2_call_64"
13031 [(set (match_operand:DI 0 "register_operand" "=a")
13032 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13033 (match_operand:DI 2 "register_operand" "0")
13036 (clobber (reg:CC FLAGS_REG))]
13037 "TARGET_64BIT && TARGET_GNU2_TLS"
13038 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13039 [(set_attr "type" "call")
13040 (set_attr "length" "2")
13041 (set_attr "length_address" "0")])
13043 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13044 [(set (match_operand:DI 0 "register_operand" "=&a")
13046 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13047 (match_operand:DI 3)
13050 (const:DI (unspec:DI
13051 [(match_operand 1 "tls_symbolic_operand")]
13053 (clobber (reg:CC FLAGS_REG))]
13054 "TARGET_64BIT && TARGET_GNU2_TLS"
13057 [(set (match_dup 0) (match_dup 4))]
13059 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13060 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13063 ;; These patterns match the binary 387 instructions for addM3, subM3,
13064 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13065 ;; SFmode. The first is the normal insn, the second the same insn but
13066 ;; with one operand a conversion, and the third the same insn but with
13067 ;; the other operand a conversion. The conversion may be SFmode or
13068 ;; SImode if the target mode DFmode, but only SImode if the target mode
13071 ;; Gcc is slightly more smart about handling normal two address instructions
13072 ;; so use special patterns for add and mull.
13074 (define_insn "*fop_<mode>_comm_mixed"
13075 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13076 (match_operator:MODEF 3 "binary_fp_operator"
13077 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13078 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13079 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13080 && COMMUTATIVE_ARITH_P (operands[3])
13081 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13082 "* return output_387_binary_op (insn, operands);"
13083 [(set (attr "type")
13084 (if_then_else (eq_attr "alternative" "1,2")
13085 (if_then_else (match_operand:MODEF 3 "mult_operator")
13086 (const_string "ssemul")
13087 (const_string "sseadd"))
13088 (if_then_else (match_operand:MODEF 3 "mult_operator")
13089 (const_string "fmul")
13090 (const_string "fop"))))
13091 (set_attr "isa" "*,noavx,avx")
13092 (set_attr "prefix" "orig,orig,vex")
13093 (set_attr "mode" "<MODE>")])
13095 (define_insn "*fop_<mode>_comm_sse"
13096 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13097 (match_operator:MODEF 3 "binary_fp_operator"
13098 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13099 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13100 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13101 && COMMUTATIVE_ARITH_P (operands[3])
13102 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13103 "* return output_387_binary_op (insn, operands);"
13104 [(set (attr "type")
13105 (if_then_else (match_operand:MODEF 3 "mult_operator")
13106 (const_string "ssemul")
13107 (const_string "sseadd")))
13108 (set_attr "isa" "noavx,avx")
13109 (set_attr "prefix" "orig,vex")
13110 (set_attr "mode" "<MODE>")])
13112 (define_insn "*fop_<mode>_comm_i387"
13113 [(set (match_operand:MODEF 0 "register_operand" "=f")
13114 (match_operator:MODEF 3 "binary_fp_operator"
13115 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13116 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13117 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13118 && COMMUTATIVE_ARITH_P (operands[3])
13119 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13120 "* return output_387_binary_op (insn, operands);"
13121 [(set (attr "type")
13122 (if_then_else (match_operand:MODEF 3 "mult_operator")
13123 (const_string "fmul")
13124 (const_string "fop")))
13125 (set_attr "mode" "<MODE>")])
13127 (define_insn "*fop_<mode>_1_mixed"
13128 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13129 (match_operator:MODEF 3 "binary_fp_operator"
13130 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13131 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13132 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13133 && !COMMUTATIVE_ARITH_P (operands[3])
13134 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13135 "* return output_387_binary_op (insn, operands);"
13136 [(set (attr "type")
13137 (cond [(and (eq_attr "alternative" "2,3")
13138 (match_operand:MODEF 3 "mult_operator"))
13139 (const_string "ssemul")
13140 (and (eq_attr "alternative" "2,3")
13141 (match_operand:MODEF 3 "div_operator"))
13142 (const_string "ssediv")
13143 (eq_attr "alternative" "2,3")
13144 (const_string "sseadd")
13145 (match_operand:MODEF 3 "mult_operator")
13146 (const_string "fmul")
13147 (match_operand:MODEF 3 "div_operator")
13148 (const_string "fdiv")
13150 (const_string "fop")))
13151 (set_attr "isa" "*,*,noavx,avx")
13152 (set_attr "prefix" "orig,orig,orig,vex")
13153 (set_attr "mode" "<MODE>")])
13155 (define_insn "*rcpsf2_sse"
13156 [(set (match_operand:SF 0 "register_operand" "=x")
13157 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13160 "%vrcpss\t{%1, %d0|%d0, %1}"
13161 [(set_attr "type" "sse")
13162 (set_attr "atom_sse_attr" "rcp")
13163 (set_attr "btver2_sse_attr" "rcp")
13164 (set_attr "prefix" "maybe_vex")
13165 (set_attr "mode" "SF")])
13167 (define_insn "*fop_<mode>_1_sse"
13168 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13169 (match_operator:MODEF 3 "binary_fp_operator"
13170 [(match_operand:MODEF 1 "register_operand" "0,x")
13171 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13172 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13173 && !COMMUTATIVE_ARITH_P (operands[3])"
13174 "* return output_387_binary_op (insn, operands);"
13175 [(set (attr "type")
13176 (cond [(match_operand:MODEF 3 "mult_operator")
13177 (const_string "ssemul")
13178 (match_operand:MODEF 3 "div_operator")
13179 (const_string "ssediv")
13181 (const_string "sseadd")))
13182 (set_attr "isa" "noavx,avx")
13183 (set_attr "prefix" "orig,vex")
13184 (set_attr "mode" "<MODE>")])
13186 ;; This pattern is not fully shadowed by the pattern above.
13187 (define_insn "*fop_<mode>_1_i387"
13188 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13189 (match_operator:MODEF 3 "binary_fp_operator"
13190 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13191 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13192 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13193 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13194 && !COMMUTATIVE_ARITH_P (operands[3])
13195 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13196 "* return output_387_binary_op (insn, operands);"
13197 [(set (attr "type")
13198 (cond [(match_operand:MODEF 3 "mult_operator")
13199 (const_string "fmul")
13200 (match_operand:MODEF 3 "div_operator")
13201 (const_string "fdiv")
13203 (const_string "fop")))
13204 (set_attr "mode" "<MODE>")])
13206 ;; ??? Add SSE splitters for these!
13207 (define_insn "*fop_<MODEF:mode>_2_i387"
13208 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13209 (match_operator:MODEF 3 "binary_fp_operator"
13211 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13212 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13213 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13214 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13215 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13216 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13217 [(set (attr "type")
13218 (cond [(match_operand:MODEF 3 "mult_operator")
13219 (const_string "fmul")
13220 (match_operand:MODEF 3 "div_operator")
13221 (const_string "fdiv")
13223 (const_string "fop")))
13224 (set_attr "fp_int_src" "true")
13225 (set_attr "mode" "<SWI24:MODE>")])
13227 (define_insn "*fop_<MODEF:mode>_3_i387"
13228 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13229 (match_operator:MODEF 3 "binary_fp_operator"
13230 [(match_operand:MODEF 1 "register_operand" "0,0")
13232 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13233 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13234 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13235 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13236 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13237 [(set (attr "type")
13238 (cond [(match_operand:MODEF 3 "mult_operator")
13239 (const_string "fmul")
13240 (match_operand:MODEF 3 "div_operator")
13241 (const_string "fdiv")
13243 (const_string "fop")))
13244 (set_attr "fp_int_src" "true")
13245 (set_attr "mode" "<MODE>")])
13247 (define_insn "*fop_df_4_i387"
13248 [(set (match_operand:DF 0 "register_operand" "=f,f")
13249 (match_operator:DF 3 "binary_fp_operator"
13251 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13252 (match_operand:DF 2 "register_operand" "0,f")]))]
13253 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13254 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13255 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13256 "* return output_387_binary_op (insn, operands);"
13257 [(set (attr "type")
13258 (cond [(match_operand:DF 3 "mult_operator")
13259 (const_string "fmul")
13260 (match_operand:DF 3 "div_operator")
13261 (const_string "fdiv")
13263 (const_string "fop")))
13264 (set_attr "mode" "SF")])
13266 (define_insn "*fop_df_5_i387"
13267 [(set (match_operand:DF 0 "register_operand" "=f,f")
13268 (match_operator:DF 3 "binary_fp_operator"
13269 [(match_operand:DF 1 "register_operand" "0,f")
13271 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13272 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13273 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13274 "* return output_387_binary_op (insn, operands);"
13275 [(set (attr "type")
13276 (cond [(match_operand:DF 3 "mult_operator")
13277 (const_string "fmul")
13278 (match_operand:DF 3 "div_operator")
13279 (const_string "fdiv")
13281 (const_string "fop")))
13282 (set_attr "mode" "SF")])
13284 (define_insn "*fop_df_6_i387"
13285 [(set (match_operand:DF 0 "register_operand" "=f,f")
13286 (match_operator:DF 3 "binary_fp_operator"
13288 (match_operand:SF 1 "register_operand" "0,f"))
13290 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13291 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13292 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13293 "* return output_387_binary_op (insn, operands);"
13294 [(set (attr "type")
13295 (cond [(match_operand:DF 3 "mult_operator")
13296 (const_string "fmul")
13297 (match_operand:DF 3 "div_operator")
13298 (const_string "fdiv")
13300 (const_string "fop")))
13301 (set_attr "mode" "SF")])
13303 (define_insn "*fop_xf_comm_i387"
13304 [(set (match_operand:XF 0 "register_operand" "=f")
13305 (match_operator:XF 3 "binary_fp_operator"
13306 [(match_operand:XF 1 "register_operand" "%0")
13307 (match_operand:XF 2 "register_operand" "f")]))]
13309 && COMMUTATIVE_ARITH_P (operands[3])"
13310 "* return output_387_binary_op (insn, operands);"
13311 [(set (attr "type")
13312 (if_then_else (match_operand:XF 3 "mult_operator")
13313 (const_string "fmul")
13314 (const_string "fop")))
13315 (set_attr "mode" "XF")])
13317 (define_insn "*fop_xf_1_i387"
13318 [(set (match_operand:XF 0 "register_operand" "=f,f")
13319 (match_operator:XF 3 "binary_fp_operator"
13320 [(match_operand:XF 1 "register_operand" "0,f")
13321 (match_operand:XF 2 "register_operand" "f,0")]))]
13323 && !COMMUTATIVE_ARITH_P (operands[3])"
13324 "* return output_387_binary_op (insn, operands);"
13325 [(set (attr "type")
13326 (cond [(match_operand:XF 3 "mult_operator")
13327 (const_string "fmul")
13328 (match_operand:XF 3 "div_operator")
13329 (const_string "fdiv")
13331 (const_string "fop")))
13332 (set_attr "mode" "XF")])
13334 (define_insn "*fop_xf_2_i387"
13335 [(set (match_operand:XF 0 "register_operand" "=f,f")
13336 (match_operator:XF 3 "binary_fp_operator"
13338 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13339 (match_operand:XF 2 "register_operand" "0,0")]))]
13340 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13341 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13342 [(set (attr "type")
13343 (cond [(match_operand:XF 3 "mult_operator")
13344 (const_string "fmul")
13345 (match_operand:XF 3 "div_operator")
13346 (const_string "fdiv")
13348 (const_string "fop")))
13349 (set_attr "fp_int_src" "true")
13350 (set_attr "mode" "<MODE>")])
13352 (define_insn "*fop_xf_3_i387"
13353 [(set (match_operand:XF 0 "register_operand" "=f,f")
13354 (match_operator:XF 3 "binary_fp_operator"
13355 [(match_operand:XF 1 "register_operand" "0,0")
13357 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13358 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13359 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13360 [(set (attr "type")
13361 (cond [(match_operand:XF 3 "mult_operator")
13362 (const_string "fmul")
13363 (match_operand:XF 3 "div_operator")
13364 (const_string "fdiv")
13366 (const_string "fop")))
13367 (set_attr "fp_int_src" "true")
13368 (set_attr "mode" "<MODE>")])
13370 (define_insn "*fop_xf_4_i387"
13371 [(set (match_operand:XF 0 "register_operand" "=f,f")
13372 (match_operator:XF 3 "binary_fp_operator"
13374 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13375 (match_operand:XF 2 "register_operand" "0,f")]))]
13377 "* return output_387_binary_op (insn, operands);"
13378 [(set (attr "type")
13379 (cond [(match_operand:XF 3 "mult_operator")
13380 (const_string "fmul")
13381 (match_operand:XF 3 "div_operator")
13382 (const_string "fdiv")
13384 (const_string "fop")))
13385 (set_attr "mode" "<MODE>")])
13387 (define_insn "*fop_xf_5_i387"
13388 [(set (match_operand:XF 0 "register_operand" "=f,f")
13389 (match_operator:XF 3 "binary_fp_operator"
13390 [(match_operand:XF 1 "register_operand" "0,f")
13392 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13394 "* return output_387_binary_op (insn, operands);"
13395 [(set (attr "type")
13396 (cond [(match_operand:XF 3 "mult_operator")
13397 (const_string "fmul")
13398 (match_operand:XF 3 "div_operator")
13399 (const_string "fdiv")
13401 (const_string "fop")))
13402 (set_attr "mode" "<MODE>")])
13404 (define_insn "*fop_xf_6_i387"
13405 [(set (match_operand:XF 0 "register_operand" "=f,f")
13406 (match_operator:XF 3 "binary_fp_operator"
13408 (match_operand:MODEF 1 "register_operand" "0,f"))
13410 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13412 "* return output_387_binary_op (insn, operands);"
13413 [(set (attr "type")
13414 (cond [(match_operand:XF 3 "mult_operator")
13415 (const_string "fmul")
13416 (match_operand:XF 3 "div_operator")
13417 (const_string "fdiv")
13419 (const_string "fop")))
13420 (set_attr "mode" "<MODE>")])
13423 [(set (match_operand 0 "register_operand")
13424 (match_operator 3 "binary_fp_operator"
13425 [(float (match_operand:SWI24 1 "register_operand"))
13426 (match_operand 2 "register_operand")]))]
13428 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13429 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13432 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13433 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13434 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13435 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13436 GET_MODE (operands[3]),
13439 ix86_free_from_memory (GET_MODE (operands[1]));
13444 [(set (match_operand 0 "register_operand")
13445 (match_operator 3 "binary_fp_operator"
13446 [(match_operand 1 "register_operand")
13447 (float (match_operand:SWI24 2 "register_operand"))]))]
13449 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13450 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13453 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13454 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13455 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13456 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13457 GET_MODE (operands[3]),
13460 ix86_free_from_memory (GET_MODE (operands[2]));
13464 ;; FPU special functions.
13466 ;; This pattern implements a no-op XFmode truncation for
13467 ;; all fancy i386 XFmode math functions.
13469 (define_insn "truncxf<mode>2_i387_noop_unspec"
13470 [(set (match_operand:MODEF 0 "register_operand" "=f")
13471 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13472 UNSPEC_TRUNC_NOOP))]
13473 "TARGET_USE_FANCY_MATH_387"
13474 "* return output_387_reg_move (insn, operands);"
13475 [(set_attr "type" "fmov")
13476 (set_attr "mode" "<MODE>")])
13478 (define_insn "sqrtxf2"
13479 [(set (match_operand:XF 0 "register_operand" "=f")
13480 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13481 "TARGET_USE_FANCY_MATH_387"
13483 [(set_attr "type" "fpspc")
13484 (set_attr "mode" "XF")
13485 (set_attr "athlon_decode" "direct")
13486 (set_attr "amdfam10_decode" "direct")
13487 (set_attr "bdver1_decode" "direct")])
13489 (define_insn "sqrt_extend<mode>xf2_i387"
13490 [(set (match_operand:XF 0 "register_operand" "=f")
13493 (match_operand:MODEF 1 "register_operand" "0"))))]
13494 "TARGET_USE_FANCY_MATH_387"
13496 [(set_attr "type" "fpspc")
13497 (set_attr "mode" "XF")
13498 (set_attr "athlon_decode" "direct")
13499 (set_attr "amdfam10_decode" "direct")
13500 (set_attr "bdver1_decode" "direct")])
13502 (define_insn "*rsqrtsf2_sse"
13503 [(set (match_operand:SF 0 "register_operand" "=x")
13504 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13507 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13508 [(set_attr "type" "sse")
13509 (set_attr "atom_sse_attr" "rcp")
13510 (set_attr "btver2_sse_attr" "rcp")
13511 (set_attr "prefix" "maybe_vex")
13512 (set_attr "mode" "SF")])
13514 (define_expand "rsqrtsf2"
13515 [(set (match_operand:SF 0 "register_operand")
13516 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13520 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13524 (define_insn "*sqrt<mode>2_sse"
13525 [(set (match_operand:MODEF 0 "register_operand" "=x")
13527 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13528 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13529 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13530 [(set_attr "type" "sse")
13531 (set_attr "atom_sse_attr" "sqrt")
13532 (set_attr "btver2_sse_attr" "sqrt")
13533 (set_attr "prefix" "maybe_vex")
13534 (set_attr "mode" "<MODE>")
13535 (set_attr "athlon_decode" "*")
13536 (set_attr "amdfam10_decode" "*")
13537 (set_attr "bdver1_decode" "*")])
13539 (define_expand "sqrt<mode>2"
13540 [(set (match_operand:MODEF 0 "register_operand")
13542 (match_operand:MODEF 1 "nonimmediate_operand")))]
13543 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13544 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13546 if (<MODE>mode == SFmode
13548 && TARGET_RECIP_SQRT
13549 && !optimize_function_for_size_p (cfun)
13550 && flag_finite_math_only && !flag_trapping_math
13551 && flag_unsafe_math_optimizations)
13553 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13557 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13559 rtx op0 = gen_reg_rtx (XFmode);
13560 rtx op1 = force_reg (<MODE>mode, operands[1]);
13562 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13563 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13568 (define_insn "fpremxf4_i387"
13569 [(set (match_operand:XF 0 "register_operand" "=f")
13570 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13571 (match_operand:XF 3 "register_operand" "1")]
13573 (set (match_operand:XF 1 "register_operand" "=u")
13574 (unspec:XF [(match_dup 2) (match_dup 3)]
13576 (set (reg:CCFP FPSR_REG)
13577 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13579 "TARGET_USE_FANCY_MATH_387"
13581 [(set_attr "type" "fpspc")
13582 (set_attr "mode" "XF")])
13584 (define_expand "fmodxf3"
13585 [(use (match_operand:XF 0 "register_operand"))
13586 (use (match_operand:XF 1 "general_operand"))
13587 (use (match_operand:XF 2 "general_operand"))]
13588 "TARGET_USE_FANCY_MATH_387"
13590 rtx label = gen_label_rtx ();
13592 rtx op1 = gen_reg_rtx (XFmode);
13593 rtx op2 = gen_reg_rtx (XFmode);
13595 emit_move_insn (op2, operands[2]);
13596 emit_move_insn (op1, operands[1]);
13598 emit_label (label);
13599 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13600 ix86_emit_fp_unordered_jump (label);
13601 LABEL_NUSES (label) = 1;
13603 emit_move_insn (operands[0], op1);
13607 (define_expand "fmod<mode>3"
13608 [(use (match_operand:MODEF 0 "register_operand"))
13609 (use (match_operand:MODEF 1 "general_operand"))
13610 (use (match_operand:MODEF 2 "general_operand"))]
13611 "TARGET_USE_FANCY_MATH_387"
13613 rtx (*gen_truncxf) (rtx, rtx);
13615 rtx label = gen_label_rtx ();
13617 rtx op1 = gen_reg_rtx (XFmode);
13618 rtx op2 = gen_reg_rtx (XFmode);
13620 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13621 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13623 emit_label (label);
13624 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13625 ix86_emit_fp_unordered_jump (label);
13626 LABEL_NUSES (label) = 1;
13628 /* Truncate the result properly for strict SSE math. */
13629 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13630 && !TARGET_MIX_SSE_I387)
13631 gen_truncxf = gen_truncxf<mode>2;
13633 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13635 emit_insn (gen_truncxf (operands[0], op1));
13639 (define_insn "fprem1xf4_i387"
13640 [(set (match_operand:XF 0 "register_operand" "=f")
13641 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13642 (match_operand:XF 3 "register_operand" "1")]
13644 (set (match_operand:XF 1 "register_operand" "=u")
13645 (unspec:XF [(match_dup 2) (match_dup 3)]
13647 (set (reg:CCFP FPSR_REG)
13648 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13650 "TARGET_USE_FANCY_MATH_387"
13652 [(set_attr "type" "fpspc")
13653 (set_attr "mode" "XF")])
13655 (define_expand "remainderxf3"
13656 [(use (match_operand:XF 0 "register_operand"))
13657 (use (match_operand:XF 1 "general_operand"))
13658 (use (match_operand:XF 2 "general_operand"))]
13659 "TARGET_USE_FANCY_MATH_387"
13661 rtx label = gen_label_rtx ();
13663 rtx op1 = gen_reg_rtx (XFmode);
13664 rtx op2 = gen_reg_rtx (XFmode);
13666 emit_move_insn (op2, operands[2]);
13667 emit_move_insn (op1, operands[1]);
13669 emit_label (label);
13670 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13671 ix86_emit_fp_unordered_jump (label);
13672 LABEL_NUSES (label) = 1;
13674 emit_move_insn (operands[0], op1);
13678 (define_expand "remainder<mode>3"
13679 [(use (match_operand:MODEF 0 "register_operand"))
13680 (use (match_operand:MODEF 1 "general_operand"))
13681 (use (match_operand:MODEF 2 "general_operand"))]
13682 "TARGET_USE_FANCY_MATH_387"
13684 rtx (*gen_truncxf) (rtx, rtx);
13686 rtx label = gen_label_rtx ();
13688 rtx op1 = gen_reg_rtx (XFmode);
13689 rtx op2 = gen_reg_rtx (XFmode);
13691 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13692 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13694 emit_label (label);
13696 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13697 ix86_emit_fp_unordered_jump (label);
13698 LABEL_NUSES (label) = 1;
13700 /* Truncate the result properly for strict SSE math. */
13701 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13702 && !TARGET_MIX_SSE_I387)
13703 gen_truncxf = gen_truncxf<mode>2;
13705 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13707 emit_insn (gen_truncxf (operands[0], op1));
13711 (define_int_iterator SINCOS
13715 (define_int_attr sincos
13716 [(UNSPEC_SIN "sin")
13717 (UNSPEC_COS "cos")])
13719 (define_insn "*<sincos>xf2_i387"
13720 [(set (match_operand:XF 0 "register_operand" "=f")
13721 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13723 "TARGET_USE_FANCY_MATH_387
13724 && flag_unsafe_math_optimizations"
13726 [(set_attr "type" "fpspc")
13727 (set_attr "mode" "XF")])
13729 (define_insn "*<sincos>_extend<mode>xf2_i387"
13730 [(set (match_operand:XF 0 "register_operand" "=f")
13731 (unspec:XF [(float_extend:XF
13732 (match_operand:MODEF 1 "register_operand" "0"))]
13734 "TARGET_USE_FANCY_MATH_387
13735 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13736 || TARGET_MIX_SSE_I387)
13737 && flag_unsafe_math_optimizations"
13739 [(set_attr "type" "fpspc")
13740 (set_attr "mode" "XF")])
13742 ;; When sincos pattern is defined, sin and cos builtin functions will be
13743 ;; expanded to sincos pattern with one of its outputs left unused.
13744 ;; CSE pass will figure out if two sincos patterns can be combined,
13745 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13746 ;; depending on the unused output.
13748 (define_insn "sincosxf3"
13749 [(set (match_operand:XF 0 "register_operand" "=f")
13750 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13751 UNSPEC_SINCOS_COS))
13752 (set (match_operand:XF 1 "register_operand" "=u")
13753 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13754 "TARGET_USE_FANCY_MATH_387
13755 && flag_unsafe_math_optimizations"
13757 [(set_attr "type" "fpspc")
13758 (set_attr "mode" "XF")])
13761 [(set (match_operand:XF 0 "register_operand")
13762 (unspec:XF [(match_operand:XF 2 "register_operand")]
13763 UNSPEC_SINCOS_COS))
13764 (set (match_operand:XF 1 "register_operand")
13765 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13766 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13767 && can_create_pseudo_p ()"
13768 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13771 [(set (match_operand:XF 0 "register_operand")
13772 (unspec:XF [(match_operand:XF 2 "register_operand")]
13773 UNSPEC_SINCOS_COS))
13774 (set (match_operand:XF 1 "register_operand")
13775 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13776 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13777 && can_create_pseudo_p ()"
13778 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13780 (define_insn "sincos_extend<mode>xf3_i387"
13781 [(set (match_operand:XF 0 "register_operand" "=f")
13782 (unspec:XF [(float_extend:XF
13783 (match_operand:MODEF 2 "register_operand" "0"))]
13784 UNSPEC_SINCOS_COS))
13785 (set (match_operand:XF 1 "register_operand" "=u")
13786 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13787 "TARGET_USE_FANCY_MATH_387
13788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13789 || TARGET_MIX_SSE_I387)
13790 && flag_unsafe_math_optimizations"
13792 [(set_attr "type" "fpspc")
13793 (set_attr "mode" "XF")])
13796 [(set (match_operand:XF 0 "register_operand")
13797 (unspec:XF [(float_extend:XF
13798 (match_operand:MODEF 2 "register_operand"))]
13799 UNSPEC_SINCOS_COS))
13800 (set (match_operand:XF 1 "register_operand")
13801 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13802 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13803 && can_create_pseudo_p ()"
13804 [(set (match_dup 1)
13805 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13808 [(set (match_operand:XF 0 "register_operand")
13809 (unspec:XF [(float_extend:XF
13810 (match_operand:MODEF 2 "register_operand"))]
13811 UNSPEC_SINCOS_COS))
13812 (set (match_operand:XF 1 "register_operand")
13813 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13814 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13815 && can_create_pseudo_p ()"
13816 [(set (match_dup 0)
13817 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13819 (define_expand "sincos<mode>3"
13820 [(use (match_operand:MODEF 0 "register_operand"))
13821 (use (match_operand:MODEF 1 "register_operand"))
13822 (use (match_operand:MODEF 2 "register_operand"))]
13823 "TARGET_USE_FANCY_MATH_387
13824 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13825 || TARGET_MIX_SSE_I387)
13826 && flag_unsafe_math_optimizations"
13828 rtx op0 = gen_reg_rtx (XFmode);
13829 rtx op1 = gen_reg_rtx (XFmode);
13831 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13832 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13833 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13837 (define_insn "fptanxf4_i387"
13838 [(set (match_operand:XF 0 "register_operand" "=f")
13839 (match_operand:XF 3 "const_double_operand" "F"))
13840 (set (match_operand:XF 1 "register_operand" "=u")
13841 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13843 "TARGET_USE_FANCY_MATH_387
13844 && flag_unsafe_math_optimizations
13845 && standard_80387_constant_p (operands[3]) == 2"
13847 [(set_attr "type" "fpspc")
13848 (set_attr "mode" "XF")])
13850 (define_insn "fptan_extend<mode>xf4_i387"
13851 [(set (match_operand:MODEF 0 "register_operand" "=f")
13852 (match_operand:MODEF 3 "const_double_operand" "F"))
13853 (set (match_operand:XF 1 "register_operand" "=u")
13854 (unspec:XF [(float_extend:XF
13855 (match_operand:MODEF 2 "register_operand" "0"))]
13857 "TARGET_USE_FANCY_MATH_387
13858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13859 || TARGET_MIX_SSE_I387)
13860 && flag_unsafe_math_optimizations
13861 && standard_80387_constant_p (operands[3]) == 2"
13863 [(set_attr "type" "fpspc")
13864 (set_attr "mode" "XF")])
13866 (define_expand "tanxf2"
13867 [(use (match_operand:XF 0 "register_operand"))
13868 (use (match_operand:XF 1 "register_operand"))]
13869 "TARGET_USE_FANCY_MATH_387
13870 && flag_unsafe_math_optimizations"
13872 rtx one = gen_reg_rtx (XFmode);
13873 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13875 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13879 (define_expand "tan<mode>2"
13880 [(use (match_operand:MODEF 0 "register_operand"))
13881 (use (match_operand:MODEF 1 "register_operand"))]
13882 "TARGET_USE_FANCY_MATH_387
13883 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13884 || TARGET_MIX_SSE_I387)
13885 && flag_unsafe_math_optimizations"
13887 rtx op0 = gen_reg_rtx (XFmode);
13889 rtx one = gen_reg_rtx (<MODE>mode);
13890 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13892 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13893 operands[1], op2));
13894 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13898 (define_insn "*fpatanxf3_i387"
13899 [(set (match_operand:XF 0 "register_operand" "=f")
13900 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13901 (match_operand:XF 2 "register_operand" "u")]
13903 (clobber (match_scratch:XF 3 "=2"))]
13904 "TARGET_USE_FANCY_MATH_387
13905 && flag_unsafe_math_optimizations"
13907 [(set_attr "type" "fpspc")
13908 (set_attr "mode" "XF")])
13910 (define_insn "fpatan_extend<mode>xf3_i387"
13911 [(set (match_operand:XF 0 "register_operand" "=f")
13912 (unspec:XF [(float_extend:XF
13913 (match_operand:MODEF 1 "register_operand" "0"))
13915 (match_operand:MODEF 2 "register_operand" "u"))]
13917 (clobber (match_scratch:XF 3 "=2"))]
13918 "TARGET_USE_FANCY_MATH_387
13919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13920 || TARGET_MIX_SSE_I387)
13921 && flag_unsafe_math_optimizations"
13923 [(set_attr "type" "fpspc")
13924 (set_attr "mode" "XF")])
13926 (define_expand "atan2xf3"
13927 [(parallel [(set (match_operand:XF 0 "register_operand")
13928 (unspec:XF [(match_operand:XF 2 "register_operand")
13929 (match_operand:XF 1 "register_operand")]
13931 (clobber (match_scratch:XF 3))])]
13932 "TARGET_USE_FANCY_MATH_387
13933 && flag_unsafe_math_optimizations")
13935 (define_expand "atan2<mode>3"
13936 [(use (match_operand:MODEF 0 "register_operand"))
13937 (use (match_operand:MODEF 1 "register_operand"))
13938 (use (match_operand:MODEF 2 "register_operand"))]
13939 "TARGET_USE_FANCY_MATH_387
13940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13941 || TARGET_MIX_SSE_I387)
13942 && flag_unsafe_math_optimizations"
13944 rtx op0 = gen_reg_rtx (XFmode);
13946 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13947 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13951 (define_expand "atanxf2"
13952 [(parallel [(set (match_operand:XF 0 "register_operand")
13953 (unspec:XF [(match_dup 2)
13954 (match_operand:XF 1 "register_operand")]
13956 (clobber (match_scratch:XF 3))])]
13957 "TARGET_USE_FANCY_MATH_387
13958 && flag_unsafe_math_optimizations"
13960 operands[2] = gen_reg_rtx (XFmode);
13961 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13964 (define_expand "atan<mode>2"
13965 [(use (match_operand:MODEF 0 "register_operand"))
13966 (use (match_operand:MODEF 1 "register_operand"))]
13967 "TARGET_USE_FANCY_MATH_387
13968 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13969 || TARGET_MIX_SSE_I387)
13970 && flag_unsafe_math_optimizations"
13972 rtx op0 = gen_reg_rtx (XFmode);
13974 rtx op2 = gen_reg_rtx (<MODE>mode);
13975 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13977 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13978 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13982 (define_expand "asinxf2"
13983 [(set (match_dup 2)
13984 (mult:XF (match_operand:XF 1 "register_operand")
13986 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13987 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13988 (parallel [(set (match_operand:XF 0 "register_operand")
13989 (unspec:XF [(match_dup 5) (match_dup 1)]
13991 (clobber (match_scratch:XF 6))])]
13992 "TARGET_USE_FANCY_MATH_387
13993 && flag_unsafe_math_optimizations"
13997 if (optimize_insn_for_size_p ())
14000 for (i = 2; i < 6; i++)
14001 operands[i] = gen_reg_rtx (XFmode);
14003 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14006 (define_expand "asin<mode>2"
14007 [(use (match_operand:MODEF 0 "register_operand"))
14008 (use (match_operand:MODEF 1 "general_operand"))]
14009 "TARGET_USE_FANCY_MATH_387
14010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011 || TARGET_MIX_SSE_I387)
14012 && flag_unsafe_math_optimizations"
14014 rtx op0 = gen_reg_rtx (XFmode);
14015 rtx op1 = gen_reg_rtx (XFmode);
14017 if (optimize_insn_for_size_p ())
14020 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14021 emit_insn (gen_asinxf2 (op0, op1));
14022 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14026 (define_expand "acosxf2"
14027 [(set (match_dup 2)
14028 (mult:XF (match_operand:XF 1 "register_operand")
14030 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14031 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14032 (parallel [(set (match_operand:XF 0 "register_operand")
14033 (unspec:XF [(match_dup 1) (match_dup 5)]
14035 (clobber (match_scratch:XF 6))])]
14036 "TARGET_USE_FANCY_MATH_387
14037 && flag_unsafe_math_optimizations"
14041 if (optimize_insn_for_size_p ())
14044 for (i = 2; i < 6; i++)
14045 operands[i] = gen_reg_rtx (XFmode);
14047 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14050 (define_expand "acos<mode>2"
14051 [(use (match_operand:MODEF 0 "register_operand"))
14052 (use (match_operand:MODEF 1 "general_operand"))]
14053 "TARGET_USE_FANCY_MATH_387
14054 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14055 || TARGET_MIX_SSE_I387)
14056 && flag_unsafe_math_optimizations"
14058 rtx op0 = gen_reg_rtx (XFmode);
14059 rtx op1 = gen_reg_rtx (XFmode);
14061 if (optimize_insn_for_size_p ())
14064 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14065 emit_insn (gen_acosxf2 (op0, op1));
14066 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14070 (define_insn "fyl2xxf3_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 "fyl2x_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"))
14086 (match_operand:XF 2 "register_operand" "u")]
14088 (clobber (match_scratch:XF 3 "=2"))]
14089 "TARGET_USE_FANCY_MATH_387
14090 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14091 || TARGET_MIX_SSE_I387)
14092 && flag_unsafe_math_optimizations"
14094 [(set_attr "type" "fpspc")
14095 (set_attr "mode" "XF")])
14097 (define_expand "logxf2"
14098 [(parallel [(set (match_operand:XF 0 "register_operand")
14099 (unspec:XF [(match_operand:XF 1 "register_operand")
14100 (match_dup 2)] UNSPEC_FYL2X))
14101 (clobber (match_scratch:XF 3))])]
14102 "TARGET_USE_FANCY_MATH_387
14103 && flag_unsafe_math_optimizations"
14105 operands[2] = gen_reg_rtx (XFmode);
14106 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14109 (define_expand "log<mode>2"
14110 [(use (match_operand:MODEF 0 "register_operand"))
14111 (use (match_operand:MODEF 1 "register_operand"))]
14112 "TARGET_USE_FANCY_MATH_387
14113 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14114 || TARGET_MIX_SSE_I387)
14115 && flag_unsafe_math_optimizations"
14117 rtx op0 = gen_reg_rtx (XFmode);
14119 rtx op2 = gen_reg_rtx (XFmode);
14120 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14122 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14123 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14127 (define_expand "log10xf2"
14128 [(parallel [(set (match_operand:XF 0 "register_operand")
14129 (unspec:XF [(match_operand:XF 1 "register_operand")
14130 (match_dup 2)] UNSPEC_FYL2X))
14131 (clobber (match_scratch:XF 3))])]
14132 "TARGET_USE_FANCY_MATH_387
14133 && flag_unsafe_math_optimizations"
14135 operands[2] = gen_reg_rtx (XFmode);
14136 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14139 (define_expand "log10<mode>2"
14140 [(use (match_operand:MODEF 0 "register_operand"))
14141 (use (match_operand:MODEF 1 "register_operand"))]
14142 "TARGET_USE_FANCY_MATH_387
14143 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14144 || TARGET_MIX_SSE_I387)
14145 && flag_unsafe_math_optimizations"
14147 rtx op0 = gen_reg_rtx (XFmode);
14149 rtx op2 = gen_reg_rtx (XFmode);
14150 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14152 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14153 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14157 (define_expand "log2xf2"
14158 [(parallel [(set (match_operand:XF 0 "register_operand")
14159 (unspec:XF [(match_operand:XF 1 "register_operand")
14160 (match_dup 2)] UNSPEC_FYL2X))
14161 (clobber (match_scratch:XF 3))])]
14162 "TARGET_USE_FANCY_MATH_387
14163 && flag_unsafe_math_optimizations"
14165 operands[2] = gen_reg_rtx (XFmode);
14166 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14169 (define_expand "log2<mode>2"
14170 [(use (match_operand:MODEF 0 "register_operand"))
14171 (use (match_operand:MODEF 1 "register_operand"))]
14172 "TARGET_USE_FANCY_MATH_387
14173 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14174 || TARGET_MIX_SSE_I387)
14175 && flag_unsafe_math_optimizations"
14177 rtx op0 = gen_reg_rtx (XFmode);
14179 rtx op2 = gen_reg_rtx (XFmode);
14180 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14182 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14183 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14187 (define_insn "fyl2xp1xf3_i387"
14188 [(set (match_operand:XF 0 "register_operand" "=f")
14189 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14190 (match_operand:XF 2 "register_operand" "u")]
14192 (clobber (match_scratch:XF 3 "=2"))]
14193 "TARGET_USE_FANCY_MATH_387
14194 && flag_unsafe_math_optimizations"
14196 [(set_attr "type" "fpspc")
14197 (set_attr "mode" "XF")])
14199 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14200 [(set (match_operand:XF 0 "register_operand" "=f")
14201 (unspec:XF [(float_extend:XF
14202 (match_operand:MODEF 1 "register_operand" "0"))
14203 (match_operand:XF 2 "register_operand" "u")]
14205 (clobber (match_scratch:XF 3 "=2"))]
14206 "TARGET_USE_FANCY_MATH_387
14207 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14208 || TARGET_MIX_SSE_I387)
14209 && flag_unsafe_math_optimizations"
14211 [(set_attr "type" "fpspc")
14212 (set_attr "mode" "XF")])
14214 (define_expand "log1pxf2"
14215 [(use (match_operand:XF 0 "register_operand"))
14216 (use (match_operand:XF 1 "register_operand"))]
14217 "TARGET_USE_FANCY_MATH_387
14218 && flag_unsafe_math_optimizations"
14220 if (optimize_insn_for_size_p ())
14223 ix86_emit_i387_log1p (operands[0], operands[1]);
14227 (define_expand "log1p<mode>2"
14228 [(use (match_operand:MODEF 0 "register_operand"))
14229 (use (match_operand:MODEF 1 "register_operand"))]
14230 "TARGET_USE_FANCY_MATH_387
14231 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14232 || TARGET_MIX_SSE_I387)
14233 && flag_unsafe_math_optimizations"
14237 if (optimize_insn_for_size_p ())
14240 op0 = gen_reg_rtx (XFmode);
14242 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14244 ix86_emit_i387_log1p (op0, operands[1]);
14245 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14249 (define_insn "fxtractxf3_i387"
14250 [(set (match_operand:XF 0 "register_operand" "=f")
14251 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14252 UNSPEC_XTRACT_FRACT))
14253 (set (match_operand:XF 1 "register_operand" "=u")
14254 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14255 "TARGET_USE_FANCY_MATH_387
14256 && flag_unsafe_math_optimizations"
14258 [(set_attr "type" "fpspc")
14259 (set_attr "mode" "XF")])
14261 (define_insn "fxtract_extend<mode>xf3_i387"
14262 [(set (match_operand:XF 0 "register_operand" "=f")
14263 (unspec:XF [(float_extend:XF
14264 (match_operand:MODEF 2 "register_operand" "0"))]
14265 UNSPEC_XTRACT_FRACT))
14266 (set (match_operand:XF 1 "register_operand" "=u")
14267 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14268 "TARGET_USE_FANCY_MATH_387
14269 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14270 || TARGET_MIX_SSE_I387)
14271 && flag_unsafe_math_optimizations"
14273 [(set_attr "type" "fpspc")
14274 (set_attr "mode" "XF")])
14276 (define_expand "logbxf2"
14277 [(parallel [(set (match_dup 2)
14278 (unspec:XF [(match_operand:XF 1 "register_operand")]
14279 UNSPEC_XTRACT_FRACT))
14280 (set (match_operand:XF 0 "register_operand")
14281 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14282 "TARGET_USE_FANCY_MATH_387
14283 && flag_unsafe_math_optimizations"
14284 "operands[2] = gen_reg_rtx (XFmode);")
14286 (define_expand "logb<mode>2"
14287 [(use (match_operand:MODEF 0 "register_operand"))
14288 (use (match_operand:MODEF 1 "register_operand"))]
14289 "TARGET_USE_FANCY_MATH_387
14290 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14291 || TARGET_MIX_SSE_I387)
14292 && flag_unsafe_math_optimizations"
14294 rtx op0 = gen_reg_rtx (XFmode);
14295 rtx op1 = gen_reg_rtx (XFmode);
14297 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14298 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14302 (define_expand "ilogbxf2"
14303 [(use (match_operand:SI 0 "register_operand"))
14304 (use (match_operand:XF 1 "register_operand"))]
14305 "TARGET_USE_FANCY_MATH_387
14306 && flag_unsafe_math_optimizations"
14310 if (optimize_insn_for_size_p ())
14313 op0 = gen_reg_rtx (XFmode);
14314 op1 = gen_reg_rtx (XFmode);
14316 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14317 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14321 (define_expand "ilogb<mode>2"
14322 [(use (match_operand:SI 0 "register_operand"))
14323 (use (match_operand:MODEF 1 "register_operand"))]
14324 "TARGET_USE_FANCY_MATH_387
14325 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14326 || TARGET_MIX_SSE_I387)
14327 && flag_unsafe_math_optimizations"
14331 if (optimize_insn_for_size_p ())
14334 op0 = gen_reg_rtx (XFmode);
14335 op1 = gen_reg_rtx (XFmode);
14337 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14338 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14342 (define_insn "*f2xm1xf2_i387"
14343 [(set (match_operand:XF 0 "register_operand" "=f")
14344 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14346 "TARGET_USE_FANCY_MATH_387
14347 && flag_unsafe_math_optimizations"
14349 [(set_attr "type" "fpspc")
14350 (set_attr "mode" "XF")])
14352 (define_insn "*fscalexf4_i387"
14353 [(set (match_operand:XF 0 "register_operand" "=f")
14354 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14355 (match_operand:XF 3 "register_operand" "1")]
14356 UNSPEC_FSCALE_FRACT))
14357 (set (match_operand:XF 1 "register_operand" "=u")
14358 (unspec:XF [(match_dup 2) (match_dup 3)]
14359 UNSPEC_FSCALE_EXP))]
14360 "TARGET_USE_FANCY_MATH_387
14361 && flag_unsafe_math_optimizations"
14363 [(set_attr "type" "fpspc")
14364 (set_attr "mode" "XF")])
14366 (define_expand "expNcorexf3"
14367 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14368 (match_operand:XF 2 "register_operand")))
14369 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14370 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14371 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14372 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14373 (parallel [(set (match_operand:XF 0 "register_operand")
14374 (unspec:XF [(match_dup 8) (match_dup 4)]
14375 UNSPEC_FSCALE_FRACT))
14377 (unspec:XF [(match_dup 8) (match_dup 4)]
14378 UNSPEC_FSCALE_EXP))])]
14379 "TARGET_USE_FANCY_MATH_387
14380 && flag_unsafe_math_optimizations"
14384 if (optimize_insn_for_size_p ())
14387 for (i = 3; i < 10; i++)
14388 operands[i] = gen_reg_rtx (XFmode);
14390 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14393 (define_expand "expxf2"
14394 [(use (match_operand:XF 0 "register_operand"))
14395 (use (match_operand:XF 1 "register_operand"))]
14396 "TARGET_USE_FANCY_MATH_387
14397 && flag_unsafe_math_optimizations"
14401 if (optimize_insn_for_size_p ())
14404 op2 = gen_reg_rtx (XFmode);
14405 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14407 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14411 (define_expand "exp<mode>2"
14412 [(use (match_operand:MODEF 0 "register_operand"))
14413 (use (match_operand:MODEF 1 "general_operand"))]
14414 "TARGET_USE_FANCY_MATH_387
14415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14416 || TARGET_MIX_SSE_I387)
14417 && flag_unsafe_math_optimizations"
14421 if (optimize_insn_for_size_p ())
14424 op0 = gen_reg_rtx (XFmode);
14425 op1 = gen_reg_rtx (XFmode);
14427 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14428 emit_insn (gen_expxf2 (op0, op1));
14429 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14433 (define_expand "exp10xf2"
14434 [(use (match_operand:XF 0 "register_operand"))
14435 (use (match_operand:XF 1 "register_operand"))]
14436 "TARGET_USE_FANCY_MATH_387
14437 && flag_unsafe_math_optimizations"
14441 if (optimize_insn_for_size_p ())
14444 op2 = gen_reg_rtx (XFmode);
14445 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14447 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14451 (define_expand "exp10<mode>2"
14452 [(use (match_operand:MODEF 0 "register_operand"))
14453 (use (match_operand:MODEF 1 "general_operand"))]
14454 "TARGET_USE_FANCY_MATH_387
14455 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14456 || TARGET_MIX_SSE_I387)
14457 && flag_unsafe_math_optimizations"
14461 if (optimize_insn_for_size_p ())
14464 op0 = gen_reg_rtx (XFmode);
14465 op1 = gen_reg_rtx (XFmode);
14467 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14468 emit_insn (gen_exp10xf2 (op0, op1));
14469 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14473 (define_expand "exp2xf2"
14474 [(use (match_operand:XF 0 "register_operand"))
14475 (use (match_operand:XF 1 "register_operand"))]
14476 "TARGET_USE_FANCY_MATH_387
14477 && flag_unsafe_math_optimizations"
14481 if (optimize_insn_for_size_p ())
14484 op2 = gen_reg_rtx (XFmode);
14485 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14487 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14491 (define_expand "exp2<mode>2"
14492 [(use (match_operand:MODEF 0 "register_operand"))
14493 (use (match_operand:MODEF 1 "general_operand"))]
14494 "TARGET_USE_FANCY_MATH_387
14495 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14496 || TARGET_MIX_SSE_I387)
14497 && flag_unsafe_math_optimizations"
14501 if (optimize_insn_for_size_p ())
14504 op0 = gen_reg_rtx (XFmode);
14505 op1 = gen_reg_rtx (XFmode);
14507 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14508 emit_insn (gen_exp2xf2 (op0, op1));
14509 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14513 (define_expand "expm1xf2"
14514 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14516 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14517 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14518 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14519 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14520 (parallel [(set (match_dup 7)
14521 (unspec:XF [(match_dup 6) (match_dup 4)]
14522 UNSPEC_FSCALE_FRACT))
14524 (unspec:XF [(match_dup 6) (match_dup 4)]
14525 UNSPEC_FSCALE_EXP))])
14526 (parallel [(set (match_dup 10)
14527 (unspec:XF [(match_dup 9) (match_dup 8)]
14528 UNSPEC_FSCALE_FRACT))
14529 (set (match_dup 11)
14530 (unspec:XF [(match_dup 9) (match_dup 8)]
14531 UNSPEC_FSCALE_EXP))])
14532 (set (match_dup 12) (minus:XF (match_dup 10)
14533 (float_extend:XF (match_dup 13))))
14534 (set (match_operand:XF 0 "register_operand")
14535 (plus:XF (match_dup 12) (match_dup 7)))]
14536 "TARGET_USE_FANCY_MATH_387
14537 && flag_unsafe_math_optimizations"
14541 if (optimize_insn_for_size_p ())
14544 for (i = 2; i < 13; i++)
14545 operands[i] = gen_reg_rtx (XFmode);
14548 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14550 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14553 (define_expand "expm1<mode>2"
14554 [(use (match_operand:MODEF 0 "register_operand"))
14555 (use (match_operand:MODEF 1 "general_operand"))]
14556 "TARGET_USE_FANCY_MATH_387
14557 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14558 || TARGET_MIX_SSE_I387)
14559 && flag_unsafe_math_optimizations"
14563 if (optimize_insn_for_size_p ())
14566 op0 = gen_reg_rtx (XFmode);
14567 op1 = gen_reg_rtx (XFmode);
14569 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14570 emit_insn (gen_expm1xf2 (op0, op1));
14571 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14575 (define_expand "ldexpxf3"
14576 [(set (match_dup 3)
14577 (float:XF (match_operand:SI 2 "register_operand")))
14578 (parallel [(set (match_operand:XF 0 " register_operand")
14579 (unspec:XF [(match_operand:XF 1 "register_operand")
14581 UNSPEC_FSCALE_FRACT))
14583 (unspec:XF [(match_dup 1) (match_dup 3)]
14584 UNSPEC_FSCALE_EXP))])]
14585 "TARGET_USE_FANCY_MATH_387
14586 && flag_unsafe_math_optimizations"
14588 if (optimize_insn_for_size_p ())
14591 operands[3] = gen_reg_rtx (XFmode);
14592 operands[4] = gen_reg_rtx (XFmode);
14595 (define_expand "ldexp<mode>3"
14596 [(use (match_operand:MODEF 0 "register_operand"))
14597 (use (match_operand:MODEF 1 "general_operand"))
14598 (use (match_operand:SI 2 "register_operand"))]
14599 "TARGET_USE_FANCY_MATH_387
14600 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14601 || TARGET_MIX_SSE_I387)
14602 && flag_unsafe_math_optimizations"
14606 if (optimize_insn_for_size_p ())
14609 op0 = gen_reg_rtx (XFmode);
14610 op1 = gen_reg_rtx (XFmode);
14612 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14613 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14614 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14618 (define_expand "scalbxf3"
14619 [(parallel [(set (match_operand:XF 0 " register_operand")
14620 (unspec:XF [(match_operand:XF 1 "register_operand")
14621 (match_operand:XF 2 "register_operand")]
14622 UNSPEC_FSCALE_FRACT))
14624 (unspec:XF [(match_dup 1) (match_dup 2)]
14625 UNSPEC_FSCALE_EXP))])]
14626 "TARGET_USE_FANCY_MATH_387
14627 && flag_unsafe_math_optimizations"
14629 if (optimize_insn_for_size_p ())
14632 operands[3] = gen_reg_rtx (XFmode);
14635 (define_expand "scalb<mode>3"
14636 [(use (match_operand:MODEF 0 "register_operand"))
14637 (use (match_operand:MODEF 1 "general_operand"))
14638 (use (match_operand:MODEF 2 "general_operand"))]
14639 "TARGET_USE_FANCY_MATH_387
14640 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14641 || TARGET_MIX_SSE_I387)
14642 && flag_unsafe_math_optimizations"
14646 if (optimize_insn_for_size_p ())
14649 op0 = gen_reg_rtx (XFmode);
14650 op1 = gen_reg_rtx (XFmode);
14651 op2 = gen_reg_rtx (XFmode);
14653 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14654 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14655 emit_insn (gen_scalbxf3 (op0, op1, op2));
14656 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14660 (define_expand "significandxf2"
14661 [(parallel [(set (match_operand:XF 0 "register_operand")
14662 (unspec:XF [(match_operand:XF 1 "register_operand")]
14663 UNSPEC_XTRACT_FRACT))
14665 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14666 "TARGET_USE_FANCY_MATH_387
14667 && flag_unsafe_math_optimizations"
14668 "operands[2] = gen_reg_rtx (XFmode);")
14670 (define_expand "significand<mode>2"
14671 [(use (match_operand:MODEF 0 "register_operand"))
14672 (use (match_operand:MODEF 1 "register_operand"))]
14673 "TARGET_USE_FANCY_MATH_387
14674 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14675 || TARGET_MIX_SSE_I387)
14676 && flag_unsafe_math_optimizations"
14678 rtx op0 = gen_reg_rtx (XFmode);
14679 rtx op1 = gen_reg_rtx (XFmode);
14681 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14682 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14687 (define_insn "sse4_1_round<mode>2"
14688 [(set (match_operand:MODEF 0 "register_operand" "=x")
14689 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14690 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14693 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14694 [(set_attr "type" "ssecvt")
14695 (set_attr "prefix_extra" "1")
14696 (set_attr "prefix" "maybe_vex")
14697 (set_attr "mode" "<MODE>")])
14699 (define_insn "rintxf2"
14700 [(set (match_operand:XF 0 "register_operand" "=f")
14701 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14703 "TARGET_USE_FANCY_MATH_387
14704 && flag_unsafe_math_optimizations"
14706 [(set_attr "type" "fpspc")
14707 (set_attr "mode" "XF")])
14709 (define_expand "rint<mode>2"
14710 [(use (match_operand:MODEF 0 "register_operand"))
14711 (use (match_operand:MODEF 1 "register_operand"))]
14712 "(TARGET_USE_FANCY_MATH_387
14713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14714 || TARGET_MIX_SSE_I387)
14715 && flag_unsafe_math_optimizations)
14716 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14717 && !flag_trapping_math)"
14719 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14720 && !flag_trapping_math)
14723 emit_insn (gen_sse4_1_round<mode>2
14724 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14725 else if (optimize_insn_for_size_p ())
14728 ix86_expand_rint (operands[0], operands[1]);
14732 rtx op0 = gen_reg_rtx (XFmode);
14733 rtx op1 = gen_reg_rtx (XFmode);
14735 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14736 emit_insn (gen_rintxf2 (op0, op1));
14738 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14743 (define_expand "round<mode>2"
14744 [(match_operand:X87MODEF 0 "register_operand")
14745 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14746 "(TARGET_USE_FANCY_MATH_387
14747 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14748 || TARGET_MIX_SSE_I387)
14749 && flag_unsafe_math_optimizations)
14750 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14751 && !flag_trapping_math && !flag_rounding_math)"
14753 if (optimize_insn_for_size_p ())
14756 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14757 && !flag_trapping_math && !flag_rounding_math)
14761 operands[1] = force_reg (<MODE>mode, operands[1]);
14762 ix86_expand_round_sse4 (operands[0], operands[1]);
14764 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14765 ix86_expand_round (operands[0], operands[1]);
14767 ix86_expand_rounddf_32 (operands[0], operands[1]);
14771 operands[1] = force_reg (<MODE>mode, operands[1]);
14772 ix86_emit_i387_round (operands[0], operands[1]);
14777 (define_insn_and_split "*fistdi2_1"
14778 [(set (match_operand:DI 0 "nonimmediate_operand")
14779 (unspec:DI [(match_operand:XF 1 "register_operand")]
14781 "TARGET_USE_FANCY_MATH_387
14782 && can_create_pseudo_p ()"
14787 if (memory_operand (operands[0], VOIDmode))
14788 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14791 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14792 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14797 [(set_attr "type" "fpspc")
14798 (set_attr "mode" "DI")])
14800 (define_insn "fistdi2"
14801 [(set (match_operand:DI 0 "memory_operand" "=m")
14802 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14804 (clobber (match_scratch:XF 2 "=&1f"))]
14805 "TARGET_USE_FANCY_MATH_387"
14806 "* return output_fix_trunc (insn, operands, false);"
14807 [(set_attr "type" "fpspc")
14808 (set_attr "mode" "DI")])
14810 (define_insn "fistdi2_with_temp"
14811 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14812 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14814 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14815 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14816 "TARGET_USE_FANCY_MATH_387"
14818 [(set_attr "type" "fpspc")
14819 (set_attr "mode" "DI")])
14822 [(set (match_operand:DI 0 "register_operand")
14823 (unspec:DI [(match_operand:XF 1 "register_operand")]
14825 (clobber (match_operand:DI 2 "memory_operand"))
14826 (clobber (match_scratch 3))]
14828 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14829 (clobber (match_dup 3))])
14830 (set (match_dup 0) (match_dup 2))])
14833 [(set (match_operand:DI 0 "memory_operand")
14834 (unspec:DI [(match_operand:XF 1 "register_operand")]
14836 (clobber (match_operand:DI 2 "memory_operand"))
14837 (clobber (match_scratch 3))]
14839 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14840 (clobber (match_dup 3))])])
14842 (define_insn_and_split "*fist<mode>2_1"
14843 [(set (match_operand:SWI24 0 "register_operand")
14844 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14846 "TARGET_USE_FANCY_MATH_387
14847 && can_create_pseudo_p ()"
14852 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14853 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14857 [(set_attr "type" "fpspc")
14858 (set_attr "mode" "<MODE>")])
14860 (define_insn "fist<mode>2"
14861 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14862 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14864 "TARGET_USE_FANCY_MATH_387"
14865 "* return output_fix_trunc (insn, operands, false);"
14866 [(set_attr "type" "fpspc")
14867 (set_attr "mode" "<MODE>")])
14869 (define_insn "fist<mode>2_with_temp"
14870 [(set (match_operand:SWI24 0 "register_operand" "=r")
14871 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14873 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14874 "TARGET_USE_FANCY_MATH_387"
14876 [(set_attr "type" "fpspc")
14877 (set_attr "mode" "<MODE>")])
14880 [(set (match_operand:SWI24 0 "register_operand")
14881 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14883 (clobber (match_operand:SWI24 2 "memory_operand"))]
14885 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14886 (set (match_dup 0) (match_dup 2))])
14889 [(set (match_operand:SWI24 0 "memory_operand")
14890 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14892 (clobber (match_operand:SWI24 2 "memory_operand"))]
14894 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14896 (define_expand "lrintxf<mode>2"
14897 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14898 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14900 "TARGET_USE_FANCY_MATH_387")
14902 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14903 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14904 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14905 UNSPEC_FIX_NOTRUNC))]
14906 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14908 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14909 [(match_operand:SWI248x 0 "nonimmediate_operand")
14910 (match_operand:X87MODEF 1 "register_operand")]
14911 "(TARGET_USE_FANCY_MATH_387
14912 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14913 || TARGET_MIX_SSE_I387)
14914 && flag_unsafe_math_optimizations)
14915 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14916 && <SWI248x:MODE>mode != HImode
14917 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14918 && !flag_trapping_math && !flag_rounding_math)"
14920 if (optimize_insn_for_size_p ())
14923 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14924 && <SWI248x:MODE>mode != HImode
14925 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14926 && !flag_trapping_math && !flag_rounding_math)
14927 ix86_expand_lround (operands[0], operands[1]);
14929 ix86_emit_i387_round (operands[0], operands[1]);
14933 (define_int_iterator FRNDINT_ROUNDING
14934 [UNSPEC_FRNDINT_FLOOR
14935 UNSPEC_FRNDINT_CEIL
14936 UNSPEC_FRNDINT_TRUNC])
14938 (define_int_iterator FIST_ROUNDING
14942 ;; Base name for define_insn
14943 (define_int_attr rounding_insn
14944 [(UNSPEC_FRNDINT_FLOOR "floor")
14945 (UNSPEC_FRNDINT_CEIL "ceil")
14946 (UNSPEC_FRNDINT_TRUNC "btrunc")
14947 (UNSPEC_FIST_FLOOR "floor")
14948 (UNSPEC_FIST_CEIL "ceil")])
14950 (define_int_attr rounding
14951 [(UNSPEC_FRNDINT_FLOOR "floor")
14952 (UNSPEC_FRNDINT_CEIL "ceil")
14953 (UNSPEC_FRNDINT_TRUNC "trunc")
14954 (UNSPEC_FIST_FLOOR "floor")
14955 (UNSPEC_FIST_CEIL "ceil")])
14957 (define_int_attr ROUNDING
14958 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14959 (UNSPEC_FRNDINT_CEIL "CEIL")
14960 (UNSPEC_FRNDINT_TRUNC "TRUNC")
14961 (UNSPEC_FIST_FLOOR "FLOOR")
14962 (UNSPEC_FIST_CEIL "CEIL")])
14964 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14965 (define_insn_and_split "frndintxf2_<rounding>"
14966 [(set (match_operand:XF 0 "register_operand")
14967 (unspec:XF [(match_operand:XF 1 "register_operand")]
14969 (clobber (reg:CC FLAGS_REG))]
14970 "TARGET_USE_FANCY_MATH_387
14971 && flag_unsafe_math_optimizations
14972 && can_create_pseudo_p ()"
14977 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14979 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14980 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14982 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14983 operands[2], operands[3]));
14986 [(set_attr "type" "frndint")
14987 (set_attr "i387_cw" "<rounding>")
14988 (set_attr "mode" "XF")])
14990 (define_insn "frndintxf2_<rounding>_i387"
14991 [(set (match_operand:XF 0 "register_operand" "=f")
14992 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14994 (use (match_operand:HI 2 "memory_operand" "m"))
14995 (use (match_operand:HI 3 "memory_operand" "m"))]
14996 "TARGET_USE_FANCY_MATH_387
14997 && flag_unsafe_math_optimizations"
14998 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14999 [(set_attr "type" "frndint")
15000 (set_attr "i387_cw" "<rounding>")
15001 (set_attr "mode" "XF")])
15003 (define_expand "<rounding_insn>xf2"
15004 [(parallel [(set (match_operand:XF 0 "register_operand")
15005 (unspec:XF [(match_operand:XF 1 "register_operand")]
15007 (clobber (reg:CC FLAGS_REG))])]
15008 "TARGET_USE_FANCY_MATH_387
15009 && flag_unsafe_math_optimizations
15010 && !optimize_insn_for_size_p ()")
15012 (define_expand "<rounding_insn><mode>2"
15013 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15014 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15016 (clobber (reg:CC FLAGS_REG))])]
15017 "(TARGET_USE_FANCY_MATH_387
15018 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15019 || TARGET_MIX_SSE_I387)
15020 && flag_unsafe_math_optimizations)
15021 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15022 && !flag_trapping_math)"
15024 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15025 && !flag_trapping_math)
15028 emit_insn (gen_sse4_1_round<mode>2
15029 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15030 else if (optimize_insn_for_size_p ())
15032 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15034 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15035 ix86_expand_floorceil (operands[0], operands[1], true);
15036 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15037 ix86_expand_floorceil (operands[0], operands[1], false);
15038 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15039 ix86_expand_trunc (operands[0], operands[1]);
15041 gcc_unreachable ();
15045 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15046 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15047 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15048 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15049 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15050 ix86_expand_truncdf_32 (operands[0], operands[1]);
15052 gcc_unreachable ();
15059 if (optimize_insn_for_size_p ())
15062 op0 = gen_reg_rtx (XFmode);
15063 op1 = gen_reg_rtx (XFmode);
15064 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15065 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15067 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15072 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15073 (define_insn_and_split "frndintxf2_mask_pm"
15074 [(set (match_operand:XF 0 "register_operand")
15075 (unspec:XF [(match_operand:XF 1 "register_operand")]
15076 UNSPEC_FRNDINT_MASK_PM))
15077 (clobber (reg:CC FLAGS_REG))]
15078 "TARGET_USE_FANCY_MATH_387
15079 && flag_unsafe_math_optimizations
15080 && can_create_pseudo_p ()"
15085 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15087 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15088 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15090 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15091 operands[2], operands[3]));
15094 [(set_attr "type" "frndint")
15095 (set_attr "i387_cw" "mask_pm")
15096 (set_attr "mode" "XF")])
15098 (define_insn "frndintxf2_mask_pm_i387"
15099 [(set (match_operand:XF 0 "register_operand" "=f")
15100 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15101 UNSPEC_FRNDINT_MASK_PM))
15102 (use (match_operand:HI 2 "memory_operand" "m"))
15103 (use (match_operand:HI 3 "memory_operand" "m"))]
15104 "TARGET_USE_FANCY_MATH_387
15105 && flag_unsafe_math_optimizations"
15106 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15107 [(set_attr "type" "frndint")
15108 (set_attr "i387_cw" "mask_pm")
15109 (set_attr "mode" "XF")])
15111 (define_expand "nearbyintxf2"
15112 [(parallel [(set (match_operand:XF 0 "register_operand")
15113 (unspec:XF [(match_operand:XF 1 "register_operand")]
15114 UNSPEC_FRNDINT_MASK_PM))
15115 (clobber (reg:CC FLAGS_REG))])]
15116 "TARGET_USE_FANCY_MATH_387
15117 && flag_unsafe_math_optimizations")
15119 (define_expand "nearbyint<mode>2"
15120 [(use (match_operand:MODEF 0 "register_operand"))
15121 (use (match_operand:MODEF 1 "register_operand"))]
15122 "TARGET_USE_FANCY_MATH_387
15123 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15124 || TARGET_MIX_SSE_I387)
15125 && flag_unsafe_math_optimizations"
15127 rtx op0 = gen_reg_rtx (XFmode);
15128 rtx op1 = gen_reg_rtx (XFmode);
15130 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15131 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15133 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15137 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15138 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15139 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15140 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15142 (clobber (reg:CC FLAGS_REG))]
15143 "TARGET_USE_FANCY_MATH_387
15144 && flag_unsafe_math_optimizations
15145 && can_create_pseudo_p ()"
15150 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15152 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15153 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15154 if (memory_operand (operands[0], VOIDmode))
15155 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15156 operands[2], operands[3]));
15159 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15160 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15161 (operands[0], operands[1], operands[2],
15162 operands[3], operands[4]));
15166 [(set_attr "type" "fistp")
15167 (set_attr "i387_cw" "<rounding>")
15168 (set_attr "mode" "<MODE>")])
15170 (define_insn "fistdi2_<rounding>"
15171 [(set (match_operand:DI 0 "memory_operand" "=m")
15172 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15174 (use (match_operand:HI 2 "memory_operand" "m"))
15175 (use (match_operand:HI 3 "memory_operand" "m"))
15176 (clobber (match_scratch:XF 4 "=&1f"))]
15177 "TARGET_USE_FANCY_MATH_387
15178 && flag_unsafe_math_optimizations"
15179 "* return output_fix_trunc (insn, operands, false);"
15180 [(set_attr "type" "fistp")
15181 (set_attr "i387_cw" "<rounding>")
15182 (set_attr "mode" "DI")])
15184 (define_insn "fistdi2_<rounding>_with_temp"
15185 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15186 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15188 (use (match_operand:HI 2 "memory_operand" "m,m"))
15189 (use (match_operand:HI 3 "memory_operand" "m,m"))
15190 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15191 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15192 "TARGET_USE_FANCY_MATH_387
15193 && flag_unsafe_math_optimizations"
15195 [(set_attr "type" "fistp")
15196 (set_attr "i387_cw" "<rounding>")
15197 (set_attr "mode" "DI")])
15200 [(set (match_operand:DI 0 "register_operand")
15201 (unspec:DI [(match_operand:XF 1 "register_operand")]
15203 (use (match_operand:HI 2 "memory_operand"))
15204 (use (match_operand:HI 3 "memory_operand"))
15205 (clobber (match_operand:DI 4 "memory_operand"))
15206 (clobber (match_scratch 5))]
15208 [(parallel [(set (match_dup 4)
15209 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15210 (use (match_dup 2))
15211 (use (match_dup 3))
15212 (clobber (match_dup 5))])
15213 (set (match_dup 0) (match_dup 4))])
15216 [(set (match_operand:DI 0 "memory_operand")
15217 (unspec:DI [(match_operand:XF 1 "register_operand")]
15219 (use (match_operand:HI 2 "memory_operand"))
15220 (use (match_operand:HI 3 "memory_operand"))
15221 (clobber (match_operand:DI 4 "memory_operand"))
15222 (clobber (match_scratch 5))]
15224 [(parallel [(set (match_dup 0)
15225 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15226 (use (match_dup 2))
15227 (use (match_dup 3))
15228 (clobber (match_dup 5))])])
15230 (define_insn "fist<mode>2_<rounding>"
15231 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15232 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15234 (use (match_operand:HI 2 "memory_operand" "m"))
15235 (use (match_operand:HI 3 "memory_operand" "m"))]
15236 "TARGET_USE_FANCY_MATH_387
15237 && flag_unsafe_math_optimizations"
15238 "* return output_fix_trunc (insn, operands, false);"
15239 [(set_attr "type" "fistp")
15240 (set_attr "i387_cw" "<rounding>")
15241 (set_attr "mode" "<MODE>")])
15243 (define_insn "fist<mode>2_<rounding>_with_temp"
15244 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15245 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15247 (use (match_operand:HI 2 "memory_operand" "m,m"))
15248 (use (match_operand:HI 3 "memory_operand" "m,m"))
15249 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15250 "TARGET_USE_FANCY_MATH_387
15251 && flag_unsafe_math_optimizations"
15253 [(set_attr "type" "fistp")
15254 (set_attr "i387_cw" "<rounding>")
15255 (set_attr "mode" "<MODE>")])
15258 [(set (match_operand:SWI24 0 "register_operand")
15259 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15261 (use (match_operand:HI 2 "memory_operand"))
15262 (use (match_operand:HI 3 "memory_operand"))
15263 (clobber (match_operand:SWI24 4 "memory_operand"))]
15265 [(parallel [(set (match_dup 4)
15266 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15267 (use (match_dup 2))
15268 (use (match_dup 3))])
15269 (set (match_dup 0) (match_dup 4))])
15272 [(set (match_operand:SWI24 0 "memory_operand")
15273 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15275 (use (match_operand:HI 2 "memory_operand"))
15276 (use (match_operand:HI 3 "memory_operand"))
15277 (clobber (match_operand:SWI24 4 "memory_operand"))]
15279 [(parallel [(set (match_dup 0)
15280 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15281 (use (match_dup 2))
15282 (use (match_dup 3))])])
15284 (define_expand "l<rounding_insn>xf<mode>2"
15285 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15286 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15288 (clobber (reg:CC FLAGS_REG))])]
15289 "TARGET_USE_FANCY_MATH_387
15290 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15291 && flag_unsafe_math_optimizations")
15293 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15294 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15295 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15297 (clobber (reg:CC FLAGS_REG))])]
15298 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15299 && !flag_trapping_math"
15301 if (TARGET_64BIT && optimize_insn_for_size_p ())
15304 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15305 ix86_expand_lfloorceil (operands[0], operands[1], true);
15306 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15307 ix86_expand_lfloorceil (operands[0], operands[1], false);
15309 gcc_unreachable ();
15314 (define_insn "fxam<mode>2_i387"
15315 [(set (match_operand:HI 0 "register_operand" "=a")
15317 [(match_operand:X87MODEF 1 "register_operand" "f")]
15319 "TARGET_USE_FANCY_MATH_387"
15320 "fxam\n\tfnstsw\t%0"
15321 [(set_attr "type" "multi")
15322 (set_attr "length" "4")
15323 (set_attr "unit" "i387")
15324 (set_attr "mode" "<MODE>")])
15326 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15327 [(set (match_operand:HI 0 "register_operand")
15329 [(match_operand:MODEF 1 "memory_operand")]
15331 "TARGET_USE_FANCY_MATH_387
15332 && can_create_pseudo_p ()"
15335 [(set (match_dup 2)(match_dup 1))
15337 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15339 operands[2] = gen_reg_rtx (<MODE>mode);
15341 MEM_VOLATILE_P (operands[1]) = 1;
15343 [(set_attr "type" "multi")
15344 (set_attr "unit" "i387")
15345 (set_attr "mode" "<MODE>")])
15347 (define_expand "isinfxf2"
15348 [(use (match_operand:SI 0 "register_operand"))
15349 (use (match_operand:XF 1 "register_operand"))]
15350 "TARGET_USE_FANCY_MATH_387
15351 && ix86_libc_has_function (function_c99_misc)"
15353 rtx mask = GEN_INT (0x45);
15354 rtx val = GEN_INT (0x05);
15358 rtx scratch = gen_reg_rtx (HImode);
15359 rtx res = gen_reg_rtx (QImode);
15361 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15363 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15364 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15365 cond = gen_rtx_fmt_ee (EQ, QImode,
15366 gen_rtx_REG (CCmode, FLAGS_REG),
15368 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15369 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15373 (define_expand "isinf<mode>2"
15374 [(use (match_operand:SI 0 "register_operand"))
15375 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15376 "TARGET_USE_FANCY_MATH_387
15377 && ix86_libc_has_function (function_c99_misc)
15378 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15380 rtx mask = GEN_INT (0x45);
15381 rtx val = GEN_INT (0x05);
15385 rtx scratch = gen_reg_rtx (HImode);
15386 rtx res = gen_reg_rtx (QImode);
15388 /* Remove excess precision by forcing value through memory. */
15389 if (memory_operand (operands[1], VOIDmode))
15390 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15393 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15395 emit_move_insn (temp, operands[1]);
15396 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15399 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15400 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15401 cond = gen_rtx_fmt_ee (EQ, QImode,
15402 gen_rtx_REG (CCmode, FLAGS_REG),
15404 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15405 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15409 (define_expand "signbitxf2"
15410 [(use (match_operand:SI 0 "register_operand"))
15411 (use (match_operand:XF 1 "register_operand"))]
15412 "TARGET_USE_FANCY_MATH_387"
15414 rtx scratch = gen_reg_rtx (HImode);
15416 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15417 emit_insn (gen_andsi3 (operands[0],
15418 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15422 (define_insn "movmsk_df"
15423 [(set (match_operand:SI 0 "register_operand" "=r")
15425 [(match_operand:DF 1 "register_operand" "x")]
15427 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15428 "%vmovmskpd\t{%1, %0|%0, %1}"
15429 [(set_attr "type" "ssemov")
15430 (set_attr "prefix" "maybe_vex")
15431 (set_attr "mode" "DF")])
15433 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15434 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15435 (define_expand "signbitdf2"
15436 [(use (match_operand:SI 0 "register_operand"))
15437 (use (match_operand:DF 1 "register_operand"))]
15438 "TARGET_USE_FANCY_MATH_387
15439 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15441 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15443 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15444 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15448 rtx scratch = gen_reg_rtx (HImode);
15450 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15451 emit_insn (gen_andsi3 (operands[0],
15452 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15457 (define_expand "signbitsf2"
15458 [(use (match_operand:SI 0 "register_operand"))
15459 (use (match_operand:SF 1 "register_operand"))]
15460 "TARGET_USE_FANCY_MATH_387
15461 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15463 rtx scratch = gen_reg_rtx (HImode);
15465 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15466 emit_insn (gen_andsi3 (operands[0],
15467 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15471 ;; Block operation instructions
15474 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15477 [(set_attr "length" "1")
15478 (set_attr "length_immediate" "0")
15479 (set_attr "modrm" "0")])
15481 (define_expand "movmem<mode>"
15482 [(use (match_operand:BLK 0 "memory_operand"))
15483 (use (match_operand:BLK 1 "memory_operand"))
15484 (use (match_operand:SWI48 2 "nonmemory_operand"))
15485 (use (match_operand:SWI48 3 "const_int_operand"))
15486 (use (match_operand:SI 4 "const_int_operand"))
15487 (use (match_operand:SI 5 "const_int_operand"))]
15490 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15491 operands[4], operands[5]))
15497 ;; Most CPUs don't like single string operations
15498 ;; Handle this case here to simplify previous expander.
15500 (define_expand "strmov"
15501 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15502 (set (match_operand 1 "memory_operand") (match_dup 4))
15503 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15504 (clobber (reg:CC FLAGS_REG))])
15505 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15506 (clobber (reg:CC FLAGS_REG))])]
15509 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15511 /* If .md ever supports :P for Pmode, these can be directly
15512 in the pattern above. */
15513 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15514 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15516 /* Can't use this if the user has appropriated esi or edi. */
15517 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15518 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15520 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15521 operands[2], operands[3],
15522 operands[5], operands[6]));
15526 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15529 (define_expand "strmov_singleop"
15530 [(parallel [(set (match_operand 1 "memory_operand")
15531 (match_operand 3 "memory_operand"))
15532 (set (match_operand 0 "register_operand")
15534 (set (match_operand 2 "register_operand")
15535 (match_operand 5))])]
15537 "ix86_current_function_needs_cld = 1;")
15539 (define_insn "*strmovdi_rex_1"
15540 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15541 (mem:DI (match_operand:P 3 "register_operand" "1")))
15542 (set (match_operand:P 0 "register_operand" "=D")
15543 (plus:P (match_dup 2)
15545 (set (match_operand:P 1 "register_operand" "=S")
15546 (plus:P (match_dup 3)
15549 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15551 [(set_attr "type" "str")
15552 (set_attr "memory" "both")
15553 (set_attr "mode" "DI")])
15555 (define_insn "*strmovsi_1"
15556 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15557 (mem:SI (match_operand:P 3 "register_operand" "1")))
15558 (set (match_operand:P 0 "register_operand" "=D")
15559 (plus:P (match_dup 2)
15561 (set (match_operand:P 1 "register_operand" "=S")
15562 (plus:P (match_dup 3)
15564 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15566 [(set_attr "type" "str")
15567 (set_attr "memory" "both")
15568 (set_attr "mode" "SI")])
15570 (define_insn "*strmovhi_1"
15571 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15572 (mem:HI (match_operand:P 3 "register_operand" "1")))
15573 (set (match_operand:P 0 "register_operand" "=D")
15574 (plus:P (match_dup 2)
15576 (set (match_operand:P 1 "register_operand" "=S")
15577 (plus:P (match_dup 3)
15579 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15581 [(set_attr "type" "str")
15582 (set_attr "memory" "both")
15583 (set_attr "mode" "HI")])
15585 (define_insn "*strmovqi_1"
15586 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15587 (mem:QI (match_operand:P 3 "register_operand" "1")))
15588 (set (match_operand:P 0 "register_operand" "=D")
15589 (plus:P (match_dup 2)
15591 (set (match_operand:P 1 "register_operand" "=S")
15592 (plus:P (match_dup 3)
15594 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15596 [(set_attr "type" "str")
15597 (set_attr "memory" "both")
15598 (set (attr "prefix_rex")
15600 (match_test "<P:MODE>mode == DImode")
15602 (const_string "*")))
15603 (set_attr "mode" "QI")])
15605 (define_expand "rep_mov"
15606 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15607 (set (match_operand 0 "register_operand")
15609 (set (match_operand 2 "register_operand")
15611 (set (match_operand 1 "memory_operand")
15612 (match_operand 3 "memory_operand"))
15613 (use (match_dup 4))])]
15615 "ix86_current_function_needs_cld = 1;")
15617 (define_insn "*rep_movdi_rex64"
15618 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15619 (set (match_operand:P 0 "register_operand" "=D")
15620 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15622 (match_operand:P 3 "register_operand" "0")))
15623 (set (match_operand:P 1 "register_operand" "=S")
15624 (plus:P (ashift:P (match_dup 5) (const_int 3))
15625 (match_operand:P 4 "register_operand" "1")))
15626 (set (mem:BLK (match_dup 3))
15627 (mem:BLK (match_dup 4)))
15628 (use (match_dup 5))]
15630 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15632 [(set_attr "type" "str")
15633 (set_attr "prefix_rep" "1")
15634 (set_attr "memory" "both")
15635 (set_attr "mode" "DI")])
15637 (define_insn "*rep_movsi"
15638 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15639 (set (match_operand:P 0 "register_operand" "=D")
15640 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15642 (match_operand:P 3 "register_operand" "0")))
15643 (set (match_operand:P 1 "register_operand" "=S")
15644 (plus:P (ashift:P (match_dup 5) (const_int 2))
15645 (match_operand:P 4 "register_operand" "1")))
15646 (set (mem:BLK (match_dup 3))
15647 (mem:BLK (match_dup 4)))
15648 (use (match_dup 5))]
15649 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15650 "%^rep{%;} movs{l|d}"
15651 [(set_attr "type" "str")
15652 (set_attr "prefix_rep" "1")
15653 (set_attr "memory" "both")
15654 (set_attr "mode" "SI")])
15656 (define_insn "*rep_movqi"
15657 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15658 (set (match_operand:P 0 "register_operand" "=D")
15659 (plus:P (match_operand:P 3 "register_operand" "0")
15660 (match_operand:P 5 "register_operand" "2")))
15661 (set (match_operand:P 1 "register_operand" "=S")
15662 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15663 (set (mem:BLK (match_dup 3))
15664 (mem:BLK (match_dup 4)))
15665 (use (match_dup 5))]
15666 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15668 [(set_attr "type" "str")
15669 (set_attr "prefix_rep" "1")
15670 (set_attr "memory" "both")
15671 (set_attr "mode" "QI")])
15673 (define_expand "setmem<mode>"
15674 [(use (match_operand:BLK 0 "memory_operand"))
15675 (use (match_operand:SWI48 1 "nonmemory_operand"))
15676 (use (match_operand:QI 2 "nonmemory_operand"))
15677 (use (match_operand 3 "const_int_operand"))
15678 (use (match_operand:SI 4 "const_int_operand"))
15679 (use (match_operand:SI 5 "const_int_operand"))]
15682 if (ix86_expand_setmem (operands[0], operands[1],
15683 operands[2], operands[3],
15684 operands[4], operands[5]))
15690 ;; Most CPUs don't like single string operations
15691 ;; Handle this case here to simplify previous expander.
15693 (define_expand "strset"
15694 [(set (match_operand 1 "memory_operand")
15695 (match_operand 2 "register_operand"))
15696 (parallel [(set (match_operand 0 "register_operand")
15698 (clobber (reg:CC FLAGS_REG))])]
15701 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15702 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15704 /* If .md ever supports :P for Pmode, this can be directly
15705 in the pattern above. */
15706 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15707 GEN_INT (GET_MODE_SIZE (GET_MODE
15709 /* Can't use this if the user has appropriated eax or edi. */
15710 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15711 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15713 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15719 (define_expand "strset_singleop"
15720 [(parallel [(set (match_operand 1 "memory_operand")
15721 (match_operand 2 "register_operand"))
15722 (set (match_operand 0 "register_operand")
15724 (unspec [(const_int 0)] UNSPEC_STOS)])]
15726 "ix86_current_function_needs_cld = 1;")
15728 (define_insn "*strsetdi_rex_1"
15729 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15730 (match_operand:DI 2 "register_operand" "a"))
15731 (set (match_operand:P 0 "register_operand" "=D")
15732 (plus:P (match_dup 1)
15734 (unspec [(const_int 0)] UNSPEC_STOS)]
15736 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15738 [(set_attr "type" "str")
15739 (set_attr "memory" "store")
15740 (set_attr "mode" "DI")])
15742 (define_insn "*strsetsi_1"
15743 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15744 (match_operand:SI 2 "register_operand" "a"))
15745 (set (match_operand:P 0 "register_operand" "=D")
15746 (plus:P (match_dup 1)
15748 (unspec [(const_int 0)] UNSPEC_STOS)]
15749 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15751 [(set_attr "type" "str")
15752 (set_attr "memory" "store")
15753 (set_attr "mode" "SI")])
15755 (define_insn "*strsethi_1"
15756 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15757 (match_operand:HI 2 "register_operand" "a"))
15758 (set (match_operand:P 0 "register_operand" "=D")
15759 (plus:P (match_dup 1)
15761 (unspec [(const_int 0)] UNSPEC_STOS)]
15762 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15764 [(set_attr "type" "str")
15765 (set_attr "memory" "store")
15766 (set_attr "mode" "HI")])
15768 (define_insn "*strsetqi_1"
15769 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15770 (match_operand:QI 2 "register_operand" "a"))
15771 (set (match_operand:P 0 "register_operand" "=D")
15772 (plus:P (match_dup 1)
15774 (unspec [(const_int 0)] UNSPEC_STOS)]
15775 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15777 [(set_attr "type" "str")
15778 (set_attr "memory" "store")
15779 (set (attr "prefix_rex")
15781 (match_test "<P:MODE>mode == DImode")
15783 (const_string "*")))
15784 (set_attr "mode" "QI")])
15786 (define_expand "rep_stos"
15787 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15788 (set (match_operand 0 "register_operand")
15790 (set (match_operand 2 "memory_operand") (const_int 0))
15791 (use (match_operand 3 "register_operand"))
15792 (use (match_dup 1))])]
15794 "ix86_current_function_needs_cld = 1;")
15796 (define_insn "*rep_stosdi_rex64"
15797 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15798 (set (match_operand:P 0 "register_operand" "=D")
15799 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15801 (match_operand:P 3 "register_operand" "0")))
15802 (set (mem:BLK (match_dup 3))
15804 (use (match_operand:DI 2 "register_operand" "a"))
15805 (use (match_dup 4))]
15807 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15809 [(set_attr "type" "str")
15810 (set_attr "prefix_rep" "1")
15811 (set_attr "memory" "store")
15812 (set_attr "mode" "DI")])
15814 (define_insn "*rep_stossi"
15815 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15816 (set (match_operand:P 0 "register_operand" "=D")
15817 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15819 (match_operand:P 3 "register_operand" "0")))
15820 (set (mem:BLK (match_dup 3))
15822 (use (match_operand:SI 2 "register_operand" "a"))
15823 (use (match_dup 4))]
15824 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15825 "%^rep{%;} stos{l|d}"
15826 [(set_attr "type" "str")
15827 (set_attr "prefix_rep" "1")
15828 (set_attr "memory" "store")
15829 (set_attr "mode" "SI")])
15831 (define_insn "*rep_stosqi"
15832 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15833 (set (match_operand:P 0 "register_operand" "=D")
15834 (plus:P (match_operand:P 3 "register_operand" "0")
15835 (match_operand:P 4 "register_operand" "1")))
15836 (set (mem:BLK (match_dup 3))
15838 (use (match_operand:QI 2 "register_operand" "a"))
15839 (use (match_dup 4))]
15840 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15842 [(set_attr "type" "str")
15843 (set_attr "prefix_rep" "1")
15844 (set_attr "memory" "store")
15845 (set (attr "prefix_rex")
15847 (match_test "<P:MODE>mode == DImode")
15849 (const_string "*")))
15850 (set_attr "mode" "QI")])
15852 (define_expand "cmpstrnsi"
15853 [(set (match_operand:SI 0 "register_operand")
15854 (compare:SI (match_operand:BLK 1 "general_operand")
15855 (match_operand:BLK 2 "general_operand")))
15856 (use (match_operand 3 "general_operand"))
15857 (use (match_operand 4 "immediate_operand"))]
15860 rtx addr1, addr2, out, outlow, count, countreg, align;
15862 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15865 /* Can't use this if the user has appropriated ecx, esi or edi. */
15866 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15871 out = gen_reg_rtx (SImode);
15873 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15874 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15875 if (addr1 != XEXP (operands[1], 0))
15876 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15877 if (addr2 != XEXP (operands[2], 0))
15878 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15880 count = operands[3];
15881 countreg = ix86_zero_extend_to_Pmode (count);
15883 /* %%% Iff we are testing strict equality, we can use known alignment
15884 to good advantage. This may be possible with combine, particularly
15885 once cc0 is dead. */
15886 align = operands[4];
15888 if (CONST_INT_P (count))
15890 if (INTVAL (count) == 0)
15892 emit_move_insn (operands[0], const0_rtx);
15895 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15896 operands[1], operands[2]));
15900 rtx (*gen_cmp) (rtx, rtx);
15902 gen_cmp = (TARGET_64BIT
15903 ? gen_cmpdi_1 : gen_cmpsi_1);
15905 emit_insn (gen_cmp (countreg, countreg));
15906 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15907 operands[1], operands[2]));
15910 outlow = gen_lowpart (QImode, out);
15911 emit_insn (gen_cmpintqi (outlow));
15912 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15914 if (operands[0] != out)
15915 emit_move_insn (operands[0], out);
15920 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15922 (define_expand "cmpintqi"
15923 [(set (match_dup 1)
15924 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15926 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15927 (parallel [(set (match_operand:QI 0 "register_operand")
15928 (minus:QI (match_dup 1)
15930 (clobber (reg:CC FLAGS_REG))])]
15933 operands[1] = gen_reg_rtx (QImode);
15934 operands[2] = gen_reg_rtx (QImode);
15937 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15938 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15940 (define_expand "cmpstrnqi_nz_1"
15941 [(parallel [(set (reg:CC FLAGS_REG)
15942 (compare:CC (match_operand 4 "memory_operand")
15943 (match_operand 5 "memory_operand")))
15944 (use (match_operand 2 "register_operand"))
15945 (use (match_operand:SI 3 "immediate_operand"))
15946 (clobber (match_operand 0 "register_operand"))
15947 (clobber (match_operand 1 "register_operand"))
15948 (clobber (match_dup 2))])]
15950 "ix86_current_function_needs_cld = 1;")
15952 (define_insn "*cmpstrnqi_nz_1"
15953 [(set (reg:CC FLAGS_REG)
15954 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15955 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15956 (use (match_operand:P 6 "register_operand" "2"))
15957 (use (match_operand:SI 3 "immediate_operand" "i"))
15958 (clobber (match_operand:P 0 "register_operand" "=S"))
15959 (clobber (match_operand:P 1 "register_operand" "=D"))
15960 (clobber (match_operand:P 2 "register_operand" "=c"))]
15961 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15963 [(set_attr "type" "str")
15964 (set_attr "mode" "QI")
15965 (set (attr "prefix_rex")
15967 (match_test "<P:MODE>mode == DImode")
15969 (const_string "*")))
15970 (set_attr "prefix_rep" "1")])
15972 ;; The same, but the count is not known to not be zero.
15974 (define_expand "cmpstrnqi_1"
15975 [(parallel [(set (reg:CC FLAGS_REG)
15976 (if_then_else:CC (ne (match_operand 2 "register_operand")
15978 (compare:CC (match_operand 4 "memory_operand")
15979 (match_operand 5 "memory_operand"))
15981 (use (match_operand:SI 3 "immediate_operand"))
15982 (use (reg:CC FLAGS_REG))
15983 (clobber (match_operand 0 "register_operand"))
15984 (clobber (match_operand 1 "register_operand"))
15985 (clobber (match_dup 2))])]
15987 "ix86_current_function_needs_cld = 1;")
15989 (define_insn "*cmpstrnqi_1"
15990 [(set (reg:CC FLAGS_REG)
15991 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15993 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15994 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15996 (use (match_operand:SI 3 "immediate_operand" "i"))
15997 (use (reg:CC FLAGS_REG))
15998 (clobber (match_operand:P 0 "register_operand" "=S"))
15999 (clobber (match_operand:P 1 "register_operand" "=D"))
16000 (clobber (match_operand:P 2 "register_operand" "=c"))]
16001 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16003 [(set_attr "type" "str")
16004 (set_attr "mode" "QI")
16005 (set (attr "prefix_rex")
16007 (match_test "<P:MODE>mode == DImode")
16009 (const_string "*")))
16010 (set_attr "prefix_rep" "1")])
16012 (define_expand "strlen<mode>"
16013 [(set (match_operand:P 0 "register_operand")
16014 (unspec:P [(match_operand:BLK 1 "general_operand")
16015 (match_operand:QI 2 "immediate_operand")
16016 (match_operand 3 "immediate_operand")]
16020 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16026 (define_expand "strlenqi_1"
16027 [(parallel [(set (match_operand 0 "register_operand")
16029 (clobber (match_operand 1 "register_operand"))
16030 (clobber (reg:CC FLAGS_REG))])]
16032 "ix86_current_function_needs_cld = 1;")
16034 (define_insn "*strlenqi_1"
16035 [(set (match_operand:P 0 "register_operand" "=&c")
16036 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16037 (match_operand:QI 2 "register_operand" "a")
16038 (match_operand:P 3 "immediate_operand" "i")
16039 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16040 (clobber (match_operand:P 1 "register_operand" "=D"))
16041 (clobber (reg:CC FLAGS_REG))]
16042 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16043 "%^repnz{%;} scasb"
16044 [(set_attr "type" "str")
16045 (set_attr "mode" "QI")
16046 (set (attr "prefix_rex")
16048 (match_test "<P:MODE>mode == DImode")
16050 (const_string "*")))
16051 (set_attr "prefix_rep" "1")])
16053 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16054 ;; handled in combine, but it is not currently up to the task.
16055 ;; When used for their truth value, the cmpstrn* expanders generate
16064 ;; The intermediate three instructions are unnecessary.
16066 ;; This one handles cmpstrn*_nz_1...
16069 (set (reg:CC FLAGS_REG)
16070 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16071 (mem:BLK (match_operand 5 "register_operand"))))
16072 (use (match_operand 6 "register_operand"))
16073 (use (match_operand:SI 3 "immediate_operand"))
16074 (clobber (match_operand 0 "register_operand"))
16075 (clobber (match_operand 1 "register_operand"))
16076 (clobber (match_operand 2 "register_operand"))])
16077 (set (match_operand:QI 7 "register_operand")
16078 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16079 (set (match_operand:QI 8 "register_operand")
16080 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16081 (set (reg FLAGS_REG)
16082 (compare (match_dup 7) (match_dup 8)))
16084 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16086 (set (reg:CC FLAGS_REG)
16087 (compare:CC (mem:BLK (match_dup 4))
16088 (mem:BLK (match_dup 5))))
16089 (use (match_dup 6))
16090 (use (match_dup 3))
16091 (clobber (match_dup 0))
16092 (clobber (match_dup 1))
16093 (clobber (match_dup 2))])])
16095 ;; ...and this one handles cmpstrn*_1.
16098 (set (reg:CC FLAGS_REG)
16099 (if_then_else:CC (ne (match_operand 6 "register_operand")
16101 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16102 (mem:BLK (match_operand 5 "register_operand")))
16104 (use (match_operand:SI 3 "immediate_operand"))
16105 (use (reg:CC FLAGS_REG))
16106 (clobber (match_operand 0 "register_operand"))
16107 (clobber (match_operand 1 "register_operand"))
16108 (clobber (match_operand 2 "register_operand"))])
16109 (set (match_operand:QI 7 "register_operand")
16110 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16111 (set (match_operand:QI 8 "register_operand")
16112 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16113 (set (reg FLAGS_REG)
16114 (compare (match_dup 7) (match_dup 8)))
16116 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16118 (set (reg:CC FLAGS_REG)
16119 (if_then_else:CC (ne (match_dup 6)
16121 (compare:CC (mem:BLK (match_dup 4))
16122 (mem:BLK (match_dup 5)))
16124 (use (match_dup 3))
16125 (use (reg:CC FLAGS_REG))
16126 (clobber (match_dup 0))
16127 (clobber (match_dup 1))
16128 (clobber (match_dup 2))])])
16130 ;; Conditional move instructions.
16132 (define_expand "mov<mode>cc"
16133 [(set (match_operand:SWIM 0 "register_operand")
16134 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16135 (match_operand:SWIM 2 "<general_operand>")
16136 (match_operand:SWIM 3 "<general_operand>")))]
16138 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16140 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16141 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16142 ;; So just document what we're doing explicitly.
16144 (define_expand "x86_mov<mode>cc_0_m1"
16146 [(set (match_operand:SWI48 0 "register_operand")
16147 (if_then_else:SWI48
16148 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16149 [(match_operand 1 "flags_reg_operand")
16153 (clobber (reg:CC FLAGS_REG))])])
16155 (define_insn "*x86_mov<mode>cc_0_m1"
16156 [(set (match_operand:SWI48 0 "register_operand" "=r")
16157 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16158 [(reg FLAGS_REG) (const_int 0)])
16161 (clobber (reg:CC FLAGS_REG))]
16163 "sbb{<imodesuffix>}\t%0, %0"
16164 ; Since we don't have the proper number of operands for an alu insn,
16165 ; fill in all the blanks.
16166 [(set_attr "type" "alu")
16167 (set_attr "use_carry" "1")
16168 (set_attr "pent_pair" "pu")
16169 (set_attr "memory" "none")
16170 (set_attr "imm_disp" "false")
16171 (set_attr "mode" "<MODE>")
16172 (set_attr "length_immediate" "0")])
16174 (define_insn "*x86_mov<mode>cc_0_m1_se"
16175 [(set (match_operand:SWI48 0 "register_operand" "=r")
16176 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16177 [(reg FLAGS_REG) (const_int 0)])
16180 (clobber (reg:CC FLAGS_REG))]
16182 "sbb{<imodesuffix>}\t%0, %0"
16183 [(set_attr "type" "alu")
16184 (set_attr "use_carry" "1")
16185 (set_attr "pent_pair" "pu")
16186 (set_attr "memory" "none")
16187 (set_attr "imm_disp" "false")
16188 (set_attr "mode" "<MODE>")
16189 (set_attr "length_immediate" "0")])
16191 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16192 [(set (match_operand:SWI48 0 "register_operand" "=r")
16193 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16194 [(reg FLAGS_REG) (const_int 0)])))
16195 (clobber (reg:CC FLAGS_REG))]
16197 "sbb{<imodesuffix>}\t%0, %0"
16198 [(set_attr "type" "alu")
16199 (set_attr "use_carry" "1")
16200 (set_attr "pent_pair" "pu")
16201 (set_attr "memory" "none")
16202 (set_attr "imm_disp" "false")
16203 (set_attr "mode" "<MODE>")
16204 (set_attr "length_immediate" "0")])
16206 (define_insn "*mov<mode>cc_noc"
16207 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16208 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16209 [(reg FLAGS_REG) (const_int 0)])
16210 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16211 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16212 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16214 cmov%O2%C1\t{%2, %0|%0, %2}
16215 cmov%O2%c1\t{%3, %0|%0, %3}"
16216 [(set_attr "type" "icmov")
16217 (set_attr "mode" "<MODE>")])
16219 ;; Don't do conditional moves with memory inputs. This splitter helps
16220 ;; register starved x86_32 by forcing inputs into registers before reload.
16222 [(set (match_operand:SWI248 0 "register_operand")
16223 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16224 [(reg FLAGS_REG) (const_int 0)])
16225 (match_operand:SWI248 2 "nonimmediate_operand")
16226 (match_operand:SWI248 3 "nonimmediate_operand")))]
16227 "!TARGET_64BIT && TARGET_CMOVE
16228 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16229 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16230 && can_create_pseudo_p ()
16231 && optimize_insn_for_speed_p ()"
16232 [(set (match_dup 0)
16233 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16235 if (MEM_P (operands[2]))
16236 operands[2] = force_reg (<MODE>mode, operands[2]);
16237 if (MEM_P (operands[3]))
16238 operands[3] = force_reg (<MODE>mode, operands[3]);
16241 (define_insn "*movqicc_noc"
16242 [(set (match_operand:QI 0 "register_operand" "=r,r")
16243 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16244 [(reg FLAGS_REG) (const_int 0)])
16245 (match_operand:QI 2 "register_operand" "r,0")
16246 (match_operand:QI 3 "register_operand" "0,r")))]
16247 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16249 [(set_attr "type" "icmov")
16250 (set_attr "mode" "QI")])
16253 [(set (match_operand:SWI12 0 "register_operand")
16254 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16255 [(reg FLAGS_REG) (const_int 0)])
16256 (match_operand:SWI12 2 "register_operand")
16257 (match_operand:SWI12 3 "register_operand")))]
16258 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16259 && reload_completed"
16260 [(set (match_dup 0)
16261 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16263 operands[0] = gen_lowpart (SImode, operands[0]);
16264 operands[2] = gen_lowpart (SImode, operands[2]);
16265 operands[3] = gen_lowpart (SImode, operands[3]);
16268 ;; Don't do conditional moves with memory inputs
16270 [(match_scratch:SWI248 2 "r")
16271 (set (match_operand:SWI248 0 "register_operand")
16272 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16273 [(reg FLAGS_REG) (const_int 0)])
16275 (match_operand:SWI248 3 "memory_operand")))]
16276 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16277 && optimize_insn_for_speed_p ()"
16278 [(set (match_dup 2) (match_dup 3))
16280 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16283 [(match_scratch:SWI248 2 "r")
16284 (set (match_operand:SWI248 0 "register_operand")
16285 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16286 [(reg FLAGS_REG) (const_int 0)])
16287 (match_operand:SWI248 3 "memory_operand")
16289 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16290 && optimize_insn_for_speed_p ()"
16291 [(set (match_dup 2) (match_dup 3))
16293 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16295 (define_expand "mov<mode>cc"
16296 [(set (match_operand:X87MODEF 0 "register_operand")
16297 (if_then_else:X87MODEF
16298 (match_operand 1 "comparison_operator")
16299 (match_operand:X87MODEF 2 "register_operand")
16300 (match_operand:X87MODEF 3 "register_operand")))]
16301 "(TARGET_80387 && TARGET_CMOVE)
16302 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16303 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16305 (define_insn "*movxfcc_1"
16306 [(set (match_operand:XF 0 "register_operand" "=f,f")
16307 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16308 [(reg FLAGS_REG) (const_int 0)])
16309 (match_operand:XF 2 "register_operand" "f,0")
16310 (match_operand:XF 3 "register_operand" "0,f")))]
16311 "TARGET_80387 && TARGET_CMOVE"
16313 fcmov%F1\t{%2, %0|%0, %2}
16314 fcmov%f1\t{%3, %0|%0, %3}"
16315 [(set_attr "type" "fcmov")
16316 (set_attr "mode" "XF")])
16318 (define_insn "*movdfcc_1"
16319 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16320 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16321 [(reg FLAGS_REG) (const_int 0)])
16322 (match_operand:DF 2 "nonimmediate_operand"
16324 (match_operand:DF 3 "nonimmediate_operand"
16325 "0 ,f,0 ,rm,0, rm")))]
16326 "TARGET_80387 && TARGET_CMOVE
16327 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16329 fcmov%F1\t{%2, %0|%0, %2}
16330 fcmov%f1\t{%3, %0|%0, %3}
16333 cmov%O2%C1\t{%2, %0|%0, %2}
16334 cmov%O2%c1\t{%3, %0|%0, %3}"
16335 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16336 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16337 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16340 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16341 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16342 [(reg FLAGS_REG) (const_int 0)])
16343 (match_operand:DF 2 "nonimmediate_operand")
16344 (match_operand:DF 3 "nonimmediate_operand")))]
16345 "!TARGET_64BIT && reload_completed"
16346 [(set (match_dup 2)
16347 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16349 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16351 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16352 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16355 (define_insn "*movsfcc_1_387"
16356 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16357 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16358 [(reg FLAGS_REG) (const_int 0)])
16359 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16360 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16361 "TARGET_80387 && TARGET_CMOVE
16362 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16364 fcmov%F1\t{%2, %0|%0, %2}
16365 fcmov%f1\t{%3, %0|%0, %3}
16366 cmov%O2%C1\t{%2, %0|%0, %2}
16367 cmov%O2%c1\t{%3, %0|%0, %3}"
16368 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16369 (set_attr "mode" "SF,SF,SI,SI")])
16371 ;; Don't do conditional moves with memory inputs. This splitter helps
16372 ;; register starved x86_32 by forcing inputs into registers before reload.
16374 [(set (match_operand:MODEF 0 "register_operand")
16375 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16376 [(reg FLAGS_REG) (const_int 0)])
16377 (match_operand:MODEF 2 "nonimmediate_operand")
16378 (match_operand:MODEF 3 "nonimmediate_operand")))]
16379 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16380 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16381 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16382 && can_create_pseudo_p ()
16383 && optimize_insn_for_speed_p ()"
16384 [(set (match_dup 0)
16385 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16387 if (MEM_P (operands[2]))
16388 operands[2] = force_reg (<MODE>mode, operands[2]);
16389 if (MEM_P (operands[3]))
16390 operands[3] = force_reg (<MODE>mode, operands[3]);
16393 ;; Don't do conditional moves with memory inputs
16395 [(match_scratch:MODEF 2 "r")
16396 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16397 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16398 [(reg FLAGS_REG) (const_int 0)])
16400 (match_operand:MODEF 3 "memory_operand")))]
16401 "(<MODE>mode != DFmode || TARGET_64BIT)
16402 && TARGET_80387 && TARGET_CMOVE
16403 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16404 && optimize_insn_for_speed_p ()"
16405 [(set (match_dup 2) (match_dup 3))
16407 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16410 [(match_scratch:MODEF 2 "r")
16411 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16412 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16413 [(reg FLAGS_REG) (const_int 0)])
16414 (match_operand:MODEF 3 "memory_operand")
16416 "(<MODE>mode != DFmode || TARGET_64BIT)
16417 && TARGET_80387 && TARGET_CMOVE
16418 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16419 && optimize_insn_for_speed_p ()"
16420 [(set (match_dup 2) (match_dup 3))
16422 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16424 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16425 ;; the scalar versions to have only XMM registers as operands.
16427 ;; XOP conditional move
16428 (define_insn "*xop_pcmov_<mode>"
16429 [(set (match_operand:MODEF 0 "register_operand" "=x")
16430 (if_then_else:MODEF
16431 (match_operand:MODEF 1 "register_operand" "x")
16432 (match_operand:MODEF 2 "register_operand" "x")
16433 (match_operand:MODEF 3 "register_operand" "x")))]
16435 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16436 [(set_attr "type" "sse4arg")])
16438 ;; These versions of the min/max patterns are intentionally ignorant of
16439 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16440 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16441 ;; are undefined in this condition, we're certain this is correct.
16443 (define_insn "<code><mode>3"
16444 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16446 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16447 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16448 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16450 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16451 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16452 [(set_attr "isa" "noavx,avx")
16453 (set_attr "prefix" "orig,vex")
16454 (set_attr "type" "sseadd")
16455 (set_attr "mode" "<MODE>")])
16457 ;; These versions of the min/max patterns implement exactly the operations
16458 ;; min = (op1 < op2 ? op1 : op2)
16459 ;; max = (!(op1 < op2) ? op1 : op2)
16460 ;; Their operands are not commutative, and thus they may be used in the
16461 ;; presence of -0.0 and NaN.
16463 (define_int_iterator IEEE_MAXMIN
16467 (define_int_attr ieee_maxmin
16468 [(UNSPEC_IEEE_MAX "max")
16469 (UNSPEC_IEEE_MIN "min")])
16471 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16472 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16474 [(match_operand:MODEF 1 "register_operand" "0,x")
16475 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16477 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16479 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16480 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16481 [(set_attr "isa" "noavx,avx")
16482 (set_attr "prefix" "orig,vex")
16483 (set_attr "type" "sseadd")
16484 (set_attr "mode" "<MODE>")])
16486 ;; Make two stack loads independent:
16488 ;; fld %st(0) -> fld bb
16489 ;; fmul bb fmul %st(1), %st
16491 ;; Actually we only match the last two instructions for simplicity.
16493 [(set (match_operand 0 "fp_register_operand")
16494 (match_operand 1 "fp_register_operand"))
16496 (match_operator 2 "binary_fp_operator"
16498 (match_operand 3 "memory_operand")]))]
16499 "REGNO (operands[0]) != REGNO (operands[1])"
16500 [(set (match_dup 0) (match_dup 3))
16501 (set (match_dup 0) (match_dup 4))]
16503 ;; The % modifier is not operational anymore in peephole2's, so we have to
16504 ;; swap the operands manually in the case of addition and multiplication.
16508 if (COMMUTATIVE_ARITH_P (operands[2]))
16509 op0 = operands[0], op1 = operands[1];
16511 op0 = operands[1], op1 = operands[0];
16513 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16514 GET_MODE (operands[2]),
16518 ;; Conditional addition patterns
16519 (define_expand "add<mode>cc"
16520 [(match_operand:SWI 0 "register_operand")
16521 (match_operand 1 "ordered_comparison_operator")
16522 (match_operand:SWI 2 "register_operand")
16523 (match_operand:SWI 3 "const_int_operand")]
16525 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16527 ;; Misc patterns (?)
16529 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16530 ;; Otherwise there will be nothing to keep
16532 ;; [(set (reg ebp) (reg esp))]
16533 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16534 ;; (clobber (eflags)]
16535 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16537 ;; in proper program order.
16539 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16540 [(set (match_operand:P 0 "register_operand" "=r,r")
16541 (plus:P (match_operand:P 1 "register_operand" "0,r")
16542 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16543 (clobber (reg:CC FLAGS_REG))
16544 (clobber (mem:BLK (scratch)))]
16547 switch (get_attr_type (insn))
16550 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16553 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16554 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16555 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16557 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16560 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16561 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16564 [(set (attr "type")
16565 (cond [(and (eq_attr "alternative" "0")
16566 (not (match_test "TARGET_OPT_AGU")))
16567 (const_string "alu")
16568 (match_operand:<MODE> 2 "const0_operand")
16569 (const_string "imov")
16571 (const_string "lea")))
16572 (set (attr "length_immediate")
16573 (cond [(eq_attr "type" "imov")
16575 (and (eq_attr "type" "alu")
16576 (match_operand 2 "const128_operand"))
16579 (const_string "*")))
16580 (set_attr "mode" "<MODE>")])
16582 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16583 [(set (match_operand:P 0 "register_operand" "=r")
16584 (minus:P (match_operand:P 1 "register_operand" "0")
16585 (match_operand:P 2 "register_operand" "r")))
16586 (clobber (reg:CC FLAGS_REG))
16587 (clobber (mem:BLK (scratch)))]
16589 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16590 [(set_attr "type" "alu")
16591 (set_attr "mode" "<MODE>")])
16593 (define_insn "allocate_stack_worker_probe_<mode>"
16594 [(set (match_operand:P 0 "register_operand" "=a")
16595 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16596 UNSPECV_STACK_PROBE))
16597 (clobber (reg:CC FLAGS_REG))]
16598 "ix86_target_stack_probe ()"
16599 "call\t___chkstk_ms"
16600 [(set_attr "type" "multi")
16601 (set_attr "length" "5")])
16603 (define_expand "allocate_stack"
16604 [(match_operand 0 "register_operand")
16605 (match_operand 1 "general_operand")]
16606 "ix86_target_stack_probe ()"
16610 #ifndef CHECK_STACK_LIMIT
16611 #define CHECK_STACK_LIMIT 0
16614 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16615 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16619 rtx (*insn) (rtx, rtx);
16621 x = copy_to_mode_reg (Pmode, operands[1]);
16623 insn = (TARGET_64BIT
16624 ? gen_allocate_stack_worker_probe_di
16625 : gen_allocate_stack_worker_probe_si);
16627 emit_insn (insn (x, x));
16630 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16631 stack_pointer_rtx, 0, OPTAB_DIRECT);
16633 if (x != stack_pointer_rtx)
16634 emit_move_insn (stack_pointer_rtx, x);
16636 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16640 ;; Use IOR for stack probes, this is shorter.
16641 (define_expand "probe_stack"
16642 [(match_operand 0 "memory_operand")]
16645 rtx (*gen_ior3) (rtx, rtx, rtx);
16647 gen_ior3 = (GET_MODE (operands[0]) == DImode
16648 ? gen_iordi3 : gen_iorsi3);
16650 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16654 (define_insn "adjust_stack_and_probe<mode>"
16655 [(set (match_operand:P 0 "register_operand" "=r")
16656 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16657 UNSPECV_PROBE_STACK_RANGE))
16658 (set (reg:P SP_REG)
16659 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16660 (clobber (reg:CC FLAGS_REG))
16661 (clobber (mem:BLK (scratch)))]
16663 "* return output_adjust_stack_and_probe (operands[0]);"
16664 [(set_attr "type" "multi")])
16666 (define_insn "probe_stack_range<mode>"
16667 [(set (match_operand:P 0 "register_operand" "=r")
16668 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16669 (match_operand:P 2 "const_int_operand" "n")]
16670 UNSPECV_PROBE_STACK_RANGE))
16671 (clobber (reg:CC FLAGS_REG))]
16673 "* return output_probe_stack_range (operands[0], operands[2]);"
16674 [(set_attr "type" "multi")])
16676 (define_expand "builtin_setjmp_receiver"
16677 [(label_ref (match_operand 0))]
16678 "!TARGET_64BIT && flag_pic"
16684 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16685 rtx label_rtx = gen_label_rtx ();
16686 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16687 xops[0] = xops[1] = picreg;
16688 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16689 ix86_expand_binary_operator (MINUS, SImode, xops);
16693 emit_insn (gen_set_got (pic_offset_table_rtx));
16697 (define_insn_and_split "nonlocal_goto_receiver"
16698 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16699 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16701 "&& reload_completed"
16704 if (crtl->uses_pic_offset_table)
16707 rtx label_rtx = gen_label_rtx ();
16710 /* Get a new pic base. */
16711 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16712 /* Correct this with the offset from the new to the old. */
16713 xops[0] = xops[1] = pic_offset_table_rtx;
16714 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16715 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16716 UNSPEC_MACHOPIC_OFFSET);
16717 xops[2] = gen_rtx_CONST (Pmode, tmp);
16718 ix86_expand_binary_operator (MINUS, SImode, xops);
16721 /* No pic reg restore needed. */
16722 emit_note (NOTE_INSN_DELETED);
16727 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16728 ;; Do not split instructions with mask registers.
16730 [(set (match_operand 0 "general_reg_operand")
16731 (match_operator 3 "promotable_binary_operator"
16732 [(match_operand 1 "general_reg_operand")
16733 (match_operand 2 "aligned_operand")]))
16734 (clobber (reg:CC FLAGS_REG))]
16735 "! TARGET_PARTIAL_REG_STALL && reload_completed
16736 && ((GET_MODE (operands[0]) == HImode
16737 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16738 /* ??? next two lines just !satisfies_constraint_K (...) */
16739 || !CONST_INT_P (operands[2])
16740 || satisfies_constraint_K (operands[2])))
16741 || (GET_MODE (operands[0]) == QImode
16742 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16743 [(parallel [(set (match_dup 0)
16744 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16745 (clobber (reg:CC FLAGS_REG))])]
16747 operands[0] = gen_lowpart (SImode, operands[0]);
16748 operands[1] = gen_lowpart (SImode, operands[1]);
16749 if (GET_CODE (operands[3]) != ASHIFT)
16750 operands[2] = gen_lowpart (SImode, operands[2]);
16751 PUT_MODE (operands[3], SImode);
16754 ; Promote the QImode tests, as i386 has encoding of the AND
16755 ; instruction with 32-bit sign-extended immediate and thus the
16756 ; instruction size is unchanged, except in the %eax case for
16757 ; which it is increased by one byte, hence the ! optimize_size.
16759 [(set (match_operand 0 "flags_reg_operand")
16760 (match_operator 2 "compare_operator"
16761 [(and (match_operand 3 "aligned_operand")
16762 (match_operand 4 "const_int_operand"))
16764 (set (match_operand 1 "register_operand")
16765 (and (match_dup 3) (match_dup 4)))]
16766 "! TARGET_PARTIAL_REG_STALL && reload_completed
16767 && optimize_insn_for_speed_p ()
16768 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16769 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16770 /* Ensure that the operand will remain sign-extended immediate. */
16771 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16772 [(parallel [(set (match_dup 0)
16773 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16776 (and:SI (match_dup 3) (match_dup 4)))])]
16779 = gen_int_mode (INTVAL (operands[4])
16780 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16781 operands[1] = gen_lowpart (SImode, operands[1]);
16782 operands[3] = gen_lowpart (SImode, operands[3]);
16785 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16786 ; the TEST instruction with 32-bit sign-extended immediate and thus
16787 ; the instruction size would at least double, which is not what we
16788 ; want even with ! optimize_size.
16790 [(set (match_operand 0 "flags_reg_operand")
16791 (match_operator 1 "compare_operator"
16792 [(and (match_operand:HI 2 "aligned_operand")
16793 (match_operand:HI 3 "const_int_operand"))
16795 "! TARGET_PARTIAL_REG_STALL && reload_completed
16796 && ! TARGET_FAST_PREFIX
16797 && optimize_insn_for_speed_p ()
16798 /* Ensure that the operand will remain sign-extended immediate. */
16799 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16800 [(set (match_dup 0)
16801 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16805 = gen_int_mode (INTVAL (operands[3])
16806 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16807 operands[2] = gen_lowpart (SImode, operands[2]);
16811 [(set (match_operand 0 "register_operand")
16812 (neg (match_operand 1 "register_operand")))
16813 (clobber (reg:CC FLAGS_REG))]
16814 "! TARGET_PARTIAL_REG_STALL && reload_completed
16815 && (GET_MODE (operands[0]) == HImode
16816 || (GET_MODE (operands[0]) == QImode
16817 && (TARGET_PROMOTE_QImode
16818 || optimize_insn_for_size_p ())))"
16819 [(parallel [(set (match_dup 0)
16820 (neg:SI (match_dup 1)))
16821 (clobber (reg:CC FLAGS_REG))])]
16823 operands[0] = gen_lowpart (SImode, operands[0]);
16824 operands[1] = gen_lowpart (SImode, operands[1]);
16827 ;; Do not split instructions with mask regs.
16829 [(set (match_operand 0 "general_reg_operand")
16830 (not (match_operand 1 "general_reg_operand")))]
16831 "! TARGET_PARTIAL_REG_STALL && reload_completed
16832 && (GET_MODE (operands[0]) == HImode
16833 || (GET_MODE (operands[0]) == QImode
16834 && (TARGET_PROMOTE_QImode
16835 || optimize_insn_for_size_p ())))"
16836 [(set (match_dup 0)
16837 (not:SI (match_dup 1)))]
16839 operands[0] = gen_lowpart (SImode, operands[0]);
16840 operands[1] = gen_lowpart (SImode, operands[1]);
16843 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16844 ;; transform a complex memory operation into two memory to register operations.
16846 ;; Don't push memory operands
16848 [(set (match_operand:SWI 0 "push_operand")
16849 (match_operand:SWI 1 "memory_operand"))
16850 (match_scratch:SWI 2 "<r>")]
16851 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16852 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16853 [(set (match_dup 2) (match_dup 1))
16854 (set (match_dup 0) (match_dup 2))])
16856 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16859 [(set (match_operand:SF 0 "push_operand")
16860 (match_operand:SF 1 "memory_operand"))
16861 (match_scratch:SF 2 "r")]
16862 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16863 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16864 [(set (match_dup 2) (match_dup 1))
16865 (set (match_dup 0) (match_dup 2))])
16867 ;; Don't move an immediate directly to memory when the instruction
16868 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16870 [(match_scratch:SWI124 1 "<r>")
16871 (set (match_operand:SWI124 0 "memory_operand")
16873 "optimize_insn_for_speed_p ()
16874 && ((<MODE>mode == HImode
16875 && TARGET_LCP_STALL)
16876 || (!TARGET_USE_MOV0
16877 && TARGET_SPLIT_LONG_MOVES
16878 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16879 && peep2_regno_dead_p (0, FLAGS_REG)"
16880 [(parallel [(set (match_dup 2) (const_int 0))
16881 (clobber (reg:CC FLAGS_REG))])
16882 (set (match_dup 0) (match_dup 1))]
16883 "operands[2] = gen_lowpart (SImode, operands[1]);")
16886 [(match_scratch:SWI124 2 "<r>")
16887 (set (match_operand:SWI124 0 "memory_operand")
16888 (match_operand:SWI124 1 "immediate_operand"))]
16889 "optimize_insn_for_speed_p ()
16890 && ((<MODE>mode == HImode
16891 && TARGET_LCP_STALL)
16892 || (TARGET_SPLIT_LONG_MOVES
16893 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16894 [(set (match_dup 2) (match_dup 1))
16895 (set (match_dup 0) (match_dup 2))])
16897 ;; Don't compare memory with zero, load and use a test instead.
16899 [(set (match_operand 0 "flags_reg_operand")
16900 (match_operator 1 "compare_operator"
16901 [(match_operand:SI 2 "memory_operand")
16903 (match_scratch:SI 3 "r")]
16904 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16905 [(set (match_dup 3) (match_dup 2))
16906 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16908 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16909 ;; Don't split NOTs with a displacement operand, because resulting XOR
16910 ;; will not be pairable anyway.
16912 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16913 ;; represented using a modRM byte. The XOR replacement is long decoded,
16914 ;; so this split helps here as well.
16916 ;; Note: Can't do this as a regular split because we can't get proper
16917 ;; lifetime information then.
16920 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16921 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16922 "optimize_insn_for_speed_p ()
16923 && ((TARGET_NOT_UNPAIRABLE
16924 && (!MEM_P (operands[0])
16925 || !memory_displacement_operand (operands[0], <MODE>mode)))
16926 || (TARGET_NOT_VECTORMODE
16927 && long_memory_operand (operands[0], <MODE>mode)))
16928 && peep2_regno_dead_p (0, FLAGS_REG)"
16929 [(parallel [(set (match_dup 0)
16930 (xor:SWI124 (match_dup 1) (const_int -1)))
16931 (clobber (reg:CC FLAGS_REG))])])
16933 ;; Non pairable "test imm, reg" instructions can be translated to
16934 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16935 ;; byte opcode instead of two, have a short form for byte operands),
16936 ;; so do it for other CPUs as well. Given that the value was dead,
16937 ;; this should not create any new dependencies. Pass on the sub-word
16938 ;; versions if we're concerned about partial register stalls.
16941 [(set (match_operand 0 "flags_reg_operand")
16942 (match_operator 1 "compare_operator"
16943 [(and:SI (match_operand:SI 2 "register_operand")
16944 (match_operand:SI 3 "immediate_operand"))
16946 "ix86_match_ccmode (insn, CCNOmode)
16947 && (true_regnum (operands[2]) != AX_REG
16948 || satisfies_constraint_K (operands[3]))
16949 && peep2_reg_dead_p (1, operands[2])"
16951 [(set (match_dup 0)
16952 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16955 (and:SI (match_dup 2) (match_dup 3)))])])
16957 ;; We don't need to handle HImode case, because it will be promoted to SImode
16958 ;; on ! TARGET_PARTIAL_REG_STALL
16961 [(set (match_operand 0 "flags_reg_operand")
16962 (match_operator 1 "compare_operator"
16963 [(and:QI (match_operand:QI 2 "register_operand")
16964 (match_operand:QI 3 "immediate_operand"))
16966 "! TARGET_PARTIAL_REG_STALL
16967 && ix86_match_ccmode (insn, CCNOmode)
16968 && true_regnum (operands[2]) != AX_REG
16969 && peep2_reg_dead_p (1, operands[2])"
16971 [(set (match_dup 0)
16972 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16975 (and:QI (match_dup 2) (match_dup 3)))])])
16978 [(set (match_operand 0 "flags_reg_operand")
16979 (match_operator 1 "compare_operator"
16982 (match_operand 2 "ext_register_operand")
16985 (match_operand 3 "const_int_operand"))
16987 "! TARGET_PARTIAL_REG_STALL
16988 && ix86_match_ccmode (insn, CCNOmode)
16989 && true_regnum (operands[2]) != AX_REG
16990 && peep2_reg_dead_p (1, operands[2])"
16991 [(parallel [(set (match_dup 0)
17000 (set (zero_extract:SI (match_dup 2)
17008 (match_dup 3)))])])
17010 ;; Don't do logical operations with memory inputs.
17012 [(match_scratch:SI 2 "r")
17013 (parallel [(set (match_operand:SI 0 "register_operand")
17014 (match_operator:SI 3 "arith_or_logical_operator"
17016 (match_operand:SI 1 "memory_operand")]))
17017 (clobber (reg:CC FLAGS_REG))])]
17018 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17019 [(set (match_dup 2) (match_dup 1))
17020 (parallel [(set (match_dup 0)
17021 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17022 (clobber (reg:CC FLAGS_REG))])])
17025 [(match_scratch:SI 2 "r")
17026 (parallel [(set (match_operand:SI 0 "register_operand")
17027 (match_operator:SI 3 "arith_or_logical_operator"
17028 [(match_operand:SI 1 "memory_operand")
17030 (clobber (reg:CC FLAGS_REG))])]
17031 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17032 [(set (match_dup 2) (match_dup 1))
17033 (parallel [(set (match_dup 0)
17034 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17035 (clobber (reg:CC FLAGS_REG))])])
17037 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17038 ;; refers to the destination of the load!
17041 [(set (match_operand:SI 0 "register_operand")
17042 (match_operand:SI 1 "register_operand"))
17043 (parallel [(set (match_dup 0)
17044 (match_operator:SI 3 "commutative_operator"
17046 (match_operand:SI 2 "memory_operand")]))
17047 (clobber (reg:CC FLAGS_REG))])]
17048 "REGNO (operands[0]) != REGNO (operands[1])
17049 && GENERAL_REGNO_P (REGNO (operands[0]))
17050 && GENERAL_REGNO_P (REGNO (operands[1]))"
17051 [(set (match_dup 0) (match_dup 4))
17052 (parallel [(set (match_dup 0)
17053 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17054 (clobber (reg:CC FLAGS_REG))])]
17055 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17058 [(set (match_operand 0 "register_operand")
17059 (match_operand 1 "register_operand"))
17061 (match_operator 3 "commutative_operator"
17063 (match_operand 2 "memory_operand")]))]
17064 "REGNO (operands[0]) != REGNO (operands[1])
17065 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17066 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17067 [(set (match_dup 0) (match_dup 2))
17069 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17071 ; Don't do logical operations with memory outputs
17073 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17074 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17075 ; the same decoder scheduling characteristics as the original.
17078 [(match_scratch:SI 2 "r")
17079 (parallel [(set (match_operand:SI 0 "memory_operand")
17080 (match_operator:SI 3 "arith_or_logical_operator"
17082 (match_operand:SI 1 "nonmemory_operand")]))
17083 (clobber (reg:CC FLAGS_REG))])]
17084 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17085 /* Do not split stack checking probes. */
17086 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17087 [(set (match_dup 2) (match_dup 0))
17088 (parallel [(set (match_dup 2)
17089 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17090 (clobber (reg:CC FLAGS_REG))])
17091 (set (match_dup 0) (match_dup 2))])
17094 [(match_scratch:SI 2 "r")
17095 (parallel [(set (match_operand:SI 0 "memory_operand")
17096 (match_operator:SI 3 "arith_or_logical_operator"
17097 [(match_operand:SI 1 "nonmemory_operand")
17099 (clobber (reg:CC FLAGS_REG))])]
17100 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17101 /* Do not split stack checking probes. */
17102 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17103 [(set (match_dup 2) (match_dup 0))
17104 (parallel [(set (match_dup 2)
17105 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17106 (clobber (reg:CC FLAGS_REG))])
17107 (set (match_dup 0) (match_dup 2))])
17109 ;; Attempt to use arith or logical operations with memory outputs with
17110 ;; setting of flags.
17112 [(set (match_operand:SWI 0 "register_operand")
17113 (match_operand:SWI 1 "memory_operand"))
17114 (parallel [(set (match_dup 0)
17115 (match_operator:SWI 3 "plusminuslogic_operator"
17117 (match_operand:SWI 2 "<nonmemory_operand>")]))
17118 (clobber (reg:CC FLAGS_REG))])
17119 (set (match_dup 1) (match_dup 0))
17120 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17121 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17122 && peep2_reg_dead_p (4, operands[0])
17123 && !reg_overlap_mentioned_p (operands[0], operands[1])
17124 && !reg_overlap_mentioned_p (operands[0], operands[2])
17125 && (<MODE>mode != QImode
17126 || immediate_operand (operands[2], QImode)
17127 || q_regs_operand (operands[2], QImode))
17128 && ix86_match_ccmode (peep2_next_insn (3),
17129 (GET_CODE (operands[3]) == PLUS
17130 || GET_CODE (operands[3]) == MINUS)
17131 ? CCGOCmode : CCNOmode)"
17132 [(parallel [(set (match_dup 4) (match_dup 5))
17133 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17134 (match_dup 2)]))])]
17136 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17137 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17138 copy_rtx (operands[1]),
17139 copy_rtx (operands[2]));
17140 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17141 operands[5], const0_rtx);
17145 [(parallel [(set (match_operand:SWI 0 "register_operand")
17146 (match_operator:SWI 2 "plusminuslogic_operator"
17148 (match_operand:SWI 1 "memory_operand")]))
17149 (clobber (reg:CC FLAGS_REG))])
17150 (set (match_dup 1) (match_dup 0))
17151 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17152 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17153 && GET_CODE (operands[2]) != MINUS
17154 && peep2_reg_dead_p (3, operands[0])
17155 && !reg_overlap_mentioned_p (operands[0], operands[1])
17156 && ix86_match_ccmode (peep2_next_insn (2),
17157 GET_CODE (operands[2]) == PLUS
17158 ? CCGOCmode : CCNOmode)"
17159 [(parallel [(set (match_dup 3) (match_dup 4))
17160 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17161 (match_dup 0)]))])]
17163 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17164 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17165 copy_rtx (operands[1]),
17166 copy_rtx (operands[0]));
17167 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17168 operands[4], const0_rtx);
17172 [(set (match_operand:SWI12 0 "register_operand")
17173 (match_operand:SWI12 1 "memory_operand"))
17174 (parallel [(set (match_operand:SI 4 "register_operand")
17175 (match_operator:SI 3 "plusminuslogic_operator"
17177 (match_operand:SI 2 "nonmemory_operand")]))
17178 (clobber (reg:CC FLAGS_REG))])
17179 (set (match_dup 1) (match_dup 0))
17180 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17181 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17182 && REG_P (operands[0]) && REG_P (operands[4])
17183 && REGNO (operands[0]) == REGNO (operands[4])
17184 && peep2_reg_dead_p (4, operands[0])
17185 && (<MODE>mode != QImode
17186 || immediate_operand (operands[2], SImode)
17187 || q_regs_operand (operands[2], SImode))
17188 && !reg_overlap_mentioned_p (operands[0], operands[1])
17189 && !reg_overlap_mentioned_p (operands[0], operands[2])
17190 && ix86_match_ccmode (peep2_next_insn (3),
17191 (GET_CODE (operands[3]) == PLUS
17192 || GET_CODE (operands[3]) == MINUS)
17193 ? CCGOCmode : CCNOmode)"
17194 [(parallel [(set (match_dup 4) (match_dup 5))
17195 (set (match_dup 1) (match_dup 6))])]
17197 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17198 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17199 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17200 copy_rtx (operands[1]), operands[2]);
17201 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17202 operands[5], const0_rtx);
17203 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17204 copy_rtx (operands[1]),
17205 copy_rtx (operands[2]));
17208 ;; Attempt to always use XOR for zeroing registers.
17210 [(set (match_operand 0 "register_operand")
17211 (match_operand 1 "const0_operand"))]
17212 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17213 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17214 && GENERAL_REG_P (operands[0])
17215 && peep2_regno_dead_p (0, FLAGS_REG)"
17216 [(parallel [(set (match_dup 0) (const_int 0))
17217 (clobber (reg:CC FLAGS_REG))])]
17218 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17221 [(set (strict_low_part (match_operand 0 "register_operand"))
17223 "(GET_MODE (operands[0]) == QImode
17224 || GET_MODE (operands[0]) == HImode)
17225 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17226 && peep2_regno_dead_p (0, FLAGS_REG)"
17227 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17228 (clobber (reg:CC FLAGS_REG))])])
17230 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17232 [(set (match_operand:SWI248 0 "register_operand")
17234 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17235 && peep2_regno_dead_p (0, FLAGS_REG)"
17236 [(parallel [(set (match_dup 0) (const_int -1))
17237 (clobber (reg:CC FLAGS_REG))])]
17239 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17240 operands[0] = gen_lowpart (SImode, operands[0]);
17243 ;; Attempt to convert simple lea to add/shift.
17244 ;; These can be created by move expanders.
17245 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17246 ;; relevant lea instructions were already split.
17249 [(set (match_operand:SWI48 0 "register_operand")
17250 (plus:SWI48 (match_dup 0)
17251 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17253 && peep2_regno_dead_p (0, FLAGS_REG)"
17254 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17255 (clobber (reg:CC FLAGS_REG))])])
17258 [(set (match_operand:SWI48 0 "register_operand")
17259 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17262 && peep2_regno_dead_p (0, FLAGS_REG)"
17263 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17264 (clobber (reg:CC FLAGS_REG))])])
17267 [(set (match_operand:DI 0 "register_operand")
17269 (plus:SI (match_operand:SI 1 "register_operand")
17270 (match_operand:SI 2 "nonmemory_operand"))))]
17271 "TARGET_64BIT && !TARGET_OPT_AGU
17272 && REGNO (operands[0]) == REGNO (operands[1])
17273 && peep2_regno_dead_p (0, FLAGS_REG)"
17274 [(parallel [(set (match_dup 0)
17275 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17276 (clobber (reg:CC FLAGS_REG))])])
17279 [(set (match_operand:DI 0 "register_operand")
17281 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17282 (match_operand:SI 2 "register_operand"))))]
17283 "TARGET_64BIT && !TARGET_OPT_AGU
17284 && REGNO (operands[0]) == REGNO (operands[2])
17285 && peep2_regno_dead_p (0, FLAGS_REG)"
17286 [(parallel [(set (match_dup 0)
17287 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17288 (clobber (reg:CC FLAGS_REG))])])
17291 [(set (match_operand:SWI48 0 "register_operand")
17292 (mult:SWI48 (match_dup 0)
17293 (match_operand:SWI48 1 "const_int_operand")))]
17294 "exact_log2 (INTVAL (operands[1])) >= 0
17295 && peep2_regno_dead_p (0, FLAGS_REG)"
17296 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17297 (clobber (reg:CC FLAGS_REG))])]
17298 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17301 [(set (match_operand:DI 0 "register_operand")
17303 (mult:SI (match_operand:SI 1 "register_operand")
17304 (match_operand:SI 2 "const_int_operand"))))]
17306 && exact_log2 (INTVAL (operands[2])) >= 0
17307 && REGNO (operands[0]) == REGNO (operands[1])
17308 && peep2_regno_dead_p (0, FLAGS_REG)"
17309 [(parallel [(set (match_dup 0)
17310 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
17311 (clobber (reg:CC FLAGS_REG))])]
17312 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17314 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17315 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17316 ;; On many CPUs it is also faster, since special hardware to avoid esp
17317 ;; dependencies is present.
17319 ;; While some of these conversions may be done using splitters, we use
17320 ;; peepholes in order to allow combine_stack_adjustments pass to see
17321 ;; nonobfuscated RTL.
17323 ;; Convert prologue esp subtractions to push.
17324 ;; We need register to push. In order to keep verify_flow_info happy we have
17326 ;; - use scratch and clobber it in order to avoid dependencies
17327 ;; - use already live register
17328 ;; We can't use the second way right now, since there is no reliable way how to
17329 ;; verify that given register is live. First choice will also most likely in
17330 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17331 ;; call clobbered registers are dead. We may want to use base pointer as an
17332 ;; alternative when no register is available later.
17335 [(match_scratch:W 1 "r")
17336 (parallel [(set (reg:P SP_REG)
17337 (plus:P (reg:P SP_REG)
17338 (match_operand:P 0 "const_int_operand")))
17339 (clobber (reg:CC FLAGS_REG))
17340 (clobber (mem:BLK (scratch)))])]
17341 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17342 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17343 [(clobber (match_dup 1))
17344 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17345 (clobber (mem:BLK (scratch)))])])
17348 [(match_scratch:W 1 "r")
17349 (parallel [(set (reg:P SP_REG)
17350 (plus:P (reg:P SP_REG)
17351 (match_operand:P 0 "const_int_operand")))
17352 (clobber (reg:CC FLAGS_REG))
17353 (clobber (mem:BLK (scratch)))])]
17354 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17355 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17356 [(clobber (match_dup 1))
17357 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17358 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17359 (clobber (mem:BLK (scratch)))])])
17361 ;; Convert esp subtractions to push.
17363 [(match_scratch:W 1 "r")
17364 (parallel [(set (reg:P SP_REG)
17365 (plus:P (reg:P SP_REG)
17366 (match_operand:P 0 "const_int_operand")))
17367 (clobber (reg:CC FLAGS_REG))])]
17368 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17369 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17370 [(clobber (match_dup 1))
17371 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17374 [(match_scratch:W 1 "r")
17375 (parallel [(set (reg:P SP_REG)
17376 (plus:P (reg:P SP_REG)
17377 (match_operand:P 0 "const_int_operand")))
17378 (clobber (reg:CC FLAGS_REG))])]
17379 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17380 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17381 [(clobber (match_dup 1))
17382 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17383 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17385 ;; Convert epilogue deallocator to pop.
17387 [(match_scratch:W 1 "r")
17388 (parallel [(set (reg:P SP_REG)
17389 (plus:P (reg:P SP_REG)
17390 (match_operand:P 0 "const_int_operand")))
17391 (clobber (reg:CC FLAGS_REG))
17392 (clobber (mem:BLK (scratch)))])]
17393 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17394 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17395 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17396 (clobber (mem:BLK (scratch)))])])
17398 ;; Two pops case is tricky, since pop causes dependency
17399 ;; on destination register. We use two registers if available.
17401 [(match_scratch:W 1 "r")
17402 (match_scratch:W 2 "r")
17403 (parallel [(set (reg:P SP_REG)
17404 (plus:P (reg:P SP_REG)
17405 (match_operand:P 0 "const_int_operand")))
17406 (clobber (reg:CC FLAGS_REG))
17407 (clobber (mem:BLK (scratch)))])]
17408 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17409 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17410 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17411 (clobber (mem:BLK (scratch)))])
17412 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17415 [(match_scratch:W 1 "r")
17416 (parallel [(set (reg:P SP_REG)
17417 (plus:P (reg:P SP_REG)
17418 (match_operand:P 0 "const_int_operand")))
17419 (clobber (reg:CC FLAGS_REG))
17420 (clobber (mem:BLK (scratch)))])]
17421 "optimize_insn_for_size_p ()
17422 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17423 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17424 (clobber (mem:BLK (scratch)))])
17425 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17427 ;; Convert esp additions to pop.
17429 [(match_scratch:W 1 "r")
17430 (parallel [(set (reg:P SP_REG)
17431 (plus:P (reg:P SP_REG)
17432 (match_operand:P 0 "const_int_operand")))
17433 (clobber (reg:CC FLAGS_REG))])]
17434 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17435 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17437 ;; Two pops case is tricky, since pop causes dependency
17438 ;; on destination register. We use two registers if available.
17440 [(match_scratch:W 1 "r")
17441 (match_scratch:W 2 "r")
17442 (parallel [(set (reg:P SP_REG)
17443 (plus:P (reg:P SP_REG)
17444 (match_operand:P 0 "const_int_operand")))
17445 (clobber (reg:CC FLAGS_REG))])]
17446 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17447 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17448 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17451 [(match_scratch:W 1 "r")
17452 (parallel [(set (reg:P SP_REG)
17453 (plus:P (reg:P SP_REG)
17454 (match_operand:P 0 "const_int_operand")))
17455 (clobber (reg:CC FLAGS_REG))])]
17456 "optimize_insn_for_size_p ()
17457 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17458 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17459 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17461 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17462 ;; required and register dies. Similarly for 128 to -128.
17464 [(set (match_operand 0 "flags_reg_operand")
17465 (match_operator 1 "compare_operator"
17466 [(match_operand 2 "register_operand")
17467 (match_operand 3 "const_int_operand")]))]
17468 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17469 && incdec_operand (operands[3], GET_MODE (operands[3])))
17470 || (!TARGET_FUSE_CMP_AND_BRANCH
17471 && INTVAL (operands[3]) == 128))
17472 && ix86_match_ccmode (insn, CCGCmode)
17473 && peep2_reg_dead_p (1, operands[2])"
17474 [(parallel [(set (match_dup 0)
17475 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17476 (clobber (match_dup 2))])])
17478 ;; Convert imul by three, five and nine into lea
17481 [(set (match_operand:SWI48 0 "register_operand")
17482 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17483 (match_operand:SWI48 2 "const359_operand")))
17484 (clobber (reg:CC FLAGS_REG))])]
17485 "!TARGET_PARTIAL_REG_STALL
17486 || <MODE>mode == SImode
17487 || optimize_function_for_size_p (cfun)"
17488 [(set (match_dup 0)
17489 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17491 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17495 [(set (match_operand:SWI48 0 "register_operand")
17496 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17497 (match_operand:SWI48 2 "const359_operand")))
17498 (clobber (reg:CC FLAGS_REG))])]
17499 "optimize_insn_for_speed_p ()
17500 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17501 [(set (match_dup 0) (match_dup 1))
17503 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17505 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17507 ;; imul $32bit_imm, mem, reg is vector decoded, while
17508 ;; imul $32bit_imm, reg, reg is direct decoded.
17510 [(match_scratch:SWI48 3 "r")
17511 (parallel [(set (match_operand:SWI48 0 "register_operand")
17512 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17513 (match_operand:SWI48 2 "immediate_operand")))
17514 (clobber (reg:CC FLAGS_REG))])]
17515 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17516 && !satisfies_constraint_K (operands[2])"
17517 [(set (match_dup 3) (match_dup 1))
17518 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17519 (clobber (reg:CC FLAGS_REG))])])
17522 [(match_scratch:SI 3 "r")
17523 (parallel [(set (match_operand:DI 0 "register_operand")
17525 (mult:SI (match_operand:SI 1 "memory_operand")
17526 (match_operand:SI 2 "immediate_operand"))))
17527 (clobber (reg:CC FLAGS_REG))])]
17529 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17530 && !satisfies_constraint_K (operands[2])"
17531 [(set (match_dup 3) (match_dup 1))
17532 (parallel [(set (match_dup 0)
17533 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17534 (clobber (reg:CC FLAGS_REG))])])
17536 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17537 ;; Convert it into imul reg, reg
17538 ;; It would be better to force assembler to encode instruction using long
17539 ;; immediate, but there is apparently no way to do so.
17541 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17543 (match_operand:SWI248 1 "nonimmediate_operand")
17544 (match_operand:SWI248 2 "const_int_operand")))
17545 (clobber (reg:CC FLAGS_REG))])
17546 (match_scratch:SWI248 3 "r")]
17547 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17548 && satisfies_constraint_K (operands[2])"
17549 [(set (match_dup 3) (match_dup 2))
17550 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17551 (clobber (reg:CC FLAGS_REG))])]
17553 if (!rtx_equal_p (operands[0], operands[1]))
17554 emit_move_insn (operands[0], operands[1]);
17557 ;; After splitting up read-modify operations, array accesses with memory
17558 ;; operands might end up in form:
17560 ;; movl 4(%esp), %edx
17562 ;; instead of pre-splitting:
17564 ;; addl 4(%esp), %eax
17566 ;; movl 4(%esp), %edx
17567 ;; leal (%edx,%eax,4), %eax
17570 [(match_scratch:W 5 "r")
17571 (parallel [(set (match_operand 0 "register_operand")
17572 (ashift (match_operand 1 "register_operand")
17573 (match_operand 2 "const_int_operand")))
17574 (clobber (reg:CC FLAGS_REG))])
17575 (parallel [(set (match_operand 3 "register_operand")
17576 (plus (match_dup 0)
17577 (match_operand 4 "x86_64_general_operand")))
17578 (clobber (reg:CC FLAGS_REG))])]
17579 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17580 /* Validate MODE for lea. */
17581 && ((!TARGET_PARTIAL_REG_STALL
17582 && (GET_MODE (operands[0]) == QImode
17583 || GET_MODE (operands[0]) == HImode))
17584 || GET_MODE (operands[0]) == SImode
17585 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17586 && (rtx_equal_p (operands[0], operands[3])
17587 || peep2_reg_dead_p (2, operands[0]))
17588 /* We reorder load and the shift. */
17589 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17590 [(set (match_dup 5) (match_dup 4))
17591 (set (match_dup 0) (match_dup 1))]
17593 enum machine_mode op1mode = GET_MODE (operands[1]);
17594 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17595 int scale = 1 << INTVAL (operands[2]);
17596 rtx index = gen_lowpart (word_mode, operands[1]);
17597 rtx base = gen_lowpart (word_mode, operands[5]);
17598 rtx dest = gen_lowpart (mode, operands[3]);
17600 operands[1] = gen_rtx_PLUS (word_mode, base,
17601 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17602 operands[5] = base;
17603 if (mode != word_mode)
17604 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17605 if (op1mode != word_mode)
17606 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17607 operands[0] = dest;
17610 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17611 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17612 ;; caught for use by garbage collectors and the like. Using an insn that
17613 ;; maps to SIGILL makes it more likely the program will rightfully die.
17614 ;; Keeping with tradition, "6" is in honor of #UD.
17615 (define_insn "trap"
17616 [(trap_if (const_int 1) (const_int 6))]
17618 { return ASM_SHORT "0x0b0f"; }
17619 [(set_attr "length" "2")])
17621 (define_expand "prefetch"
17622 [(prefetch (match_operand 0 "address_operand")
17623 (match_operand:SI 1 "const_int_operand")
17624 (match_operand:SI 2 "const_int_operand"))]
17625 "TARGET_PREFETCH_SSE || TARGET_PRFCHW"
17627 bool write = INTVAL (operands[1]) != 0;
17628 int locality = INTVAL (operands[2]);
17630 gcc_assert (IN_RANGE (locality, 0, 3));
17632 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17633 supported by SSE counterpart or the SSE prefetch is not available
17634 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17636 if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17637 operands[2] = GEN_INT (3);
17639 operands[1] = const0_rtx;
17642 (define_insn "*prefetch_sse"
17643 [(prefetch (match_operand 0 "address_operand" "p")
17645 (match_operand:SI 1 "const_int_operand"))]
17646 "TARGET_PREFETCH_SSE"
17648 static const char * const patterns[4] = {
17649 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17652 int locality = INTVAL (operands[1]);
17653 gcc_assert (IN_RANGE (locality, 0, 3));
17655 return patterns[locality];
17657 [(set_attr "type" "sse")
17658 (set_attr "atom_sse_attr" "prefetch")
17659 (set (attr "length_address")
17660 (symbol_ref "memory_address_length (operands[0], false)"))
17661 (set_attr "memory" "none")])
17663 (define_insn "*prefetch_3dnow"
17664 [(prefetch (match_operand 0 "address_operand" "p")
17665 (match_operand:SI 1 "const_int_operand" "n")
17669 if (INTVAL (operands[1]) == 0)
17670 return "prefetch\t%a0";
17672 return "prefetchw\t%a0";
17674 [(set_attr "type" "mmx")
17675 (set (attr "length_address")
17676 (symbol_ref "memory_address_length (operands[0], false)"))
17677 (set_attr "memory" "none")])
17679 (define_expand "stack_protect_set"
17680 [(match_operand 0 "memory_operand")
17681 (match_operand 1 "memory_operand")]
17682 "TARGET_SSP_TLS_GUARD"
17684 rtx (*insn)(rtx, rtx);
17686 #ifdef TARGET_THREAD_SSP_OFFSET
17687 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17688 insn = (TARGET_LP64
17689 ? gen_stack_tls_protect_set_di
17690 : gen_stack_tls_protect_set_si);
17692 insn = (TARGET_LP64
17693 ? gen_stack_protect_set_di
17694 : gen_stack_protect_set_si);
17697 emit_insn (insn (operands[0], operands[1]));
17701 (define_insn "stack_protect_set_<mode>"
17702 [(set (match_operand:PTR 0 "memory_operand" "=m")
17703 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17705 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17706 (clobber (reg:CC FLAGS_REG))]
17707 "TARGET_SSP_TLS_GUARD"
17708 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17709 [(set_attr "type" "multi")])
17711 (define_insn "stack_tls_protect_set_<mode>"
17712 [(set (match_operand:PTR 0 "memory_operand" "=m")
17713 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17714 UNSPEC_SP_TLS_SET))
17715 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17716 (clobber (reg:CC FLAGS_REG))]
17718 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17719 [(set_attr "type" "multi")])
17721 (define_expand "stack_protect_test"
17722 [(match_operand 0 "memory_operand")
17723 (match_operand 1 "memory_operand")
17725 "TARGET_SSP_TLS_GUARD"
17727 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17729 rtx (*insn)(rtx, rtx, rtx);
17731 #ifdef TARGET_THREAD_SSP_OFFSET
17732 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17733 insn = (TARGET_LP64
17734 ? gen_stack_tls_protect_test_di
17735 : gen_stack_tls_protect_test_si);
17737 insn = (TARGET_LP64
17738 ? gen_stack_protect_test_di
17739 : gen_stack_protect_test_si);
17742 emit_insn (insn (flags, operands[0], operands[1]));
17744 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17745 flags, const0_rtx, operands[2]));
17749 (define_insn "stack_protect_test_<mode>"
17750 [(set (match_operand:CCZ 0 "flags_reg_operand")
17751 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17752 (match_operand:PTR 2 "memory_operand" "m")]
17754 (clobber (match_scratch:PTR 3 "=&r"))]
17755 "TARGET_SSP_TLS_GUARD"
17756 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17757 [(set_attr "type" "multi")])
17759 (define_insn "stack_tls_protect_test_<mode>"
17760 [(set (match_operand:CCZ 0 "flags_reg_operand")
17761 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17762 (match_operand:PTR 2 "const_int_operand" "i")]
17763 UNSPEC_SP_TLS_TEST))
17764 (clobber (match_scratch:PTR 3 "=r"))]
17766 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17767 [(set_attr "type" "multi")])
17769 (define_insn "sse4_2_crc32<mode>"
17770 [(set (match_operand:SI 0 "register_operand" "=r")
17772 [(match_operand:SI 1 "register_operand" "0")
17773 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17775 "TARGET_SSE4_2 || TARGET_CRC32"
17776 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17777 [(set_attr "type" "sselog1")
17778 (set_attr "prefix_rep" "1")
17779 (set_attr "prefix_extra" "1")
17780 (set (attr "prefix_data16")
17781 (if_then_else (match_operand:HI 2)
17783 (const_string "*")))
17784 (set (attr "prefix_rex")
17785 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17787 (const_string "*")))
17788 (set_attr "mode" "SI")])
17790 (define_insn "sse4_2_crc32di"
17791 [(set (match_operand:DI 0 "register_operand" "=r")
17793 [(match_operand:DI 1 "register_operand" "0")
17794 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17796 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17797 "crc32{q}\t{%2, %0|%0, %2}"
17798 [(set_attr "type" "sselog1")
17799 (set_attr "prefix_rep" "1")
17800 (set_attr "prefix_extra" "1")
17801 (set_attr "mode" "DI")])
17803 (define_insn "rdpmc"
17804 [(set (match_operand:DI 0 "register_operand" "=A")
17805 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17809 [(set_attr "type" "other")
17810 (set_attr "length" "2")])
17812 (define_insn "rdpmc_rex64"
17813 [(set (match_operand:DI 0 "register_operand" "=a")
17814 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17816 (set (match_operand:DI 1 "register_operand" "=d")
17817 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17820 [(set_attr "type" "other")
17821 (set_attr "length" "2")])
17823 (define_insn "rdtsc"
17824 [(set (match_operand:DI 0 "register_operand" "=A")
17825 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17828 [(set_attr "type" "other")
17829 (set_attr "length" "2")])
17831 (define_insn "rdtsc_rex64"
17832 [(set (match_operand:DI 0 "register_operand" "=a")
17833 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17834 (set (match_operand:DI 1 "register_operand" "=d")
17835 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17838 [(set_attr "type" "other")
17839 (set_attr "length" "2")])
17841 (define_insn "rdtscp"
17842 [(set (match_operand:DI 0 "register_operand" "=A")
17843 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17844 (set (match_operand:SI 1 "register_operand" "=c")
17845 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17848 [(set_attr "type" "other")
17849 (set_attr "length" "3")])
17851 (define_insn "rdtscp_rex64"
17852 [(set (match_operand:DI 0 "register_operand" "=a")
17853 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17854 (set (match_operand:DI 1 "register_operand" "=d")
17855 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17856 (set (match_operand:SI 2 "register_operand" "=c")
17857 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17860 [(set_attr "type" "other")
17861 (set_attr "length" "3")])
17863 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17865 ;; FXSR, XSAVE and XSAVEOPT instructions
17867 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17869 (define_insn "fxsave"
17870 [(set (match_operand:BLK 0 "memory_operand" "=m")
17871 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17874 [(set_attr "type" "other")
17875 (set_attr "memory" "store")
17876 (set (attr "length")
17877 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17879 (define_insn "fxsave64"
17880 [(set (match_operand:BLK 0 "memory_operand" "=m")
17881 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17882 "TARGET_64BIT && TARGET_FXSR"
17884 [(set_attr "type" "other")
17885 (set_attr "memory" "store")
17886 (set (attr "length")
17887 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17889 (define_insn "fxrstor"
17890 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17894 [(set_attr "type" "other")
17895 (set_attr "memory" "load")
17896 (set (attr "length")
17897 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17899 (define_insn "fxrstor64"
17900 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17901 UNSPECV_FXRSTOR64)]
17902 "TARGET_64BIT && TARGET_FXSR"
17904 [(set_attr "type" "other")
17905 (set_attr "memory" "load")
17906 (set (attr "length")
17907 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17909 (define_int_iterator ANY_XSAVE
17911 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17913 (define_int_iterator ANY_XSAVE64
17915 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17917 (define_int_attr xsave
17918 [(UNSPECV_XSAVE "xsave")
17919 (UNSPECV_XSAVE64 "xsave64")
17920 (UNSPECV_XSAVEOPT "xsaveopt")
17921 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17923 (define_insn "<xsave>"
17924 [(set (match_operand:BLK 0 "memory_operand" "=m")
17925 (unspec_volatile:BLK
17926 [(match_operand:DI 1 "register_operand" "A")]
17928 "!TARGET_64BIT && TARGET_XSAVE"
17930 [(set_attr "type" "other")
17931 (set_attr "memory" "store")
17932 (set (attr "length")
17933 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17935 (define_insn "<xsave>_rex64"
17936 [(set (match_operand:BLK 0 "memory_operand" "=m")
17937 (unspec_volatile:BLK
17938 [(match_operand:SI 1 "register_operand" "a")
17939 (match_operand:SI 2 "register_operand" "d")]
17941 "TARGET_64BIT && TARGET_XSAVE"
17943 [(set_attr "type" "other")
17944 (set_attr "memory" "store")
17945 (set (attr "length")
17946 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17948 (define_insn "<xsave>"
17949 [(set (match_operand:BLK 0 "memory_operand" "=m")
17950 (unspec_volatile:BLK
17951 [(match_operand:SI 1 "register_operand" "a")
17952 (match_operand:SI 2 "register_operand" "d")]
17954 "TARGET_64BIT && TARGET_XSAVE"
17956 [(set_attr "type" "other")
17957 (set_attr "memory" "store")
17958 (set (attr "length")
17959 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17961 (define_insn "xrstor"
17962 [(unspec_volatile:BLK
17963 [(match_operand:BLK 0 "memory_operand" "m")
17964 (match_operand:DI 1 "register_operand" "A")]
17966 "!TARGET_64BIT && TARGET_XSAVE"
17968 [(set_attr "type" "other")
17969 (set_attr "memory" "load")
17970 (set (attr "length")
17971 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17973 (define_insn "xrstor_rex64"
17974 [(unspec_volatile:BLK
17975 [(match_operand:BLK 0 "memory_operand" "m")
17976 (match_operand:SI 1 "register_operand" "a")
17977 (match_operand:SI 2 "register_operand" "d")]
17979 "TARGET_64BIT && TARGET_XSAVE"
17981 [(set_attr "type" "other")
17982 (set_attr "memory" "load")
17983 (set (attr "length")
17984 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17986 (define_insn "xrstor64"
17987 [(unspec_volatile:BLK
17988 [(match_operand:BLK 0 "memory_operand" "m")
17989 (match_operand:SI 1 "register_operand" "a")
17990 (match_operand:SI 2 "register_operand" "d")]
17992 "TARGET_64BIT && TARGET_XSAVE"
17994 [(set_attr "type" "other")
17995 (set_attr "memory" "load")
17996 (set (attr "length")
17997 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17999 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18001 ;; LWP instructions
18003 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18005 (define_expand "lwp_llwpcb"
18006 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18007 UNSPECV_LLWP_INTRINSIC)]
18010 (define_insn "*lwp_llwpcb<mode>1"
18011 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18012 UNSPECV_LLWP_INTRINSIC)]
18015 [(set_attr "type" "lwp")
18016 (set_attr "mode" "<MODE>")
18017 (set_attr "length" "5")])
18019 (define_expand "lwp_slwpcb"
18020 [(set (match_operand 0 "register_operand" "=r")
18021 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18026 insn = (Pmode == DImode
18028 : gen_lwp_slwpcbsi);
18030 emit_insn (insn (operands[0]));
18034 (define_insn "lwp_slwpcb<mode>"
18035 [(set (match_operand:P 0 "register_operand" "=r")
18036 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18039 [(set_attr "type" "lwp")
18040 (set_attr "mode" "<MODE>")
18041 (set_attr "length" "5")])
18043 (define_expand "lwp_lwpval<mode>3"
18044 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18045 (match_operand:SI 2 "nonimmediate_operand" "rm")
18046 (match_operand:SI 3 "const_int_operand" "i")]
18047 UNSPECV_LWPVAL_INTRINSIC)]
18049 ;; Avoid unused variable warning.
18050 "(void) operands[0];")
18052 (define_insn "*lwp_lwpval<mode>3_1"
18053 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18054 (match_operand:SI 1 "nonimmediate_operand" "rm")
18055 (match_operand:SI 2 "const_int_operand" "i")]
18056 UNSPECV_LWPVAL_INTRINSIC)]
18058 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18059 [(set_attr "type" "lwp")
18060 (set_attr "mode" "<MODE>")
18061 (set (attr "length")
18062 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18064 (define_expand "lwp_lwpins<mode>3"
18065 [(set (reg:CCC FLAGS_REG)
18066 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18067 (match_operand:SI 2 "nonimmediate_operand" "rm")
18068 (match_operand:SI 3 "const_int_operand" "i")]
18069 UNSPECV_LWPINS_INTRINSIC))
18070 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18071 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18074 (define_insn "*lwp_lwpins<mode>3_1"
18075 [(set (reg:CCC FLAGS_REG)
18076 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18077 (match_operand:SI 1 "nonimmediate_operand" "rm")
18078 (match_operand:SI 2 "const_int_operand" "i")]
18079 UNSPECV_LWPINS_INTRINSIC))]
18081 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18082 [(set_attr "type" "lwp")
18083 (set_attr "mode" "<MODE>")
18084 (set (attr "length")
18085 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18087 (define_int_iterator RDFSGSBASE
18091 (define_int_iterator WRFSGSBASE
18095 (define_int_attr fsgs
18096 [(UNSPECV_RDFSBASE "fs")
18097 (UNSPECV_RDGSBASE "gs")
18098 (UNSPECV_WRFSBASE "fs")
18099 (UNSPECV_WRGSBASE "gs")])
18101 (define_insn "rd<fsgs>base<mode>"
18102 [(set (match_operand:SWI48 0 "register_operand" "=r")
18103 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18104 "TARGET_64BIT && TARGET_FSGSBASE"
18106 [(set_attr "type" "other")
18107 (set_attr "prefix_extra" "2")])
18109 (define_insn "wr<fsgs>base<mode>"
18110 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18112 "TARGET_64BIT && TARGET_FSGSBASE"
18114 [(set_attr "type" "other")
18115 (set_attr "prefix_extra" "2")])
18117 (define_insn "rdrand<mode>_1"
18118 [(set (match_operand:SWI248 0 "register_operand" "=r")
18119 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18120 (set (reg:CCC FLAGS_REG)
18121 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18124 [(set_attr "type" "other")
18125 (set_attr "prefix_extra" "1")])
18127 (define_insn "rdseed<mode>_1"
18128 [(set (match_operand:SWI248 0 "register_operand" "=r")
18129 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18130 (set (reg:CCC FLAGS_REG)
18131 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18134 [(set_attr "type" "other")
18135 (set_attr "prefix_extra" "1")])
18137 (define_expand "pause"
18138 [(set (match_dup 0)
18139 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18142 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18143 MEM_VOLATILE_P (operands[0]) = 1;
18146 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18147 ;; They have the same encoding.
18148 (define_insn "*pause"
18149 [(set (match_operand:BLK 0)
18150 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18153 [(set_attr "length" "2")
18154 (set_attr "memory" "unknown")])
18156 (define_expand "xbegin"
18157 [(set (match_operand:SI 0 "register_operand")
18158 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18161 rtx label = gen_label_rtx ();
18163 /* xbegin is emitted as jump_insn, so reload won't be able
18164 to reload its operand. Force the value into AX hard register. */
18165 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18166 emit_move_insn (ax_reg, constm1_rtx);
18168 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18170 emit_label (label);
18171 LABEL_NUSES (label) = 1;
18173 emit_move_insn (operands[0], ax_reg);
18178 (define_insn "xbegin_1"
18180 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18182 (label_ref (match_operand 1))
18184 (set (match_operand:SI 0 "register_operand" "+a")
18185 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18188 [(set_attr "type" "other")
18189 (set_attr "length" "6")])
18191 (define_insn "xend"
18192 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18195 [(set_attr "type" "other")
18196 (set_attr "length" "3")])
18198 (define_insn "xabort"
18199 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18203 [(set_attr "type" "other")
18204 (set_attr "length" "3")])
18206 (define_expand "xtest"
18207 [(set (match_operand:QI 0 "register_operand")
18208 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18211 emit_insn (gen_xtest_1 ());
18213 ix86_expand_setcc (operands[0], NE,
18214 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18218 (define_insn "xtest_1"
18219 [(set (reg:CCZ FLAGS_REG)
18220 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18223 [(set_attr "type" "other")
18224 (set_attr "length" "3")])
18226 ;; MPX instructions
18228 (define_expand "<mode>_mk"
18229 [(set (match_operand:BND 0 "register_operand")
18233 [(match_operand:<bnd_ptr> 1 "register_operand")
18234 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18238 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18240 UNSPEC_BNDMK_ADDR);
18243 (define_insn "*<mode>_mk"
18244 [(set (match_operand:BND 0 "register_operand" "=B")
18246 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18248 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18249 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18250 UNSPEC_BNDMK_ADDR)])]
18253 "bndmk\t{%3, %0|%0, %3}"
18254 [(set_attr "type" "mpxmk")])
18256 (define_expand "mov<mode>"
18257 [(set (match_operand:BND 0 "general_operand")
18258 (match_operand:BND 1 "general_operand"))]
18261 ix86_expand_move (<MODE>mode, operands);DONE;
18264 (define_insn "*mov<mode>_internal_mpx"
18265 [(set (match_operand:BND 0 "nonimmediate_operand" "=B,m")
18266 (match_operand:BND 1 "general_operand" "Bm,B"))]
18268 "bndmov\t{%1, %0|%0, %1}"
18269 [(set_attr "type" "mpxmov")])
18271 (define_expand "<mode>_<bndcheck>"
18272 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18273 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18275 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18278 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18279 MEM_VOLATILE_P (operands[2]) = 1;
18282 (define_insn "*<mode>_<bndcheck>"
18283 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "B")
18284 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "p")] BNDCHECK)
18285 (set (match_operand:BLK 2 "bnd_mem_operator")
18286 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18288 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18289 [(set_attr "type" "mpxchk")])
18291 (define_expand "<mode>_ldx"
18292 [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18296 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18297 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18299 (use (mem:BLK (match_dup 1)))])]
18302 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18304 UNSPEC_BNDLDX_ADDR);
18307 (define_insn "*<mode>_ldx"
18308 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=B")
18310 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18312 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18313 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18314 UNSPEC_BNDLDX_ADDR)])]
18316 (use (mem:BLK (match_dup 1)))])]
18318 "bndldx\t{%3, %0|%0, %3}"
18319 [(set_attr "type" "mpxld")])
18321 (define_expand "<mode>_stx"
18322 [(parallel [(unspec [(mem:<bnd_ptr>
18324 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18325 (match_operand:<bnd_ptr> 1 "register_operand")]))
18326 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18328 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18331 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18333 UNSPEC_BNDLDX_ADDR);
18334 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18335 MEM_VOLATILE_P (operands[4]) = 1;
18338 (define_insn "*<mode>_stx"
18339 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18341 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18342 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18343 UNSPEC_BNDLDX_ADDR)])
18344 (match_operand:BND 2 "register_operand" "B")] UNSPEC_BNDSTX)
18345 (set (match_operand:BLK 4 "bnd_mem_operator")
18346 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18348 "bndstx\t{%2, %3|%3, %2}"
18349 [(set_attr "type" "mpxst")])
18353 (include "sync.md")